xref: /openbsd/sys/arch/sparc64/dev/raptor.c (revision 63294167)
1*63294167Skettenis /*	$OpenBSD: raptor.c,v 1.12 2022/07/15 17:57:26 kettenis Exp $	*/
2116a2209Skettenis 
3116a2209Skettenis /*
4116a2209Skettenis  * Copyright (c) 2009 Mark Kettenis.
5116a2209Skettenis  *
6116a2209Skettenis  * Permission to use, copy, modify, and distribute this software for any
7116a2209Skettenis  * purpose with or without fee is hereby granted, provided that the above
8116a2209Skettenis  * copyright notice and this permission notice appear in all copies.
9116a2209Skettenis  *
10116a2209Skettenis  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11116a2209Skettenis  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12116a2209Skettenis  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13116a2209Skettenis  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14116a2209Skettenis  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15116a2209Skettenis  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16116a2209Skettenis  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17116a2209Skettenis  */
18116a2209Skettenis 
19116a2209Skettenis #include <sys/param.h>
20116a2209Skettenis #include <sys/device.h>
21116a2209Skettenis #include <sys/pciio.h>
22116a2209Skettenis #include <sys/systm.h>
23116a2209Skettenis 
24116a2209Skettenis #include <machine/autoconf.h>
25116a2209Skettenis #include <machine/bus.h>
26116a2209Skettenis 
27116a2209Skettenis #include <dev/pci/pcireg.h>
28116a2209Skettenis #include <dev/pci/pcivar.h>
29116a2209Skettenis #include <dev/pci/pcidevs.h>
30116a2209Skettenis 
31116a2209Skettenis #include <dev/wscons/wsconsio.h>
32116a2209Skettenis #include <dev/wscons/wsdisplayvar.h>
33116a2209Skettenis 
34116a2209Skettenis #include <dev/rasops/rasops.h>
35116a2209Skettenis 
36116a2209Skettenis #include <machine/fbvar.h>
37116a2209Skettenis 
38116a2209Skettenis /*
39116a2209Skettenis  * Tech Source uses the Raptor name for most of its graphics cards.
4036fd90dcSjsg  * This driver supports the original Raptor GFX cards built around
41116a2209Skettenis  * the Number 9 Imagine-128 chips.
42116a2209Skettenis  *
43116a2209Skettenis  * Official documentation for the Imagine-128 isn't available.  The
44116a2209Skettenis  * information used for writing this driver comes mostly from the Xorg
45116a2209Skettenis  * i128 driver.
46116a2209Skettenis  */
47116a2209Skettenis 
48f5dba3b0Skettenis #define I128_PCI_MW0		0x10
49f5dba3b0Skettenis #define I128_PCI_MW1		0x14
50f5dba3b0Skettenis #define I128_PCI_RBASE		0x20
51f5dba3b0Skettenis 
52bb48a507Skettenis #define I128_WR_ADR		0x0000
53bb48a507Skettenis #define I128_PAL_DAT		0x0004
54bb48a507Skettenis #define I128_PEL_MASK		0x0008
55bb48a507Skettenis 
56116a2209Skettenis #define I128_INTM		0x4004
57116a2209Skettenis #define I128_FLOW		0x4008
58116a2209Skettenis #define  I128_FLOW_DEB		0x00000001
59116a2209Skettenis #define  I128_FLOW_MCB		0x00000002
60116a2209Skettenis #define  I128_FLOW_CLP		0x00000004
61116a2209Skettenis #define  I128_FLOW_PRV		0x00000008
62116a2209Skettenis #define  I128_FLOW_ACTIVE	0x0000000f
63116a2209Skettenis #define I128_BUSY		0x400c
64116a2209Skettenis #define  I128_BUSY_BUSY		0x00000001
65116a2209Skettenis #define I128_BUF_CTRL		0x4020
66116a2209Skettenis #define  I128_BC_PSIZ_8B	0x00000000
67116a2209Skettenis #define  I128_BC_PSIZ_16B	0x01000000
68116a2209Skettenis #define  I128_BC_PSIZ_32B	0x02000000
69116a2209Skettenis #define I128_DE_PGE		0x4024
70116a2209Skettenis #define I128_DE_SORG		0x4028
71116a2209Skettenis #define I128_DE_DORG		0x402c
72116a2209Skettenis #define I128_DE_MSRC		0x4030
73116a2209Skettenis #define I128_DE_WKEY		0x4038
74116a2209Skettenis #define I128_DE_ZPTCH		0x403c
75116a2209Skettenis #define I128_DE_SPTCH		0x4040
76116a2209Skettenis #define I128_DE_DPTCH		0x4044
77116a2209Skettenis #define I128_CMD		0x4048
78116a2209Skettenis #define I128_CMD_OPC		0x4050
79116a2209Skettenis #define  I128_CO_BITBLT		0x00000001
80116a2209Skettenis #define I128_CMD_ROP		0x4054
81116a2209Skettenis #define  I128_CR_COPY		0x0000000c
82116a2209Skettenis #define I128_CMD_STYLE		0x4058
83116a2209Skettenis #define  I128_CS_SOLID		0x00000001
84116a2209Skettenis #define I128_CMD_PATRN		0x405c
85116a2209Skettenis #define I128_CMD_CLP		0x4060
86116a2209Skettenis #define I128_CMD_HDF		0x4064
87116a2209Skettenis #define I128_FORE		0x4068
88116a2209Skettenis #define I128_MASK		0x4070
89116a2209Skettenis #define I128_RMSK		0x4074
90116a2209Skettenis #define I128_LPAT		0x4078
91116a2209Skettenis #define I128_PCTRL		0x407c
92116a2209Skettenis #define I128_CLPTL		0x4080
93116a2209Skettenis #define I128_CLPBR		0x4084
94116a2209Skettenis #define I128_XY0_SRC		0x4088
95116a2209Skettenis #define I128_XY1_DST		0x408c
96116a2209Skettenis #define I128_XY2_WH		0x4090
97116a2209Skettenis #define I128_XY3_DIR		0x4094
98116a2209Skettenis #define  I128_DIR_BT		0x00000001
99116a2209Skettenis #define  I128_DIR_RL		0x00000002
100116a2209Skettenis #define I128_XY4_ZM		0x4098
101116a2209Skettenis #define  I128_ZOOM_NONE		0x00000000
102116a2209Skettenis #define I128_ACNTRL		0x416c
103116a2209Skettenis 
104116a2209Skettenis #define I128_COORDS(x, y)	((x << 16) | (y))
105116a2209Skettenis 
106116a2209Skettenis 
107116a2209Skettenis #ifdef APERTURE
108116a2209Skettenis extern int allowaperture;
109116a2209Skettenis #endif
110116a2209Skettenis 
111116a2209Skettenis struct raptor_softc {
112116a2209Skettenis 	struct sunfb	sc_sunfb;
113116a2209Skettenis 
114116a2209Skettenis 	bus_space_tag_t sc_memt;
115116a2209Skettenis 	bus_space_handle_t sc_memh;
116116a2209Skettenis 	bus_addr_t	sc_membase;
117116a2209Skettenis 	bus_size_t	sc_memsize;
118116a2209Skettenis 
119116a2209Skettenis 	bus_space_tag_t	sc_mmiot;
120116a2209Skettenis 	bus_space_handle_t sc_mmioh;
121116a2209Skettenis 	bus_addr_t	sc_mmiobase;
122116a2209Skettenis 	bus_size_t	sc_mmiosize;
123116a2209Skettenis 
124116a2209Skettenis 	pcitag_t	sc_pcitag;
125116a2209Skettenis 
126116a2209Skettenis 	int		sc_mode;
127bb48a507Skettenis 	u_int8_t	sc_cmap_red[256];
128bb48a507Skettenis 	u_int8_t	sc_cmap_green[256];
129bb48a507Skettenis 	u_int8_t	sc_cmap_blue[256];
130116a2209Skettenis };
131116a2209Skettenis 
132116a2209Skettenis int	raptor_ioctl(void *, u_long, caddr_t, int, struct proc *);
133116a2209Skettenis paddr_t	raptor_mmap(void *, off_t, int);
134116a2209Skettenis 
135116a2209Skettenis struct wsdisplay_accessops raptor_accessops = {
13687eec248Smiod 	.ioctl = raptor_ioctl,
13787eec248Smiod 	.mmap = raptor_mmap
138116a2209Skettenis };
139116a2209Skettenis 
140116a2209Skettenis int	raptor_match(struct device *, void *, void *);
141116a2209Skettenis void	raptor_attach(struct device *, struct device *, void *);
142116a2209Skettenis 
143eb7eaf8dSmpi const struct cfattach raptor_ca = {
144116a2209Skettenis 	sizeof(struct raptor_softc), raptor_match, raptor_attach
145116a2209Skettenis };
146116a2209Skettenis 
147116a2209Skettenis struct cfdriver raptor_cd = {
148116a2209Skettenis 	NULL, "raptor", DV_DULL
149116a2209Skettenis };
150116a2209Skettenis 
151116a2209Skettenis int	raptor_is_console(int);
1528972c31eSkettenis int	raptor_getcmap(struct raptor_softc *, struct wsdisplay_cmap *);
1538972c31eSkettenis int	raptor_putcmap(struct raptor_softc *, struct wsdisplay_cmap *);
154bb48a507Skettenis void	raptor_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
155116a2209Skettenis 
156072953e3Smiod int	raptor_copycols(void *, int, int, int, int);
157e0c3e559Sjsg int	raptor_erasecols(void *, int, int, int, uint32_t);
158072953e3Smiod int	raptor_copyrows(void *, int, int, int);
159e0c3e559Sjsg int	raptor_eraserows(void *, int, int, uint32_t);
160116a2209Skettenis 
161116a2209Skettenis void	raptor_init(struct raptor_softc *);
162116a2209Skettenis int	raptor_wait(struct raptor_softc *);
163116a2209Skettenis void	raptor_copyrect(struct raptor_softc *, int, int, int, int, int, int);
164116a2209Skettenis void	raptor_fillrect(struct raptor_softc *, int, int, int, int, int);
165116a2209Skettenis 
166116a2209Skettenis int
raptor_match(struct device * parent,void * cf,void * aux)167116a2209Skettenis raptor_match(struct device *parent, void *cf, void *aux)
168116a2209Skettenis {
169116a2209Skettenis 	struct pci_attach_args *pa = aux;
170116a2209Skettenis 	int node;
171116a2209Skettenis 	char *name;
172116a2209Skettenis 
173116a2209Skettenis 	node = PCITAG_NODE(pa->pa_tag);
174116a2209Skettenis 	name = getpropstring(node, "name");
175116a2209Skettenis 	if (strcmp(name, "TECH-SOURCE,raptor") == 0 ||
176116a2209Skettenis 	    strcmp(name, "TSI,raptor") == 0)
177116a2209Skettenis 		return (10);
178116a2209Skettenis 
179116a2209Skettenis 	return (0);
180116a2209Skettenis }
181116a2209Skettenis 
182116a2209Skettenis void
raptor_attach(struct device * parent,struct device * self,void * aux)183116a2209Skettenis raptor_attach(struct device *parent, struct device *self, void *aux)
184116a2209Skettenis {
185116a2209Skettenis 	struct raptor_softc *sc = (struct raptor_softc *)self;
186116a2209Skettenis 	struct pci_attach_args *pa = aux;
187116a2209Skettenis 	struct rasops_info *ri;
188116a2209Skettenis 	int node, console;
189116a2209Skettenis 	char *model;
190116a2209Skettenis 
191116a2209Skettenis 	sc->sc_pcitag = pa->pa_tag;
192116a2209Skettenis 
193116a2209Skettenis 	node = PCITAG_NODE(pa->pa_tag);
194116a2209Skettenis 	console = raptor_is_console(node);
195116a2209Skettenis 
196116a2209Skettenis 	printf("\n");
197116a2209Skettenis 
198116a2209Skettenis 	model = getpropstring(node, "model");
199116a2209Skettenis 	printf("%s: %s", self->dv_xname, model);
200116a2209Skettenis 
201f5dba3b0Skettenis 	if (pci_mapreg_map(pa, I128_PCI_MW0, PCI_MAPREG_TYPE_MEM,
202116a2209Skettenis 	    BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh,
203116a2209Skettenis 	    &sc->sc_membase, &sc->sc_memsize, 0)) {
204116a2209Skettenis 		printf("\n%s: can't map video memory\n", self->dv_xname);
205116a2209Skettenis 		return;
206116a2209Skettenis 	}
207116a2209Skettenis 
208f5dba3b0Skettenis 	if (pci_mapreg_map(pa, I128_PCI_RBASE, PCI_MAPREG_TYPE_MEM, 0,
209116a2209Skettenis 	    &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmiobase,
210116a2209Skettenis 	    &sc->sc_mmiosize, 0)) {
211116a2209Skettenis 		bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_memsize);
212116a2209Skettenis 		printf("\n%s: can't map mmio\n", self->dv_xname);
213116a2209Skettenis 		return;
214116a2209Skettenis 	}
215116a2209Skettenis 
216116a2209Skettenis 	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
217116a2209Skettenis 
218116a2209Skettenis 	printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
219116a2209Skettenis 
220116a2209Skettenis 	ri = &sc->sc_sunfb.sf_ro;
221116a2209Skettenis 	ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
222116a2209Skettenis 	ri->ri_hw = sc;
223116a2209Skettenis 
224116a2209Skettenis 	fbwscons_init(&sc->sc_sunfb, RI_BSWAP, console);
225bb48a507Skettenis 	fbwscons_setcolormap(&sc->sc_sunfb, raptor_setcolor);
226116a2209Skettenis 	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
227116a2209Skettenis 
228116a2209Skettenis 	raptor_init(sc);
229116a2209Skettenis 	ri->ri_ops.copyrows = raptor_copyrows;
230116a2209Skettenis 	ri->ri_ops.copycols = raptor_copycols;
231116a2209Skettenis 	ri->ri_ops.eraserows = raptor_eraserows;
232116a2209Skettenis 	ri->ri_ops.erasecols = raptor_erasecols;
233116a2209Skettenis 
234116a2209Skettenis 	if (console)
235116a2209Skettenis 		fbwscons_console_init(&sc->sc_sunfb, -1);
236116a2209Skettenis 	fbwscons_attach(&sc->sc_sunfb, &raptor_accessops, console);
237116a2209Skettenis }
238116a2209Skettenis 
239116a2209Skettenis int
raptor_ioctl(void * v,u_long cmd,caddr_t data,int flags,struct proc * p)240116a2209Skettenis raptor_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
241116a2209Skettenis {
242116a2209Skettenis 	struct raptor_softc *sc = v;
243116a2209Skettenis 	struct wsdisplay_fbinfo *wdf;
244116a2209Skettenis 	struct pcisel *sel;
245116a2209Skettenis 
246116a2209Skettenis 	switch (cmd) {
247116a2209Skettenis 	case WSDISPLAYIO_GTYPE:
248993ff338Skettenis 		*(u_int *)data = WSDISPLAY_TYPE_RAPTOR;
249116a2209Skettenis 		break;
250116a2209Skettenis 	case WSDISPLAYIO_SMODE:
251116a2209Skettenis 		sc->sc_mode = *(u_int *)data;
252bb48a507Skettenis 		if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)
253bb48a507Skettenis 			fbwscons_setcolormap(&sc->sc_sunfb, raptor_setcolor);
254116a2209Skettenis 		break;
255116a2209Skettenis 	case WSDISPLAYIO_GINFO:
256116a2209Skettenis 		wdf = (void *)data;
257116a2209Skettenis 		wdf->height = sc->sc_sunfb.sf_height;
258116a2209Skettenis 		wdf->width  = sc->sc_sunfb.sf_width;
259116a2209Skettenis 		wdf->depth  = sc->sc_sunfb.sf_depth;
260*63294167Skettenis 		wdf->stride = sc->sc_sunfb.sf_linebytes;
261*63294167Skettenis 		wdf->offset = 0;
262116a2209Skettenis 		wdf->cmsize = 256;
263116a2209Skettenis 		break;
264116a2209Skettenis 	case WSDISPLAYIO_LINEBYTES:
265116a2209Skettenis 		*(u_int *)data = sc->sc_sunfb.sf_linebytes;
266116a2209Skettenis 		break;
267116a2209Skettenis 
268116a2209Skettenis 	case WSDISPLAYIO_GETCMAP:
269116a2209Skettenis 		return raptor_getcmap(sc, (struct wsdisplay_cmap *)data);
270116a2209Skettenis 	case WSDISPLAYIO_PUTCMAP:
271116a2209Skettenis 		return raptor_putcmap(sc, (struct wsdisplay_cmap *)data);
272116a2209Skettenis 
273116a2209Skettenis 	case WSDISPLAYIO_GPCIID:
274116a2209Skettenis 		sel = (struct pcisel *)data;
275116a2209Skettenis 		sel->pc_bus = PCITAG_BUS(sc->sc_pcitag);
276116a2209Skettenis 		sel->pc_dev = PCITAG_DEV(sc->sc_pcitag);
277116a2209Skettenis 		sel->pc_func = PCITAG_FUN(sc->sc_pcitag);
278116a2209Skettenis 		break;
279116a2209Skettenis 
280116a2209Skettenis 	case WSDISPLAYIO_SVIDEO:
281116a2209Skettenis 	case WSDISPLAYIO_GVIDEO:
282116a2209Skettenis 		break;
283116a2209Skettenis 
284116a2209Skettenis 	case WSDISPLAYIO_GCURPOS:
285116a2209Skettenis 	case WSDISPLAYIO_SCURPOS:
286116a2209Skettenis 	case WSDISPLAYIO_GCURMAX:
287116a2209Skettenis 	case WSDISPLAYIO_GCURSOR:
288116a2209Skettenis 	case WSDISPLAYIO_SCURSOR:
289116a2209Skettenis 	default:
290116a2209Skettenis 		return -1; /* not supported yet */
291116a2209Skettenis         }
292116a2209Skettenis 
293116a2209Skettenis 	return (0);
294116a2209Skettenis }
295116a2209Skettenis 
296116a2209Skettenis paddr_t
raptor_mmap(void * v,off_t off,int prot)297116a2209Skettenis raptor_mmap(void *v, off_t off, int prot)
298116a2209Skettenis {
299116a2209Skettenis 	struct raptor_softc *sc = v;
300116a2209Skettenis 
301116a2209Skettenis 	if (off & PGOFSET)
302116a2209Skettenis 		return (-1);
303116a2209Skettenis 
304116a2209Skettenis 	switch (sc->sc_mode) {
305116a2209Skettenis 	case WSDISPLAYIO_MODE_MAPPED:
306116a2209Skettenis #ifdef APERTURE
307116a2209Skettenis 		if (allowaperture == 0)
308116a2209Skettenis 			return (-1);
309116a2209Skettenis #endif
310116a2209Skettenis 
311116a2209Skettenis 		if (sc->sc_mmiosize == 0)
312116a2209Skettenis 			return (-1);
313116a2209Skettenis 
314116a2209Skettenis 		if (off >= sc->sc_membase &&
315116a2209Skettenis 		    off < (sc->sc_membase + sc->sc_memsize))
316116a2209Skettenis 			return (bus_space_mmap(sc->sc_memt,
317116a2209Skettenis 			    sc->sc_membase, off - sc->sc_membase,
318116a2209Skettenis 			    prot, BUS_SPACE_MAP_LINEAR));
319116a2209Skettenis 
320116a2209Skettenis 		if (off >= sc->sc_mmiobase &&
321116a2209Skettenis 		    off < (sc->sc_mmiobase + sc->sc_mmiosize))
322116a2209Skettenis 			return (bus_space_mmap(sc->sc_mmiot,
323116a2209Skettenis 			    sc->sc_mmiobase, off - sc->sc_mmiobase,
324116a2209Skettenis 			    prot, BUS_SPACE_MAP_LINEAR));
325116a2209Skettenis 		break;
326116a2209Skettenis 
327116a2209Skettenis 	case WSDISPLAYIO_MODE_DUMBFB:
328116a2209Skettenis 		if (off >= 0 && off < sc->sc_memsize)
329116a2209Skettenis 			return (bus_space_mmap(sc->sc_memt, sc->sc_membase,
330116a2209Skettenis 			    off, prot, BUS_SPACE_MAP_LINEAR));
331116a2209Skettenis 		break;
332116a2209Skettenis 	}
333116a2209Skettenis 
334116a2209Skettenis 	return (-1);
335116a2209Skettenis }
336116a2209Skettenis 
337116a2209Skettenis int
raptor_is_console(int node)338116a2209Skettenis raptor_is_console(int node)
339116a2209Skettenis {
340116a2209Skettenis 	extern int fbnode;
341116a2209Skettenis 
342116a2209Skettenis 	return (fbnode == node);
343116a2209Skettenis }
344116a2209Skettenis 
3458972c31eSkettenis int
raptor_getcmap(struct raptor_softc * sc,struct wsdisplay_cmap * cm)3468972c31eSkettenis raptor_getcmap(struct raptor_softc *sc, struct wsdisplay_cmap *cm)
3478972c31eSkettenis {
3488972c31eSkettenis 	u_int index = cm->index;
3498972c31eSkettenis 	u_int count = cm->count;
3508972c31eSkettenis 	int error;
3518972c31eSkettenis 
3528972c31eSkettenis 	if (index >= 256 || count > 256 - index)
3538972c31eSkettenis 		return (EINVAL);
3548972c31eSkettenis 
3558972c31eSkettenis 	error = copyout(&sc->sc_cmap_red[index], cm->red, count);
3568972c31eSkettenis 	if (error)
3578972c31eSkettenis 		return (error);
3588972c31eSkettenis 	error = copyout(&sc->sc_cmap_green[index], cm->green, count);
3598972c31eSkettenis 	if (error)
3608972c31eSkettenis 		return (error);
3618972c31eSkettenis 	error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
3628972c31eSkettenis 	if (error)
3638972c31eSkettenis 		return (error);
3648972c31eSkettenis 	return (0);
3658972c31eSkettenis }
3668972c31eSkettenis 
3678972c31eSkettenis int
raptor_putcmap(struct raptor_softc * sc,struct wsdisplay_cmap * cm)3688972c31eSkettenis raptor_putcmap(struct raptor_softc *sc, struct wsdisplay_cmap *cm)
3698972c31eSkettenis {
3708972c31eSkettenis 	u_int index = cm->index;
3718972c31eSkettenis 	u_int count = cm->count;
3728972c31eSkettenis 	u_int i;
3738972c31eSkettenis 	int error;
3748972c31eSkettenis 	u_char *r, *g, *b;
3758972c31eSkettenis 
3768972c31eSkettenis 	if (index >= 256 || count > 256 - index)
3778972c31eSkettenis 		return (EINVAL);
3788972c31eSkettenis 
3798972c31eSkettenis 	if ((error = copyin(cm->red, &sc->sc_cmap_red[index], count)) != 0)
3808972c31eSkettenis 		return (error);
3818972c31eSkettenis 	if ((error = copyin(cm->green, &sc->sc_cmap_green[index], count)) != 0)
3828972c31eSkettenis 		return (error);
3838972c31eSkettenis 	if ((error = copyin(cm->blue, &sc->sc_cmap_blue[index], count)) != 0)
3848972c31eSkettenis 		return (error);
3858972c31eSkettenis 
3868972c31eSkettenis 	r = &sc->sc_cmap_red[index];
3878972c31eSkettenis 	g = &sc->sc_cmap_green[index];
3888972c31eSkettenis 	b = &sc->sc_cmap_blue[index];
3898972c31eSkettenis 
3908972c31eSkettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PEL_MASK, 0xff);
3918972c31eSkettenis 	for (i = 0; i < count; i++) {
3928972c31eSkettenis 		bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
3938972c31eSkettenis 		    I128_WR_ADR, index);
3948972c31eSkettenis 		bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
3958972c31eSkettenis 		    I128_PAL_DAT, *r);
3968972c31eSkettenis 		bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
3978972c31eSkettenis 		    I128_PAL_DAT, *g);
3988972c31eSkettenis 		bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
3998972c31eSkettenis 		    I128_PAL_DAT, *b);
4008972c31eSkettenis 		r++, g++, b++, index++;
4018972c31eSkettenis 	}
4028972c31eSkettenis 	return (0);
4038972c31eSkettenis }
4048972c31eSkettenis 
405bb48a507Skettenis void
raptor_setcolor(void * v,u_int index,u_int8_t r,u_int8_t g,u_int8_t b)406bb48a507Skettenis raptor_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
407bb48a507Skettenis {
408bb48a507Skettenis 	struct raptor_softc *sc = v;
409bb48a507Skettenis 
410bb48a507Skettenis 	sc->sc_cmap_red[index] = r;
411bb48a507Skettenis 	sc->sc_cmap_green[index] = g;
412bb48a507Skettenis 	sc->sc_cmap_blue[index] = b;
413bb48a507Skettenis 
414bb48a507Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PEL_MASK, 0xff);
415bb48a507Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_WR_ADR, index);
416bb48a507Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, r);
417bb48a507Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, g);
418bb48a507Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, b);
419bb48a507Skettenis }
420bb48a507Skettenis 
421116a2209Skettenis /*
422116a2209Skettenis  * Accelerated routines.
423116a2209Skettenis  */
424116a2209Skettenis 
425072953e3Smiod int
raptor_copycols(void * cookie,int row,int src,int dst,int num)426116a2209Skettenis raptor_copycols(void *cookie, int row, int src, int dst, int num)
427116a2209Skettenis {
428116a2209Skettenis 	struct rasops_info *ri = cookie;
429116a2209Skettenis 	struct raptor_softc *sc = ri->ri_hw;
430116a2209Skettenis 
431116a2209Skettenis 	num *= ri->ri_font->fontwidth;
432116a2209Skettenis 	src *= ri->ri_font->fontwidth;
433116a2209Skettenis 	dst *= ri->ri_font->fontwidth;
434116a2209Skettenis 	row *= ri->ri_font->fontheight;
435116a2209Skettenis 
436116a2209Skettenis 	raptor_copyrect(sc, ri->ri_xorigin + src, ri->ri_yorigin + row,
437116a2209Skettenis 	    ri->ri_xorigin + dst, ri->ri_yorigin + row,
438116a2209Skettenis 	    num, ri->ri_font->fontheight);
439072953e3Smiod 
440072953e3Smiod 	return 0;
441116a2209Skettenis }
442116a2209Skettenis 
443072953e3Smiod int
raptor_erasecols(void * cookie,int row,int col,int num,uint32_t attr)444e0c3e559Sjsg raptor_erasecols(void *cookie, int row, int col, int num, uint32_t attr)
445116a2209Skettenis {
446116a2209Skettenis 	struct rasops_info *ri = cookie;
447116a2209Skettenis 	struct raptor_softc *sc = ri->ri_hw;
448116a2209Skettenis 	int bg, fg;
449116a2209Skettenis 
450116a2209Skettenis 	ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
451116a2209Skettenis 
452116a2209Skettenis 	row *= ri->ri_font->fontheight;
453116a2209Skettenis 	col *= ri->ri_font->fontwidth;
454116a2209Skettenis 	num *= ri->ri_font->fontwidth;
455116a2209Skettenis 
456116a2209Skettenis 	raptor_fillrect(sc, ri->ri_xorigin + col, ri->ri_yorigin + row,
457116a2209Skettenis 	    num, ri->ri_font->fontheight, ri->ri_devcmap[bg]);
458072953e3Smiod 
459072953e3Smiod 	return 0;
460116a2209Skettenis }
461116a2209Skettenis 
462072953e3Smiod int
raptor_copyrows(void * cookie,int src,int dst,int num)463116a2209Skettenis raptor_copyrows(void *cookie, int src, int dst, int num)
464116a2209Skettenis {
465116a2209Skettenis 	struct rasops_info *ri = cookie;
466116a2209Skettenis 	struct raptor_softc *sc = ri->ri_hw;
467116a2209Skettenis 
468116a2209Skettenis 	num *= ri->ri_font->fontheight;
469116a2209Skettenis 	src *= ri->ri_font->fontheight;
470116a2209Skettenis 	dst *= ri->ri_font->fontheight;
471116a2209Skettenis 
472116a2209Skettenis 	raptor_copyrect(sc, ri->ri_xorigin, ri->ri_yorigin + src,
473116a2209Skettenis 	    ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, num);
474072953e3Smiod 
475072953e3Smiod 	return 0;
476116a2209Skettenis }
477116a2209Skettenis 
478072953e3Smiod int
raptor_eraserows(void * cookie,int row,int num,uint32_t attr)479e0c3e559Sjsg raptor_eraserows(void *cookie, int row, int num, uint32_t attr)
480116a2209Skettenis {
481116a2209Skettenis 	struct rasops_info *ri = cookie;
482116a2209Skettenis 	struct raptor_softc *sc = ri->ri_hw;
483116a2209Skettenis 	int bg, fg;
484116a2209Skettenis 	int x, y, w;
485116a2209Skettenis 
486116a2209Skettenis 	ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
487116a2209Skettenis 
488116a2209Skettenis 	if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) {
489116a2209Skettenis 		num = ri->ri_height;
490116a2209Skettenis 		x = y = 0;
491116a2209Skettenis 		w = ri->ri_width;
492116a2209Skettenis 	} else {
493116a2209Skettenis 		num *= ri->ri_font->fontheight;
494116a2209Skettenis 		x = ri->ri_xorigin;
495116a2209Skettenis 		y = ri->ri_yorigin + row * ri->ri_font->fontheight;
496116a2209Skettenis 		w = ri->ri_emuwidth;
497116a2209Skettenis 	}
498116a2209Skettenis 	raptor_fillrect(sc, x, y, w, num, ri->ri_devcmap[bg]);
499072953e3Smiod 
500072953e3Smiod 	return 0;
501116a2209Skettenis }
502116a2209Skettenis 
503116a2209Skettenis void
raptor_init(struct raptor_softc * sc)504116a2209Skettenis raptor_init(struct raptor_softc *sc)
505116a2209Skettenis {
506116a2209Skettenis 	/* Configure pixel format based on depth. */
507116a2209Skettenis 	switch(sc->sc_sunfb.sf_depth) {
508116a2209Skettenis 	case 8:
509116a2209Skettenis 		bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
510116a2209Skettenis 		    I128_BUF_CTRL, I128_BC_PSIZ_8B);
511116a2209Skettenis 		break;
512116a2209Skettenis 	case 16:
513116a2209Skettenis 		bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
514116a2209Skettenis 		    I128_BUF_CTRL, I128_BC_PSIZ_16B);
515116a2209Skettenis 		break;
516116a2209Skettenis 	case 24:
517116a2209Skettenis 	case 32:
518116a2209Skettenis 		bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
519116a2209Skettenis 		    I128_BUF_CTRL, I128_BC_PSIZ_32B);
520116a2209Skettenis 		break;
521116a2209Skettenis 	default:
522859d5ed4Skrw 		panic("unsupported depth");
523116a2209Skettenis 		break;
524116a2209Skettenis 	}
525116a2209Skettenis 
526116a2209Skettenis 	/* Mostly magic. */
527116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_PGE, 0);
528116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_SORG, 0);
529116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_DORG, 0);
530116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_MSRC, 0);
531116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_WKEY, 0);
532116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_SPTCH,
533116a2209Skettenis 	    sc->sc_sunfb.sf_linebytes);
534116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_DPTCH,
535116a2209Skettenis 	    sc->sc_sunfb.sf_linebytes);
536116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_ZPTCH,
537116a2209Skettenis 	    sc->sc_sunfb.sf_linebytes);
538116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_RMSK, 0);
539116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY4_ZM,
540116a2209Skettenis 	    I128_ZOOM_NONE);
541116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_LPAT,
542116a2209Skettenis 	    0xffffffff);
543116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PCTRL, 0);
544116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CLPTL, 0);
545116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CLPBR,
546f5dba3b0Skettenis 	    I128_COORDS(4095, 2047));
547116a2209Skettenis #if 0
548116a2209Skettenis 	/* XXX For some reason this makes schizo(4) freak out. */
549116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_ACNTRL, 0);
550116a2209Skettenis #endif
551116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_INTM, 3);
552116a2209Skettenis }
553116a2209Skettenis 
554116a2209Skettenis int
raptor_wait(struct raptor_softc * sc)555116a2209Skettenis raptor_wait(struct raptor_softc *sc)
556116a2209Skettenis {
557116a2209Skettenis 	int i;
558116a2209Skettenis 
559116a2209Skettenis 	for (i = 1000000; i != 0; i--) {
560116a2209Skettenis 		if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
561116a2209Skettenis 		    I128_FLOW) & I128_FLOW_ACTIVE) == 0)
562116a2209Skettenis 			break;
563116a2209Skettenis 		DELAY(1);
564116a2209Skettenis 	}
565116a2209Skettenis 
566116a2209Skettenis 	return i;
567116a2209Skettenis }
568116a2209Skettenis 
569116a2209Skettenis void
raptor_copyrect(struct raptor_softc * sc,int sx,int sy,int dx,int dy,int w,int h)570116a2209Skettenis raptor_copyrect(struct raptor_softc *sc, int sx, int sy, int dx, int dy,
571116a2209Skettenis     int w, int h)
572116a2209Skettenis {
573116a2209Skettenis 	int dir = 0;
574116a2209Skettenis 
575116a2209Skettenis 	while (bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
576116a2209Skettenis 	    I128_BUSY) & I128_BUSY_BUSY)
577116a2209Skettenis 		DELAY(1);
578116a2209Skettenis 
579116a2209Skettenis 	if (sx < dx) {
580116a2209Skettenis 		sx += w - 1;
581116a2209Skettenis 		dx += w - 1;
582116a2209Skettenis 		dir |= I128_DIR_RL;
583116a2209Skettenis 	}
584116a2209Skettenis 	if (sy < dy) {
585116a2209Skettenis 		sy += h - 1;
586116a2209Skettenis 		dy += h - 1;
587116a2209Skettenis 		dir |= I128_DIR_BT;
588116a2209Skettenis 	}
589116a2209Skettenis 
590116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CMD,
591116a2209Skettenis 	    I128_CR_COPY << 8 | I128_CO_BITBLT);
592116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY3_DIR, dir);
593116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY2_WH,
594116a2209Skettenis 	    I128_COORDS(w , h));
595116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY0_SRC,
596116a2209Skettenis 	    I128_COORDS(sx, sy));
597116a2209Skettenis 	/* Must be last; triggers operation. */
598116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY1_DST,
599116a2209Skettenis 	    I128_COORDS(dx, dy));
600116a2209Skettenis 
601116a2209Skettenis 	raptor_wait(sc);
602116a2209Skettenis }
603116a2209Skettenis 
604116a2209Skettenis void
raptor_fillrect(struct raptor_softc * sc,int x,int y,int w,int h,int color)605116a2209Skettenis raptor_fillrect(struct raptor_softc *sc, int x, int y, int w, int h, int color)
606116a2209Skettenis {
607116a2209Skettenis 	while (bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
608116a2209Skettenis 	    I128_BUSY) & I128_BUSY_BUSY)
609116a2209Skettenis 		DELAY(1);
610116a2209Skettenis 
611116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CMD,
612116a2209Skettenis 	    I128_CS_SOLID << 16 | I128_CR_COPY << 8 | I128_CO_BITBLT);
613116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_FORE, color);
614116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY3_DIR, 0);
615116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY2_WH,
616116a2209Skettenis 	    I128_COORDS(w, h));
617116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY0_SRC, 0);
618116a2209Skettenis 	/* Must be last; triggers operation. */
619116a2209Skettenis 	bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY1_DST,
620116a2209Skettenis 	    I128_COORDS(x, y));
621116a2209Skettenis 
622116a2209Skettenis 	raptor_wait(sc);
623116a2209Skettenis }
624