1 /* $NetBSD: grf_hy.c,v 1.36 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
38 * Science Department and Mark Davies of the Department of Computer
39 * Science, Victoria University of Wellington, New Zealand.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * from: Utah $Hdr: grf_hy.c 1.2 93/08/13$
67 * @(#)grf_hy.c 8.4 (Berkeley) 1/12/94
71 * Copyright (c) 1991 University of Utah.
73 * This code is derived from software contributed to Berkeley by
74 * the Systems Programming Group of the University of Utah Computer
75 * Science Department and Mark Davies of the Department of Computer
76 * Science, Victoria University of Wellington, New Zealand.
78 * Redistribution and use in source and binary forms, with or without
79 * modification, are permitted provided that the following conditions
81 * 1. Redistributions of source code must retain the above copyright
82 * notice, this list of conditions and the following disclaimer.
83 * 2. Redistributions in binary form must reproduce the above copyright
84 * notice, this list of conditions and the following disclaimer in the
85 * documentation and/or other materials provided with the distribution.
86 * 3. All advertising materials mentioning features or use of this software
87 * must display the following acknowledgement:
88 * This product includes software developed by the University of
89 * California, Berkeley and its contributors.
90 * 4. Neither the name of the University nor the names of its contributors
91 * may be used to endorse or promote products derived from this software
92 * without specific prior written permission.
94 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
95 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
96 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
97 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
98 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
99 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
100 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
101 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
102 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
103 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
106 * from: Utah $Hdr: grf_hy.c 1.2 93/08/13$
108 * @(#)grf_hy.c 8.4 (Berkeley) 1/12/94
112 * Graphics routines for HYPERION frame buffer
115 #include <sys/cdefs.h>
116 __KERNEL_RCSID(0, "$NetBSD: grf_hy.c,v 1.36 2008/03/29 06:47:07 tsutsui Exp $");
118 #include <sys/param.h>
119 #include <sys/systm.h>
120 #include <sys/conf.h>
121 #include <sys/device.h>
122 #include <sys/errno.h>
123 #include <sys/ioctl.h>
124 #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_hyreg.h>
145 #include <hp300/dev/itevar.h>
146 #include <hp300/dev/itereg.h>
150 static int hy_init(struct grf_data
*gp
, int, uint8_t *);
151 static int hy_mode(struct grf_data
*gp
, int, void *);
153 static int hyper_dio_match(device_t
, cfdata_t
, void *);
154 static void hyper_dio_attach(device_t
, device_t
, void *);
156 int hypercnattach(bus_space_tag_t
, bus_addr_t
, int);
158 CFATTACH_DECL_NEW(hyper_dio
, sizeof(struct grfdev_softc
),
159 hyper_dio_match
, hyper_dio_attach
, NULL
, NULL
);
161 /* Hyperion grf switch */
162 static struct grfsw hyper_grfsw
= {
163 GID_HYPERION
, GRFHYPERION
, "hyperion", hy_init
, hy_mode
166 static int hyperconscode
;
167 static void *hyperconaddr
;
170 static void hyper_init(struct ite_data
*);
171 static void hyper_deinit(struct ite_data
*);
172 static void hyper_ite_fontinit(struct ite_data
*);
173 static void hyper_putc(struct ite_data
*, int, int, int, int);
174 static void hyper_cursor(struct ite_data
*, int);
175 static void hyper_clear(struct ite_data
*, int, int, int, int);
176 static void hyper_scroll(struct ite_data
*, int, int, int, int);
177 static void hyper_windowmove(struct ite_data
*, int, int, int, int,
180 /* Hyperion ite switch */
181 static struct itesw hyper_itesw
= {
182 hyper_init
, hyper_deinit
, hyper_clear
, hyper_putc
,
183 hyper_cursor
, hyper_scroll
, ite_readbyte
, ite_writeglyph
185 #endif /* NITE > 0 */
188 hyper_dio_match(device_t parent
, cfdata_t cf
, void *aux
)
190 struct dio_attach_args
*da
= aux
;
192 if (da
->da_id
== DIO_DEVICE_ID_FRAMEBUFFER
&&
193 da
->da_secid
== DIO_DEVICE_SECID_HYPERION
)
200 hyper_dio_attach(device_t parent
, device_t self
, void *aux
)
202 struct grfdev_softc
*sc
= device_private(self
);
203 struct dio_attach_args
*da
= aux
;
204 bus_space_handle_t bsh
;
208 sc
->sc_scode
= da
->da_scode
;
209 if (sc
->sc_scode
== hyperconscode
)
212 if (bus_space_map(da
->da_bst
, da
->da_addr
, da
->da_size
,
214 aprint_error(": can't map framebuffer\n");
217 grf
= bus_space_vaddr(da
->da_bst
, bsh
);
220 sc
->sc_isconsole
= (sc
->sc_scode
== hyperconscode
);
221 grfdev_attach(sc
, hy_init
, grf
, &hyper_grfsw
);
225 * Initialize hardware.
226 * Must fill in the grfinfo structure in g_softc.
227 * Returns 0 if hardware not present, non-zero ow.
230 hy_init(struct grf_data
*gp
, int scode
, uint8_t *addr
)
232 struct hyboxfb
*hy
= (struct hyboxfb
*)addr
;
233 struct grfinfo
*gi
= &gp
->g_display
;
237 * If the console has been initialized, and it was us, there's
238 * no need to repeat this.
240 if (scode
!= hyperconscode
) {
242 gi
->gd_regaddr
= (void *)IIOP(addr
);
244 gi
->gd_regaddr
= dio_scodetopa(scode
);
245 gi
->gd_regsize
= 0x20000;
246 gi
->gd_fbwidth
= (hy
->fbwmsb
<< 8) | hy
->fbwlsb
;
247 gi
->gd_fbheight
= (hy
->fbhmsb
<< 8) | hy
->fbhlsb
;
248 gi
->gd_fbsize
= (gi
->gd_fbwidth
* gi
->gd_fbheight
) >> 3;
249 fboff
= (hy
->fbomsb
<< 8) | hy
->fbolsb
;
250 gi
->gd_fbaddr
= (void *)(*(addr
+ fboff
) << 16);
251 if ((vaddr_t
)gi
->gd_regaddr
>= DIOIIBASE
) {
253 * For DIO II space the fbaddr just computed is
254 * the offset from the select code base (regaddr)
255 * of the framebuffer. Hence it is also implicitly
256 * the size of the register set.
258 gi
->gd_regsize
= (int)gi
->gd_fbaddr
;
259 gi
->gd_fbaddr
+= (int)gi
->gd_regaddr
;
261 gp
->g_fbkva
= addr
+ gi
->gd_regsize
;
264 * For DIO space we need to map the separate
268 gp
->g_fbkva
= iomap(gi
->gd_fbaddr
, gi
->gd_fbsize
);
270 gi
->gd_dwidth
= (hy
->dwmsb
<< 8) | hy
->dwlsb
;
271 gi
->gd_dheight
= (hy
->dhmsb
<< 8) | hy
->dhlsb
;
272 gi
->gd_planes
= hy
->num_planes
;
273 gi
->gd_colors
= 1 << gi
->gd_planes
;
279 * Change the mode of the display.
280 * Right now all we can do is grfon/grfoff.
281 * Return a UNIX error number or 0 for success.
282 * Function may not be needed anymore.
285 hy_mode(struct grf_data
*gp
, int cmd
, void *data
)
295 * Remember UVA of mapping for GCDESCRIBE.
296 * XXX this should be per-process.
316 * Hyperion ite routines
319 #define REGBASE ((struct hyboxfb *)(ip->regbase))
320 #define WINDOWMOVER hyper_windowmove
323 #define charX(ip,c) \
324 (((c) % (ip)->cpl) * ((((ip)->ftwidth + 7) / 8) * 8) + (ip)->fontx)
327 hyper_init(struct ite_data
*ip
)
332 if (ip
->regbase
== NULL
) {
333 struct grf_data
*gp
= ip
->grf
;
335 ip
->regbase
= gp
->g_regkva
;
336 ip
->fbbase
= gp
->g_fbkva
;
337 ip
->fbwidth
= gp
->g_display
.gd_fbwidth
;
338 ip
->fbheight
= gp
->g_display
.gd_fbheight
;
339 ip
->dwidth
= gp
->g_display
.gd_dwidth
;
340 ip
->dheight
= gp
->g_display
.gd_dheight
;
344 width
= ((ip
->ftwidth
+ 7) / 8) * 8;
345 ip
->cpl
= (ip
->fbwidth
- ip
->dwidth
) / width
;
346 ip
->cblanky
= ip
->fonty
+ ((128 / ip
->cpl
) +1) * ip
->ftheight
;
349 * Clear the framebuffer on all planes.
351 hyper_windowmove(ip
, 0, 0, 0, 0, ip
->fbheight
, ip
->fbwidth
, RR_CLEAR
);
353 hyper_ite_fontinit(ip
);
355 REGBASE
->nblank
= 0x05;
358 * Stash the inverted cursor.
360 hyper_windowmove(ip
, charY(ip
, ' '), charX(ip
, ' '),
361 ip
->cblanky
, ip
->cblankx
, ip
->ftheight
,
362 ip
->ftwidth
, RR_COPYINVERTED
);
366 hyper_deinit(struct ite_data
*ip
)
368 hyper_windowmove(ip
, 0, 0, 0, 0, ip
->fbheight
, ip
->fbwidth
, RR_CLEAR
);
370 REGBASE
->nblank
= 0x05;
371 ip
->flags
&= ~ITE_INITED
;
375 hyper_ite_fontinit(struct ite_data
*ip
)
377 volatile u_char
*fbmem
;
382 dp
= (u_char
*)(getword(ip
, getword(ip
, FONTROM
) + FONTADDR
) +
383 ip
->regbase
) + FONTDATA
;
384 stride
= ip
->fbwidth
>> 3;
385 width
= (ip
->ftwidth
+ 7) / 8;
387 for (c
= 0; c
< 128; c
++) {
389 (ip
->fonty
+ (c
/ ip
->cpl
) * ip
->ftheight
) *
391 fbmem
+= (ip
->fontx
>> 3) + (c
% ip
->cpl
) * width
;
392 for (l
= 0; l
< ip
->ftheight
; l
++) {
393 for (b
= 0; b
< width
; b
++) {
404 hyper_putc(struct ite_data
*ip
, int c
, int dy
, int dx
, int mode
)
406 int wmrr
= ((mode
== ATTR_INV
) ? RR_COPYINVERTED
: RR_COPY
);
408 hyper_windowmove(ip
, charY(ip
, c
), charX(ip
, c
),
409 dy
* ip
->ftheight
, dx
* ip
->ftwidth
,
410 ip
->ftheight
, ip
->ftwidth
, wmrr
);
414 hyper_cursor(struct ite_data
*ip
, int flag
)
416 if (flag
== DRAW_CURSOR
)
418 else if (flag
== MOVE_CURSOR
) {
427 hyper_clear(struct ite_data
*ip
, int sy
, int sx
, int h
, int w
)
429 hyper_windowmove(ip
, sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
430 sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
431 h
* ip
->ftheight
, w
* ip
->ftwidth
,
436 hyper_scroll(struct ite_data
*ip
, int sy
, int sx
, int count
, int dir
)
441 int width
= ip
->cols
;
443 if (dir
== SCROLL_UP
) {
445 height
= ip
->rows
- sy
;
447 else if (dir
== SCROLL_DOWN
) {
449 height
= ip
->rows
- dy
- 1;
451 else if (dir
== SCROLL_RIGHT
) {
454 width
= ip
->cols
- dx
;
459 width
= ip
->cols
- sx
;
462 hyper_windowmove(ip
, sy
* ip
->ftheight
, sx
* ip
->ftwidth
,
463 dy
* ip
->ftheight
, dx
* ip
->ftwidth
,
464 height
* ip
->ftheight
,
465 width
* ip
->ftwidth
, RR_COPY
);
468 #include <hp300/dev/maskbits.h>
471 * the first element in starttab could be 0xffffffff. making it 0
472 * lets us deal with a full first word in the middle loop, rather
473 * than having to do the multiple reads and masks that we'd
474 * have to do if we thought it was partial.
476 static const int starttab
[32] = {
511 static const int endtab
[32] = {
547 hyper_windowmove(struct ite_data
*ip
, int sy
, int sx
, int dy
, int dx
, int h
,
550 int width
; /* add to get to same position in next line */
552 unsigned int *psrcLine
, *pdstLine
;
553 /* pointers to line with current src and dst */
554 unsigned int *psrc
; /* pointer to current src longword */
555 unsigned int *pdst
; /* pointer to current dst longword */
557 /* following used for looping through a line */
558 unsigned int startmask
, endmask
; /* masks for writing ends of dst */
559 int nlMiddle
; /* whole longwords in dst */
560 int nl
; /* temp copy of nlMiddle */
562 /* place to store full source word */
563 int xoffSrc
; /* offset (>= 0, < 32) from which to
564 fetch whole longwords fetched
566 int nstart
; /* number of ragged bits at start of dst */
567 int nend
; /* number of ragged bits at end of dst */
569 int srcStartOver
; /* pulling nstart bits from src
570 overflows into the next word? */
572 if (h
== 0 || w
== 0)
575 width
= ip
->fbwidth
>> 5;
578 /* start at last scanline of rectangle */
579 psrcLine
= ((unsigned int *) ip
->fbbase
) + ((sy
+h
-1) * width
);
580 pdstLine
= ((unsigned int *) ip
->fbbase
) + ((dy
+h
-1) * width
);
583 /* start at first scanline */
584 psrcLine
= ((unsigned int *) ip
->fbbase
) + (sy
* width
);
585 pdstLine
= ((unsigned int *) ip
->fbbase
) + (dy
* width
);
588 /* x direction doesn't matter for < 1 longword */
590 int srcBit
, dstBit
; /* bit offset of src and dst */
592 pdstLine
+= (dx
>> 5);
593 psrcLine
+= (sx
>> 5);
601 getandputrop(psrc
, srcBit
, dstBit
, w
, pdst
, func
);
606 maskbits(dx
, w
, startmask
, endmask
, nlMiddle
);
608 nstart
= 32 - (dx
& 0x1f);
612 nend
= (dx
+ w
) & 0x1f;
616 xoffSrc
= ((sx
& 0x1f) + nstart
) & 0x1f;
617 srcStartOver
= ((sx
& 0x1f) + nstart
) > 31;
620 /* move left to right */
621 pdstLine
+= (dx
>> 5);
622 psrcLine
+= (sx
>> 5);
629 getandputrop(psrc
, (sx
& 0x1f),
630 (dx
& 0x1f), nstart
, pdst
, func
);
636 /* special case for aligned operations */
640 DoRop(*pdst
, func
, *psrc
++,
647 getunalignedword(psrc
,
649 DoRop(*pdst
, func
, tmpSrc
,
657 getandputrop0(psrc
, xoffSrc
, nend
,
665 /* move right to left */
666 pdstLine
+= ((dx
+ w
) >> 5);
667 psrcLine
+= ((sx
+ w
) >> 5);
669 * if fetch of last partial bits from source crosses
670 * a longword boundary, start at the previous longword
672 if (xoffSrc
+ nend
>= 32)
680 getandputrop0(psrc
, xoffSrc
, nend
,
688 getunalignedword(psrc
, xoffSrc
, tmpSrc
);
689 DoRop(*pdst
, func
, tmpSrc
, *pdst
);
696 getandputrop(psrc
, (sx
& 0x1f),
697 (dx
& 0x1f), nstart
, pdst
, func
);
703 } /* move right to left */
708 * Hyperion console support
711 hypercnattach(bus_space_tag_t bst
, bus_addr_t addr
, int scode
)
713 bus_space_handle_t bsh
;
716 struct grf_data
*gp
= &grf_cn
;
719 if (bus_space_map(bst
, addr
, PAGE_SIZE
, 0, &bsh
))
721 va
= bus_space_vaddr(bst
, bsh
);
722 grf
= (struct grfreg
*)va
;
725 (grf
->gr_id
!= GRFHWID
) || (grf
->gr_id2
!= GID_HYPERION
)) {
726 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
730 size
= DIO_SIZE(scode
, va
);
732 bus_space_unmap(bst
, bsh
, PAGE_SIZE
);
733 if (bus_space_map(bst
, addr
, size
, 0, &bsh
))
735 va
= bus_space_vaddr(bst
, bsh
);
738 * Initialize the framebuffer hardware.
740 (void)hy_init(gp
, scode
, va
);
741 hyperconscode
= scode
;
745 * Set up required grf data.
747 gp
->g_sw
= &hyper_grfsw
;
748 gp
->g_display
.gd_id
= gp
->g_sw
->gd_swid
;
749 gp
->g_flags
= GF_ALIVE
;
752 * Initialize the terminal emulator.
754 itedisplaycnattach(gp
, &hyper_itesw
);
758 #endif /* NITE > 0 */