1 /* $NetBSD: grf_dv.c,v 1.39 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_dv.c 1.12 93/08/13$
66 * @(#)grf_dv.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_dv.c 1.12 93/08/13$
105 * @(#)grf_dv.c 8.4 (Berkeley) 1/12/94
109 * Graphics routines for the DaVinci, HP98730/98731 Graphics system.
112 #include <sys/cdefs.h>
113 __KERNEL_RCSID(0, "$NetBSD: grf_dv.c,v 1.39 2008/03/29 06:47:07 tsutsui Exp $");
115 #include <sys/param.h>
116 #include <sys/systm.h>
117 #include <sys/conf.h>
118 #include <sys/device.h>
119 #include <sys/errno.h>
120 #include <sys/ioctl.h>
121 #include <sys/proc.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_dvreg.h>
141 #include <hp300/dev/itevar.h>
142 #include <hp300/dev/itereg.h>
146 static int dv_init(struct grf_data
*, int, uint8_t *);
147 static int dv_mode(struct grf_data
*, int, void *);
148 static void dv_reset(struct dvboxfb
*);
150 static int dvbox_intio_match(device_t
, cfdata_t
, void *);
151 static void dvbox_intio_attach(device_t
, device_t
, void *);
153 static int dvbox_dio_match(device_t
, cfdata_t
, void *);
154 static void dvbox_dio_attach(device_t
, device_t
, void *);
156 int dvboxcnattach(bus_space_tag_t
, bus_addr_t
, int);
158 CFATTACH_DECL_NEW(dvbox_intio
, sizeof(struct grfdev_softc
),
159 dvbox_intio_match
, dvbox_intio_attach
, NULL
, NULL
);
161 CFATTACH_DECL_NEW(dvbox_dio
, sizeof(struct grfdev_softc
),
162 dvbox_dio_match
, dvbox_dio_attach
, NULL
, NULL
);
164 /* DaVinci grf switch */
165 static struct grfsw dvbox_grfsw
= {
166 GID_DAVINCI
, GRFDAVINCI
, "dvbox", dv_init
, dv_mode
169 static int dvconscode
;
170 static void *dvconaddr
;
173 static void dvbox_init(struct ite_data
*);
174 static void dvbox_deinit(struct ite_data
*);
175 static void dvbox_putc(struct ite_data
*, int, int, int, int);
176 static void dvbox_cursor(struct ite_data
*, int);
177 static void dvbox_clear(struct ite_data
*, int, int, int, int);
178 static void dvbox_scroll(struct ite_data
*, int, int, int, int);
179 static void dvbox_windowmove(struct ite_data
*, int, int, int, int,
182 /* DaVinci ite switch */
183 static struct itesw dvbox_itesw
= {
184 dvbox_init
, dvbox_deinit
, dvbox_clear
, dvbox_putc
,
185 dvbox_cursor
, dvbox_scroll
, ite_readbyte
, ite_writeglyph
187 #endif /* NITE > 0 */
190 dvbox_intio_match(device_t parent
, cfdata_t cf
, void *aux
)
192 struct intio_attach_args
*ia
= aux
;
195 if (strcmp("fb",ia
->ia_modname
) != 0)
198 if (badaddr((void *)ia
->ia_addr
))
201 grf
= (struct grfreg
*)ia
->ia_addr
;
203 if (grf
->gr_id
== DIO_DEVICE_ID_FRAMEBUFFER
&&
204 grf
->gr_id2
== DIO_DEVICE_SECID_DAVINCI
) {
212 dvbox_intio_attach(device_t parent
, device_t self
, void *aux
)
214 struct grfdev_softc
*sc
= device_private(self
);
215 struct intio_attach_args
*ia
= aux
;
220 grf
= (void *)ia
->ia_addr
;
221 sc
->sc_scode
= -1; /* XXX internal i/o */
223 sc
->sc_isconsole
= (sc
->sc_scode
== dvconscode
);
224 grfdev_attach(sc
, dv_init
, grf
, &dvbox_grfsw
);
228 dvbox_dio_match(device_t parent
, cfdata_t cf
, void *aux
)
230 struct dio_attach_args
*da
= aux
;
232 if (da
->da_id
== DIO_DEVICE_ID_FRAMEBUFFER
&&
233 da
->da_secid
== DIO_DEVICE_SECID_DAVINCI
)
240 dvbox_dio_attach(device_t parent
, device_t self
, void *aux
)
242 struct grfdev_softc
*sc
= device_private(self
);
243 struct dio_attach_args
*da
= aux
;
244 bus_space_handle_t bsh
;
248 sc
->sc_scode
= da
->da_scode
;
249 if (sc
->sc_scode
== dvconscode
)
252 if (bus_space_map(da
->da_bst
, da
->da_addr
, da
->da_size
,
254 aprint_error(": can't map framebuffer\n");
257 grf
= bus_space_vaddr(da
->da_bst
, bsh
);
260 sc
->sc_isconsole
= (sc
->sc_scode
== dvconscode
);
261 grfdev_attach(sc
, dv_init
, grf
, &dvbox_grfsw
);
265 * Initialize hardware.
266 * Must point g_display at a grfinfo structure describing the hardware.
267 * Returns 0 if hardware not present, non-zero ow.
270 dv_init(struct grf_data
*gp
, int scode
, uint8_t *addr
)
273 struct grfinfo
*gi
= &gp
->g_display
;
277 * If the console has been initialized, and it was us, there's
278 * no need to repeat this.
280 if (scode
!= dvconscode
) {
281 dbp
= (struct dvboxfb
*)addr
;
283 gi
->gd_regaddr
= (void *)IIOP(addr
);
285 gi
->gd_regaddr
= dio_scodetopa(scode
);
286 gi
->gd_regsize
= 0x20000;
287 gi
->gd_fbwidth
= (dbp
->fbwmsb
<< 8) | dbp
->fbwlsb
;
288 gi
->gd_fbheight
= (dbp
->fbhmsb
<< 8) | dbp
->fbhlsb
;
289 gi
->gd_fbsize
= gi
->gd_fbwidth
* gi
->gd_fbheight
;
290 fboff
= (dbp
->fbomsb
<< 8) | dbp
->fbolsb
;
291 gi
->gd_fbaddr
= (void *)(*(addr
+ fboff
) << 16);
292 if ((vaddr_t
)gi
->gd_regaddr
>= DIOIIBASE
) {
294 * For DIO II space the fbaddr just computed is
295 * the offset from the select code base (regaddr)
296 * of the framebuffer. Hence it is also implicitly
297 * the size of the set.
299 gi
->gd_regsize
= (int)gi
->gd_fbaddr
;
300 gi
->gd_fbaddr
+= (int)gi
->gd_regaddr
;
302 gp
->g_fbkva
= addr
+ gi
->gd_regsize
;
305 * For DIO space we need to map the separate
309 gp
->g_fbkva
= iomap(gi
->gd_fbaddr
, gi
->gd_fbsize
);
311 gi
->gd_dwidth
= (dbp
->dwmsb
<< 8) | dbp
->dwlsb
;
312 gi
->gd_dheight
= (dbp
->dwmsb
<< 8) | dbp
->dwlsb
;
313 gi
->gd_planes
= 0; /* ?? */
325 dv_reset(struct dvboxfb
*dbp
)
330 dbp
->interrupt
= 0x04;
336 dbp
->rep_rule
= 0x33;
348 while (dbp
->wbusy
& 0x01)
372 * Change the mode of the display.
373 * Right now all we can do is grfon/grfoff.
374 * Return a UNIX error number or 0 for success.
377 dv_mode(struct grf_data
*gp
, int cmd
, void *data
)
382 dbp
= (struct dvboxfb
*) gp
->g_regkva
;
402 * Remember UVA of mapping for GCDESCRIBE.
403 * XXX this should be per-process.
423 * DaVinci ite routines
426 #define REGBASE ((struct dvboxfb *)(ip->regbase))
427 #define WINDOWMOVER dvbox_windowmove
430 dvbox_init(struct ite_data
*ip
)
435 if (ip
->regbase
== 0) {
436 struct grf_data
*gp
= ip
->grf
;
438 ip
->regbase
= gp
->g_regkva
;
439 ip
->fbbase
= gp
->g_fbkva
;
440 ip
->fbwidth
= gp
->g_display
.gd_fbwidth
;
441 ip
->fbheight
= gp
->g_display
.gd_fbheight
;
442 ip
->dwidth
= gp
->g_display
.gd_dwidth
;
443 ip
->dheight
= gp
->g_display
.gd_dheight
;
445 * XXX some displays (e.g. the davinci) appear
446 * to return a display height greater than the
447 * returned FB height. Guess we should go back
448 * to getting the display dimensions from the
451 if (ip
->dwidth
> ip
->fbwidth
)
452 ip
->dwidth
= ip
->fbwidth
;
453 if (ip
->dheight
> ip
->fbheight
)
454 ip
->dheight
= ip
->fbheight
;
457 dv_reset((struct dvboxfb
*)ip
->regbase
);
460 * Turn on frame buffer, turn on overlay planes, set replacement
461 * rule, enable top overlay plane writes for ite, disable all frame
462 * buffer planes, set byte per pixel, and display frame buffer 0.
463 * Lastly, turn on the box.
465 REGBASE
->interrupt
= 0x04;
466 REGBASE
->drive
= 0x10;
467 REGBASE
->rep_rule
= RR_COPY
<< 4 | RR_COPY
;
468 REGBASE
->opwen
= 0x01;
469 REGBASE
->fbwen
= 0x0;
470 REGBASE
->fold
= 0x01;
471 REGBASE
->vdrive
= 0x0;
472 REGBASE
->dispen
= 0x01;
475 * Video enable top overlay plane.
477 REGBASE
->opvenp
= 0x01;
478 REGBASE
->opvens
= 0x01;
481 * Make sure that overlay planes override frame buffer planes.
483 REGBASE
->ovly0p
= 0x0;
484 REGBASE
->ovly0s
= 0x0;
485 REGBASE
->ovly1p
= 0x0;
486 REGBASE
->ovly1s
= 0x0;
487 REGBASE
->fv_trig
= 0x1;
491 * Setup the overlay colormaps. Need to set the 0,1 (black/white)
492 * color for both banks.
495 for (i
= 0; i
<= 1; i
++) {
496 REGBASE
->cmapbank
= i
;
497 REGBASE
->rgb
[0].red
= 0x00;
498 REGBASE
->rgb
[0].green
= 0x00;
499 REGBASE
->rgb
[0].blue
= 0x00;
500 REGBASE
->rgb
[1].red
= 0xFF;
501 REGBASE
->rgb
[1].green
= 0xFF;
502 REGBASE
->rgb
[1].blue
= 0xFF;
504 REGBASE
->cmapbank
= 0;
506 db_waitbusy(ip
->regbase
);
512 * Clear the (visible) framebuffer.
514 dvbox_windowmove(ip
, 0, 0, 0, 0, ip
->dheight
, ip
->dwidth
, RR_CLEAR
);
515 db_waitbusy(ip
->regbase
);
518 * Stash the inverted cursor.
520 dvbox_windowmove(ip
, charY(ip
, ' '), charX(ip
, ' '),
521 ip
->cblanky
, ip
->cblankx
, ip
->ftheight
,
522 ip
->ftwidth
, RR_COPYINVERTED
);
526 dvbox_deinit(struct ite_data
*ip
)
528 dvbox_windowmove(ip
, 0, 0, 0, 0, ip
->fbheight
, ip
->fbwidth
, RR_CLEAR
);
529 db_waitbusy(ip
->regbase
);
531 ip
->flags
&= ~ITE_INITED
;
535 dvbox_putc(struct ite_data
*ip
, int c
, int dy
, int dx
, int mode
)
537 int wrr
= ((mode
== ATTR_INV
) ? RR_COPYINVERTED
: RR_COPY
);
539 dvbox_windowmove(ip
, charY(ip
, c
), charX(ip
, c
),
540 dy
* ip
->ftheight
, dx
* ip
->ftwidth
,
541 ip
->ftheight
, ip
->ftwidth
, wrr
);
545 dvbox_cursor(struct ite_data
*ip
, int flag
)
547 if (flag
== DRAW_CURSOR
)
549 else if (flag
== MOVE_CURSOR
) {
558 dvbox_clear(struct ite_data
*ip
, int sy
, int sx
, int h
, int w
)
560 dvbox_windowmove(ip
, sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
561 sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
562 h
* ip
->ftheight
, w
* ip
->ftwidth
,
567 dvbox_scroll(struct ite_data
*ip
, int sy
, int sx
, int count
, int dir
)
572 int width
= ip
->cols
;
574 if (dir
== SCROLL_UP
) {
576 height
= ip
->rows
- sy
;
578 else if (dir
== SCROLL_DOWN
) {
580 height
= ip
->rows
- dy
- 1;
582 else if (dir
== SCROLL_RIGHT
) {
585 width
= ip
->cols
- dx
;
590 width
= ip
->cols
- sx
;
593 dvbox_windowmove(ip
, sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
594 dy
* ip
->ftheight
, dx
* ip
->ftwidth
,
595 height
* ip
->ftheight
,
596 width
* ip
->ftwidth
, RR_COPY
);
600 dvbox_windowmove(struct ite_data
*ip
, int sy
, int sx
, int dy
, int dx
, int h
,
603 struct dvboxfb
*dp
= REGBASE
;
604 if (h
== 0 || w
== 0)
607 db_waitbusy(ip
->regbase
);
608 dp
->rep_rule
= func
<< 4 | func
;
619 * DaVinci console support
623 dvboxcnattach(bus_space_tag_t bst
, bus_addr_t addr
, int scode
)
625 bus_space_handle_t bsh
;
628 struct grf_data
*gp
= &grf_cn
;
631 if (bus_space_map(bst
, addr
, PAGE_SIZE
, 0, &bsh
))
633 va
= bus_space_vaddr(bst
, bsh
);
634 grf
= (struct grfreg
*)va
;
637 (grf
->gr_id
!= GRFHWID
) || (grf
->gr_id2
!= GID_DAVINCI
)) {
638 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
642 size
= DIO_SIZE(scode
, va
);
644 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
645 if (bus_space_map(bst
, addr
, size
, 0, &bsh
))
647 va
= bus_space_vaddr(bst
, bsh
);
650 * Initialize the framebuffer hardware.
652 (void)dv_init(gp
, scode
, va
);
657 * Set up required grf data.
659 gp
->g_sw
= &dvbox_grfsw
;
660 gp
->g_display
.gd_id
= gp
->g_sw
->gd_swid
;
661 gp
->g_flags
= GF_ALIVE
;
664 * Initialize the terminal emulator.
666 itedisplaycnattach(gp
, &dvbox_itesw
);
670 #endif /* NITE > 0 */