1 /* $OpenBSD: raptor.c,v 1.12 2022/07/15 17:57:26 kettenis Exp $ */
2
3 /*
4 * Copyright (c) 2009 Mark Kettenis.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/param.h>
20 #include <sys/device.h>
21 #include <sys/pciio.h>
22 #include <sys/systm.h>
23
24 #include <machine/autoconf.h>
25 #include <machine/bus.h>
26
27 #include <dev/pci/pcireg.h>
28 #include <dev/pci/pcivar.h>
29 #include <dev/pci/pcidevs.h>
30
31 #include <dev/wscons/wsconsio.h>
32 #include <dev/wscons/wsdisplayvar.h>
33
34 #include <dev/rasops/rasops.h>
35
36 #include <machine/fbvar.h>
37
38 /*
39 * Tech Source uses the Raptor name for most of its graphics cards.
40 * This driver supports the original Raptor GFX cards built around
41 * the Number 9 Imagine-128 chips.
42 *
43 * Official documentation for the Imagine-128 isn't available. The
44 * information used for writing this driver comes mostly from the Xorg
45 * i128 driver.
46 */
47
48 #define I128_PCI_MW0 0x10
49 #define I128_PCI_MW1 0x14
50 #define I128_PCI_RBASE 0x20
51
52 #define I128_WR_ADR 0x0000
53 #define I128_PAL_DAT 0x0004
54 #define I128_PEL_MASK 0x0008
55
56 #define I128_INTM 0x4004
57 #define I128_FLOW 0x4008
58 #define I128_FLOW_DEB 0x00000001
59 #define I128_FLOW_MCB 0x00000002
60 #define I128_FLOW_CLP 0x00000004
61 #define I128_FLOW_PRV 0x00000008
62 #define I128_FLOW_ACTIVE 0x0000000f
63 #define I128_BUSY 0x400c
64 #define I128_BUSY_BUSY 0x00000001
65 #define I128_BUF_CTRL 0x4020
66 #define I128_BC_PSIZ_8B 0x00000000
67 #define I128_BC_PSIZ_16B 0x01000000
68 #define I128_BC_PSIZ_32B 0x02000000
69 #define I128_DE_PGE 0x4024
70 #define I128_DE_SORG 0x4028
71 #define I128_DE_DORG 0x402c
72 #define I128_DE_MSRC 0x4030
73 #define I128_DE_WKEY 0x4038
74 #define I128_DE_ZPTCH 0x403c
75 #define I128_DE_SPTCH 0x4040
76 #define I128_DE_DPTCH 0x4044
77 #define I128_CMD 0x4048
78 #define I128_CMD_OPC 0x4050
79 #define I128_CO_BITBLT 0x00000001
80 #define I128_CMD_ROP 0x4054
81 #define I128_CR_COPY 0x0000000c
82 #define I128_CMD_STYLE 0x4058
83 #define I128_CS_SOLID 0x00000001
84 #define I128_CMD_PATRN 0x405c
85 #define I128_CMD_CLP 0x4060
86 #define I128_CMD_HDF 0x4064
87 #define I128_FORE 0x4068
88 #define I128_MASK 0x4070
89 #define I128_RMSK 0x4074
90 #define I128_LPAT 0x4078
91 #define I128_PCTRL 0x407c
92 #define I128_CLPTL 0x4080
93 #define I128_CLPBR 0x4084
94 #define I128_XY0_SRC 0x4088
95 #define I128_XY1_DST 0x408c
96 #define I128_XY2_WH 0x4090
97 #define I128_XY3_DIR 0x4094
98 #define I128_DIR_BT 0x00000001
99 #define I128_DIR_RL 0x00000002
100 #define I128_XY4_ZM 0x4098
101 #define I128_ZOOM_NONE 0x00000000
102 #define I128_ACNTRL 0x416c
103
104 #define I128_COORDS(x, y) ((x << 16) | (y))
105
106
107 #ifdef APERTURE
108 extern int allowaperture;
109 #endif
110
111 struct raptor_softc {
112 struct sunfb sc_sunfb;
113
114 bus_space_tag_t sc_memt;
115 bus_space_handle_t sc_memh;
116 bus_addr_t sc_membase;
117 bus_size_t sc_memsize;
118
119 bus_space_tag_t sc_mmiot;
120 bus_space_handle_t sc_mmioh;
121 bus_addr_t sc_mmiobase;
122 bus_size_t sc_mmiosize;
123
124 pcitag_t sc_pcitag;
125
126 int sc_mode;
127 u_int8_t sc_cmap_red[256];
128 u_int8_t sc_cmap_green[256];
129 u_int8_t sc_cmap_blue[256];
130 };
131
132 int raptor_ioctl(void *, u_long, caddr_t, int, struct proc *);
133 paddr_t raptor_mmap(void *, off_t, int);
134
135 struct wsdisplay_accessops raptor_accessops = {
136 .ioctl = raptor_ioctl,
137 .mmap = raptor_mmap
138 };
139
140 int raptor_match(struct device *, void *, void *);
141 void raptor_attach(struct device *, struct device *, void *);
142
143 const struct cfattach raptor_ca = {
144 sizeof(struct raptor_softc), raptor_match, raptor_attach
145 };
146
147 struct cfdriver raptor_cd = {
148 NULL, "raptor", DV_DULL
149 };
150
151 int raptor_is_console(int);
152 int raptor_getcmap(struct raptor_softc *, struct wsdisplay_cmap *);
153 int raptor_putcmap(struct raptor_softc *, struct wsdisplay_cmap *);
154 void raptor_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
155
156 int raptor_copycols(void *, int, int, int, int);
157 int raptor_erasecols(void *, int, int, int, uint32_t);
158 int raptor_copyrows(void *, int, int, int);
159 int raptor_eraserows(void *, int, int, uint32_t);
160
161 void raptor_init(struct raptor_softc *);
162 int raptor_wait(struct raptor_softc *);
163 void raptor_copyrect(struct raptor_softc *, int, int, int, int, int, int);
164 void raptor_fillrect(struct raptor_softc *, int, int, int, int, int);
165
166 int
raptor_match(struct device * parent,void * cf,void * aux)167 raptor_match(struct device *parent, void *cf, void *aux)
168 {
169 struct pci_attach_args *pa = aux;
170 int node;
171 char *name;
172
173 node = PCITAG_NODE(pa->pa_tag);
174 name = getpropstring(node, "name");
175 if (strcmp(name, "TECH-SOURCE,raptor") == 0 ||
176 strcmp(name, "TSI,raptor") == 0)
177 return (10);
178
179 return (0);
180 }
181
182 void
raptor_attach(struct device * parent,struct device * self,void * aux)183 raptor_attach(struct device *parent, struct device *self, void *aux)
184 {
185 struct raptor_softc *sc = (struct raptor_softc *)self;
186 struct pci_attach_args *pa = aux;
187 struct rasops_info *ri;
188 int node, console;
189 char *model;
190
191 sc->sc_pcitag = pa->pa_tag;
192
193 node = PCITAG_NODE(pa->pa_tag);
194 console = raptor_is_console(node);
195
196 printf("\n");
197
198 model = getpropstring(node, "model");
199 printf("%s: %s", self->dv_xname, model);
200
201 if (pci_mapreg_map(pa, I128_PCI_MW0, PCI_MAPREG_TYPE_MEM,
202 BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh,
203 &sc->sc_membase, &sc->sc_memsize, 0)) {
204 printf("\n%s: can't map video memory\n", self->dv_xname);
205 return;
206 }
207
208 if (pci_mapreg_map(pa, I128_PCI_RBASE, PCI_MAPREG_TYPE_MEM, 0,
209 &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmiobase,
210 &sc->sc_mmiosize, 0)) {
211 bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_memsize);
212 printf("\n%s: can't map mmio\n", self->dv_xname);
213 return;
214 }
215
216 fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
217
218 printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
219
220 ri = &sc->sc_sunfb.sf_ro;
221 ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
222 ri->ri_hw = sc;
223
224 fbwscons_init(&sc->sc_sunfb, RI_BSWAP, console);
225 fbwscons_setcolormap(&sc->sc_sunfb, raptor_setcolor);
226 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
227
228 raptor_init(sc);
229 ri->ri_ops.copyrows = raptor_copyrows;
230 ri->ri_ops.copycols = raptor_copycols;
231 ri->ri_ops.eraserows = raptor_eraserows;
232 ri->ri_ops.erasecols = raptor_erasecols;
233
234 if (console)
235 fbwscons_console_init(&sc->sc_sunfb, -1);
236 fbwscons_attach(&sc->sc_sunfb, &raptor_accessops, console);
237 }
238
239 int
raptor_ioctl(void * v,u_long cmd,caddr_t data,int flags,struct proc * p)240 raptor_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
241 {
242 struct raptor_softc *sc = v;
243 struct wsdisplay_fbinfo *wdf;
244 struct pcisel *sel;
245
246 switch (cmd) {
247 case WSDISPLAYIO_GTYPE:
248 *(u_int *)data = WSDISPLAY_TYPE_RAPTOR;
249 break;
250 case WSDISPLAYIO_SMODE:
251 sc->sc_mode = *(u_int *)data;
252 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)
253 fbwscons_setcolormap(&sc->sc_sunfb, raptor_setcolor);
254 break;
255 case WSDISPLAYIO_GINFO:
256 wdf = (void *)data;
257 wdf->height = sc->sc_sunfb.sf_height;
258 wdf->width = sc->sc_sunfb.sf_width;
259 wdf->depth = sc->sc_sunfb.sf_depth;
260 wdf->stride = sc->sc_sunfb.sf_linebytes;
261 wdf->offset = 0;
262 wdf->cmsize = 256;
263 break;
264 case WSDISPLAYIO_LINEBYTES:
265 *(u_int *)data = sc->sc_sunfb.sf_linebytes;
266 break;
267
268 case WSDISPLAYIO_GETCMAP:
269 return raptor_getcmap(sc, (struct wsdisplay_cmap *)data);
270 case WSDISPLAYIO_PUTCMAP:
271 return raptor_putcmap(sc, (struct wsdisplay_cmap *)data);
272
273 case WSDISPLAYIO_GPCIID:
274 sel = (struct pcisel *)data;
275 sel->pc_bus = PCITAG_BUS(sc->sc_pcitag);
276 sel->pc_dev = PCITAG_DEV(sc->sc_pcitag);
277 sel->pc_func = PCITAG_FUN(sc->sc_pcitag);
278 break;
279
280 case WSDISPLAYIO_SVIDEO:
281 case WSDISPLAYIO_GVIDEO:
282 break;
283
284 case WSDISPLAYIO_GCURPOS:
285 case WSDISPLAYIO_SCURPOS:
286 case WSDISPLAYIO_GCURMAX:
287 case WSDISPLAYIO_GCURSOR:
288 case WSDISPLAYIO_SCURSOR:
289 default:
290 return -1; /* not supported yet */
291 }
292
293 return (0);
294 }
295
296 paddr_t
raptor_mmap(void * v,off_t off,int prot)297 raptor_mmap(void *v, off_t off, int prot)
298 {
299 struct raptor_softc *sc = v;
300
301 if (off & PGOFSET)
302 return (-1);
303
304 switch (sc->sc_mode) {
305 case WSDISPLAYIO_MODE_MAPPED:
306 #ifdef APERTURE
307 if (allowaperture == 0)
308 return (-1);
309 #endif
310
311 if (sc->sc_mmiosize == 0)
312 return (-1);
313
314 if (off >= sc->sc_membase &&
315 off < (sc->sc_membase + sc->sc_memsize))
316 return (bus_space_mmap(sc->sc_memt,
317 sc->sc_membase, off - sc->sc_membase,
318 prot, BUS_SPACE_MAP_LINEAR));
319
320 if (off >= sc->sc_mmiobase &&
321 off < (sc->sc_mmiobase + sc->sc_mmiosize))
322 return (bus_space_mmap(sc->sc_mmiot,
323 sc->sc_mmiobase, off - sc->sc_mmiobase,
324 prot, BUS_SPACE_MAP_LINEAR));
325 break;
326
327 case WSDISPLAYIO_MODE_DUMBFB:
328 if (off >= 0 && off < sc->sc_memsize)
329 return (bus_space_mmap(sc->sc_memt, sc->sc_membase,
330 off, prot, BUS_SPACE_MAP_LINEAR));
331 break;
332 }
333
334 return (-1);
335 }
336
337 int
raptor_is_console(int node)338 raptor_is_console(int node)
339 {
340 extern int fbnode;
341
342 return (fbnode == node);
343 }
344
345 int
raptor_getcmap(struct raptor_softc * sc,struct wsdisplay_cmap * cm)346 raptor_getcmap(struct raptor_softc *sc, struct wsdisplay_cmap *cm)
347 {
348 u_int index = cm->index;
349 u_int count = cm->count;
350 int error;
351
352 if (index >= 256 || count > 256 - index)
353 return (EINVAL);
354
355 error = copyout(&sc->sc_cmap_red[index], cm->red, count);
356 if (error)
357 return (error);
358 error = copyout(&sc->sc_cmap_green[index], cm->green, count);
359 if (error)
360 return (error);
361 error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
362 if (error)
363 return (error);
364 return (0);
365 }
366
367 int
raptor_putcmap(struct raptor_softc * sc,struct wsdisplay_cmap * cm)368 raptor_putcmap(struct raptor_softc *sc, struct wsdisplay_cmap *cm)
369 {
370 u_int index = cm->index;
371 u_int count = cm->count;
372 u_int i;
373 int error;
374 u_char *r, *g, *b;
375
376 if (index >= 256 || count > 256 - index)
377 return (EINVAL);
378
379 if ((error = copyin(cm->red, &sc->sc_cmap_red[index], count)) != 0)
380 return (error);
381 if ((error = copyin(cm->green, &sc->sc_cmap_green[index], count)) != 0)
382 return (error);
383 if ((error = copyin(cm->blue, &sc->sc_cmap_blue[index], count)) != 0)
384 return (error);
385
386 r = &sc->sc_cmap_red[index];
387 g = &sc->sc_cmap_green[index];
388 b = &sc->sc_cmap_blue[index];
389
390 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PEL_MASK, 0xff);
391 for (i = 0; i < count; i++) {
392 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
393 I128_WR_ADR, index);
394 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
395 I128_PAL_DAT, *r);
396 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
397 I128_PAL_DAT, *g);
398 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
399 I128_PAL_DAT, *b);
400 r++, g++, b++, index++;
401 }
402 return (0);
403 }
404
405 void
raptor_setcolor(void * v,u_int index,u_int8_t r,u_int8_t g,u_int8_t b)406 raptor_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
407 {
408 struct raptor_softc *sc = v;
409
410 sc->sc_cmap_red[index] = r;
411 sc->sc_cmap_green[index] = g;
412 sc->sc_cmap_blue[index] = b;
413
414 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PEL_MASK, 0xff);
415 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_WR_ADR, index);
416 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, r);
417 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, g);
418 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, b);
419 }
420
421 /*
422 * Accelerated routines.
423 */
424
425 int
raptor_copycols(void * cookie,int row,int src,int dst,int num)426 raptor_copycols(void *cookie, int row, int src, int dst, int num)
427 {
428 struct rasops_info *ri = cookie;
429 struct raptor_softc *sc = ri->ri_hw;
430
431 num *= ri->ri_font->fontwidth;
432 src *= ri->ri_font->fontwidth;
433 dst *= ri->ri_font->fontwidth;
434 row *= ri->ri_font->fontheight;
435
436 raptor_copyrect(sc, ri->ri_xorigin + src, ri->ri_yorigin + row,
437 ri->ri_xorigin + dst, ri->ri_yorigin + row,
438 num, ri->ri_font->fontheight);
439
440 return 0;
441 }
442
443 int
raptor_erasecols(void * cookie,int row,int col,int num,uint32_t attr)444 raptor_erasecols(void *cookie, int row, int col, int num, uint32_t attr)
445 {
446 struct rasops_info *ri = cookie;
447 struct raptor_softc *sc = ri->ri_hw;
448 int bg, fg;
449
450 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
451
452 row *= ri->ri_font->fontheight;
453 col *= ri->ri_font->fontwidth;
454 num *= ri->ri_font->fontwidth;
455
456 raptor_fillrect(sc, ri->ri_xorigin + col, ri->ri_yorigin + row,
457 num, ri->ri_font->fontheight, ri->ri_devcmap[bg]);
458
459 return 0;
460 }
461
462 int
raptor_copyrows(void * cookie,int src,int dst,int num)463 raptor_copyrows(void *cookie, int src, int dst, int num)
464 {
465 struct rasops_info *ri = cookie;
466 struct raptor_softc *sc = ri->ri_hw;
467
468 num *= ri->ri_font->fontheight;
469 src *= ri->ri_font->fontheight;
470 dst *= ri->ri_font->fontheight;
471
472 raptor_copyrect(sc, ri->ri_xorigin, ri->ri_yorigin + src,
473 ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, num);
474
475 return 0;
476 }
477
478 int
raptor_eraserows(void * cookie,int row,int num,uint32_t attr)479 raptor_eraserows(void *cookie, int row, int num, uint32_t attr)
480 {
481 struct rasops_info *ri = cookie;
482 struct raptor_softc *sc = ri->ri_hw;
483 int bg, fg;
484 int x, y, w;
485
486 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
487
488 if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) {
489 num = ri->ri_height;
490 x = y = 0;
491 w = ri->ri_width;
492 } else {
493 num *= ri->ri_font->fontheight;
494 x = ri->ri_xorigin;
495 y = ri->ri_yorigin + row * ri->ri_font->fontheight;
496 w = ri->ri_emuwidth;
497 }
498 raptor_fillrect(sc, x, y, w, num, ri->ri_devcmap[bg]);
499
500 return 0;
501 }
502
503 void
raptor_init(struct raptor_softc * sc)504 raptor_init(struct raptor_softc *sc)
505 {
506 /* Configure pixel format based on depth. */
507 switch(sc->sc_sunfb.sf_depth) {
508 case 8:
509 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
510 I128_BUF_CTRL, I128_BC_PSIZ_8B);
511 break;
512 case 16:
513 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
514 I128_BUF_CTRL, I128_BC_PSIZ_16B);
515 break;
516 case 24:
517 case 32:
518 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
519 I128_BUF_CTRL, I128_BC_PSIZ_32B);
520 break;
521 default:
522 panic("unsupported depth");
523 break;
524 }
525
526 /* Mostly magic. */
527 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_PGE, 0);
528 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_SORG, 0);
529 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_DORG, 0);
530 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_MSRC, 0);
531 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_WKEY, 0);
532 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_SPTCH,
533 sc->sc_sunfb.sf_linebytes);
534 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_DPTCH,
535 sc->sc_sunfb.sf_linebytes);
536 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_ZPTCH,
537 sc->sc_sunfb.sf_linebytes);
538 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_RMSK, 0);
539 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY4_ZM,
540 I128_ZOOM_NONE);
541 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_LPAT,
542 0xffffffff);
543 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PCTRL, 0);
544 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CLPTL, 0);
545 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CLPBR,
546 I128_COORDS(4095, 2047));
547 #if 0
548 /* XXX For some reason this makes schizo(4) freak out. */
549 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_ACNTRL, 0);
550 #endif
551 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_INTM, 3);
552 }
553
554 int
raptor_wait(struct raptor_softc * sc)555 raptor_wait(struct raptor_softc *sc)
556 {
557 int i;
558
559 for (i = 1000000; i != 0; i--) {
560 if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
561 I128_FLOW) & I128_FLOW_ACTIVE) == 0)
562 break;
563 DELAY(1);
564 }
565
566 return i;
567 }
568
569 void
raptor_copyrect(struct raptor_softc * sc,int sx,int sy,int dx,int dy,int w,int h)570 raptor_copyrect(struct raptor_softc *sc, int sx, int sy, int dx, int dy,
571 int w, int h)
572 {
573 int dir = 0;
574
575 while (bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
576 I128_BUSY) & I128_BUSY_BUSY)
577 DELAY(1);
578
579 if (sx < dx) {
580 sx += w - 1;
581 dx += w - 1;
582 dir |= I128_DIR_RL;
583 }
584 if (sy < dy) {
585 sy += h - 1;
586 dy += h - 1;
587 dir |= I128_DIR_BT;
588 }
589
590 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CMD,
591 I128_CR_COPY << 8 | I128_CO_BITBLT);
592 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY3_DIR, dir);
593 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY2_WH,
594 I128_COORDS(w , h));
595 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY0_SRC,
596 I128_COORDS(sx, sy));
597 /* Must be last; triggers operation. */
598 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY1_DST,
599 I128_COORDS(dx, dy));
600
601 raptor_wait(sc);
602 }
603
604 void
raptor_fillrect(struct raptor_softc * sc,int x,int y,int w,int h,int color)605 raptor_fillrect(struct raptor_softc *sc, int x, int y, int w, int h, int color)
606 {
607 while (bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
608 I128_BUSY) & I128_BUSY_BUSY)
609 DELAY(1);
610
611 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CMD,
612 I128_CS_SOLID << 16 | I128_CR_COPY << 8 | I128_CO_BITBLT);
613 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_FORE, color);
614 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY3_DIR, 0);
615 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY2_WH,
616 I128_COORDS(w, h));
617 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY0_SRC, 0);
618 /* Must be last; triggers operation. */
619 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY1_DST,
620 I128_COORDS(x, y));
621
622 raptor_wait(sc);
623 }
624