1 /* $NetBSD: grf_gb.c,v 1.38 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_gb.c 1.18 93/08/13$
66 * @(#)grf_gb.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_gb.c 1.18 93/08/13$
105 * @(#)grf_gb.c 8.4 (Berkeley) 1/12/94
109 * Graphics routines for the Gatorbox.
111 * Note: In the context of this system, "gator" and "gatorbox" both refer to
112 * HP 987x0 graphics systems. "Gator" is not used for high res mono.
113 * (as in 9837 Gator systems)
116 #include <sys/cdefs.h>
117 __KERNEL_RCSID(0, "$NetBSD: grf_gb.c,v 1.38 2008/03/29 06:47:07 tsutsui Exp $");
119 #include <sys/param.h>
120 #include <sys/systm.h>
121 #include <sys/conf.h>
122 #include <sys/device.h>
123 #include <sys/errno.h>
124 #include <sys/ioctl.h>
125 #include <sys/proc.h>
128 #include <uvm/uvm_extern.h>
130 #include <machine/autoconf.h>
131 #include <machine/cpu.h>
133 #include <dev/cons.h>
135 #include <hp300/dev/dioreg.h>
136 #include <hp300/dev/diovar.h>
137 #include <hp300/dev/diodevs.h>
138 #include <hp300/dev/intiovar.h>
140 #include <hp300/dev/grfioctl.h>
141 #include <hp300/dev/grfvar.h>
142 #include <hp300/dev/grfreg.h>
143 #include <hp300/dev/grf_gbreg.h>
145 #include <hp300/dev/itevar.h>
146 #include <hp300/dev/itereg.h>
150 #define CRTC_DATA_LENGTH 0x0e
151 static uint8_t crtc_init_data
[CRTC_DATA_LENGTH
] = {
152 0x29, 0x20, 0x23, 0x04, 0x30, 0x0b, 0x30,
153 0x30, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00
156 static int gb_init(struct grf_data
*gp
, int, uint8_t *);
157 static int gb_mode(struct grf_data
*gp
, int, void *);
158 static void gb_microcode(struct gboxfb
*);
160 static int gbox_intio_match(device_t
, cfdata_t
, void *);
161 static void gbox_intio_attach(device_t
, device_t
, void *);
163 static int gbox_dio_match(device_t
, cfdata_t
, void *);
164 static void gbox_dio_attach(device_t
, device_t
, void *);
166 int gboxcnattach(bus_space_tag_t
, bus_addr_t
, int);
168 CFATTACH_DECL_NEW(gbox_intio
, sizeof(struct grfdev_softc
),
169 gbox_intio_match
, gbox_intio_attach
, NULL
, NULL
);
171 CFATTACH_DECL_NEW(gbox_dio
, sizeof(struct grfdev_softc
),
172 gbox_dio_match
, gbox_dio_attach
, NULL
, NULL
);
174 /* Gatorbox grf switch */
175 static struct grfsw gbox_grfsw
= {
176 GID_GATORBOX
, GRFGATOR
, "gatorbox", gb_init
, gb_mode
179 static int gbconscode
;
180 static void *gbconaddr
;
183 static void gbox_init(struct ite_data
*);
184 static void gbox_deinit(struct ite_data
*);
185 static void gbox_putc(struct ite_data
*, int, int, int, int);
186 static void gbox_cursor(struct ite_data
*, int);
187 static void gbox_clear(struct ite_data
*, int, int, int, int);
188 static void gbox_scroll(struct ite_data
*, int, int, int, int);
189 static void gbox_windowmove(struct ite_data
*, int, int, int, int,
192 /* Gatorbox ite switch */
193 static struct itesw gbox_itesw
= {
194 gbox_init
, gbox_deinit
, gbox_clear
, gbox_putc
,
195 gbox_cursor
, gbox_scroll
, ite_readbyte
, ite_writeglyph
197 #endif /* NITE > 0 */
200 gbox_intio_match(device_t parent
, cfdata_t cf
, void *aux
)
202 struct intio_attach_args
*ia
= aux
;
205 if (strcmp("fb",ia
->ia_modname
) != 0)
208 if (badaddr((void *)ia
->ia_addr
))
211 grf
= (struct grfreg
*)ia
->ia_addr
;
213 if (grf
->gr_id
== DIO_DEVICE_ID_FRAMEBUFFER
&&
214 grf
->gr_id2
== DIO_DEVICE_SECID_GATORBOX
) {
222 gbox_intio_attach(device_t parent
, device_t self
, void *aux
)
224 struct grfdev_softc
*sc
= device_private(self
);
225 struct intio_attach_args
*ia
= aux
;
230 grf
= (void *)ia
->ia_addr
;
231 sc
->sc_scode
= -1; /* XXX internal i/o */
233 sc
->sc_isconsole
= (sc
->sc_scode
== gbconscode
);
234 grfdev_attach(sc
, gb_init
, grf
, &gbox_grfsw
);
238 gbox_dio_match(device_t parent
, cfdata_t match
, void *aux
)
240 struct dio_attach_args
*da
= aux
;
242 if (da
->da_id
== DIO_DEVICE_ID_FRAMEBUFFER
&&
243 da
->da_secid
== DIO_DEVICE_SECID_GATORBOX
)
250 gbox_dio_attach(device_t parent
, device_t self
, void *aux
)
252 struct grfdev_softc
*sc
= device_private(self
);
253 struct dio_attach_args
*da
= aux
;
254 bus_space_handle_t bsh
;
258 sc
->sc_scode
= da
->da_scode
;
259 if (sc
->sc_scode
== gbconscode
)
262 if (bus_space_map(da
->da_bst
, da
->da_addr
, da
->da_size
,
264 aprint_error(": can't map framebuffer\n");
267 grf
= bus_space_vaddr(da
->da_bst
, bsh
);
270 sc
->sc_isconsole
= (sc
->sc_scode
== gbconscode
);
271 grfdev_attach(sc
, gb_init
, grf
, &gbox_grfsw
);
275 * Initialize hardware.
276 * Must point g_display at a grfinfo structure describing the hardware.
277 * Returns 0 if hardware not present, non-zero ow.
280 gb_init(struct grf_data
*gp
, int scode
, uint8_t *addr
)
283 struct grfinfo
*gi
= &gp
->g_display
;
284 volatile uint8_t *fbp
;
289 * If the console has been initialized, and it was us, there's
290 * no need to repeat this.
292 if (scode
!= gbconscode
) {
293 gbp
= (struct gboxfb
*)addr
;
295 gi
->gd_regaddr
= (void *)IIOP(addr
);
297 gi
->gd_regaddr
= dio_scodetopa(scode
);
298 gi
->gd_regsize
= 0x10000;
299 gi
->gd_fbwidth
= 1024; /* XXX */
300 gi
->gd_fbheight
= 1024; /* XXX */
301 gi
->gd_fbsize
= gi
->gd_fbwidth
* gi
->gd_fbheight
;
302 fboff
= (gbp
->fbomsb
<< 8) | gbp
->fbolsb
;
303 gi
->gd_fbaddr
= (void *)(*(addr
+ fboff
) << 16);
305 gp
->g_fbkva
= iomap(gi
->gd_fbaddr
, gi
->gd_fbsize
);
306 gi
->gd_dwidth
= 1024; /* XXX */
307 gi
->gd_dheight
= 768; /* XXX */
308 gi
->gd_planes
= 0; /* how do we do this? */
310 * The minimal info here is from the Gatorbox X driver.
313 gbp
->write_protect
= 0;
314 gbp
->interrupt
= 4; /** fb_enable ? **/
315 gbp
->rep_rule
= 3; /* GXcopy */
322 * Find out how many colors are available by determining
323 * which planes are installed. That is, write all ones to
324 * a frame buffer location, see how many ones are read back.
328 gi
->gd_colors
= *fbp
+ 1;
338 gb_microcode(struct gboxfb
*gbp
)
342 for (i
= 0; i
< CRTC_DATA_LENGTH
; i
++) {
343 gbp
->crtc_address
= i
;
344 gbp
->crtc_data
= crtc_init_data
[i
];
349 * Change the mode of the display.
350 * Right now all we can do is grfon/grfoff.
351 * Return a UNIX error number or 0 for success.
354 gb_mode(struct grf_data
*gp
, int cmd
, void *data
)
359 gbp
= (struct gboxfb
*)gp
->g_regkva
;
362 gbp
->sec_interrupt
= 1;
369 * Remember UVA of mapping for GCDESCRIBE.
370 * XXX this should be per-process.
390 * Gatorbox ite routines
393 #define REGBASE ((struct gboxfb *)(ip->regbase))
394 #define WINDOWMOVER gbox_windowmove
397 gbox_init(struct ite_data
*ip
)
400 if (ip
->regbase
== 0) {
401 struct grf_data
*gp
= ip
->grf
;
403 ip
->regbase
= gp
->g_regkva
;
404 ip
->fbbase
= gp
->g_fbkva
;
405 ip
->fbwidth
= gp
->g_display
.gd_fbwidth
;
406 ip
->fbheight
= gp
->g_display
.gd_fbheight
;
407 ip
->dwidth
= gp
->g_display
.gd_dwidth
;
408 ip
->dheight
= gp
->g_display
.gd_dheight
;
411 REGBASE
->write_protect
= 0x0;
412 REGBASE
->interrupt
= 0x4;
413 REGBASE
->rep_rule
= RR_COPY
;
414 REGBASE
->blink1
= 0xff;
415 REGBASE
->blink2
= 0xff;
416 gb_microcode((struct gboxfb
*)ip
->regbase
);
417 REGBASE
->sec_interrupt
= 0x01;
420 * Set up the color map entries. We use three entries in the
421 * color map. The first, is for black, the second is for
422 * white, and the very last entry is for the inverted cursor.
424 REGBASE
->creg_select
= 0x00;
425 REGBASE
->cmap_red
= 0x00;
426 REGBASE
->cmap_grn
= 0x00;
427 REGBASE
->cmap_blu
= 0x00;
428 REGBASE
->cmap_write
= 0x00;
429 gbcm_waitbusy(ip
->regbase
);
431 REGBASE
->creg_select
= 0x01;
432 REGBASE
->cmap_red
= 0xFF;
433 REGBASE
->cmap_grn
= 0xFF;
434 REGBASE
->cmap_blu
= 0xFF;
435 REGBASE
->cmap_write
= 0x01;
436 gbcm_waitbusy(ip
->regbase
);
438 REGBASE
->creg_select
= 0xFF;
439 REGBASE
->cmap_red
= 0xFF;
440 REGBASE
->cmap_grn
= 0xFF;
441 REGBASE
->cmap_blu
= 0xFF;
442 REGBASE
->cmap_write
= 0x01;
443 gbcm_waitbusy(ip
->regbase
);
449 * Clear the display. This used to be before the font unpacking
450 * but it crashes. Figure it out later.
452 gbox_windowmove(ip
, 0, 0, 0, 0, ip
->dheight
, ip
->dwidth
, RR_CLEAR
);
453 tile_mover_waitbusy(ip
->regbase
);
456 * Stash the inverted cursor.
458 gbox_windowmove(ip
, charY(ip
, ' '), charX(ip
, ' '),
459 ip
->cblanky
, ip
->cblankx
, ip
->ftheight
,
460 ip
->ftwidth
, RR_COPYINVERTED
);
464 gbox_deinit(struct ite_data
*ip
)
466 gbox_windowmove(ip
, 0, 0, 0, 0, ip
->dheight
, ip
->dwidth
, RR_CLEAR
);
467 tile_mover_waitbusy(ip
->regbase
);
469 ip
->flags
&= ~ITE_INITED
;
473 gbox_putc(struct ite_data
*ip
, int c
, int dy
, int dx
, int mode
)
475 int wrr
= ((mode
== ATTR_INV
) ? RR_COPYINVERTED
: RR_COPY
);
477 gbox_windowmove(ip
, charY(ip
, c
), charX(ip
, c
),
478 dy
* ip
->ftheight
, dx
* ip
->ftwidth
,
479 ip
->ftheight
, ip
->ftwidth
, wrr
);
483 gbox_cursor(struct ite_data
*ip
, int flag
)
485 if (flag
== DRAW_CURSOR
)
487 else if (flag
== MOVE_CURSOR
) {
496 gbox_clear(struct ite_data
*ip
, int sy
, int sx
, int h
, int w
)
498 gbox_windowmove(ip
, sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
499 sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
500 h
* ip
->ftheight
, w
* ip
->ftwidth
,
503 #define gbox_blockmove(ip, sy, sx, dy, dx, h, w) \
504 gbox_windowmove((ip), \
505 (sy) * ip->ftheight, \
506 (sx) * ip->ftwidth, \
507 (dy) * ip->ftheight, \
508 (dx) * ip->ftwidth, \
509 (h) * ip->ftheight, \
514 gbox_scroll(struct ite_data
*ip
, int sy
, int sx
, int count
, int dir
)
518 tile_mover_waitbusy(ip
->regbase
);
519 REGBASE
->write_protect
= 0x0;
521 if (dir
== SCROLL_UP
) {
523 height
= ip
->rows
- sy
;
524 for (i
= 0; i
< height
; i
++)
525 gbox_blockmove(ip
, sy
+ i
, sx
, dy
+ i
, 0, 1, ip
->cols
);
527 else if (dir
== SCROLL_DOWN
) {
529 height
= ip
->rows
- dy
;
530 for (i
= (height
- 1); i
>= 0; i
--)
531 gbox_blockmove(ip
, sy
+ i
, sx
, dy
+ i
, 0, 1, ip
->cols
);
533 else if (dir
== SCROLL_RIGHT
) {
534 gbox_blockmove(ip
, sy
, sx
, sy
, sx
+ count
,
535 1, ip
->cols
- (sx
+ count
));
538 gbox_blockmove(ip
, sy
, sx
, sy
, sx
- count
,
544 gbox_windowmove(struct ite_data
*ip
, int sy
, int sx
, int dy
, int dx
, int h
,
549 src
= (sy
* 1024) + sx
; /* upper left corner in pixels */
550 dest
= (dy
* 1024) + dx
;
552 tile_mover_waitbusy(ip
->regbase
);
553 REGBASE
->width
= -(w
/ 4);
554 REGBASE
->height
= -(h
/ 4);
556 REGBASE
->rep_rule
= MOVE_DOWN_RIGHT
|mask
;
558 REGBASE
->rep_rule
= MOVE_UP_LEFT
|mask
;
560 * Adjust to top of lower right tile of the block.
562 src
= src
+ ((h
- 4) * 1024) + (w
- 4);
563 dest
= dest
+ ((h
- 4) * 1024) + (w
- 4);
565 FBBASE
[dest
] = FBBASE
[src
];
569 * Gatorbox console support
572 gboxcnattach(bus_space_tag_t bst
, bus_addr_t addr
, int scode
)
574 bus_space_handle_t bsh
;
577 struct grf_data
*gp
= &grf_cn
;
580 if (bus_space_map(bst
, addr
, PAGE_SIZE
, 0, &bsh
))
582 va
= bus_space_vaddr(bst
, bsh
);
583 grf
= (struct grfreg
*)va
;
586 (grf
->gr_id
!= GRFHWID
) || (grf
->gr_id2
!= GID_GATORBOX
)) {
587 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
591 size
= DIO_SIZE(scode
, va
);
593 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
594 if (bus_space_map(bst
, addr
, size
, 0, &bsh
))
596 va
= bus_space_vaddr(bst
, bsh
);
599 * Initialize the framebuffer hardware.
601 (void)gb_init(gp
, scode
, va
);
606 * Set up required grf data.
608 gp
->g_sw
= &gbox_grfsw
;
609 gp
->g_display
.gd_id
= gp
->g_sw
->gd_swid
;
610 gp
->g_flags
= GF_ALIVE
;
613 * Initialize the terminal emulator.
615 itedisplaycnattach(gp
, &gbox_itesw
);
619 #endif /* NITE > 0 */