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