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