1 /* $OpenBSD: raptor.c,v 1.8 2013/10/20 20:07:27 miod 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 origional 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 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, long); 158 int raptor_copyrows(void *, int, int, int); 159 int raptor_eraserows(void *, int, int, long); 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 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 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 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->cmsize = 256; 261 break; 262 case WSDISPLAYIO_LINEBYTES: 263 *(u_int *)data = sc->sc_sunfb.sf_linebytes; 264 break; 265 266 case WSDISPLAYIO_GETCMAP: 267 return raptor_getcmap(sc, (struct wsdisplay_cmap *)data); 268 case WSDISPLAYIO_PUTCMAP: 269 return raptor_putcmap(sc, (struct wsdisplay_cmap *)data); 270 271 case WSDISPLAYIO_GPCIID: 272 sel = (struct pcisel *)data; 273 sel->pc_bus = PCITAG_BUS(sc->sc_pcitag); 274 sel->pc_dev = PCITAG_DEV(sc->sc_pcitag); 275 sel->pc_func = PCITAG_FUN(sc->sc_pcitag); 276 break; 277 278 case WSDISPLAYIO_SVIDEO: 279 case WSDISPLAYIO_GVIDEO: 280 break; 281 282 case WSDISPLAYIO_GCURPOS: 283 case WSDISPLAYIO_SCURPOS: 284 case WSDISPLAYIO_GCURMAX: 285 case WSDISPLAYIO_GCURSOR: 286 case WSDISPLAYIO_SCURSOR: 287 default: 288 return -1; /* not supported yet */ 289 } 290 291 return (0); 292 } 293 294 paddr_t 295 raptor_mmap(void *v, off_t off, int prot) 296 { 297 struct raptor_softc *sc = v; 298 299 if (off & PGOFSET) 300 return (-1); 301 302 switch (sc->sc_mode) { 303 case WSDISPLAYIO_MODE_MAPPED: 304 #ifdef APERTURE 305 if (allowaperture == 0) 306 return (-1); 307 #endif 308 309 if (sc->sc_mmiosize == 0) 310 return (-1); 311 312 if (off >= sc->sc_membase && 313 off < (sc->sc_membase + sc->sc_memsize)) 314 return (bus_space_mmap(sc->sc_memt, 315 sc->sc_membase, off - sc->sc_membase, 316 prot, BUS_SPACE_MAP_LINEAR)); 317 318 if (off >= sc->sc_mmiobase && 319 off < (sc->sc_mmiobase + sc->sc_mmiosize)) 320 return (bus_space_mmap(sc->sc_mmiot, 321 sc->sc_mmiobase, off - sc->sc_mmiobase, 322 prot, BUS_SPACE_MAP_LINEAR)); 323 break; 324 325 case WSDISPLAYIO_MODE_DUMBFB: 326 if (off >= 0 && off < sc->sc_memsize) 327 return (bus_space_mmap(sc->sc_memt, sc->sc_membase, 328 off, prot, BUS_SPACE_MAP_LINEAR)); 329 break; 330 } 331 332 return (-1); 333 } 334 335 int 336 raptor_is_console(int node) 337 { 338 extern int fbnode; 339 340 return (fbnode == node); 341 } 342 343 int 344 raptor_getcmap(struct raptor_softc *sc, struct wsdisplay_cmap *cm) 345 { 346 u_int index = cm->index; 347 u_int count = cm->count; 348 int error; 349 350 if (index >= 256 || count > 256 - index) 351 return (EINVAL); 352 353 error = copyout(&sc->sc_cmap_red[index], cm->red, count); 354 if (error) 355 return (error); 356 error = copyout(&sc->sc_cmap_green[index], cm->green, count); 357 if (error) 358 return (error); 359 error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); 360 if (error) 361 return (error); 362 return (0); 363 } 364 365 int 366 raptor_putcmap(struct raptor_softc *sc, struct wsdisplay_cmap *cm) 367 { 368 u_int index = cm->index; 369 u_int count = cm->count; 370 u_int i; 371 int error; 372 u_char *r, *g, *b; 373 374 if (index >= 256 || count > 256 - index) 375 return (EINVAL); 376 377 if ((error = copyin(cm->red, &sc->sc_cmap_red[index], count)) != 0) 378 return (error); 379 if ((error = copyin(cm->green, &sc->sc_cmap_green[index], count)) != 0) 380 return (error); 381 if ((error = copyin(cm->blue, &sc->sc_cmap_blue[index], count)) != 0) 382 return (error); 383 384 r = &sc->sc_cmap_red[index]; 385 g = &sc->sc_cmap_green[index]; 386 b = &sc->sc_cmap_blue[index]; 387 388 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PEL_MASK, 0xff); 389 for (i = 0; i < count; i++) { 390 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 391 I128_WR_ADR, index); 392 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 393 I128_PAL_DAT, *r); 394 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 395 I128_PAL_DAT, *g); 396 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 397 I128_PAL_DAT, *b); 398 r++, g++, b++, index++; 399 } 400 return (0); 401 } 402 403 void 404 raptor_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b) 405 { 406 struct raptor_softc *sc = v; 407 408 sc->sc_cmap_red[index] = r; 409 sc->sc_cmap_green[index] = g; 410 sc->sc_cmap_blue[index] = b; 411 412 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PEL_MASK, 0xff); 413 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_WR_ADR, index); 414 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, r); 415 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, g); 416 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PAL_DAT, b); 417 } 418 419 /* 420 * Accelerated routines. 421 */ 422 423 int 424 raptor_copycols(void *cookie, int row, int src, int dst, int num) 425 { 426 struct rasops_info *ri = cookie; 427 struct raptor_softc *sc = ri->ri_hw; 428 429 num *= ri->ri_font->fontwidth; 430 src *= ri->ri_font->fontwidth; 431 dst *= ri->ri_font->fontwidth; 432 row *= ri->ri_font->fontheight; 433 434 raptor_copyrect(sc, ri->ri_xorigin + src, ri->ri_yorigin + row, 435 ri->ri_xorigin + dst, ri->ri_yorigin + row, 436 num, ri->ri_font->fontheight); 437 438 return 0; 439 } 440 441 int 442 raptor_erasecols(void *cookie, int row, int col, int num, long attr) 443 { 444 struct rasops_info *ri = cookie; 445 struct raptor_softc *sc = ri->ri_hw; 446 int bg, fg; 447 448 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); 449 450 row *= ri->ri_font->fontheight; 451 col *= ri->ri_font->fontwidth; 452 num *= ri->ri_font->fontwidth; 453 454 raptor_fillrect(sc, ri->ri_xorigin + col, ri->ri_yorigin + row, 455 num, ri->ri_font->fontheight, ri->ri_devcmap[bg]); 456 457 return 0; 458 } 459 460 int 461 raptor_copyrows(void *cookie, int src, int dst, int num) 462 { 463 struct rasops_info *ri = cookie; 464 struct raptor_softc *sc = ri->ri_hw; 465 466 num *= ri->ri_font->fontheight; 467 src *= ri->ri_font->fontheight; 468 dst *= ri->ri_font->fontheight; 469 470 raptor_copyrect(sc, ri->ri_xorigin, ri->ri_yorigin + src, 471 ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, num); 472 473 return 0; 474 } 475 476 int 477 raptor_eraserows(void *cookie, int row, int num, long attr) 478 { 479 struct rasops_info *ri = cookie; 480 struct raptor_softc *sc = ri->ri_hw; 481 int bg, fg; 482 int x, y, w; 483 484 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); 485 486 if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) { 487 num = ri->ri_height; 488 x = y = 0; 489 w = ri->ri_width; 490 } else { 491 num *= ri->ri_font->fontheight; 492 x = ri->ri_xorigin; 493 y = ri->ri_yorigin + row * ri->ri_font->fontheight; 494 w = ri->ri_emuwidth; 495 } 496 raptor_fillrect(sc, x, y, w, num, ri->ri_devcmap[bg]); 497 498 return 0; 499 } 500 501 void 502 raptor_init(struct raptor_softc *sc) 503 { 504 /* Configure pixel format based on depth. */ 505 switch(sc->sc_sunfb.sf_depth) { 506 case 8: 507 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 508 I128_BUF_CTRL, I128_BC_PSIZ_8B); 509 break; 510 case 16: 511 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 512 I128_BUF_CTRL, I128_BC_PSIZ_16B); 513 break; 514 case 24: 515 case 32: 516 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 517 I128_BUF_CTRL, I128_BC_PSIZ_32B); 518 break; 519 default: 520 panic("unsupported depth"); 521 break; 522 } 523 524 /* Mostly magic. */ 525 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_PGE, 0); 526 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_SORG, 0); 527 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_DORG, 0); 528 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_MSRC, 0); 529 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_WKEY, 0); 530 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_SPTCH, 531 sc->sc_sunfb.sf_linebytes); 532 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_DPTCH, 533 sc->sc_sunfb.sf_linebytes); 534 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_DE_ZPTCH, 535 sc->sc_sunfb.sf_linebytes); 536 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_RMSK, 0); 537 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY4_ZM, 538 I128_ZOOM_NONE); 539 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_LPAT, 540 0xffffffff); 541 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_PCTRL, 0); 542 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CLPTL, 0); 543 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CLPBR, 544 I128_COORDS(4095, 2047)); 545 #if 0 546 /* XXX For some reason this makes schizo(4) freak out. */ 547 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_ACNTRL, 0); 548 #endif 549 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_INTM, 3); 550 } 551 552 int 553 raptor_wait(struct raptor_softc *sc) 554 { 555 int i; 556 557 for (i = 1000000; i != 0; i--) { 558 if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh, 559 I128_FLOW) & I128_FLOW_ACTIVE) == 0) 560 break; 561 DELAY(1); 562 } 563 564 return i; 565 } 566 567 void 568 raptor_copyrect(struct raptor_softc *sc, int sx, int sy, int dx, int dy, 569 int w, int h) 570 { 571 int dir = 0; 572 573 while (bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh, 574 I128_BUSY) & I128_BUSY_BUSY) 575 DELAY(1); 576 577 if (sx < dx) { 578 sx += w - 1; 579 dx += w - 1; 580 dir |= I128_DIR_RL; 581 } 582 if (sy < dy) { 583 sy += h - 1; 584 dy += h - 1; 585 dir |= I128_DIR_BT; 586 } 587 588 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CMD, 589 I128_CR_COPY << 8 | I128_CO_BITBLT); 590 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY3_DIR, dir); 591 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY2_WH, 592 I128_COORDS(w , h)); 593 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY0_SRC, 594 I128_COORDS(sx, sy)); 595 /* Must be last; triggers operation. */ 596 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY1_DST, 597 I128_COORDS(dx, dy)); 598 599 raptor_wait(sc); 600 } 601 602 void 603 raptor_fillrect(struct raptor_softc *sc, int x, int y, int w, int h, int color) 604 { 605 while (bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh, 606 I128_BUSY) & I128_BUSY_BUSY) 607 DELAY(1); 608 609 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_CMD, 610 I128_CS_SOLID << 16 | I128_CR_COPY << 8 | I128_CO_BITBLT); 611 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_FORE, color); 612 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY3_DIR, 0); 613 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY2_WH, 614 I128_COORDS(w, h)); 615 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY0_SRC, 0); 616 /* Must be last; triggers operation. */ 617 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, I128_XY1_DST, 618 I128_COORDS(x, y)); 619 620 raptor_wait(sc); 621 } 622