1 /* $OpenBSD: radeonfb.c,v 1.2 2017/01/15 20:22:33 fcambus 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/bus.h> 25 #include <machine/cpu.h> 26 27 #include <uvm/uvm_extern.h> 28 29 #include <dev/pci/pcireg.h> 30 #include <dev/pci/pcivar.h> 31 #include <dev/pci/pcidevs.h> 32 33 #include <dev/wscons/wsconsio.h> 34 #include <dev/wscons/wsdisplayvar.h> 35 #include <dev/rasops/rasops.h> 36 37 #define RADEON_PCI_MEM 0x10 38 #define RADEON_PCI_MMIO 0x18 39 40 #define RADEON_CRTC_OFFSET 0x0224 41 42 #define RADEON_RBBM_STATUS 0x0e40 43 #define RADEON_RBBM_FIFOCNT_MASK 0x0000007f 44 #define RADEON_RBBM_ACTIVE 0x80000000 45 46 #define RADEON_SRC_Y_X 0x1434 47 #define RADEON_DST_Y_X 0x1438 48 #define RADEON_DST_HEIGHT_WIDTH 0x143c 49 50 #define RADEON_DP_GUI_MASTER_CNTL 0x146c 51 #define RADEON_GMC_DST_8BPP 0x00000200 52 #define RADEON_GMC_DST_16BPP 0x00000400 53 #define RADEON_GMC_DST_32BPP 0x00000600 54 #define RADEON_GMC_BRUSH_NONE 0x000000e0 55 #define RADEON_GMC_BRUSH_SOLID_COLOR 0x000000d0 56 #define RADEON_GMC_SRC_DATATYPE_COLOR 0x00003000 57 #define RADEON_GMC_SRC_SOURCE_MEMORY 0x02000000 58 #define RADEON_ROP3_S 0x00cc0000 59 #define RADEON_ROP3_P 0x00f00000 60 #define RADEON_GMC_CLR_CMP_CNTL_DIS 0x10000000 61 62 #define RADEON_DP_BRUSH_BKGD_CLR 0x1478 63 #define RADEON_DP_BRUSH_FRGD_CLR 0x147c 64 65 #define RADEON_DP_CNTL 0x16c0 66 #define RADEON_DST_X_LEFT_TO_RIGHT 0x00000001 67 #define RADEON_DST_Y_TOP_TO_BOTTOM 0x00000002 68 #define RADEON_DP_WRITE_MASK 0x16cc 69 70 #define RADEON_DEFAULT_PITCH_OFFSET 0x16e0 71 #define RADEON_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 72 73 #define RADEON_WAIT_UNTIL 0x1720 74 #define RADEON_WAIT_2D_IDLECLEAN 0x00010000 75 #define RADEON_WAIT_3D_IDLECLEAN 0x00020000 76 #define RADEON_WAIT_HOST_IDLECLEAN 0x00040000 77 78 #define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c 79 #define RADEON_RB3D_DC_FLUSH_ALL 0x0000000f 80 #define RADEON_RB3D_DC_BUSY 0x80000000 81 82 #define RADEON_COORDS(x, y) ((y << 16) | (x)) 83 84 #ifdef APERTURE 85 extern int allowaperture; 86 #endif 87 88 struct radeonfb_softc; 89 90 /* minimal frame buffer information, suitable for early console */ 91 struct radeonfb { 92 struct radeonfb_softc *sc; 93 struct rasops_info ri; 94 95 bus_space_tag_t fbt; 96 bus_space_handle_t fbh; 97 98 bus_space_tag_t mmiot; 99 bus_space_handle_t mmioh; 100 bus_size_t memoff; 101 102 struct wsscreen_descr wsd; 103 }; 104 105 struct radeonfb_softc { 106 struct device sc_dev; 107 struct radeonfb *sc_fb; 108 struct radeonfb sc_fb_store; 109 110 struct wsscreen_list sc_wsl; 111 struct wsscreen_descr *sc_scrlist[1]; 112 int sc_nscr; 113 114 bus_addr_t sc_membase; 115 bus_size_t sc_memsize; 116 117 bus_addr_t sc_mmiobase; 118 bus_size_t sc_mmiosize; 119 120 pcitag_t sc_pcitag; 121 122 int sc_mode; 123 }; 124 125 int radeonfb_alloc_screen(void *, const struct wsscreen_descr *, void **, 126 int *, int *, long *); 127 void radeonfb_free_screen(void *, void *); 128 int radeonfb_ioctl(void *, u_long, caddr_t, int, struct proc *); 129 int radeonfb_list_font(void *, struct wsdisplay_font *); 130 int radeonfb_load_font(void *, void *, struct wsdisplay_font *); 131 paddr_t radeonfb_mmap(void *, off_t, int); 132 int radeonfb_show_screen(void *, void *, int, void (*)(void *, int, int), 133 void *); 134 135 struct wsdisplay_accessops radeonfb_accessops = { 136 .ioctl = radeonfb_ioctl, 137 .mmap = radeonfb_mmap, 138 .alloc_screen = radeonfb_alloc_screen, 139 .free_screen = radeonfb_free_screen, 140 .show_screen = radeonfb_show_screen, 141 .load_font = radeonfb_load_font, 142 .list_font = radeonfb_list_font 143 }; 144 145 int radeonfb_match(struct device *, void *, void *); 146 void radeonfb_attach(struct device *, struct device *, void *); 147 148 const struct cfattach radeonfb_ca = { 149 sizeof(struct radeonfb_softc), radeonfb_match, radeonfb_attach 150 }; 151 152 struct cfdriver radeonfb_cd = { 153 NULL, "radeonfb", DV_DULL 154 }; 155 156 int radeonfb_copycols(void *, int, int, int, int); 157 int radeonfb_erasecols(void *, int, int, int, long); 158 int radeonfb_copyrows(void *, int, int, int); 159 int radeonfb_eraserows(void *, int, int, long); 160 161 int radeonfb_setup(struct radeonfb *); 162 void radeonfb_wait_fifo(struct radeonfb *, int); 163 void radeonfb_wait(struct radeonfb *); 164 void radeonfb_copyrect(struct radeonfb *, int, int, int, int, int, int); 165 void radeonfb_fillrect(struct radeonfb *, int, int, int, int, int); 166 167 static struct radeonfb radeonfbcn; 168 169 const struct pci_matchid radeonfb_devices[] = { 170 { PCI_VENDOR_ATI, 0x9615 } 171 }; 172 173 int 174 radeonfb_match(struct device *parent, void *cf, void *aux) 175 { 176 struct pci_attach_args *pa = aux; 177 178 return pci_matchbyid(pa, radeonfb_devices, nitems(radeonfb_devices)); 179 } 180 181 void 182 radeonfb_attach(struct device *parent, struct device *self, void *aux) 183 { 184 struct radeonfb_softc *sc = (struct radeonfb_softc *)self; 185 struct pci_attach_args *pa = aux; 186 struct wsemuldisplaydev_attach_args waa; 187 bus_space_tag_t fbt, mmiot; 188 bus_space_handle_t fbh, mmioh; 189 #if 0 190 bus_size_t fbsize, mmiosize; 191 #endif 192 struct radeonfb *fb; 193 int console; 194 195 sc->sc_pcitag = pa->pa_tag; 196 197 if (pci_mapreg_map(pa, RADEON_PCI_MEM, PCI_MAPREG_TYPE_MEM, 198 BUS_SPACE_MAP_LINEAR, &fbt, &fbh, 199 &sc->sc_membase, &sc->sc_memsize, 0)) { 200 printf(": can't map video memory\n"); 201 return; 202 } 203 204 if (pci_mapreg_map(pa, RADEON_PCI_MMIO, PCI_MAPREG_TYPE_MEM, 0, 205 &mmiot, &mmioh, &sc->sc_mmiobase, 206 &sc->sc_mmiosize, 0)) { 207 printf(": can't map registers\n"); 208 return; 209 } 210 211 console = radeonfbcn.ri.ri_hw != NULL; 212 213 if (console) 214 fb = &radeonfbcn; 215 else 216 fb = &sc->sc_fb_store; 217 218 fb->sc = sc; 219 fb->fbt = fbt; 220 fb->fbh = fbh; 221 fb->mmiot = mmiot; 222 fb->mmioh = mmioh; 223 sc->sc_fb = fb; 224 225 if (!console) { 226 if (radeonfb_setup(fb) != 0) { 227 printf(": can't setup frame buffer\n"); 228 return; 229 } 230 } 231 232 printf(": %dx%d, %dbpp\n", 233 fb->ri.ri_width, fb->ri.ri_height, fb->ri.ri_depth); 234 235 sc->sc_scrlist[0] = &fb->wsd; 236 sc->sc_wsl.nscreens = 1; 237 sc->sc_wsl.screens = (const struct wsscreen_descr **)sc->sc_scrlist; 238 239 waa.console = console; 240 waa.scrdata = &sc->sc_wsl; 241 waa.accessops = &radeonfb_accessops; 242 waa.accesscookie = sc; 243 waa.defaultscreens = 0; 244 245 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 246 247 config_found(self, &waa, wsemuldisplaydevprint); 248 } 249 250 /* 251 * wsdisplay accessops 252 */ 253 254 int 255 radeonfb_alloc_screen(void *v, const struct wsscreen_descr *type, 256 void **cookiep, int *curxp, int *curyp, long *attrp) 257 { 258 struct radeonfb_softc *sc = (struct radeonfb_softc *)v; 259 struct rasops_info *ri = &sc->sc_fb->ri; 260 261 if (sc->sc_nscr > 0) 262 return ENOMEM; 263 264 *cookiep = ri; 265 *curxp = *curyp = 0; 266 ri->ri_ops.alloc_attr(ri, 0, 0, 0, attrp); 267 sc->sc_nscr++; 268 269 return 0; 270 } 271 272 void 273 radeonfb_free_screen(void *v, void *cookie) 274 { 275 struct radeonfb_softc *sc = (struct radeonfb_softc *)v; 276 277 sc->sc_nscr--; 278 } 279 280 int 281 radeonfb_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) 282 { 283 struct radeonfb_softc *sc = (struct radeonfb_softc *)v; 284 struct radeonfb *fb = sc->sc_fb; 285 struct rasops_info *ri = &fb->ri; 286 struct wsdisplay_fbinfo *wdf; 287 #if 0 288 struct pcisel *sel; 289 #endif 290 291 switch (cmd) { 292 case WSDISPLAYIO_GTYPE: 293 *(u_int *)data = WSDISPLAY_TYPE_RADEONFB; 294 break; 295 case WSDISPLAYIO_SMODE: 296 sc->sc_mode = *(u_int *)data; 297 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 298 /* Clear screen. */ 299 radeonfb_setup(fb); 300 radeonfb_fillrect(fb, 0, 0, ri->ri_width, 301 ri->ri_height, ri->ri_devcmap[WSCOL_BLACK]); 302 } 303 break; 304 case WSDISPLAYIO_GINFO: 305 wdf = (struct wsdisplay_fbinfo *)data; 306 wdf->width = ri->ri_width; 307 wdf->height = ri->ri_height; 308 wdf->depth = ri->ri_depth; 309 wdf->cmsize = 0; 310 break; 311 case WSDISPLAYIO_LINEBYTES: 312 *(u_int *)data = ri->ri_stride; 313 break; 314 315 #if 0 316 case WSDISPLAYIO_GPCIID: 317 sel = (struct pcisel *)data; 318 sel->pc_bus = PCITAG_BUS(sc->sc_pcitag); 319 sel->pc_dev = PCITAG_DEV(sc->sc_pcitag); 320 sel->pc_func = PCITAG_FUN(sc->sc_pcitag); 321 break; 322 #endif 323 324 case WSDISPLAYIO_SVIDEO: 325 case WSDISPLAYIO_GVIDEO: 326 break; 327 328 default: 329 return -1; 330 } 331 332 return 0; 333 } 334 335 int 336 radeonfb_show_screen(void *v, void *cookie, int waitok, 337 void (*cb)(void *, int, int), void *cbarg) 338 { 339 return 0; 340 } 341 342 paddr_t 343 radeonfb_mmap(void *v, off_t off, int prot) 344 { 345 struct radeonfb_softc *sc = (struct radeonfb_softc *)v; 346 struct radeonfb *fb = sc->sc_fb; 347 348 if ((off & PAGE_MASK) != 0) 349 return -1; 350 351 switch (sc->sc_mode) { 352 case WSDISPLAYIO_MODE_MAPPED: 353 #ifdef APERTURE 354 if (allowaperture == 0) 355 return (-1); 356 #endif 357 358 if (sc->sc_mmiosize == 0) 359 return (-1); 360 361 if (off >= sc->sc_membase && 362 off < (sc->sc_membase + sc->sc_memsize)) 363 return (bus_space_mmap(fb->fbt, 364 sc->sc_membase, off - sc->sc_membase, 365 prot, BUS_SPACE_MAP_LINEAR)); 366 367 if (off >= sc->sc_mmiobase && 368 off < (sc->sc_mmiobase + sc->sc_mmiosize)) 369 return (bus_space_mmap(fb->mmiot, 370 sc->sc_mmiobase, off - sc->sc_mmiobase, 371 prot, BUS_SPACE_MAP_LINEAR)); 372 break; 373 374 case WSDISPLAYIO_MODE_DUMBFB: 375 /* 376 * Don't allow mmap if the frame buffer area is not page aligned. 377 * XXX we should reprogram it to a page aligned boundary at attach 378 * XXX time if this isn't the case. 379 */ 380 if ((fb->memoff % PAGE_SIZE) != 0) 381 return (-1); 382 383 if (off >= 0 && off < sc->sc_memsize / 2) { 384 bus_addr_t base = sc->sc_membase + fb->memoff; 385 386 return (bus_space_mmap(fb->fbt, base, off, 387 prot, BUS_SPACE_MAP_LINEAR)); 388 } 389 break; 390 } 391 392 return (-1); 393 } 394 395 int 396 radeonfb_load_font(void *v, void *emulcookie, struct wsdisplay_font *font) 397 { 398 struct radeonfb_softc *sc = (struct radeonfb_softc *)v; 399 struct rasops_info *ri = &sc->sc_fb->ri; 400 401 return rasops_load_font(ri, emulcookie, font); 402 } 403 404 int 405 radeonfb_list_font(void *v, struct wsdisplay_font *font) 406 { 407 struct radeonfb_softc *sc = (struct radeonfb_softc *)v; 408 struct rasops_info *ri = &sc->sc_fb->ri; 409 410 return rasops_list_font(ri, font); 411 } 412 413 /* 414 * Accelerated routines. 415 */ 416 417 int 418 radeonfb_copycols(void *cookie, int row, int src, int dst, int num) 419 { 420 struct rasops_info *ri = cookie; 421 struct radeonfb *fb = ri->ri_hw; 422 423 num *= ri->ri_font->fontwidth; 424 src *= ri->ri_font->fontwidth; 425 dst *= ri->ri_font->fontwidth; 426 row *= ri->ri_font->fontheight; 427 428 radeonfb_copyrect(fb, ri->ri_xorigin + src, ri->ri_yorigin + row, 429 ri->ri_xorigin + dst, ri->ri_yorigin + row, 430 num, ri->ri_font->fontheight); 431 432 return 0; 433 } 434 435 int 436 radeonfb_erasecols(void *cookie, int row, int col, int num, long attr) 437 { 438 struct rasops_info *ri = cookie; 439 struct radeonfb *fb = ri->ri_hw; 440 int bg, fg; 441 442 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); 443 444 row *= ri->ri_font->fontheight; 445 col *= ri->ri_font->fontwidth; 446 num *= ri->ri_font->fontwidth; 447 448 radeonfb_fillrect(fb, ri->ri_xorigin + col, ri->ri_yorigin + row, 449 num, ri->ri_font->fontheight, ri->ri_devcmap[bg]); 450 451 return 0; 452 } 453 454 int 455 radeonfb_copyrows(void *cookie, int src, int dst, int num) 456 { 457 struct rasops_info *ri = cookie; 458 struct radeonfb *fb = ri->ri_hw; 459 460 num *= ri->ri_font->fontheight; 461 src *= ri->ri_font->fontheight; 462 dst *= ri->ri_font->fontheight; 463 464 radeonfb_copyrect(fb, ri->ri_xorigin, ri->ri_yorigin + src, 465 ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, num); 466 467 return 0; 468 } 469 470 int 471 radeonfb_eraserows(void *cookie, int row, int num, long attr) 472 { 473 struct rasops_info *ri = cookie; 474 struct radeonfb *fb = ri->ri_hw; 475 int bg, fg; 476 int x, y, w; 477 478 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); 479 480 if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) { 481 num = ri->ri_height; 482 x = y = 0; 483 w = ri->ri_width; 484 } else { 485 num *= ri->ri_font->fontheight; 486 x = ri->ri_xorigin; 487 y = ri->ri_yorigin + row * ri->ri_font->fontheight; 488 w = ri->ri_emuwidth; 489 } 490 radeonfb_fillrect(fb, x, y, w, num, ri->ri_devcmap[bg]); 491 492 return 0; 493 } 494 495 void 496 radeonfb_wait_fifo(struct radeonfb *fb, int n) 497 { 498 int i; 499 500 for (i = 1000000; i != 0; i--) { 501 if ((bus_space_read_4(fb->mmiot, fb->mmioh, 502 RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK) >= n) 503 break; 504 DELAY(1); 505 } 506 } 507 508 void 509 radeonfb_wait(struct radeonfb *fb) 510 { 511 int i; 512 513 radeonfb_wait_fifo(fb, 64); 514 515 for (i = 1000000; i != 0; i--) { 516 if ((bus_space_read_4(fb->mmiot, fb->mmioh, 517 RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) == 0) 518 break; 519 DELAY(1); 520 } 521 522 bus_space_write_4(fb->mmiot, fb->mmioh, 523 RADEON_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH_ALL); 524 525 for (i = 1000000; i != 0; i--) { 526 if ((bus_space_read_4(fb->mmiot, fb->mmioh, 527 RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY) == 0) 528 break; 529 DELAY(1); 530 } 531 } 532 533 void 534 radeonfb_copyrect(struct radeonfb *fb, int sx, int sy, int dx, int dy, 535 int w, int h) 536 { 537 uint32_t gmc; 538 uint32_t dir; 539 540 radeonfb_wait_fifo(fb, 1); 541 bus_space_write_4(fb->mmiot, fb->mmioh, RADEON_WAIT_UNTIL, 542 RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN); 543 544 if (dy < sy) { 545 dir = RADEON_DST_Y_TOP_TO_BOTTOM; 546 } else { 547 sy += h - 1; 548 dy += h - 1; 549 dir = 0; 550 } 551 if (dx < sx) { 552 dir |= RADEON_DST_X_LEFT_TO_RIGHT; 553 } else { 554 sx += w - 1; 555 dx += w - 1; 556 } 557 558 radeonfb_wait_fifo(fb, 6); 559 560 gmc = RADEON_GMC_DST_16BPP; 561 gmc |= RADEON_GMC_BRUSH_NONE; 562 gmc |= RADEON_GMC_SRC_DATATYPE_COLOR; 563 gmc |= RADEON_GMC_SRC_SOURCE_MEMORY; 564 gmc |= RADEON_ROP3_S; 565 gmc |= RADEON_GMC_CLR_CMP_CNTL_DIS; 566 bus_space_write_4(fb->mmiot, fb->mmioh, 567 RADEON_DP_GUI_MASTER_CNTL, gmc); 568 bus_space_write_4(fb->mmiot, fb->mmioh, 569 RADEON_DP_WRITE_MASK, 0xffffffff); 570 bus_space_write_4(fb->mmiot, fb->mmioh, 571 RADEON_DP_CNTL, dir); 572 573 bus_space_write_4(fb->mmiot, fb->mmioh, 574 RADEON_SRC_Y_X, RADEON_COORDS(sx, sy)); 575 bus_space_write_4(fb->mmiot, fb->mmioh, 576 RADEON_DST_Y_X, RADEON_COORDS(dx, dy)); 577 bus_space_write_4(fb->mmiot, fb->mmioh, 578 RADEON_DST_HEIGHT_WIDTH, RADEON_COORDS(w, h)); 579 580 radeonfb_wait(fb); 581 } 582 583 void 584 radeonfb_fillrect(struct radeonfb *fb, int x, int y, int w, int h, int color) 585 { 586 uint32_t gmc; 587 588 radeonfb_wait_fifo(fb, 1); 589 bus_space_write_4(fb->mmiot, fb->mmioh, RADEON_WAIT_UNTIL, 590 RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN); 591 592 radeonfb_wait_fifo(fb, 6); 593 594 gmc = RADEON_GMC_DST_16BPP; 595 gmc |= RADEON_GMC_BRUSH_SOLID_COLOR; 596 gmc |= RADEON_GMC_SRC_DATATYPE_COLOR; 597 gmc |= RADEON_ROP3_P; 598 gmc |= RADEON_GMC_CLR_CMP_CNTL_DIS; 599 bus_space_write_4(fb->mmiot, fb->mmioh, 600 RADEON_DP_GUI_MASTER_CNTL, gmc); 601 bus_space_write_4(fb->mmiot, fb->mmioh, 602 RADEON_DP_BRUSH_FRGD_CLR, color); 603 bus_space_write_4(fb->mmiot, fb->mmioh, 604 RADEON_DP_WRITE_MASK, 0xffffffff); 605 bus_space_write_4(fb->mmiot, fb->mmioh, RADEON_DP_CNTL, 606 RADEON_DST_Y_TOP_TO_BOTTOM | RADEON_DST_X_LEFT_TO_RIGHT); 607 608 bus_space_write_4(fb->mmiot, fb->mmioh, 609 RADEON_DST_Y_X, RADEON_COORDS(x, y)); 610 bus_space_write_4(fb->mmiot, fb->mmioh, 611 RADEON_DST_HEIGHT_WIDTH, RADEON_COORDS(w, h)); 612 613 radeonfb_wait(fb); 614 } 615 616 /* 617 * Frame buffer initialization. 618 */ 619 620 int 621 radeonfb_setup(struct radeonfb *fb) 622 { 623 struct rasops_info *ri; 624 uint width, height, bpp; 625 626 /* 627 * The firmware sets up the framebuffer such that at starts at 628 * an offset from the start of video memory. 629 */ 630 fb->memoff = 631 bus_space_read_4(fb->mmiot, fb->mmioh, RADEON_CRTC_OFFSET); 632 633 width = 800; /* XXX */ 634 height = 600; /* XXX */ 635 bpp = 16; 636 637 ri = &fb->ri; 638 ri->ri_width = width; 639 ri->ri_height = height; 640 ri->ri_depth = bpp; 641 ri->ri_stride = (ri->ri_width * ri->ri_depth) / 8; 642 ri->ri_flg = RI_CENTER | RI_CLEAR | RI_FULLCLEAR; 643 ri->ri_bits = (void *)(bus_space_vaddr(fb->fbt, fb->fbh) + fb->memoff); 644 ri->ri_hw = fb; 645 646 ri->ri_rnum = 5; 647 ri->ri_rpos = 11; 648 ri->ri_gnum = 6; 649 ri->ri_gpos = 5; 650 ri->ri_bnum = 5; 651 ri->ri_bpos = 0; 652 653 radeonfb_wait_fifo(fb, 2); 654 bus_space_write_4(fb->mmiot, fb->mmioh, RADEON_DEFAULT_PITCH_OFFSET, 655 ((ri->ri_stride >> 6) << 22) | (fb->memoff >> 10)); 656 bus_space_write_4(fb->mmiot, fb->mmioh, 657 RADEON_DEFAULT_SC_BOTTOM_RIGHT, 0x1fff1fff); 658 659 rasops_init(ri, 160, 160); 660 661 strlcpy(fb->wsd.name, "std", sizeof(fb->wsd.name)); 662 fb->wsd.ncols = ri->ri_cols; 663 fb->wsd.nrows = ri->ri_rows; 664 fb->wsd.textops = &ri->ri_ops; 665 fb->wsd.fontwidth = ri->ri_font->fontwidth; 666 fb->wsd.fontheight = ri->ri_font->fontheight; 667 fb->wsd.capabilities = ri->ri_caps; 668 669 #if 0 670 ri->ri_ops.copyrows = radeonfb_copyrows; 671 ri->ri_ops.copycols = radeonfb_copycols; 672 ri->ri_ops.eraserows = radeonfb_eraserows; 673 ri->ri_ops.erasecols = radeonfb_erasecols; 674 #endif 675 676 return 0; 677 } 678 679 /* 680 * Early console code 681 */ 682 683 int radeonfb_cnattach(bus_space_tag_t, bus_space_tag_t, pcitag_t, pcireg_t); 684 685 int 686 radeonfb_cnattach(bus_space_tag_t memt, bus_space_tag_t iot, pcitag_t tag, 687 pcireg_t id) 688 { 689 long defattr; 690 struct rasops_info *ri; 691 pcireg_t bar; 692 int rc; 693 694 /* filter out unrecognized devices */ 695 switch (id) { 696 default: 697 return ENODEV; 698 case PCI_ID_CODE(PCI_VENDOR_ATI, 0x9615): 699 break; 700 } 701 702 bar = pci_conf_read_early(tag, RADEON_PCI_MEM); 703 if (PCI_MAPREG_TYPE(bar) != PCI_MAPREG_TYPE_MEM) 704 return EINVAL; 705 radeonfbcn.fbt = memt; 706 rc = bus_space_map(memt, PCI_MAPREG_MEM_ADDR(bar), 1 /* XXX */, 707 BUS_SPACE_MAP_LINEAR, &radeonfbcn.fbh); 708 if (rc != 0) 709 return rc; 710 711 bar = pci_conf_read_early(tag, RADEON_PCI_MMIO); 712 if (PCI_MAPREG_TYPE(bar) != PCI_MAPREG_TYPE_MEM) 713 return EINVAL; 714 radeonfbcn.mmiot = memt; 715 rc = bus_space_map(memt, PCI_MAPREG_MEM_ADDR(bar), 1 /* XXX */, 716 BUS_SPACE_MAP_LINEAR, &radeonfbcn.mmioh); 717 if (rc != 0) 718 return rc; 719 720 rc = radeonfb_setup(&radeonfbcn); 721 if (rc != 0) 722 return rc; 723 724 ri = &radeonfbcn.ri; 725 ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); 726 wsdisplay_cnattach(&radeonfbcn.wsd, ri, 0, 0, defattr); 727 728 return 0; 729 } 730