1 /* $NetBSD: macfb.c,v 1.15.10.1 2007/10/03 19:24:06 garbled Exp $ */
3 * Copyright (c) 1998 Matt DeBergalis
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. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Matt DeBergalis
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: macfb.c,v 1.15.10.1 2007/10/03 19:24:06 garbled Exp $");
35 #include "opt_wsdisplay_compat.h"
38 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/device.h>
44 #include <sys/malloc.h>
46 #include <machine/cpu.h>
47 #include <machine/bus.h>
49 #include <machine/video.h>
50 #include <machine/grfioctl.h>
51 #include <mac68k/nubus/nubus.h>
52 #include <mac68k/dev/grfvar.h>
53 #include <mac68k/dev/macfbvar.h>
54 #include <dev/wscons/wsconsio.h>
56 #include <dev/rcons/raster.h>
57 #include <dev/wscons/wscons_raster.h>
58 #include <dev/wscons/wsdisplayvar.h>
60 int macfb_match(struct device
*, struct cfdata
*, void *);
61 void macfb_attach(struct device
*, struct device
*, void *);
63 CFATTACH_DECL(macfb
, sizeof(struct macfb_softc
),
64 macfb_match
, macfb_attach
, NULL
, NULL
);
66 const struct wsdisplay_emulops macfb_emulops
= {
77 struct wsscreen_descr macfb_stdscreen
= {
79 0, 0, /* will be filled in -- XXX shouldn't, it's global */
85 const struct wsscreen_descr
*_macfb_scrlist
[] = {
89 const struct wsscreen_list macfb_screenlist
= {
90 sizeof(_macfb_scrlist
) / sizeof(struct wsscreen_descr
*),
94 static int macfb_ioctl(void *, void *, u_long
, void *, int, struct lwp
*);
95 static paddr_t
macfb_mmap(void *, void *, off_t
, int);
96 static int macfb_alloc_screen(void *, const struct wsscreen_descr
*,
97 void **, int *, int *, long *);
98 static void macfb_free_screen(void *, void *);
99 static int macfb_show_screen(void *, void *, int,
100 void (*)(void *, int, int), void *);
102 const struct wsdisplay_accessops macfb_accessops
= {
111 void macfb_init(struct macfb_devconfig
*);
113 paddr_t macfb_consaddr
;
114 static int macfb_is_console(paddr_t
);
115 #ifdef WSDISPLAY_COMPAT_ITEFONT
116 static void init_itefont(void);
117 #endif /* WSDISPLAY_COMPAT_ITEFONT */
119 static struct macfb_devconfig macfb_console_dc
;
122 macfb_is_console(paddr_t addr
)
124 if (addr
!= macfb_consaddr
&&
125 (addr
>= 0xf9000000 && addr
<= 0xfeffffff)) {
127 * This is in the NuBus standard slot space range, so we
128 * may well have to look at 0xFssxxxxx, too. Mask off the
129 * slot number and duplicate it in bits 20-23, per IM:V
130 * pp 459, 463, and IM:VI ch 30 p 17.
131 * Note: this is an ugly hack and I wish I knew what
132 * to do about it. -- sr
134 addr
= (paddr_t
)(((u_long
)addr
& 0xff0fffff) |
135 (((u_long
)addr
& 0x0f000000) >> 4));
137 return ((mac68k_machine
.serial_console
& 0x03) == 0
138 && (addr
== macfb_consaddr
));
142 macfb_clear(struct macfb_devconfig
*dc
)
146 /* clear the display */
148 for (i
= 0; rows
-- > 0; i
+= dc
->dc_rowbytes
)
149 memset((u_char
*)dc
->dc_vaddr
+ dc
->dc_offset
+ i
,
154 macfb_init(struct macfb_devconfig
*dc
)
161 #ifdef WSDISPLAY_COMPAT_ITEFONT
163 #endif /* WSDISPLAY_COMPAT_ITEFONT */
165 rap
= &dc
->dc_raster
;
166 rap
->width
= dc
->dc_wid
;
167 rap
->height
= dc
->dc_ht
;
168 rap
->depth
= dc
->dc_depth
;
169 rap
->linelongs
= dc
->dc_rowbytes
/ sizeof(u_int32_t
);
170 rap
->pixels
= (u_int32_t
*)(dc
->dc_vaddr
+ dc
->dc_offset
);
172 /* initialize the raster console blitter */
175 rcp
->rc_crow
= rcp
->rc_ccol
= -1;
176 rcp
->rc_crowp
= &rcp
->rc_crow
;
177 rcp
->rc_ccolp
= &rcp
->rc_ccol
;
178 rcons_init(rcp
, 128, 192);
180 macfb_stdscreen
.nrows
= dc
->dc_rcons
.rc_maxrow
;
181 macfb_stdscreen
.ncols
= dc
->dc_rcons
.rc_maxcol
;
185 macfb_match(struct device
*parent
, struct cfdata
*match
, void *aux
)
191 macfb_attach(struct device
*parent
, struct device
*self
, void *aux
)
193 struct grfbus_attach_args
*ga
= aux
;
194 struct grfmode
*gm
= ga
->ga_grfmode
;
195 struct macfb_softc
*sc
;
196 struct wsemuldisplaydev_attach_args waa
;
199 sc
= (struct macfb_softc
*)self
;
203 isconsole
= macfb_is_console(ga
->ga_phys
+ ga
->ga_grfmode
->fboff
);
206 sc
->sc_dc
= &macfb_console_dc
;
209 sc
->sc_dc
= malloc(sizeof(struct macfb_devconfig
), M_DEVBUF
, M_WAITOK
);
210 sc
->sc_dc
->dc_vaddr
= (vaddr_t
)gm
->fbbase
;
211 sc
->sc_dc
->dc_paddr
= ga
->ga_phys
;
212 sc
->sc_dc
->dc_size
= gm
->fbsize
;
214 sc
->sc_dc
->dc_wid
= gm
->width
;
215 sc
->sc_dc
->dc_ht
= gm
->height
;
216 sc
->sc_dc
->dc_depth
= gm
->psize
;
217 sc
->sc_dc
->dc_rowbytes
= gm
->rowbytes
;
219 sc
->sc_dc
->dc_offset
= gm
->fboff
;
221 macfb_clear(sc
->sc_dc
);
226 /* initialize the raster */
227 waa
.console
= isconsole
;
228 waa
.scrdata
= &macfb_screenlist
;
229 waa
.accessops
= &macfb_accessops
;
230 waa
.accesscookie
= sc
;
232 config_found(self
, &waa
, wsemuldisplaydevprint
);
235 grf_attach(sc
, device_unit(self
));
241 macfb_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
244 struct macfb_softc
*sc
= v
;
245 struct macfb_devconfig
*dc
= sc
->sc_dc
;
246 struct wsdisplay_fbinfo
*wdf
;
249 case WSDISPLAYIO_GTYPE
:
250 *(int *)data
= dc
->dc_type
;
253 case WSDISPLAYIO_GINFO
:
254 wdf
= (struct wsdisplay_fbinfo
*)data
;
255 wdf
->height
= dc
->dc_raster
.height
;
256 wdf
->width
= dc
->dc_raster
.width
;
257 wdf
->depth
= dc
->dc_raster
.depth
;
261 case WSDISPLAYIO_GCURMAX
:
262 case WSDISPLAYIO_GCURPOS
:
263 case WSDISPLAYIO_GCURSOR
:
264 case WSDISPLAYIO_GETCMAP
:
265 case WSDISPLAYIO_GVIDEO
:
266 case WSDISPLAYIO_PUTCMAP
:
267 case WSDISPLAYIO_SCURPOS
:
268 case WSDISPLAYIO_SCURSOR
:
269 case WSDISPLAYIO_SVIDEO
:
270 /* NONE of these operations are supported. */
278 macfb_mmap(void *v
, void *vs
, off_t offset
, int prot
)
280 struct macfb_softc
*sc
= v
;
281 struct macfb_devconfig
*dc
= sc
->sc_dc
;
285 offset
< m68k_round_page(dc
->dc_rowbytes
* dc
->dc_ht
))
286 addr
= m68k_btop(dc
->dc_paddr
+ dc
->dc_offset
+ offset
);
288 addr
= (-1); /* XXX bogus */
294 macfb_alloc_screen(void *v
, const struct wsscreen_descr
*type
, void **cookiep
,
295 int *curxp
, int *curyp
, long *defattrp
)
297 struct macfb_softc
*sc
= v
;
300 if (sc
->nscreens
> 0)
303 *cookiep
= &sc
->sc_dc
->dc_rcons
; /* one and only for now */
306 rcons_allocattr(&sc
->sc_dc
->dc_rcons
, 0, 0, 0, &defattr
);
313 macfb_free_screen(void *v
, void *cookie
)
315 struct macfb_softc
*sc
= v
;
317 if (sc
->sc_dc
== &macfb_console_dc
)
318 panic("cfb_free_screen: console");
324 macfb_show_screen(void *v
, void *cookie
, int waitok
,
325 void (*cb
)(void *, int, int), void *cbarg
)
331 macfb_cnattach(paddr_t addr
)
333 struct macfb_devconfig
*dc
= &macfb_console_dc
;
336 dc
->dc_vaddr
= m68k_trunc_page(mac68k_video
.mv_kvaddr
);
337 dc
->dc_paddr
= m68k_trunc_page(mac68k_video
.mv_phys
);
339 dc
->dc_wid
= mac68k_video
.mv_width
;
340 dc
->dc_ht
= mac68k_video
.mv_height
;
341 dc
->dc_depth
= mac68k_video
.mv_depth
;
342 dc
->dc_rowbytes
= mac68k_video
.mv_stride
;
344 dc
->dc_size
= (mac68k_video
.mv_len
> 0) ?
345 mac68k_video
.mv_len
: dc
->dc_ht
* dc
->dc_rowbytes
;
346 dc
->dc_offset
= m68k_page_offset(mac68k_video
.mv_phys
);
348 /* set up the display */
349 macfb_init(&macfb_console_dc
);
351 rcons_allocattr(&dc
->dc_rcons
, 0, 0, 0, &defattr
);
353 wsdisplay_cnattach(&macfb_stdscreen
, &dc
->dc_rcons
,
356 macfb_consaddr
= addr
;
361 #ifdef WSDISPLAY_COMPAT_ITEFONT
362 #include <mac68k/dev/6x10.h>
367 static int itefont_initted
;
370 extern struct raster_font gallant19
; /* XXX */
376 /* XXX but we cannot use malloc here... */
378 gallant19
.height
= 10;
379 gallant19
.ascent
= 0;
381 for (i
= 32; i
< 128; i
++) {
384 if (gallant19
.chars
[i
].r
== NULL
)
387 gallant19
.chars
[i
].r
->width
= 6;
388 gallant19
.chars
[i
].r
->height
= 10;
389 p
= gallant19
.chars
[i
].r
->pixels
;
391 for (j
= 0; j
< 10; j
++)
392 *p
++ = Font6x10
[i
* 10 + j
] << 26;
395 #endif /* WSDISPLAY_COMPAT_ITEFONT */