1 /* $NetBSD: grf_tc.c,v 1.41 2008/03/29 06:47:07 tsutsui Exp $ */
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1990, 1993
34 * The Regents of the University of California. All rights reserved.
36 * This code is derived from software contributed to Berkeley by
37 * the Systems Programming Group of the University of Utah Computer
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * from: Utah $Hdr: grf_tc.c 1.20 93/08/13$
66 * @(#)grf_tc.c 8.4 (Berkeley) 1/12/94
69 * Copyright (c) 1988 University of Utah.
71 * This code is derived from software contributed to Berkeley by
72 * the Systems Programming Group of the University of Utah Computer
75 * Redistribution and use in source and binary forms, with or without
76 * modification, are permitted provided that the following conditions
78 * 1. Redistributions of source code must retain the above copyright
79 * notice, this list of conditions and the following disclaimer.
80 * 2. Redistributions in binary form must reproduce the above copyright
81 * notice, this list of conditions and the following disclaimer in the
82 * documentation and/or other materials provided with the distribution.
83 * 3. All advertising materials mentioning features or use of this software
84 * must display the following acknowledgement:
85 * This product includes software developed by the University of
86 * California, Berkeley and its contributors.
87 * 4. Neither the name of the University nor the names of its contributors
88 * may be used to endorse or promote products derived from this software
89 * without specific prior written permission.
91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
103 * from: Utah $Hdr: grf_tc.c 1.20 93/08/13$
105 * @(#)grf_tc.c 8.4 (Berkeley) 1/12/94
109 * Graphics routines for TOPCAT and CATSEYE frame buffers
112 #include <sys/cdefs.h>
113 __KERNEL_RCSID(0, "$NetBSD: grf_tc.c,v 1.41 2008/03/29 06:47:07 tsutsui Exp $");
115 #include <sys/param.h>
116 #include <sys/conf.h>
117 #include <sys/errno.h>
118 #include <sys/proc.h>
119 #include <sys/ioctl.h>
121 #include <sys/systm.h>
122 #include <sys/device.h>
124 #include <uvm/uvm_extern.h>
126 #include <machine/autoconf.h>
127 #include <machine/cpu.h>
129 #include <dev/cons.h>
131 #include <hp300/dev/dioreg.h>
132 #include <hp300/dev/diovar.h>
133 #include <hp300/dev/diodevs.h>
134 #include <hp300/dev/intiovar.h>
136 #include <hp300/dev/grfioctl.h>
137 #include <hp300/dev/grfvar.h>
138 #include <hp300/dev/grfreg.h>
139 #include <hp300/dev/grf_tcreg.h>
141 #include <hp300/dev/itevar.h>
142 #include <hp300/dev/itereg.h>
146 static int tc_init(struct grf_data
*, int, uint8_t *);
147 static int tc_mode(struct grf_data
*, int, void *);
149 static void topcat_common_attach(struct grfdev_softc
*, void *, uint8_t);
151 static int topcat_intio_match(device_t
, cfdata_t
, void *);
152 static void topcat_intio_attach(device_t
, device_t
, void *);
154 static int topcat_dio_match(device_t
, cfdata_t
, void *);
155 static void topcat_dio_attach(device_t
, device_t
, void *);
157 int topcatcnattach(bus_space_tag_t
, bus_addr_t
, int);
159 CFATTACH_DECL_NEW(topcat_intio
, sizeof(struct grfdev_softc
),
160 topcat_intio_match
, topcat_intio_attach
, NULL
, NULL
);
162 CFATTACH_DECL_NEW(topcat_dio
, sizeof(struct grfdev_softc
),
163 topcat_dio_match
, topcat_dio_attach
, NULL
, NULL
);
165 /* Topcat (bobcat) grf switch */
166 static struct grfsw topcat_grfsw
= {
167 GID_TOPCAT
, GRFBOBCAT
, "topcat", tc_init
, tc_mode
170 /* Lo-res catseye grf switch */
171 static struct grfsw lrcatseye_grfsw
= {
172 GID_LRCATSEYE
, GRFCATSEYE
, "lo-res catseye", tc_init
, tc_mode
175 /* Hi-res catseye grf switch */
176 static struct grfsw hrcatseye_grfsw
= {
177 GID_HRCCATSEYE
, GRFCATSEYE
, "hi-res catseye", tc_init
, tc_mode
180 /* Hi-res monochrome catseye grf switch */
181 static struct grfsw hrmcatseye_grfsw
= {
182 GID_HRMCATSEYE
, GRFCATSEYE
, "hi-res catseye", tc_init
, tc_mode
185 static int tcconscode
;
186 static void *tcconaddr
;
189 static void topcat_init(struct ite_data
*);
190 static void topcat_deinit(struct ite_data
*);
191 static void topcat_putc(struct ite_data
*, int, int, int, int);
192 static void topcat_cursor(struct ite_data
*, int);
193 static void topcat_clear(struct ite_data
*, int, int, int, int);
194 static void topcat_scroll(struct ite_data
*, int, int, int, int);
195 static void topcat_windowmove(struct ite_data
*, int, int, int, int,
198 /* Topcat/catseye ite switch */
199 static struct itesw topcat_itesw
= {
200 topcat_init
, topcat_deinit
, topcat_clear
, topcat_putc
,
201 topcat_cursor
, topcat_scroll
, ite_readbyte
, ite_writeglyph
203 #endif /* NITE > 0 */
206 topcat_intio_match(device_t parent
, cfdata_t cf
, void *aux
)
208 struct intio_attach_args
*ia
= aux
;
211 if (strcmp("fb",ia
->ia_modname
) != 0)
214 if (badaddr((void *)ia
->ia_addr
))
217 grf
= (struct grfreg
*)ia
->ia_addr
;
219 if (grf
->gr_id
== DIO_DEVICE_ID_FRAMEBUFFER
) {
220 switch (grf
->gr_id2
) {
221 case DIO_DEVICE_SECID_TOPCAT
:
222 case DIO_DEVICE_SECID_LRCATSEYE
:
223 case DIO_DEVICE_SECID_HRCCATSEYE
:
224 case DIO_DEVICE_SECID_HRMCATSEYE
:
226 case DIO_DEVICE_SECID_XXXCATSEYE
:
236 topcat_intio_attach(device_t parent
, device_t self
, void *aux
)
238 struct grfdev_softc
*sc
= device_private(self
);
239 struct intio_attach_args
*ia
= aux
;
244 grf
= (struct grfreg
*)ia
->ia_addr
;
245 sc
->sc_scode
= -1; /* XXX internal i/o */
248 topcat_common_attach(sc
, (void *)grf
, grf
->gr_id2
);
252 topcat_dio_match(device_t parent
, cfdata_t cf
, void *aux
)
254 struct dio_attach_args
*da
= aux
;
256 if (da
->da_id
== DIO_DEVICE_ID_FRAMEBUFFER
) {
257 switch (da
->da_secid
) {
258 case DIO_DEVICE_SECID_TOPCAT
:
259 case DIO_DEVICE_SECID_LRCATSEYE
:
260 case DIO_DEVICE_SECID_HRCCATSEYE
:
261 case DIO_DEVICE_SECID_HRMCATSEYE
:
263 case DIO_DEVICE_SECID_XXXCATSEYE
:
273 topcat_dio_attach(device_t parent
, device_t self
, void *aux
)
275 struct grfdev_softc
*sc
= device_private(self
);
276 struct dio_attach_args
*da
= aux
;
278 bus_space_handle_t bsh
;
281 sc
->sc_scode
= da
->da_scode
;
282 if (sc
->sc_scode
== tcconscode
)
285 if (bus_space_map(da
->da_bst
, da
->da_addr
, da
->da_size
, 0,
287 aprint_error(": can't map framebuffer\n");
290 grf
= bus_space_vaddr(da
->da_bst
, bsh
);
293 topcat_common_attach(sc
, grf
, da
->da_secid
);
297 topcat_common_attach(struct grfdev_softc
*sc
, void *grf
, uint8_t secid
)
302 case DIO_DEVICE_SECID_TOPCAT
:
306 case DIO_DEVICE_SECID_LRCATSEYE
:
307 sw
= &lrcatseye_grfsw
;
310 case DIO_DEVICE_SECID_HRCCATSEYE
:
311 sw
= &hrcatseye_grfsw
;
314 case DIO_DEVICE_SECID_HRMCATSEYE
:
315 sw
= &hrmcatseye_grfsw
;
318 case DIO_DEVICE_SECID_XXXCATSEYE
:
323 aprint_error(": unknown device 0x%x\n", secid
);
324 panic("%s: unknown topcat", __func__
);
327 sc
->sc_isconsole
= (sc
->sc_scode
== tcconscode
);
328 grfdev_attach(sc
, tc_init
, grf
, sw
);
332 * Initialize hardware.
333 * Must fill in the grfinfo structure in g_softc.
334 * Returns 0 if hardware not present, non-zero ow.
337 tc_init(struct grf_data
*gp
, int scode
, uint8_t *addr
)
339 struct tcboxfb
*tp
= (struct tcboxfb
*)addr
;
340 struct grfinfo
*gi
= &gp
->g_display
;
341 volatile uint8_t *fbp
;
346 * If the console has been initialized, and it was us, there's
347 * no need to repeat this.
349 if (scode
!= tcconscode
) {
351 gi
->gd_regaddr
= (void *)IIOP(addr
);
353 gi
->gd_regaddr
= dio_scodetopa(scode
);
354 gi
->gd_regsize
= 0x10000;
355 gi
->gd_fbwidth
= (tp
->fbwmsb
<< 8) | tp
->fbwlsb
;
356 gi
->gd_fbheight
= (tp
->fbhmsb
<< 8) | tp
->fbhlsb
;
357 gi
->gd_fbsize
= gi
->gd_fbwidth
* gi
->gd_fbheight
;
358 fboff
= (tp
->fbomsb
<< 8) | tp
->fbolsb
;
359 gi
->gd_fbaddr
= (void *)(*(addr
+ fboff
) << 16);
360 if ((vaddr_t
)gi
->gd_regaddr
>= DIOIIBASE
) {
362 * For DIO II space the fbaddr just computed is the
363 * offset from the select code base (regaddr) of the
364 * framebuffer. Hence it is also implicitly the
367 gi
->gd_regsize
= (int)gi
->gd_fbaddr
;
368 gi
->gd_fbaddr
+= (int)gi
->gd_regaddr
;
370 gp
->g_fbkva
= addr
+ gi
->gd_regsize
;
373 * For DIO space we need to map the separate
377 gp
->g_fbkva
= iomap(gi
->gd_fbaddr
, gi
->gd_fbsize
);
379 gi
->gd_dwidth
= (tp
->dwmsb
<< 8) | tp
->dwlsb
;
380 gi
->gd_dheight
= (tp
->dhmsb
<< 8) | tp
->dhlsb
;
381 gi
->gd_planes
= tp
->num_planes
;
382 gi
->gd_colors
= 1 << gi
->gd_planes
;
383 if (gi
->gd_colors
== 1) {
390 gi
->gd_colors
= *fbp
+ 1;
398 * Change the mode of the display.
399 * Right now all we can do is grfon/grfoff.
400 * Return a UNIX error number or 0 for success.
401 * Function may not be needed anymore.
405 tc_mode(struct grf_data
*gp
, int cmd
, void *data
)
415 * Remember UVA of mapping for GCDESCRIBE.
416 * XXX this should be per-process.
436 * Topcat/catseye ite routines
439 #define REGBASE ((struct tcboxfb *)(ip->regbase))
440 #define WINDOWMOVER topcat_windowmove
443 topcat_init(struct ite_data
*ip
)
447 if (ip
->regbase
== NULL
) {
448 struct grf_data
*gp
= ip
->grf
;
450 ip
->regbase
= gp
->g_regkva
;
451 ip
->fbbase
= gp
->g_fbkva
;
452 ip
->fbwidth
= gp
->g_display
.gd_fbwidth
;
453 ip
->fbheight
= gp
->g_display
.gd_fbheight
;
454 ip
->dwidth
= gp
->g_display
.gd_dwidth
;
455 ip
->dheight
= gp
->g_display
.gd_dheight
;
459 * Catseye looks a lot like a topcat, but not completely.
460 * So, we set some bits to make it work.
462 if (REGBASE
->fbid
!= GID_TOPCAT
) {
463 while ((REGBASE
->catseye_status
& 1))
465 REGBASE
->catseye_status
= 0x0;
466 REGBASE
->vb_select
= 0x0;
467 REGBASE
->tcntrl
= 0x0;
468 REGBASE
->acntrl
= 0x0;
469 REGBASE
->pncntrl
= 0x0;
470 REGBASE
->rug_cmdstat
= 0x90;
474 * Determine the number of planes by writing to the first frame
475 * buffer display location, then reading it back.
479 REGBASE
->prr
= RR_COPY
;
481 ip
->planemask
= *FBBASE
;
484 * Enable reading/writing of all the planes.
486 REGBASE
->fben
= ip
->planemask
;
487 REGBASE
->wen
= ip
->planemask
;
488 REGBASE
->ren
= ip
->planemask
;
489 REGBASE
->prr
= RR_COPY
;
494 * Clear the framebuffer on all planes.
496 topcat_windowmove(ip
, 0, 0, 0, 0, ip
->fbheight
, ip
->fbwidth
, RR_CLEAR
);
497 tc_waitbusy(ip
->regbase
, ip
->planemask
);
502 * Initialize color map for color displays
504 if (ip
->planemask
!= 1) {
505 tc_waitbusy(ip
->regbase
, ip
->planemask
);
506 REGBASE
->nblank
= 0x01;
508 tccm_waitbusy(ip
->regbase
);
509 REGBASE
->rdata
= 0x0;
510 REGBASE
->gdata
= 0x0;
511 REGBASE
->bdata
= 0x0;
512 REGBASE
->cindex
= 0xFF;
513 REGBASE
->strobe
= 0xFF;
516 tccm_waitbusy(ip
->regbase
);
517 REGBASE
->rdata
= 0x0;
518 REGBASE
->gdata
= 0x0;
519 REGBASE
->bdata
= 0x0;
520 REGBASE
->cindex
= 0x0;
523 tccm_waitbusy(ip
->regbase
);
524 REGBASE
->rdata
= 0xFF;
525 REGBASE
->gdata
= 0xFF;
526 REGBASE
->bdata
= 0xFF;
527 REGBASE
->cindex
= 0xFE;
528 REGBASE
->strobe
= 0xFF;
531 tccm_waitbusy(ip
->regbase
);
532 REGBASE
->rdata
= 0x0;
533 REGBASE
->gdata
= 0x0;
534 REGBASE
->bdata
= 0x0;
535 REGBASE
->cindex
= 0x0;
539 * Stash the inverted cursor.
541 topcat_windowmove(ip
, charY(ip
, ' '), charX(ip
, ' '),
542 ip
->cblanky
, ip
->cblankx
, ip
->ftheight
,
543 ip
->ftwidth
, RR_COPYINVERTED
);
547 topcat_deinit(struct ite_data
*ip
)
550 topcat_windowmove(ip
, 0, 0, 0, 0, ip
->fbheight
, ip
->fbwidth
, RR_CLEAR
);
551 tc_waitbusy(ip
->regbase
, ip
->planemask
);
553 REGBASE
->nblank
= ~0;
554 ip
->flags
&= ~ITE_INITED
;
558 topcat_putc(struct ite_data
*ip
, int c
, int dy
, int dx
, int mode
)
560 int wmrr
= ((mode
== ATTR_INV
) ? RR_COPYINVERTED
: RR_COPY
);
562 topcat_windowmove(ip
, charY(ip
, c
), charX(ip
, c
),
563 dy
* ip
->ftheight
, dx
* ip
->ftwidth
,
564 ip
->ftheight
, ip
->ftwidth
, wmrr
);
568 topcat_cursor(struct ite_data
*ip
, int flag
)
571 if (flag
== DRAW_CURSOR
)
573 else if (flag
== MOVE_CURSOR
) {
582 topcat_clear(struct ite_data
*ip
, int sy
, int sx
, int h
, int w
)
584 topcat_windowmove(ip
, sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
585 sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
586 h
* ip
->ftheight
, w
* ip
->ftwidth
,
591 topcat_scroll(struct ite_data
*ip
, int sy
, int sx
, int count
, int dir
)
596 int width
= ip
->cols
;
598 if (dir
== SCROLL_UP
) {
600 height
= ip
->rows
- sy
;
602 else if (dir
== SCROLL_DOWN
) {
604 height
= ip
->rows
- dy
- 1;
606 else if (dir
== SCROLL_RIGHT
) {
609 width
= ip
->cols
- dx
;
614 width
= ip
->cols
- sx
;
617 topcat_windowmove(ip
, sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
618 dy
* ip
->ftheight
, dx
* ip
->ftwidth
,
619 height
* ip
->ftheight
,
620 width
* ip
->ftwidth
, RR_COPY
);
624 topcat_windowmove(struct ite_data
*ip
, int sy
, int sx
, int dy
, int dx
, int h
,
627 struct tcboxfb
*rp
= REGBASE
;
629 if (h
== 0 || w
== 0)
631 tc_waitbusy(ip
->regbase
, ip
->planemask
);
639 rp
->wmove
= ip
->planemask
;
644 * Topcat/catseye console attachment
648 topcatcnattach(bus_space_tag_t bst
, bus_addr_t addr
, int scode
)
650 bus_space_handle_t bsh
;
653 struct grf_data
*gp
= &grf_cn
;
656 if (bus_space_map(bst
, addr
, PAGE_SIZE
, 0, &bsh
))
658 va
= bus_space_vaddr(bst
, bsh
);
659 grf
= (struct grfreg
*)va
;
661 if (badaddr(va
) || grf
->gr_id
!= GRFHWID
) {
662 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
666 switch (grf
->gr_id2
) {
668 gp
->g_sw
= &topcat_grfsw
;
672 gp
->g_sw
= &lrcatseye_grfsw
;
676 gp
->g_sw
= &hrcatseye_grfsw
;
680 gp
->g_sw
= &hrmcatseye_grfsw
;
684 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
688 size
= DIO_SIZE(scode
, va
);
690 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
691 if (bus_space_map(bst
, addr
, size
, 0, &bsh
))
693 va
= bus_space_vaddr(bst
, bsh
);
696 * Initialize the framebuffer hardware.
698 (void)tc_init(gp
, scode
, va
);
703 * Set up required grf data.
705 gp
->g_display
.gd_id
= gp
->g_sw
->gd_swid
;
706 gp
->g_flags
= GF_ALIVE
;
709 * Initialize the terminal emulator.
711 itedisplaycnattach(gp
, &topcat_itesw
);
715 #endif /* NITE > 0 */