1 /* $OpenBSD: radeonfb.c,v 1.4 2011/02/21 07:54:47 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 #include <machine/openfirm.h> 27 28 #include <dev/pci/pcireg.h> 29 #include <dev/pci/pcivar.h> 30 #include <dev/pci/pcidevs.h> 31 32 #include <dev/wscons/wsconsio.h> 33 #include <dev/wscons/wsdisplayvar.h> 34 35 #include <dev/rasops/rasops.h> 36 37 #include <machine/fbvar.h> 38 39 #define RADEON_PCI_MEM 0x10 40 #define RADEON_PCI_MMIO 0x18 41 42 #define RADEON_PALETTE_INDEX 0x00b0 43 #define RADEON_PALETTE_DATA 0x00b4 44 45 #define RADEON_CRTC_OFFSET 0x0224 46 47 #define RADEON_SURFACE_CNTL 0x0b00 48 #define RADEON_NONSURF_AP0_SWP_16BPP 0x00100000 49 #define RADEON_NONSURF_AP0_SWP_32BPP 0x00200000 50 #define RADEON_NONSURF_AP1_SWP_16BPP 0x00400000 51 #define RADEON_NONSURF_AP1_SWP_32BPP 0x00800000 52 53 #define RADEON_RBBM_STATUS 0x0e40 54 #define RADEON_RBBM_FIFOCNT_MASK 0x0000007f 55 #define RADEON_RBBM_ACTIVE 0x80000000 56 57 #define RADEON_SRC_Y_X 0x1434 58 #define RADEON_DST_Y_X 0x1438 59 #define RADEON_DST_HEIGHT_WIDTH 0x143c 60 61 #define RADEON_DP_GUI_MASTER_CNTL 0x146c 62 #define RADEON_GMC_DST_8BPP 0x00000200 63 #define RADEON_GMC_DST_32BPP 0x00000600 64 #define RADEON_GMC_BRUSH_NONE 0x000000e0 65 #define RADEON_GMC_BRUSH_SOLID_COLOR 0x000000d0 66 #define RADEON_GMC_SRC_DATATYPE_COLOR 0x00003000 67 #define RADEON_GMC_SRC_SOURCE_MEMORY 0x02000000 68 #define RADEON_ROP3_S 0x00cc0000 69 #define RADEON_ROP3_P 0x00f00000 70 #define RADEON_GMC_CLR_CMP_CNTL_DIS 0x10000000 71 72 #define RADEON_DP_BRUSH_BKGD_CLR 0x1478 73 #define RADEON_DP_BRUSH_FRGD_CLR 0x147c 74 75 #define RADEON_DP_CNTL 0x16c0 76 #define RADEON_DST_X_LEFT_TO_RIGHT 0x00000001 77 #define RADEON_DST_Y_TOP_TO_BOTTOM 0x00000002 78 #define RADEON_DP_WRITE_MASK 0x16cc 79 80 #define RADEON_DEFAULT_PITCH_OFFSET 0x16e0 81 #define RADEON_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 82 83 #define RADEON_WAIT_UNTIL 0x1720 84 #define RADEON_WAIT_2D_IDLECLEAN 0x00010000 85 #define RADEON_WAIT_3D_IDLECLEAN 0x00020000 86 #define RADEON_WAIT_HOST_IDLECLEAN 0x00040000 87 88 #define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c 89 #define RADEON_RB3D_DC_FLUSH_ALL 0x0000000f 90 #define RADEON_RB3D_DC_BUSY 0x80000000 91 92 #define RADEON_COORDS(x, y) ((y << 16) | (x)) 93 94 #ifdef APERTURE 95 extern int allowaperture; 96 #endif 97 98 struct radeonfb_softc { 99 struct sunfb sc_sunfb; 100 101 bus_space_tag_t sc_memt; 102 bus_space_handle_t sc_memh; 103 bus_addr_t sc_membase; 104 bus_size_t sc_memsize; 105 bus_size_t sc_memoff; 106 107 bus_space_tag_t sc_mmiot; 108 bus_space_handle_t sc_mmioh; 109 bus_addr_t sc_mmiobase; 110 bus_size_t sc_mmiosize; 111 112 pcitag_t sc_pcitag; 113 114 int sc_mode; 115 u_int8_t sc_cmap_red[256]; 116 u_int8_t sc_cmap_green[256]; 117 u_int8_t sc_cmap_blue[256]; 118 }; 119 120 int radeonfb_ioctl(void *, u_long, caddr_t, int, struct proc *); 121 paddr_t radeonfb_mmap(void *, off_t, int); 122 123 struct wsdisplay_accessops radeonfb_accessops = { 124 radeonfb_ioctl, 125 radeonfb_mmap, 126 NULL, /* alloc_screen */ 127 NULL, /* free_screen */ 128 NULL, /* show_screen */ 129 NULL, /* load_font */ 130 NULL, /* scrollback */ 131 NULL, /* getchar */ 132 NULL, /* burner */ 133 NULL /* pollc */ 134 }; 135 136 int radeonfb_match(struct device *, void *, void *); 137 void radeonfb_attach(struct device *, struct device *, void *); 138 139 struct cfattach radeonfb_ca = { 140 sizeof(struct radeonfb_softc), radeonfb_match, radeonfb_attach 141 }; 142 143 struct cfdriver radeonfb_cd = { 144 NULL, "radeonfb", DV_DULL 145 }; 146 147 int radeonfb_is_console(int); 148 int radeonfb_getcmap(struct radeonfb_softc *, struct wsdisplay_cmap *); 149 int radeonfb_putcmap(struct radeonfb_softc *, struct wsdisplay_cmap *); 150 void radeonfb_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t); 151 152 int radeonfb_copycols(void *, int, int, int, int); 153 int radeonfb_erasecols(void *, int, int, int, long); 154 int radeonfb_copyrows(void *, int, int, int); 155 int radeonfb_eraserows(void *, int, int, long); 156 157 void radeonfb_init(struct radeonfb_softc *); 158 void radeonfb_wait_fifo(struct radeonfb_softc *, int); 159 void radeonfb_wait(struct radeonfb_softc *); 160 void radeonfb_copyrect(struct radeonfb_softc *, int, int, int, int, int, int); 161 void radeonfb_fillrect(struct radeonfb_softc *, int, int, int, int, int); 162 163 int 164 radeonfb_match(struct device *parent, void *cf, void *aux) 165 { 166 struct pci_attach_args *pa = aux; 167 char buf[32]; 168 int node; 169 170 node = PCITAG_NODE(pa->pa_tag); 171 OF_getprop(node, "name", buf, sizeof(buf)); 172 if (strcmp(buf, "SUNW,XVR-100") == 0 || 173 strcmp(buf, "SUNW,XVR-300") == 0) 174 return (10); 175 176 return (0); 177 } 178 179 void 180 radeonfb_attach(struct device *parent, struct device *self, void *aux) 181 { 182 struct radeonfb_softc *sc = (struct radeonfb_softc *)self; 183 struct pci_attach_args *pa = aux; 184 struct rasops_info *ri; 185 int node, console, flags; 186 char *model; 187 188 sc->sc_pcitag = pa->pa_tag; 189 190 node = PCITAG_NODE(pa->pa_tag); 191 console = radeonfb_is_console(node); 192 193 printf("\n"); 194 195 model = getpropstring(node, "model"); 196 printf("%s: %s", self->dv_xname, model); 197 198 if (pci_mapreg_map(pa, RADEON_PCI_MEM, PCI_MAPREG_TYPE_MEM, 199 BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh, 200 &sc->sc_membase, &sc->sc_memsize, 0)) { 201 printf("\n%s: can't map video memory\n", self->dv_xname); 202 return; 203 } 204 205 if (pci_mapreg_map(pa, RADEON_PCI_MMIO, PCI_MAPREG_TYPE_MEM, 0, 206 &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmiobase, 207 &sc->sc_mmiosize, 0)) { 208 printf("\n%s: can't map registers\n", self->dv_xname); 209 return; 210 } 211 212 fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0); 213 214 printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); 215 216 /* 217 * The firmware sets up the framebuffer such that at starts at 218 * an offset from the start of video memory. 219 */ 220 sc->sc_memoff = 221 bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh, RADEON_CRTC_OFFSET); 222 223 ri = &sc->sc_sunfb.sf_ro; 224 ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh); 225 ri->ri_bits += sc->sc_memoff; 226 ri->ri_hw = sc; 227 228 if (sc->sc_sunfb.sf_depth == 32) 229 flags = 0; 230 else 231 flags = RI_BSWAP; 232 233 fbwscons_init(&sc->sc_sunfb, flags, console); 234 fbwscons_setcolormap(&sc->sc_sunfb, radeonfb_setcolor); 235 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 236 237 radeonfb_init(sc); 238 ri->ri_ops.copyrows = radeonfb_copyrows; 239 ri->ri_ops.copycols = radeonfb_copycols; 240 ri->ri_ops.eraserows = radeonfb_eraserows; 241 ri->ri_ops.erasecols = radeonfb_erasecols; 242 243 if (console) 244 fbwscons_console_init(&sc->sc_sunfb, -1); 245 fbwscons_attach(&sc->sc_sunfb, &radeonfb_accessops, console); 246 } 247 248 int 249 radeonfb_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) 250 { 251 struct radeonfb_softc *sc = v; 252 struct wsdisplay_fbinfo *wdf; 253 struct pcisel *sel; 254 255 switch (cmd) { 256 case WSDISPLAYIO_GTYPE: 257 *(u_int *)data = WSDISPLAY_TYPE_RADEONFB; 258 break; 259 case WSDISPLAYIO_SMODE: 260 sc->sc_mode = *(u_int *)data; 261 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 262 struct rasops_info *ri = &sc->sc_sunfb.sf_ro; 263 264 /* Restore colormap. */ 265 fbwscons_setcolormap(&sc->sc_sunfb, radeonfb_setcolor); 266 267 /* Clear screen. */ 268 radeonfb_init(sc); 269 radeonfb_fillrect(sc, 0, 0, ri->ri_width, 270 ri->ri_height, ri->ri_devcmap[WSCOL_WHITE]); 271 } 272 break; 273 274 case WSDISPLAYIO_GINFO: 275 wdf = (void *)data; 276 wdf->height = sc->sc_sunfb.sf_height; 277 wdf->width = sc->sc_sunfb.sf_width; 278 wdf->depth = sc->sc_sunfb.sf_depth; 279 if (sc->sc_sunfb.sf_depth == 32) 280 wdf->cmsize = 0; 281 else 282 wdf->cmsize = 256; 283 break; 284 case WSDISPLAYIO_GETSUPPORTEDDEPTH: 285 if (sc->sc_sunfb.sf_depth == 32) 286 *(u_int *)data = WSDISPLAYIO_DEPTH_24_32; 287 else 288 return (-1); 289 break; 290 case WSDISPLAYIO_LINEBYTES: 291 *(u_int *)data = sc->sc_sunfb.sf_linebytes; 292 break; 293 294 case WSDISPLAYIO_GETCMAP: 295 return radeonfb_getcmap(sc, (struct wsdisplay_cmap *)data); 296 case WSDISPLAYIO_PUTCMAP: 297 return radeonfb_putcmap(sc, (struct wsdisplay_cmap *)data); 298 299 case WSDISPLAYIO_GPCIID: 300 sel = (struct pcisel *)data; 301 sel->pc_bus = PCITAG_BUS(sc->sc_pcitag); 302 sel->pc_dev = PCITAG_DEV(sc->sc_pcitag); 303 sel->pc_func = PCITAG_FUN(sc->sc_pcitag); 304 break; 305 306 case WSDISPLAYIO_SVIDEO: 307 case WSDISPLAYIO_GVIDEO: 308 break; 309 310 case WSDISPLAYIO_GCURPOS: 311 case WSDISPLAYIO_SCURPOS: 312 case WSDISPLAYIO_GCURMAX: 313 case WSDISPLAYIO_GCURSOR: 314 case WSDISPLAYIO_SCURSOR: 315 default: 316 return -1; /* not supported yet */ 317 } 318 319 return (0); 320 } 321 322 paddr_t 323 radeonfb_mmap(void *v, off_t off, int prot) 324 { 325 struct radeonfb_softc *sc = v; 326 327 if (off & PGOFSET) 328 return (-1); 329 330 switch (sc->sc_mode) { 331 case WSDISPLAYIO_MODE_MAPPED: 332 #ifdef APERTURE 333 if (allowaperture == 0) 334 return (-1); 335 #endif 336 337 if (sc->sc_mmiosize == 0) 338 return (-1); 339 340 if (off >= sc->sc_membase && 341 off < (sc->sc_membase + sc->sc_memsize)) 342 return (bus_space_mmap(sc->sc_memt, 343 sc->sc_membase, off - sc->sc_membase, 344 prot, BUS_SPACE_MAP_LINEAR)); 345 346 if (off >= sc->sc_mmiobase && 347 off < (sc->sc_mmiobase + sc->sc_mmiosize)) 348 return (bus_space_mmap(sc->sc_mmiot, 349 sc->sc_mmiobase, off - sc->sc_mmiobase, 350 prot, BUS_SPACE_MAP_LINEAR)); 351 break; 352 353 case WSDISPLAYIO_MODE_DUMBFB: 354 if ((sc->sc_memoff % PAGE_SIZE) != 0) 355 return (-1); 356 357 if (off >= 0 && off < sc->sc_memsize / 2) { 358 bus_addr_t base = sc->sc_membase + sc->sc_memoff; 359 360 /* 361 * In 32bpp mode, use the second aperture, 362 * which has been set up by the firmware to do 363 * proper byte swapping. 364 */ 365 if (sc->sc_sunfb.sf_depth == 32) 366 base += sc->sc_memsize / 2; 367 368 return (bus_space_mmap(sc->sc_memt, base, off, 369 prot, BUS_SPACE_MAP_LINEAR)); 370 } 371 break; 372 } 373 374 return (-1); 375 } 376 377 int 378 radeonfb_is_console(int node) 379 { 380 extern int fbnode; 381 382 return (fbnode == node); 383 } 384 385 int 386 radeonfb_getcmap(struct radeonfb_softc *sc, struct wsdisplay_cmap *cm) 387 { 388 u_int index = cm->index; 389 u_int count = cm->count; 390 int error; 391 392 if (index >= 256 || count > 256 - index) 393 return (EINVAL); 394 395 error = copyout(&sc->sc_cmap_red[index], cm->red, count); 396 if (error) 397 return (error); 398 error = copyout(&sc->sc_cmap_green[index], cm->green, count); 399 if (error) 400 return (error); 401 error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); 402 if (error) 403 return (error); 404 return (0); 405 } 406 407 int 408 radeonfb_putcmap(struct radeonfb_softc *sc, struct wsdisplay_cmap *cm) 409 { 410 u_int index = cm->index; 411 u_int count = cm->count; 412 u_int i; 413 int error; 414 u_char *r, *g, *b; 415 416 if (index >= 256 || count > 256 - index) 417 return (EINVAL); 418 419 if ((error = copyin(cm->red, &sc->sc_cmap_red[index], count)) != 0) 420 return (error); 421 if ((error = copyin(cm->green, &sc->sc_cmap_green[index], count)) != 0) 422 return (error); 423 if ((error = copyin(cm->blue, &sc->sc_cmap_blue[index], count)) != 0) 424 return (error); 425 426 r = &sc->sc_cmap_red[index]; 427 g = &sc->sc_cmap_green[index]; 428 b = &sc->sc_cmap_blue[index]; 429 430 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 431 RADEON_PALETTE_INDEX, index); 432 for (i = 0; i < count; i++) { 433 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 434 RADEON_PALETTE_DATA, (*r << 16) | (*g << 8) | *b); 435 r++, g++, b++; 436 } 437 return (0); 438 } 439 440 void 441 radeonfb_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b) 442 { 443 struct radeonfb_softc *sc = v; 444 445 sc->sc_cmap_red[index] = r; 446 sc->sc_cmap_green[index] = g; 447 sc->sc_cmap_blue[index] = b; 448 449 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 450 RADEON_PALETTE_INDEX, index); 451 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 452 RADEON_PALETTE_DATA, (r << 16) | (g << 8) | b); 453 } 454 455 /* 456 * Accelerated routines. 457 */ 458 459 int 460 radeonfb_copycols(void *cookie, int row, int src, int dst, int num) 461 { 462 struct rasops_info *ri = cookie; 463 struct radeonfb_softc *sc = ri->ri_hw; 464 465 num *= ri->ri_font->fontwidth; 466 src *= ri->ri_font->fontwidth; 467 dst *= ri->ri_font->fontwidth; 468 row *= ri->ri_font->fontheight; 469 470 radeonfb_copyrect(sc, ri->ri_xorigin + src, ri->ri_yorigin + row, 471 ri->ri_xorigin + dst, ri->ri_yorigin + row, 472 num, ri->ri_font->fontheight); 473 474 return 0; 475 } 476 477 int 478 radeonfb_erasecols(void *cookie, int row, int col, int num, long attr) 479 { 480 struct rasops_info *ri = cookie; 481 struct radeonfb_softc *sc = ri->ri_hw; 482 int bg, fg; 483 484 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); 485 486 row *= ri->ri_font->fontheight; 487 col *= ri->ri_font->fontwidth; 488 num *= ri->ri_font->fontwidth; 489 490 radeonfb_fillrect(sc, ri->ri_xorigin + col, ri->ri_yorigin + row, 491 num, ri->ri_font->fontheight, ri->ri_devcmap[bg]); 492 493 return 0; 494 } 495 496 int 497 radeonfb_copyrows(void *cookie, int src, int dst, int num) 498 { 499 struct rasops_info *ri = cookie; 500 struct radeonfb_softc *sc = ri->ri_hw; 501 502 num *= ri->ri_font->fontheight; 503 src *= ri->ri_font->fontheight; 504 dst *= ri->ri_font->fontheight; 505 506 radeonfb_copyrect(sc, ri->ri_xorigin, ri->ri_yorigin + src, 507 ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, num); 508 509 return 0; 510 } 511 512 int 513 radeonfb_eraserows(void *cookie, int row, int num, long attr) 514 { 515 struct rasops_info *ri = cookie; 516 struct radeonfb_softc *sc = ri->ri_hw; 517 int bg, fg; 518 int x, y, w; 519 520 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); 521 522 if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) { 523 num = ri->ri_height; 524 x = y = 0; 525 w = ri->ri_width; 526 } else { 527 num *= ri->ri_font->fontheight; 528 x = ri->ri_xorigin; 529 y = ri->ri_yorigin + row * ri->ri_font->fontheight; 530 w = ri->ri_emuwidth; 531 } 532 radeonfb_fillrect(sc, x, y, w, num, ri->ri_devcmap[bg]); 533 534 return 0; 535 } 536 537 void 538 radeonfb_init(struct radeonfb_softc *sc) 539 { 540 radeonfb_wait_fifo(sc, 2); 541 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 542 RADEON_DEFAULT_PITCH_OFFSET, 543 ((sc->sc_sunfb.sf_linebytes >> 6) << 22) | (sc->sc_memoff >> 10)); 544 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 545 RADEON_DEFAULT_SC_BOTTOM_RIGHT, 0x1fff1fff); 546 } 547 548 void 549 radeonfb_wait_fifo(struct radeonfb_softc *sc, int n) 550 { 551 int i; 552 553 for (i = 1000000; i != 0; i--) { 554 if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh, 555 RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK) >= n) 556 break; 557 DELAY(1); 558 } 559 } 560 561 void 562 radeonfb_wait(struct radeonfb_softc *sc) 563 { 564 int i; 565 566 radeonfb_wait_fifo(sc, 64); 567 568 for (i = 1000000; i != 0; i--) { 569 if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh, 570 RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) == 0) 571 break; 572 DELAY(1); 573 } 574 575 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 576 RADEON_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH_ALL); 577 578 for (i = 1000000; i != 0; i--) { 579 if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh, 580 RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY) == 0) 581 break; 582 DELAY(1); 583 } 584 } 585 586 void 587 radeonfb_copyrect(struct radeonfb_softc *sc, int sx, int sy, int dx, int dy, 588 int w, int h) 589 { 590 uint32_t gmc; 591 uint32_t dir; 592 593 radeonfb_wait_fifo(sc, 1); 594 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, RADEON_WAIT_UNTIL, 595 RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN); 596 597 if (dy < sy) { 598 dir = RADEON_DST_Y_TOP_TO_BOTTOM; 599 } else { 600 sy += h - 1; 601 dy += h - 1; 602 dir = 0; 603 } 604 if (dx < sx) { 605 dir |= RADEON_DST_X_LEFT_TO_RIGHT; 606 } else { 607 sx += w - 1; 608 dx += w - 1; 609 } 610 611 radeonfb_wait_fifo(sc, 6); 612 613 if (sc->sc_sunfb.sf_depth == 32) 614 gmc = RADEON_GMC_DST_32BPP; 615 else 616 gmc = RADEON_GMC_DST_8BPP; 617 gmc |= RADEON_GMC_BRUSH_NONE; 618 gmc |= RADEON_GMC_SRC_DATATYPE_COLOR; 619 gmc |= RADEON_GMC_SRC_SOURCE_MEMORY; 620 gmc |= RADEON_ROP3_S; 621 gmc |= RADEON_GMC_CLR_CMP_CNTL_DIS; 622 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 623 RADEON_DP_GUI_MASTER_CNTL, gmc); 624 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 625 RADEON_DP_WRITE_MASK, 0xffffffff); 626 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 627 RADEON_DP_CNTL, dir); 628 629 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 630 RADEON_SRC_Y_X, RADEON_COORDS(sx, sy)); 631 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 632 RADEON_DST_Y_X, RADEON_COORDS(dx, dy)); 633 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 634 RADEON_DST_HEIGHT_WIDTH, RADEON_COORDS(w, h)); 635 636 radeonfb_wait(sc); 637 } 638 639 void 640 radeonfb_fillrect(struct radeonfb_softc *sc, int x, int y, int w, int h, 641 int color) 642 { 643 uint32_t gmc; 644 645 radeonfb_wait_fifo(sc, 1); 646 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, RADEON_WAIT_UNTIL, 647 RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN); 648 649 radeonfb_wait_fifo(sc, 6); 650 651 if (sc->sc_sunfb.sf_depth == 32) 652 gmc = RADEON_GMC_DST_32BPP; 653 else 654 gmc = RADEON_GMC_DST_8BPP; 655 gmc |= RADEON_GMC_BRUSH_SOLID_COLOR; 656 gmc |= RADEON_GMC_SRC_DATATYPE_COLOR; 657 gmc |= RADEON_ROP3_P; 658 gmc |= RADEON_GMC_CLR_CMP_CNTL_DIS; 659 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 660 RADEON_DP_GUI_MASTER_CNTL, gmc); 661 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 662 RADEON_DP_BRUSH_FRGD_CLR, color); 663 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 664 RADEON_DP_WRITE_MASK, 0xffffffff); 665 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, RADEON_DP_CNTL, 666 RADEON_DST_Y_TOP_TO_BOTTOM | RADEON_DST_X_LEFT_TO_RIGHT); 667 668 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 669 RADEON_DST_Y_X, RADEON_COORDS(x, y)); 670 bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, 671 RADEON_DST_HEIGHT_WIDTH, RADEON_COORDS(w, h)); 672 673 radeonfb_wait(sc); 674 } 675