1 /* $NetBSD: fb.c,v 1.23 2007/03/04 06:00:26 christos Exp $ */
4 * Copyright (c) 2000 Tsubai Masanari. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: fb.c,v 1.23 2007/03/04 06:00:26 christos Exp $");
32 #include <sys/param.h>
33 #include <sys/device.h>
34 #include <sys/ioctl.h>
35 #include <sys/malloc.h>
36 #include <sys/systm.h>
38 #include <uvm/uvm_extern.h>
40 #include <machine/adrsmap.h>
42 #include <newsmips/dev/hbvar.h>
44 #include <dev/wscons/wsconsio.h>
45 #include <dev/wscons/wsdisplayvar.h>
46 #include <dev/rasops/rasops.h>
49 u_char
*dc_fbbase
; /* VRAM base address */
50 struct rasops_info dc_ri
;
55 struct fb_devconfig
*sc_dc
;
59 int fb_match(device_t
, cfdata_t
, void *);
60 void fb_attach(device_t
, device_t
, void *);
62 int fb_common_init(struct fb_devconfig
*);
63 int fb_is_console(void);
65 int fb_ioctl(void *, void *, u_long
, void *, int, struct lwp
*);
66 paddr_t
fb_mmap(void *, void *, off_t
, int);
67 int fb_alloc_screen(void *, const struct wsscreen_descr
*, void **, int *,
69 void fb_free_screen(void *, void *);
70 int fb_show_screen(void *, void *, int, void (*)(void *, int, int), void *);
72 void fb_cnattach(void);
74 static void fb253_init(void);
76 CFATTACH_DECL_NEW(fb
, sizeof(struct fb_softc
),
77 fb_match
, fb_attach
, NULL
, NULL
);
79 struct fb_devconfig fb_console_dc
;
81 struct wsdisplay_accessops fb_accessops
= {
90 struct wsscreen_descr fb_stdscreen
= {
98 const struct wsscreen_descr
*fb_scrlist
[] = {
102 struct wsscreen_list fb_screenlist
= {
103 __arraycount(fb_scrlist
), fb_scrlist
106 #define NWB253_VRAM ((uint8_t *) 0x88000000)
107 #define NWB253_CTLREG ((uint16_t *)0xb8ff0000)
108 #define NWB253_CRTREG ((uint16_t *)0xb8fe0000)
110 static const char *devname
[8] = { "NWB-512", "NWB-518", "NWE-501" }; /* XXX ? */
113 fb_match(device_t parent
, cfdata_t cf
, void *aux
)
115 struct hb_attach_args
*ha
= aux
;
117 if (strcmp(ha
->ha_name
, "fb") != 0)
120 if (hb_badaddr(NWB253_CTLREG
, 2) || hb_badaddr(NWB253_CRTREG
, 2))
122 if ((*(volatile uint16_t *)NWB253_CTLREG
& 7) != 4)
129 fb_attach(device_t parent
, device_t self
, void *aux
)
131 struct fb_softc
*sc
= device_private(self
);
132 struct wsemuldisplaydev_attach_args waa
;
133 struct fb_devconfig
*dc
;
134 struct rasops_info
*ri
;
136 volatile u_short
*ctlreg
= NWB253_CTLREG
;
141 console
= fb_is_console();
148 dc
= malloc(sizeof(struct fb_devconfig
), M_DEVBUF
,
151 dc
->dc_fbbase
= NWB253_VRAM
;
156 (*ri
->ri_ops
.eraserows
)(ri
, 0, ri
->ri_rows
, 0);
162 id
= (*ctlreg
>> 8) & 0xf;
163 aprint_normal(": %s, %d x %d, %dbpp\n", devname
[id
],
164 ri
->ri_width
, ri
->ri_height
, ri
->ri_depth
);
166 waa
.console
= console
;
167 waa
.scrdata
= &fb_screenlist
;
168 waa
.accessops
= &fb_accessops
;
169 waa
.accesscookie
= sc
;
171 config_found(self
, &waa
, wsemuldisplaydevprint
);
175 fb_common_init(struct fb_devconfig
*dc
)
177 struct rasops_info
*ri
= &dc
->dc_ri
;
178 volatile uint16_t *ctlreg
= NWB253_CTLREG
;
180 int width
, height
, xoff
, yoff
, cols
, rows
;
182 id
= (*ctlreg
>> 8) & 0xf;
184 /* initialize rasops */
198 ri
->ri_width
= width
;
199 ri
->ri_height
= height
;
201 ri
->ri_stride
= 2048 / 8;
202 ri
->ri_bits
= dc
->dc_fbbase
;
203 ri
->ri_flg
= RI_FULLCLEAR
;
205 rasops_init(ri
, 24, 80);
206 rows
= (height
- 2) / ri
->ri_font
->fontheight
;
207 cols
= ((width
- 2) / ri
->ri_font
->fontwidth
) & ~7;
208 xoff
= ((width
- cols
* ri
->ri_font
->fontwidth
) / 2 / 8) & ~3;
209 yoff
= (height
- rows
* ri
->ri_font
->fontheight
) / 2;
210 rasops_reconfig(ri
, rows
, cols
);
212 ri
->ri_xorigin
= xoff
;
213 ri
->ri_yorigin
= yoff
;
214 ri
->ri_bits
= dc
->dc_fbbase
+ xoff
+ ri
->ri_stride
* yoff
;
216 fb_stdscreen
.nrows
= ri
->ri_rows
;
217 fb_stdscreen
.ncols
= ri
->ri_cols
;
218 fb_stdscreen
.textops
= &ri
->ri_ops
;
219 fb_stdscreen
.capabilities
= ri
->ri_caps
;
227 volatile u_int
*dipsw
= (void *)DIP_SWITCH
;
229 if (*dipsw
& 7) /* XXX right? */
236 fb_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
238 struct fb_softc
*sc
= v
;
239 struct fb_devconfig
*dc
= sc
->sc_dc
;
240 struct wsdisplay_fbinfo
*wdf
;
243 case WSDISPLAYIO_GTYPE
:
244 *(int *)data
= WSDISPLAY_TYPE_UNKNOWN
; /* XXX */
247 case WSDISPLAYIO_GINFO
:
249 wdf
->height
= dc
->dc_ri
.ri_height
;
250 wdf
->width
= dc
->dc_ri
.ri_width
;
251 wdf
->depth
= dc
->dc_ri
.ri_depth
;
255 case WSDISPLAYIO_SVIDEO
:
256 if (*(int *)data
== WSDISPLAYIO_VIDEO_OFF
) {
257 volatile u_short
*ctlreg
= NWB253_CTLREG
;
258 *ctlreg
= 0; /* stop crtc */
263 case WSDISPLAYIO_GETCMAP
:
264 case WSDISPLAYIO_PUTCMAP
:
271 fb_mmap(void *v
, void *vs
, off_t offset
, int prot
)
273 struct fb_softc
*sc
= v
;
274 struct fb_devconfig
*dc
= sc
->sc_dc
;
276 if (offset
>= 2048 * 2048 / 8 || offset
< 0)
279 return mips_btop((int)dc
->dc_fbbase
+ offset
);
283 fb_alloc_screen(void *v
, const struct wsscreen_descr
*scrdesc
, void **cookiep
,
284 int *ccolp
, int *crowp
, long *attrp
)
286 struct fb_softc
*sc
= v
;
287 struct rasops_info
*ri
= &sc
->sc_dc
->dc_ri
;
290 if (sc
->sc_nscreens
> 0)
295 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
303 fb_free_screen(void *v
, void *cookie
)
305 struct fb_softc
*sc
= v
;
307 if (sc
->sc_dc
== &fb_console_dc
)
308 panic("%s: console", __func__
);
314 fb_show_screen(void *v
, void *cookie
, int waitok
, void (*cb
)(void *, int, int),
324 struct fb_devconfig
*dc
= &fb_console_dc
;
325 struct rasops_info
*ri
= &dc
->dc_ri
;
328 if (!fb_is_console())
331 dc
->dc_fbbase
= NWB253_VRAM
;
334 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
335 wsdisplay_cnattach(&fb_stdscreen
, ri
, 0, ri
->ri_rows
- 1, defattr
);
415 { nwp512_data1
, nwp512_data2
},
416 { nwp518_data1
, nwp518_data2
},
417 { nwe501_data1
, nwe501_data2
}
423 volatile uint16_t *ctlreg
= NWB253_CTLREG
;
424 volatile uint16_t *crtreg
= NWB253_CRTREG
;
425 int id
= (*ctlreg
>> 8) & 0xf;
429 *ctlreg
= 0; /* stop crtc */
432 /* initialize crtc without R3{0,1,2} */
433 p
= crtc_data
[id
][0];
434 for (i
= 0; i
< 28; i
++) {
439 *ctlreg
= 0x02; /* start crtc */
442 /* set crtc control reg */
443 p
= crtc_data
[id
][1];
444 for (i
= 0; i
< 6; i
++) {
451 static struct wsdisplay_font newsrom8x16
;
452 static struct wsdisplay_font newsrom12x24
;
453 static char fontarea16
[96][32];
454 static char fontarea24
[96][96];
457 initfont(struct rasops_info
*ri
)
461 for (c
= 0; c
< 96; c
++) {
462 x
= ((c
& 0x1f) | ((c
& 0xe0) << 2)) << 7;
463 memcpy(fontarea16
+ c
, (char *)0xb8e00000 + x
+ 96, 32);
464 memcpy(fontarea24
+ c
, (char *)0xb8e00000 + x
, 96);
467 newsrom8x16
.name
= "rom8x16";
468 newsrom8x16
.firstchar
= 32;
469 newsrom8x16
.numchars
= 96;
470 newsrom8x16
.encoding
= WSDISPLAY_FONTENC_ISO
;
471 newsrom8x16
.fontwidth
= 8;
472 newsrom8x16
.fontheight
= 16;
473 newsrom8x16
.stride
= 2;
474 newsrom8x16
.bitorder
= WSDISPLAY_FONTORDER_L2R
;
475 newsrom8x16
.byteorder
= WSDISPLAY_FONTORDER_L2R
;
476 newsrom8x16
.data
= fontarea16
;
478 newsrom12x24
.name
= "rom12x24";
479 newsrom12x24
.firstchar
= 32;
480 newsrom12x24
.numchars
= 96;
481 newsrom12x24
.encoding
= WSDISPLAY_FONTENC_ISO
;
482 newsrom12x24
.fontwidth
= 12;
483 newsrom12x24
.fontheight
= 24;
484 newsrom12x24
.stride
= 4;
485 newsrom12x24
.bitorder
= WSDISPLAY_FONTORDER_L2R
;
486 newsrom12x24
.byteorder
= WSDISPLAY_FONTORDER_L2R
;
487 newsrom12x24
.data
= fontarea24
;
489 ri
->ri_font
= &newsrom8x16
;
490 ri
->ri_font
= &newsrom12x24
;
491 ri
->ri_wsfcookie
= -1; /* not using wsfont */