Home | History | Annotate | Line # | Download | only in dev
fb.c revision 1.33
      1  1.33   tsutsui /*	$NetBSD: fb.c,v 1.33 2023/10/28 21:06:05 tsutsui Exp $	*/
      2   1.5    tsubai 
      3   1.5    tsubai /*-
      4   1.5    tsubai  * Copyright (c) 2000 Tsubai Masanari.  All rights reserved.
      5   1.1    tsubai  *
      6   1.1    tsubai  * Redistribution and use in source and binary forms, with or without
      7   1.1    tsubai  * modification, are permitted provided that the following conditions
      8   1.1    tsubai  * are met:
      9   1.1    tsubai  * 1. Redistributions of source code must retain the above copyright
     10   1.1    tsubai  *    notice, this list of conditions and the following disclaimer.
     11   1.1    tsubai  * 2. Redistributions in binary form must reproduce the above copyright
     12   1.1    tsubai  *    notice, this list of conditions and the following disclaimer in the
     13   1.1    tsubai  *    documentation and/or other materials provided with the distribution.
     14   1.5    tsubai  * 3. The name of the author may not be used to endorse or promote products
     15   1.5    tsubai  *    derived from this software without specific prior written permission.
     16   1.1    tsubai  *
     17   1.5    tsubai  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18   1.5    tsubai  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19   1.5    tsubai  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20   1.5    tsubai  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21   1.5    tsubai  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22   1.5    tsubai  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23   1.5    tsubai  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24   1.5    tsubai  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25   1.5    tsubai  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26   1.5    tsubai  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27   1.1    tsubai  */
     28  1.17     lukem 
     29  1.17     lukem #include <sys/cdefs.h>
     30  1.33   tsutsui __KERNEL_RCSID(0, "$NetBSD: fb.c,v 1.33 2023/10/28 21:06:05 tsutsui Exp $");
     31   1.1    tsubai 
     32   1.1    tsubai #include <sys/param.h>
     33   1.1    tsubai #include <sys/device.h>
     34   1.5    tsubai #include <sys/ioctl.h>
     35  1.27   thorpej #include <sys/kmem.h>
     36   1.1    tsubai #include <sys/systm.h>
     37   1.1    tsubai 
     38   1.5    tsubai #include <uvm/uvm_extern.h>
     39   1.5    tsubai 
     40   1.5    tsubai #include <machine/adrsmap.h>
     41  1.16   tsutsui 
     42  1.16   tsutsui #include <newsmips/dev/hbvar.h>
     43   1.1    tsubai 
     44   1.5    tsubai #include <dev/wscons/wsconsio.h>
     45   1.5    tsubai #include <dev/wscons/wsdisplayvar.h>
     46   1.5    tsubai #include <dev/rasops/rasops.h>
     47   1.5    tsubai 
     48   1.5    tsubai struct fb_devconfig {
     49  1.31   tsutsui 	uint8_t *dc_fbbase;		/* VRAM base address */
     50   1.5    tsubai 	struct rasops_info dc_ri;
     51   1.5    tsubai };
     52   1.1    tsubai 
     53   1.1    tsubai struct fb_softc {
     54  1.24   tsutsui 	device_t sc_dev;
     55   1.5    tsubai 	struct fb_devconfig *sc_dc;
     56   1.5    tsubai 	int sc_nscreens;
     57   1.1    tsubai };
     58   1.1    tsubai 
     59  1.30   tsutsui static int fb_match(device_t, cfdata_t, void *);
     60  1.30   tsutsui static void fb_attach(device_t, device_t, void *);
     61   1.5    tsubai 
     62  1.30   tsutsui static int fb_common_init(struct fb_devconfig *);
     63  1.30   tsutsui static int fb_is_console(void);
     64   1.5    tsubai 
     65  1.30   tsutsui static int fb_ioctl(void *, void *, u_long, void *, int, struct lwp *);
     66  1.30   tsutsui static paddr_t fb_mmap(void *, void *, off_t, int);
     67  1.30   tsutsui static int fb_alloc_screen(void *, const struct wsscreen_descr *, void **,
     68  1.30   tsutsui     int *, int *, long *);
     69  1.30   tsutsui static void fb_free_screen(void *, void *);
     70  1.30   tsutsui static int fb_show_screen(void *, void *, int, void (*)(void *, int, int),
     71  1.30   tsutsui     void *);
     72   1.5    tsubai 
     73   1.5    tsubai void fb_cnattach(void);
     74   1.5    tsubai 
     75   1.9      matt static void fb253_init(void);
     76   1.1    tsubai 
     77  1.24   tsutsui CFATTACH_DECL_NEW(fb, sizeof(struct fb_softc),
     78  1.14   thorpej     fb_match, fb_attach, NULL, NULL);
     79   1.5    tsubai 
     80  1.30   tsutsui static struct fb_devconfig fb_console_dc;
     81   1.5    tsubai 
     82  1.30   tsutsui static struct wsdisplay_accessops fb_accessops = {
     83  1.32   tsutsui 	.ioctl        = fb_ioctl,
     84  1.32   tsutsui 	.mmap         = fb_mmap,
     85  1.32   tsutsui 	.alloc_screen = fb_alloc_screen,
     86  1.32   tsutsui 	.free_screen  = fb_free_screen,
     87  1.32   tsutsui 	.show_screen  = fb_show_screen,
     88  1.32   tsutsui 	.load_font    = NULL
     89   1.5    tsubai };
     90   1.5    tsubai 
     91  1.30   tsutsui static struct wsscreen_descr fb_stdscreen = {
     92  1.32   tsutsui 	.name = "std",
     93  1.32   tsutsui 	.ncols = 0,
     94  1.32   tsutsui 	.nrows = 0,
     95  1.32   tsutsui 	.textops = NULL,
     96  1.32   tsutsui 	.fontwidth = 0,
     97  1.32   tsutsui 	.fontheight = 0,
     98  1.32   tsutsui 	.capabilities = WSSCREEN_REVERSE
     99   1.1    tsubai };
    100   1.1    tsubai 
    101  1.30   tsutsui static const struct wsscreen_descr *fb_scrlist[] = {
    102   1.5    tsubai 	&fb_stdscreen
    103   1.5    tsubai };
    104   1.5    tsubai 
    105  1.30   tsutsui static struct wsscreen_list fb_screenlist = {
    106  1.32   tsutsui 	.nscreens = __arraycount(fb_scrlist),
    107  1.32   tsutsui 	.screens  = fb_scrlist
    108   1.5    tsubai };
    109   1.1    tsubai 
    110  1.24   tsutsui #define NWB253_VRAM   ((uint8_t *) 0x88000000)
    111  1.24   tsutsui #define NWB253_CTLREG ((uint16_t *)0xb8ff0000)
    112  1.24   tsutsui #define NWB253_CRTREG ((uint16_t *)0xb8fe0000)
    113   1.1    tsubai 
    114  1.20   tsutsui static const char *devname[8] = { "NWB-512", "NWB-518", "NWE-501" }; /* XXX ? */
    115   1.5    tsubai 
    116  1.30   tsutsui static int
    117  1.24   tsutsui fb_match(device_t parent, cfdata_t cf, void *aux)
    118   1.1    tsubai {
    119  1.16   tsutsui 	struct hb_attach_args *ha = aux;
    120   1.1    tsubai 
    121  1.16   tsutsui 	if (strcmp(ha->ha_name, "fb") != 0)
    122   1.1    tsubai 		return 0;
    123   1.1    tsubai 
    124  1.16   tsutsui 	if (hb_badaddr(NWB253_CTLREG, 2) || hb_badaddr(NWB253_CRTREG, 2))
    125   1.5    tsubai 		return 0;
    126  1.24   tsutsui 	if ((*(volatile uint16_t *)NWB253_CTLREG & 7) != 4)
    127   1.1    tsubai 		return 0;
    128   1.1    tsubai 
    129   1.1    tsubai 	return 1;
    130   1.1    tsubai }
    131   1.1    tsubai 
    132  1.30   tsutsui static void
    133  1.24   tsutsui fb_attach(device_t parent, device_t self, void *aux)
    134   1.1    tsubai {
    135  1.24   tsutsui 	struct fb_softc *sc = device_private(self);
    136   1.5    tsubai 	struct wsemuldisplaydev_attach_args waa;
    137   1.5    tsubai 	struct fb_devconfig *dc;
    138   1.5    tsubai 	struct rasops_info *ri;
    139   1.5    tsubai 	int console;
    140  1.31   tsutsui 	volatile uint16_t *ctlreg = NWB253_CTLREG;
    141   1.5    tsubai 	int id;
    142   1.5    tsubai 
    143  1.24   tsutsui 	sc->sc_dev = self;
    144  1.24   tsutsui 
    145   1.5    tsubai 	console = fb_is_console();
    146   1.5    tsubai 
    147   1.5    tsubai 	if (console) {
    148   1.5    tsubai 		dc = &fb_console_dc;
    149   1.5    tsubai 		ri = &dc->dc_ri;
    150  1.25   tsutsui 		ri->ri_flg &= ~RI_NO_AUTO;
    151   1.5    tsubai 		sc->sc_nscreens = 1;
    152   1.5    tsubai 	} else {
    153  1.27   thorpej 		dc = kmem_zalloc(sizeof(struct fb_devconfig), KM_SLEEP);
    154   1.5    tsubai 
    155   1.5    tsubai 		dc->dc_fbbase = NWB253_VRAM;
    156   1.5    tsubai 		fb_common_init(dc);
    157   1.5    tsubai 		ri = &dc->dc_ri;
    158   1.5    tsubai 
    159   1.5    tsubai 		/* clear screen */
    160   1.5    tsubai 		(*ri->ri_ops.eraserows)(ri, 0, ri->ri_rows, 0);
    161   1.5    tsubai 
    162   1.8    tsubai 		fb253_init();
    163   1.5    tsubai 	}
    164   1.5    tsubai 	sc->sc_dc = dc;
    165   1.5    tsubai 
    166   1.5    tsubai 	id = (*ctlreg >> 8) & 0xf;
    167  1.24   tsutsui 	aprint_normal(": %s, %d x %d, %dbpp\n", devname[id],
    168   1.5    tsubai 	    ri->ri_width, ri->ri_height, ri->ri_depth);
    169   1.5    tsubai 
    170   1.5    tsubai 	waa.console = console;
    171   1.5    tsubai 	waa.scrdata = &fb_screenlist;
    172   1.5    tsubai 	waa.accessops = &fb_accessops;
    173   1.5    tsubai 	waa.accesscookie = sc;
    174   1.1    tsubai 
    175  1.29   thorpej 	config_found(self, &waa, wsemuldisplaydevprint, CFARGS_NONE);
    176   1.1    tsubai }
    177   1.1    tsubai 
    178  1.30   tsutsui static int
    179  1.19   tsutsui fb_common_init(struct fb_devconfig *dc)
    180   1.1    tsubai {
    181   1.5    tsubai 	struct rasops_info *ri = &dc->dc_ri;
    182  1.24   tsutsui 	volatile uint16_t *ctlreg = NWB253_CTLREG;
    183   1.5    tsubai 	int id;
    184   1.5    tsubai 	int width, height, xoff, yoff, cols, rows;
    185   1.5    tsubai 
    186   1.5    tsubai 	id = (*ctlreg >> 8) & 0xf;
    187   1.5    tsubai 
    188   1.5    tsubai 	/* initialize rasops */
    189   1.5    tsubai 	switch (id) {
    190   1.5    tsubai 	case 0:
    191   1.5    tsubai 		width = 816;
    192   1.5    tsubai 		height = 1024;
    193   1.5    tsubai 		break;
    194   1.5    tsubai 	case 1:
    195   1.5    tsubai 	case 2:
    196  1.18       dsl 	default:
    197   1.5    tsubai 		width = 1024;
    198   1.5    tsubai 		height = 768;
    199   1.5    tsubai 		break;
    200   1.1    tsubai 	}
    201   1.1    tsubai 
    202   1.5    tsubai 	ri->ri_width = width;
    203   1.5    tsubai 	ri->ri_height = height;
    204   1.5    tsubai 	ri->ri_depth = 1;
    205   1.5    tsubai 	ri->ri_stride = 2048 / 8;
    206   1.5    tsubai 	ri->ri_bits = dc->dc_fbbase;
    207   1.5    tsubai 	ri->ri_flg = RI_FULLCLEAR;
    208  1.25   tsutsui 	if (dc == &fb_console_dc)
    209  1.25   tsutsui 		ri->ri_flg |= RI_NO_AUTO;
    210   1.5    tsubai 
    211   1.5    tsubai 	rasops_init(ri, 24, 80);
    212   1.5    tsubai 	rows = (height - 2) / ri->ri_font->fontheight;
    213   1.5    tsubai 	cols = ((width - 2) / ri->ri_font->fontwidth) & ~7;
    214   1.5    tsubai 	xoff = ((width - cols * ri->ri_font->fontwidth) / 2 / 8) & ~3;
    215   1.5    tsubai 	yoff = (height - rows * ri->ri_font->fontheight) / 2;
    216   1.5    tsubai 	rasops_reconfig(ri, rows, cols);
    217  1.15   tsutsui 
    218   1.5    tsubai 	ri->ri_xorigin = xoff;
    219   1.5    tsubai 	ri->ri_yorigin = yoff;
    220   1.5    tsubai 	ri->ri_bits = dc->dc_fbbase + xoff + ri->ri_stride * yoff;
    221  1.15   tsutsui 
    222   1.5    tsubai 	fb_stdscreen.nrows = ri->ri_rows;
    223  1.33   tsutsui 	fb_stdscreen.ncols = ri->ri_cols;
    224   1.5    tsubai 	fb_stdscreen.textops = &ri->ri_ops;
    225   1.5    tsubai 	fb_stdscreen.capabilities = ri->ri_caps;
    226   1.1    tsubai 
    227   1.1    tsubai 	return 0;
    228   1.1    tsubai }
    229   1.1    tsubai 
    230  1.30   tsutsui static int
    231  1.19   tsutsui fb_is_console(void)
    232   1.1    tsubai {
    233   1.5    tsubai 	volatile u_int *dipsw = (void *)DIP_SWITCH;
    234   1.1    tsubai 
    235   1.5    tsubai 	if (*dipsw & 7)					/* XXX right? */
    236   1.5    tsubai 		return 1;
    237   1.1    tsubai 
    238   1.1    tsubai 	return 0;
    239   1.1    tsubai }
    240   1.1    tsubai 
    241  1.30   tsutsui static int
    242  1.23  christos fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
    243   1.1    tsubai {
    244   1.5    tsubai 	struct fb_softc *sc = v;
    245   1.5    tsubai 	struct fb_devconfig *dc = sc->sc_dc;
    246   1.5    tsubai 	struct wsdisplay_fbinfo *wdf;
    247   1.1    tsubai 
    248   1.5    tsubai 	switch (cmd) {
    249   1.5    tsubai 	case WSDISPLAYIO_GTYPE:
    250   1.5    tsubai 		*(int *)data = WSDISPLAY_TYPE_UNKNOWN;	/* XXX */
    251   1.5    tsubai 		return 0;
    252   1.1    tsubai 
    253   1.5    tsubai 	case WSDISPLAYIO_GINFO:
    254   1.5    tsubai 		wdf = (void *)data;
    255   1.5    tsubai 		wdf->height = dc->dc_ri.ri_height;
    256   1.5    tsubai 		wdf->width = dc->dc_ri.ri_width;
    257   1.5    tsubai 		wdf->depth = dc->dc_ri.ri_depth;
    258   1.5    tsubai 		wdf->cmsize = 2;
    259   1.5    tsubai 		return 0;
    260   1.1    tsubai 
    261  1.26   tsutsui 	case WSDISPLAYIO_LINEBYTES:
    262  1.26   tsutsui 		*(u_int *)data = dc->dc_ri.ri_stride;
    263  1.26   tsutsui 		return 0;
    264  1.26   tsutsui 
    265   1.5    tsubai 	case WSDISPLAYIO_SVIDEO:
    266   1.5    tsubai 		if (*(int *)data == WSDISPLAYIO_VIDEO_OFF) {
    267  1.31   tsutsui 			volatile uint16_t *ctlreg = NWB253_CTLREG;
    268   1.5    tsubai 			*ctlreg = 0;			/* stop crtc */
    269   1.8    tsubai 		} else
    270   1.8    tsubai 			fb253_init();
    271   1.5    tsubai 		return 0;
    272   1.1    tsubai 
    273   1.5    tsubai 	case WSDISPLAYIO_GETCMAP:
    274   1.5    tsubai 	case WSDISPLAYIO_PUTCMAP:
    275  1.11   thorpej 		break;
    276   1.1    tsubai 	}
    277  1.10    atatat 	return EPASSTHROUGH;
    278   1.1    tsubai }
    279   1.1    tsubai 
    280  1.30   tsutsui static paddr_t
    281  1.22      jmmv fb_mmap(void *v, void *vs, off_t offset, int prot)
    282   1.1    tsubai {
    283   1.5    tsubai 	struct fb_softc *sc = v;
    284   1.5    tsubai 	struct fb_devconfig *dc = sc->sc_dc;
    285   1.1    tsubai 
    286   1.6    tsubai 	if (offset >= 2048 * 2048 / 8 || offset < 0)
    287   1.1    tsubai 		return -1;
    288   1.1    tsubai 
    289   1.5    tsubai 	return mips_btop((int)dc->dc_fbbase + offset);
    290   1.5    tsubai }
    291   1.1    tsubai 
    292  1.30   tsutsui static int
    293  1.19   tsutsui fb_alloc_screen(void *v, const struct wsscreen_descr *scrdesc, void **cookiep,
    294  1.19   tsutsui     int *ccolp, int *crowp, long *attrp)
    295   1.5    tsubai {
    296   1.5    tsubai 	struct fb_softc *sc = v;
    297   1.5    tsubai 	struct rasops_info *ri = &sc->sc_dc->dc_ri;
    298   1.5    tsubai 	long defattr;
    299   1.5    tsubai 
    300   1.5    tsubai 	if (sc->sc_nscreens > 0)
    301   1.5    tsubai 		return ENOMEM;
    302   1.5    tsubai 
    303   1.5    tsubai 	*cookiep = ri;
    304   1.5    tsubai 	*ccolp = *crowp = 0;
    305  1.12  junyoung 	(*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
    306   1.5    tsubai 	*attrp = defattr;
    307   1.5    tsubai 	sc->sc_nscreens++;
    308   1.1    tsubai 
    309   1.5    tsubai 	return 0;
    310   1.1    tsubai }
    311   1.1    tsubai 
    312  1.30   tsutsui static void
    313  1.19   tsutsui fb_free_screen(void *v, void *cookie)
    314   1.1    tsubai {
    315   1.5    tsubai 	struct fb_softc *sc = v;
    316   1.5    tsubai 
    317   1.5    tsubai 	if (sc->sc_dc == &fb_console_dc)
    318  1.24   tsutsui 		panic("%s: console", __func__);
    319   1.5    tsubai 
    320   1.5    tsubai 	sc->sc_nscreens--;
    321   1.1    tsubai }
    322   1.1    tsubai 
    323  1.30   tsutsui static int
    324  1.19   tsutsui fb_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int),
    325  1.19   tsutsui     void *cbarg)
    326   1.1    tsubai {
    327  1.19   tsutsui 
    328   1.5    tsubai 	return 0;
    329   1.1    tsubai }
    330   1.1    tsubai 
    331   1.5    tsubai void
    332  1.19   tsutsui fb_cnattach(void)
    333   1.1    tsubai {
    334   1.5    tsubai 	struct fb_devconfig *dc = &fb_console_dc;
    335   1.5    tsubai 	struct rasops_info *ri = &dc->dc_ri;
    336   1.5    tsubai 	long defattr;
    337   1.5    tsubai 
    338   1.5    tsubai 	if (!fb_is_console())
    339   1.5    tsubai 		return;
    340   1.5    tsubai 
    341   1.5    tsubai 	dc->dc_fbbase = NWB253_VRAM;
    342   1.5    tsubai 	fb_common_init(dc);
    343   1.5    tsubai 
    344  1.12  junyoung 	(*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
    345   1.5    tsubai 	wsdisplay_cnattach(&fb_stdscreen, ri, 0, ri->ri_rows - 1, defattr);
    346   1.5    tsubai }
    347   1.5    tsubai 
    348  1.19   tsutsui static const uint8_t
    349   1.5    tsubai nwp512_data1[] = {
    350   1.5    tsubai 	0x00, 0x44,
    351   1.5    tsubai 	0x01, 0x33,
    352   1.5    tsubai 	0x02, 0x3c,
    353   1.5    tsubai 	0x03, 0x38,
    354   1.5    tsubai 	0x04, 0x84,
    355   1.5    tsubai 	0x05, 0x03,
    356   1.5    tsubai 	0x06, 0x80,
    357   1.5    tsubai 	0x07, 0x80,
    358   1.5    tsubai 	0x08, 0x10,
    359   1.5    tsubai 	0x09, 0x07,
    360   1.5    tsubai 	0x0a, 0x20,
    361   1.5    tsubai 	0x0c, 0x00,
    362   1.5    tsubai 	0x0d, 0x00,
    363   1.5    tsubai 	0x1b, 0x03
    364   1.5    tsubai };
    365   1.1    tsubai 
    366  1.19   tsutsui static const uint8_t
    367   1.5    tsubai nwp512_data2[] = {
    368   1.5    tsubai 	0x1e, 0x08,
    369   1.5    tsubai 	0x20, 0x08,
    370   1.5    tsubai 	0x21, 0x0d
    371   1.5    tsubai };
    372   1.1    tsubai 
    373  1.19   tsutsui static const uint8_t
    374   1.5    tsubai nwp518_data1[] = {
    375   1.5    tsubai 	0x00, 0x52,
    376   1.5    tsubai 	0x01, 0x40,
    377   1.5    tsubai 	0x02, 0x4a,
    378   1.5    tsubai 	0x03, 0x49,
    379   1.5    tsubai 	0x04, 0x63,
    380   1.5    tsubai 	0x05, 0x02,
    381   1.5    tsubai 	0x06, 0x60,
    382   1.5    tsubai 	0x07, 0x60,
    383   1.5    tsubai 	0x08, 0x10,
    384   1.5    tsubai 	0x09, 0x07,
    385   1.5    tsubai 	0x0a, 0x20,
    386   1.5    tsubai 	0x0c, 0x00,
    387   1.5    tsubai 	0x0d, 0x00,
    388   1.5    tsubai 	0x1b, 0x04
    389   1.5    tsubai };
    390   1.1    tsubai 
    391  1.19   tsutsui static const uint8_t
    392   1.5    tsubai nwp518_data2[] = {
    393   1.5    tsubai 	0x1e, 0x08,
    394   1.5    tsubai 	0x20, 0x00,
    395   1.5    tsubai 	0x21, 0x00
    396   1.5    tsubai };
    397   1.1    tsubai 
    398  1.19   tsutsui static const uint8_t
    399   1.5    tsubai nwe501_data1[] = {
    400   1.5    tsubai 	0x00, 0x4b,
    401   1.5    tsubai 	0x01, 0x40,
    402   1.5    tsubai 	0x02, 0x4a,
    403   1.5    tsubai 	0x03, 0x43,
    404   1.5    tsubai 	0x04, 0x64,
    405   1.5    tsubai 	0x05, 0x02,
    406   1.5    tsubai 	0x06, 0x60,
    407   1.5    tsubai 	0x07, 0x60,
    408   1.5    tsubai 	0x08, 0x10,
    409   1.5    tsubai 	0x09, 0x07,
    410   1.5    tsubai 	0x0a, 0x20,
    411   1.5    tsubai 	0x0c, 0x00,
    412   1.5    tsubai 	0x0d, 0x00,
    413   1.5    tsubai 	0x1b, 0x04
    414   1.5    tsubai };
    415   1.1    tsubai 
    416  1.19   tsutsui static const uint8_t
    417   1.5    tsubai nwe501_data2[] = {
    418   1.5    tsubai 	0x1e, 0x08,
    419   1.5    tsubai 	0x20, 0x00,
    420   1.5    tsubai 	0x21, 0x00
    421   1.5    tsubai };
    422   1.1    tsubai 
    423  1.19   tsutsui static const uint8_t
    424   1.5    tsubai *crtc_data[3][2] = {
    425   1.5    tsubai 	{ nwp512_data1, nwp512_data2 },
    426   1.5    tsubai 	{ nwp518_data1, nwp518_data2 },
    427   1.5    tsubai 	{ nwe501_data1, nwe501_data2 }
    428   1.5    tsubai };
    429   1.1    tsubai 
    430   1.1    tsubai static void
    431   1.9      matt fb253_init(void)
    432   1.1    tsubai {
    433  1.24   tsutsui 	volatile uint16_t *ctlreg = NWB253_CTLREG;
    434  1.24   tsutsui 	volatile uint16_t *crtreg = NWB253_CRTREG;
    435   1.8    tsubai 	int id = (*ctlreg >> 8) & 0xf;
    436  1.19   tsutsui 	const uint8_t *p;
    437   1.5    tsubai 	int i;
    438   1.5    tsubai 
    439   1.5    tsubai 	*ctlreg = 0;			/* stop crtc */
    440   1.5    tsubai 	delay(10);
    441   1.5    tsubai 
    442   1.5    tsubai 	/* initialize crtc without R3{0,1,2} */
    443   1.5    tsubai 	p = crtc_data[id][0];
    444   1.5    tsubai 	for (i = 0; i < 28; i++) {
    445   1.5    tsubai 		*crtreg++ = *p++;
    446   1.5    tsubai 		delay(10);
    447   1.5    tsubai 	}
    448   1.5    tsubai 
    449   1.5    tsubai 	*ctlreg = 0x02;			/* start crtc */
    450   1.5    tsubai 	delay(10);
    451   1.5    tsubai 
    452   1.5    tsubai 	/* set crtc control reg */
    453   1.5    tsubai 	p = crtc_data[id][1];
    454   1.5    tsubai 	for (i = 0; i < 6; i++) {
    455   1.5    tsubai 		*crtreg++ = *p++;
    456   1.5    tsubai 		delay(10);
    457   1.5    tsubai 	}
    458   1.5    tsubai }
    459   1.5    tsubai 
    460   1.5    tsubai #if 0
    461   1.5    tsubai static struct wsdisplay_font newsrom8x16;
    462   1.5    tsubai static struct wsdisplay_font newsrom12x24;
    463  1.31   tsutsui static uint8_t fontarea16[96][32];
    464  1.31   tsutsui static uint8_t fontarea24[96][96];
    465   1.5    tsubai 
    466   1.5    tsubai void
    467  1.19   tsutsui initfont(struct rasops_info *ri)
    468   1.5    tsubai {
    469   1.5    tsubai 	int c, x;
    470   1.5    tsubai 
    471   1.5    tsubai 	for (c = 0; c < 96; c++) {
    472   1.5    tsubai 		x = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
    473  1.31   tsutsui 		memcpy(fontarea16 + c, (uint8_t *)0xb8e00000 + x + 96, 32);
    474  1.31   tsutsui 		memcpy(fontarea24 + c, (uint8_t *)0xb8e00000 + x, 96);
    475  1.33   tsutsui 	}
    476   1.5    tsubai 
    477   1.5    tsubai 	newsrom8x16.name = "rom8x16";
    478   1.5    tsubai 	newsrom8x16.firstchar = 32;
    479   1.5    tsubai 	newsrom8x16.numchars = 96;
    480   1.5    tsubai 	newsrom8x16.encoding = WSDISPLAY_FONTENC_ISO;
    481   1.5    tsubai 	newsrom8x16.fontwidth = 8;
    482   1.5    tsubai 	newsrom8x16.fontheight = 16;
    483   1.5    tsubai 	newsrom8x16.stride = 2;
    484   1.5    tsubai 	newsrom8x16.bitorder = WSDISPLAY_FONTORDER_L2R;
    485   1.5    tsubai 	newsrom8x16.byteorder = WSDISPLAY_FONTORDER_L2R;
    486   1.5    tsubai 	newsrom8x16.data = fontarea16;
    487   1.5    tsubai 
    488   1.5    tsubai 	newsrom12x24.name = "rom12x24";
    489   1.5    tsubai 	newsrom12x24.firstchar = 32;
    490   1.5    tsubai 	newsrom12x24.numchars = 96;
    491   1.5    tsubai 	newsrom12x24.encoding = WSDISPLAY_FONTENC_ISO;
    492   1.5    tsubai 	newsrom12x24.fontwidth = 12;
    493   1.5    tsubai 	newsrom12x24.fontheight = 24;
    494   1.5    tsubai 	newsrom12x24.stride = 4;
    495   1.5    tsubai 	newsrom12x24.bitorder = WSDISPLAY_FONTORDER_L2R;
    496   1.5    tsubai 	newsrom12x24.byteorder = WSDISPLAY_FONTORDER_L2R;
    497   1.5    tsubai 	newsrom12x24.data = fontarea24;
    498   1.5    tsubai 
    499   1.5    tsubai 	ri->ri_font = &newsrom8x16;
    500   1.5    tsubai 	ri->ri_font = &newsrom12x24;
    501   1.5    tsubai 	ri->ri_wsfcookie = -1;		/* not using wsfont */
    502   1.1    tsubai }
    503   1.5    tsubai #endif
    504