1 /* $NetBSD: summitfb.c,v 1.35 2025/10/20 09:47:05 macallan Exp $ */ 2 3 /* $OpenBSD: sti_pci.c,v 1.7 2009/02/06 22:51:04 miod Exp $ */ 4 5 /* 6 * Copyright (c) 2006, 2007 Miodrag Vallat. 7 ^ 2024 Michael Lorenz 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice, this permission notice, and the disclaimer below 12 * appear in all copies. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23 /* 24 * a native driver for HP Visualize FX graphics cards, so far tested only on 25 * my FX4 26 * STI portions are from Miodrag Vallat's sti_pci.c 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: summitfb.c,v 1.35 2025/10/20 09:47:05 macallan Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/kmem.h> 35 #include <sys/device.h> 36 #include <sys/mutex.h> 37 38 #include <dev/pci/pcivar.h> 39 #include <dev/pci/pcireg.h> 40 #include <dev/pci/pcidevs.h> 41 #include <dev/pci/pciio.h> 42 43 #include <dev/wscons/wsdisplayvar.h> 44 #include <dev/wscons/wsconsio.h> 45 #include <dev/wsfont/wsfont.h> 46 #include <dev/rasops/rasops.h> 47 #include <dev/wscons/wsdisplay_vconsvar.h> 48 #include <dev/pci/wsdisplay_pci.h> 49 #include <dev/wscons/wsdisplay_glyphcachevar.h> 50 51 #include <dev/ic/stireg.h> 52 #include <dev/ic/summitreg.h> 53 #include <dev/ic/stivar.h> 54 #include <hppa/dev/sti_pci_var.h> 55 56 #include "opt_summitfb.h" 57 58 #ifdef SUMMITFB_DEBUG 59 #define DPRINTF(s) printf s 60 #else 61 #define DPRINTF(s) __nothing 62 #endif 63 64 int summitfb_match(device_t, cfdata_t, void *); 65 void summitfb_attach(device_t, device_t, void *); 66 67 struct summitfb_softc { 68 device_t sc_dev; 69 pci_chipset_tag_t sc_pc; 70 pcitag_t sc_tag; 71 72 /* stuff we need in order to use the STI ROM */ 73 struct sti_softc sc_base; 74 struct sti_screen sc_scr; 75 bus_space_handle_t sc_romh; 76 77 int sc_width, sc_height; 78 int sc_locked; 79 struct vcons_screen sc_console_screen; 80 struct wsscreen_descr sc_defaultscreen_descr; 81 const struct wsscreen_descr *sc_screens[1]; 82 struct wsscreen_list sc_screenlist; 83 struct vcons_data vd; 84 int sc_mode; 85 u_char sc_cmap_red[256]; 86 u_char sc_cmap_green[256]; 87 u_char sc_cmap_blue[256]; 88 uint32_t sc_write_mode, sc_read_mode; 89 /* cursor stuff */ 90 int sc_cursor_x, sc_cursor_y; 91 int sc_hot_x, sc_hot_y, sc_enabled; 92 uint32_t sc_palette[16]; 93 int sc_video_on; 94 glyphcache sc_gc; 95 }; 96 97 CFATTACH_DECL_NEW(summitfb, sizeof(struct summitfb_softc), 98 summitfb_match, summitfb_attach, NULL, NULL); 99 100 void summitfb_enable_rom(struct sti_softc *); 101 void summitfb_disable_rom(struct sti_softc *); 102 103 void summitfb_setup(struct summitfb_softc *); 104 105 /* XXX these really need to go into their own header */ 106 int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t, 107 bus_space_handle_t, bus_addr_t *, u_int); 108 int sti_screen_setup(struct sti_screen *, int); 109 void sti_describe_screen(struct sti_softc *, struct sti_screen *); 110 111 #define PCI_ROM_SIZE(mr) \ 112 (PCI_MAPREG_ROM_ADDR(mr) & -PCI_MAPREG_ROM_ADDR(mr)) 113 114 /* wsdisplay stuff */ 115 static int summitfb_ioctl(void *, void *, u_long, void *, int, 116 struct lwp *); 117 static paddr_t summitfb_mmap(void *, void *, off_t, int); 118 static void summitfb_init_screen(void *, struct vcons_screen *, int, 119 long *); 120 121 static int summitfb_putcmap(struct summitfb_softc *, 122 struct wsdisplay_cmap *); 123 static int summitfb_getcmap(struct summitfb_softc *, 124 struct wsdisplay_cmap *); 125 static void summitfb_restore_palette(struct summitfb_softc *); 126 static int summitfb_putpalreg(struct summitfb_softc *, uint8_t, uint8_t, 127 uint8_t, uint8_t); 128 129 static inline void summitfb_setup_fb(struct summitfb_softc *); 130 static void summitfb_clearfb(struct summitfb_softc *); 131 static void summitfb_rectfill(struct summitfb_softc *, int, int, int, int, 132 uint32_t); 133 static void summitfb_bitblt(void *, int, int, int, int, int, 134 int, int); 135 136 static void summitfb_cursor(void *, int, int, int); 137 static void summitfb_putchar(void *, int, int, u_int, long); 138 static void summitfb_putchar_aa(void *, int, int, u_int, long); 139 static void summitfb_copycols(void *, int, int, int, int); 140 static void summitfb_erasecols(void *, int, int, int, long); 141 static void summitfb_copyrows(void *, int, int, int); 142 static void summitfb_eraserows(void *, int, int, long); 143 144 static void summitfb_move_cursor(struct summitfb_softc *, int, int); 145 static int summitfb_do_cursor(struct summitfb_softc *, 146 struct wsdisplay_cursor *); 147 148 static void summitfb_set_video(struct summitfb_softc *, int); 149 150 static void summitfb_copyfont(struct summitfb_softc *); 151 152 struct wsdisplay_accessops summitfb_accessops = { 153 .ioctl = summitfb_ioctl, 154 .mmap = summitfb_mmap, 155 .alloc_screen = NULL, 156 .free_screen = NULL, 157 .show_screen = NULL, 158 .load_font = NULL, 159 .pollc = NULL, 160 .scroll = NULL, 161 }; 162 163 static inline void summitfb_wait_fifo(struct summitfb_softc *, uint32_t); 164 static inline void summitfb_wait(struct summitfb_softc *); 165 166 int sti_fetchfonts(struct sti_screen *, struct sti_inqconfout *, uint32_t, 167 u_int); 168 169 int 170 summitfb_match(device_t parent, cfdata_t cf, void *aux) 171 { 172 struct pci_attach_args *paa = aux; 173 174 if (PCI_VENDOR(paa->pa_id) != PCI_VENDOR_HP) 175 return 0; 176 177 if (PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FX4) 178 return 10; /* beat out sti at pci */ 179 180 return 0; 181 } 182 183 static inline uint32_t 184 summitfb_read4(struct summitfb_softc *sc, uint32_t offset) 185 { 186 struct sti_rom *rom = sc->sc_base.sc_rom; 187 bus_space_tag_t memt = rom->memt; 188 bus_space_handle_t memh = rom->regh[2]; 189 190 return bus_space_read_stream_4(memt, memh, offset - 0x400000); 191 } 192 193 static inline void 194 summitfb_write4(struct summitfb_softc *sc, uint32_t offset, uint32_t val) 195 { 196 struct sti_rom *rom = sc->sc_base.sc_rom; 197 bus_space_tag_t memt = rom->memt; 198 bus_space_handle_t memh = rom->regh[2]; 199 200 bus_space_write_stream_4(memt, memh, offset - 0x400000, val); 201 } 202 203 static inline void 204 summitfb_write_mode(struct summitfb_softc *sc, uint32_t mode) 205 { 206 if (sc->sc_write_mode == mode) 207 return; 208 summitfb_wait(sc); 209 summitfb_write4(sc, VISFX_VRAM_WRITE_MODE, mode); 210 sc->sc_write_mode = mode; 211 } 212 213 static inline void 214 summitfb_read_mode(struct summitfb_softc *sc, uint32_t mode) 215 { 216 if (sc->sc_read_mode == mode) 217 return; 218 summitfb_wait(sc); 219 summitfb_write4(sc, VISFX_VRAM_READ_MODE, mode); 220 sc->sc_read_mode = mode; 221 } 222 223 void 224 summitfb_attach(device_t parent, device_t self, void *aux) 225 { 226 struct summitfb_softc *sc = device_private(self); 227 struct pci_attach_args *paa = aux; 228 struct sti_rom *rom; 229 struct rasops_info *ri; 230 struct wsemuldisplaydev_attach_args aa; 231 struct sti_dd *dd; 232 unsigned long defattr = 0; 233 int ret, is_console = 0; 234 235 sc->sc_dev = self; 236 237 sc->sc_pc = paa->pa_pc; 238 sc->sc_tag = paa->pa_tag; 239 sc->sc_base.sc_dev = self; 240 sc->sc_base.sc_enable_rom = summitfb_enable_rom; 241 sc->sc_base.sc_disable_rom = summitfb_disable_rom; 242 243 aprint_normal("\n"); 244 245 if (sti_pci_check_rom(&sc->sc_base, paa, &sc->sc_romh) != 0) 246 return; 247 248 ret = sti_pci_is_console(paa, sc->sc_base. bases); 249 if (ret != 0) { 250 sc->sc_base.sc_flags |= STI_CONSOLE; 251 is_console = 1; 252 } 253 rom = kmem_zalloc(sizeof(*rom), KM_SLEEP); 254 rom->rom_softc = &sc->sc_base; 255 ret = sti_rom_setup(rom, paa->pa_iot, paa->pa_memt, sc->sc_romh, 256 sc->sc_base.bases, STI_CODEBASE_MAIN); 257 if (ret != 0) { 258 kmem_free(rom, sizeof(*rom)); 259 return; 260 } 261 262 sc->sc_base.sc_rom = rom; 263 dd = &rom->rom_dd; 264 265 sc->sc_scr.scr_rom = sc->sc_base.sc_rom; 266 ret = sti_screen_setup(&sc->sc_scr, STI_FBMODE); 267 268 sti_fetchfonts(&sc->sc_scr, NULL, dd->dd_fntaddr, 0); 269 wsfont_init(); 270 summitfb_copyfont(sc); 271 272 sc->sc_width = sc->sc_scr.scr_cfg.scr_width; 273 sc->sc_height = sc->sc_scr.scr_cfg.scr_height; 274 sc->sc_write_mode = 0xffffffff; 275 sc->sc_read_mode = 0xffffffff; 276 277 #ifdef SUMMITFB_DEBUG 278 sc->sc_height -= 200; 279 #endif 280 281 sc->sc_defaultscreen_descr = (struct wsscreen_descr){ 282 .name = "default", 283 .ncols = 0, .nrows = 0, 284 .textops = NULL, 285 .fontwidth = 8, .fontheight = 16, 286 .capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | 287 WSSCREEN_UNDERLINE | WSSCREEN_RESIZE, 288 .modecookie = NULL, 289 }; 290 291 sc->sc_screens[0] = &sc->sc_defaultscreen_descr; 292 sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; 293 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 294 sc->sc_locked = 0; 295 296 vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, 297 &summitfb_accessops); 298 sc->vd.init_screen = summitfb_init_screen; 299 sc->vd.show_screen_cookie = &sc->sc_gc; 300 sc->vd.show_screen_cb = glyphcache_adapt; 301 ri = &sc->sc_console_screen.scr_ri; 302 303 sc->sc_gc.gc_bitblt = summitfb_bitblt; 304 sc->sc_gc.gc_blitcookie = sc; 305 sc->sc_gc.gc_rop = RopSrc; 306 307 summitfb_setup(sc); 308 309 vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr); 310 sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 311 312 sc->sc_defaultscreen_descr.textops = &ri->ri_ops; 313 sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; 314 sc->sc_defaultscreen_descr.nrows = ri->ri_rows; 315 sc->sc_defaultscreen_descr.ncols = ri->ri_cols; 316 317 /* 318 * STI lies to us - it reports a 2048x2048 framebuffer but blitter 319 * ops wrap around below 1024 and we seem to have only about 250 320 * usable columns to the right. Should still be enough to cache 321 * a font or four. 322 * So, the framebuffer seems to be 1536x1024, which is odd since the 323 * FX4 is supposed to support resolutions higher than 1280x1024. 324 * I guess video memory is allocated in 512x512 chunks 325 */ 326 glyphcache_init(&sc->sc_gc, 327 sc->sc_height, 328 sc->sc_height, 329 (sc->sc_width + 511) & (~511), 330 ri->ri_font->fontwidth, 331 ri->ri_font->fontheight, 332 defattr); 333 334 summitfb_restore_palette(sc); 335 summitfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, 336 ri->ri_devcmap[(defattr >> 16) & 0xff]); 337 summitfb_setup_fb(sc); 338 339 if (is_console) { 340 wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, 341 defattr); 342 343 vcons_replay_msgbuf(&sc->sc_console_screen); 344 } 345 346 aprint_normal_dev(sc->sc_dev, "%s at %dx%d\n", sc->sc_scr.name, 347 sc->sc_width, sc->sc_height); 348 349 /* no suspend/resume support yet */ 350 pmf_device_register(sc->sc_dev, NULL, NULL); 351 352 aa.console = is_console; 353 aa.scrdata = &sc->sc_screenlist; 354 aa.accessops = &summitfb_accessops; 355 aa.accesscookie = &sc->vd; 356 357 config_found(sc->sc_dev, &aa, wsemuldisplaydevprint, CFARGS_NONE); 358 } 359 360 /* 361 * Enable PCI ROM. 362 */ 363 364 void 365 summitfb_enable_rom(struct sti_softc *sc) 366 { 367 struct summitfb_softc *spc = device_private(sc->sc_dev); 368 uint32_t address; 369 370 if (!ISSET(sc->sc_flags, STI_ROM_ENABLED)) { 371 address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM); 372 address |= PCI_MAPREG_ROM_ENABLE; 373 pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM, address); 374 } 375 SET(sc->sc_flags, STI_ROM_ENABLED); 376 } 377 378 /* 379 * Disable PCI ROM. 380 */ 381 382 void 383 summitfb_disable_rom(struct sti_softc *sc) 384 { 385 struct summitfb_softc *spc = device_private(sc->sc_dev); 386 uint32_t address; 387 388 if (ISSET(sc->sc_flags, STI_ROM_ENABLED)) { 389 address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM); 390 address &= ~PCI_MAPREG_ROM_ENABLE; 391 pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM, address); 392 } 393 CLR(sc->sc_flags, STI_ROM_ENABLED); 394 } 395 396 static inline void 397 summitfb_wait(struct summitfb_softc *sc) 398 { 399 400 while (summitfb_read4(sc, VISFX_STATUS) != 0) 401 continue; 402 } 403 404 static inline void 405 summitfb_setup_fb(struct summitfb_softc *sc) 406 { 407 408 summitfb_wait(sc); 409 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 410 summitfb_write_mode(sc, VISFX_WRITE_MODE_PLAIN); 411 summitfb_read_mode(sc, VISFX_WRITE_MODE_PLAIN); 412 summitfb_write4(sc, VISFX_APERTURE_ACCESS, VISFX_DEPTH_8); 413 /* make overlay opaque */ 414 summitfb_write4(sc, VISFX_OTR, OTR_T | OTR_L1 | OTR_L0); 415 } else { 416 summitfb_write_mode(sc, OTC01 | BIN8F | BUFFL); 417 summitfb_read_mode(sc, OTC01 | BIN8F | BUFFL); 418 summitfb_write4(sc, VISFX_APERTURE_ACCESS, VISFX_DEPTH_32); 419 /* make overlay transparent */ 420 summitfb_write4(sc, VISFX_OTR, OTR_A); 421 } 422 summitfb_write4(sc, VISFX_IBO, RopSrc); 423 } 424 425 void 426 summitfb_setup(struct summitfb_softc *sc) 427 { 428 int i; 429 430 sc->sc_hot_x = 0; 431 sc->sc_hot_y = 0; 432 sc->sc_enabled = 0; 433 sc->sc_video_on = 1; 434 435 summitfb_wait(sc); 436 #if 1 437 /* these control byte swapping */ 438 summitfb_write4(sc, 0xb08044, 0x1b); /* MFU_BSCTD */ 439 summitfb_write4(sc, 0xb08048, 0x1b); /* MFU_BSCCTL */ 440 441 summitfb_write4(sc, 0x920860, 0xe4); /* FBC_RBS */ 442 summitfb_write4(sc, 0x921114, 0); /* CPE, clip plane enable */ 443 summitfb_write4(sc, 0x9211d8, 0); /* FCDA */ 444 445 summitfb_write4(sc, 0xa00818, 0); /* WORG window origin */ 446 summitfb_write4(sc, 0xa0081c, 0); /* FBS front buffer select*/ 447 summitfb_write4(sc, 0xa00850, 0); /* MISC_CTL */ 448 summitfb_write4(sc, 0xa0086c, 0); /* WCE window clipping enable */ 449 #endif 450 /* initialize drawiing engine */ 451 summitfb_wait(sc); 452 summitfb_write4(sc, VISFX_CONTROL, 0); // clear WFC 453 summitfb_write4(sc, VISFX_APERTURE_ACCESS, VISFX_DEPTH_8); 454 summitfb_write4(sc, VISFX_PIXEL_MASK, 0xffffffff); 455 summitfb_write4(sc, VISFX_PLANE_MASK, 0xffffffff); 456 summitfb_write4(sc, VISFX_FOE, FOE_BLEND_ROP); 457 summitfb_write4(sc, VISFX_IBO, RopSrc); 458 summitfb_write_mode(sc, VISFX_WRITE_MODE_PLAIN); 459 summitfb_read_mode(sc, OTC04 | BIN8I | BUFovl); 460 summitfb_write4(sc, VISFX_CLIP_TL, 0); 461 summitfb_write4(sc, VISFX_CLIP_WH, 462 ((sc->sc_scr.fbwidth) << 16) | (sc->sc_scr.fbheight)); 463 /* turn off the cursor sprite */ 464 summitfb_write4(sc, VISFX_CURSOR_POS, 0); 465 /* disable throttling by moving the throttle window way off screen */ 466 summitfb_write4(sc, VISFX_TCR, 0x10001000); 467 468 /* make sure the overlay is opaque */ 469 summitfb_write4(sc, VISFX_OTR, OTR_T | OTR_L1 | OTR_L0); 470 471 /* 472 * initialize XLUT, I mean attribute table 473 * set all to 24bit, CFS1 474 */ 475 for (i = 0; i < 16; i++) 476 summitfb_write4(sc, VISFX_IAA(i), IAA_8F | IAA_CFS1); 477 /* RGB8, no LUT */ 478 summitfb_write4(sc, VISFX_CFS(1), CFS_8F | CFS_BYPASS); 479 /* overlay is 8bit, uses LUT 0 */ 480 summitfb_write4(sc, VISFX_CFS(16), CFS_8I | CFS_LUT0); 481 summitfb_write4(sc, VISFX_CFS(17), CFS_8I | CFS_LUT0); 482 483 /* zero the attribute plane */ 484 summitfb_write_mode(sc, OTC04 | BINapln); 485 summitfb_wait_fifo(sc, 12); 486 summitfb_write4(sc, VISFX_PLANE_MASK, 0xff); 487 summitfb_write4(sc, VISFX_IBO, 0); /* GXclear */ 488 summitfb_write4(sc, VISFX_FG_COLOUR, 0); 489 summitfb_write4(sc, VISFX_START, 0); 490 summitfb_write4(sc, VISFX_SIZE, (sc->sc_width << 16) | sc->sc_height); 491 summitfb_wait(sc); 492 summitfb_write4(sc, VISFX_PLANE_MASK, 0xffffffff); 493 494 /* turn off force attr so the above takes effect */ 495 summitfb_write4(sc, VISFX_FATTR, 0); 496 497 summitfb_setup_fb(sc); 498 } 499 500 static int 501 summitfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 502 struct lwp *l) 503 { 504 struct vcons_data *vd = v; 505 struct summitfb_softc *sc = vd->cookie; 506 struct wsdisplay_fbinfo *wdf; 507 struct vcons_screen *ms = vd->active; 508 509 switch (cmd) { 510 case WSDISPLAYIO_GTYPE: 511 *(u_int *)data = WSDISPLAY_TYPE_STI; 512 return 0; 513 514 case GCID: 515 *(u_int *)data = sc->sc_scr.scr_rom->rom_dd.dd_grid[0]; 516 return 0; 517 518 /* PCI config read/write passthrough. */ 519 case PCI_IOC_CFGREAD: 520 case PCI_IOC_CFGWRITE: 521 return pci_devioctl(sc->sc_pc, sc->sc_tag, 522 cmd, data, flag, l); 523 524 case WSDISPLAYIO_GET_BUSID: 525 return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc, 526 sc->sc_tag, data); 527 528 case WSDISPLAYIO_GINFO: 529 if (ms == NULL) 530 return ENODEV; 531 wdf = data; 532 wdf->height = ms->scr_ri.ri_height; 533 wdf->width = ms->scr_ri.ri_width; 534 wdf->depth = ms->scr_ri.ri_depth; 535 wdf->cmsize = 256; 536 return 0; 537 538 case WSDISPLAYIO_GETCMAP: 539 return summitfb_getcmap(sc, 540 (struct wsdisplay_cmap *)data); 541 542 case WSDISPLAYIO_PUTCMAP: 543 return summitfb_putcmap(sc, 544 (struct wsdisplay_cmap *)data); 545 546 case WSDISPLAYIO_LINEBYTES: 547 *(u_int *)data = 2048; 548 return 0; 549 550 case WSDISPLAYIO_SMODE: { 551 int new_mode = *(int *)data; 552 553 if (new_mode != sc->sc_mode) { 554 sc->sc_mode = new_mode; 555 if(new_mode == WSDISPLAYIO_MODE_EMUL) { 556 summitfb_setup(sc); 557 summitfb_restore_palette(sc); 558 glyphcache_wipe(&sc->sc_gc); 559 summitfb_rectfill(sc, 0, 0, sc->sc_width, 560 sc->sc_height, ms->scr_ri.ri_devcmap[ 561 (ms->scr_defattr >> 16) & 0xff]); 562 vcons_redraw_screen(ms); 563 summitfb_set_video(sc, 1); 564 } else 565 summitfb_clearfb(sc); 566 summitfb_setup_fb(sc); 567 } 568 return 0; 569 } 570 571 case WSDISPLAYIO_GET_FBINFO: { 572 struct wsdisplayio_fbinfo *fbi = data; 573 int ret; 574 575 ret = wsdisplayio_get_fbinfo(&ms->scr_ri, fbi); 576 //fbi->fbi_fbsize = sc->sc_height * 2048; 577 fbi->fbi_stride = 8192; 578 fbi->fbi_bitsperpixel = 32; 579 fbi->fbi_pixeltype = WSFB_RGB; 580 fbi->fbi_subtype.fbi_rgbmasks.red_offset = 16; 581 fbi->fbi_subtype.fbi_rgbmasks.red_size = 8; 582 fbi->fbi_subtype.fbi_rgbmasks.green_offset = 8; 583 fbi->fbi_subtype.fbi_rgbmasks.green_size = 8; 584 fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 0; 585 fbi->fbi_subtype.fbi_rgbmasks.blue_size = 8; 586 fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 0; 587 fbi->fbi_fbsize = sc->sc_scr.fbheight * 8192; 588 return ret; 589 } 590 591 case WSDISPLAYIO_GCURPOS: { 592 struct wsdisplay_curpos *cp = data; 593 594 cp->x = sc->sc_cursor_x; 595 cp->y = sc->sc_cursor_y; 596 return 0; 597 } 598 599 case WSDISPLAYIO_SCURPOS: { 600 struct wsdisplay_curpos *cp = data; 601 602 summitfb_move_cursor(sc, cp->x, cp->y); 603 return 0; 604 } 605 606 case WSDISPLAYIO_GCURMAX: { 607 struct wsdisplay_curpos *cp = data; 608 609 cp->x = 64; 610 cp->y = 64; 611 return 0; 612 } 613 614 case WSDISPLAYIO_SCURSOR: { 615 struct wsdisplay_cursor *cursor = data; 616 617 return summitfb_do_cursor(sc, cursor); 618 } 619 620 case WSDISPLAYIO_SVIDEO: 621 summitfb_set_video(sc, *(int *)data); 622 return 0; 623 case WSDISPLAYIO_GVIDEO: 624 *(u_int *)data = sc->sc_video_on ? 625 WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF; 626 return 0; 627 } 628 return EPASSTHROUGH; 629 } 630 631 static paddr_t 632 summitfb_mmap(void *v, void *vs, off_t offset, int prot) 633 { 634 struct vcons_data *vd = v; 635 struct summitfb_softc *sc = vd->cookie; 636 struct sti_rom *rom = sc->sc_base.sc_rom; 637 paddr_t pa = -1; 638 639 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) 640 return -1; 641 642 if (offset >= 0 && offset < 0x01000000) { 643 /* framebuffer */ 644 pa = bus_space_mmap(rom->memt, sc->sc_scr.fbaddr, offset, 645 prot, BUS_SPACE_MAP_LINEAR); 646 } else if (offset >= 0x80000000 && offset < 0x81000000) { 647 /* blitter registers etc. */ 648 pa = bus_space_mmap(rom->memt, rom->regh[0], 649 offset - 0x80000000, prot, BUS_SPACE_MAP_LINEAR); 650 } 651 652 return pa; 653 } 654 655 static void 656 summitfb_init_screen(void *cookie, struct vcons_screen *scr, 657 int existing, long *defattr) 658 { 659 struct summitfb_softc *sc = cookie; 660 struct rasops_info *ri = &scr->scr_ri; 661 662 ri->ri_depth = 8; 663 ri->ri_width = sc->sc_width; 664 ri->ri_height = sc->sc_height; 665 ri->ri_stride = 2048; 666 ri->ri_flg = RI_CENTER | RI_8BIT_IS_RGB 667 | RI_ENABLE_ALPHA | RI_PREFER_ALPHA 668 ; 669 670 ri->ri_bits = (void *)sc->sc_scr.fbaddr; 671 rasops_init(ri, 0, 0); 672 ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE | 673 WSSCREEN_RESIZE; 674 scr->scr_flags |= VCONS_LOADFONT; 675 676 rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, 677 sc->sc_width / ri->ri_font->fontwidth); 678 679 ri->ri_hw = scr; 680 681 ri->ri_ops.copyrows = summitfb_copyrows; 682 ri->ri_ops.copycols = summitfb_copycols; 683 ri->ri_ops.eraserows = summitfb_eraserows; 684 ri->ri_ops.erasecols = summitfb_erasecols; 685 ri->ri_ops.cursor = summitfb_cursor; 686 if (FONT_IS_ALPHA(ri->ri_font)) { 687 ri->ri_ops.putchar = summitfb_putchar_aa; 688 } else 689 ri->ri_ops.putchar = summitfb_putchar; 690 } 691 692 static int 693 summitfb_putcmap(struct summitfb_softc *sc, struct wsdisplay_cmap *cm) 694 { 695 u_char *r, *g, *b; 696 u_int index = cm->index; 697 u_int count = cm->count; 698 int i, error; 699 u_char rbuf[256], gbuf[256], bbuf[256]; 700 701 if (cm->index >= 256 || cm->count > 256 || 702 (cm->index + cm->count) > 256) 703 return EINVAL; 704 error = copyin(cm->red, &rbuf[index], count); 705 if (error) 706 return error; 707 error = copyin(cm->green, &gbuf[index], count); 708 if (error) 709 return error; 710 error = copyin(cm->blue, &bbuf[index], count); 711 if (error) 712 return error; 713 714 memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); 715 memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); 716 memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); 717 718 r = &sc->sc_cmap_red[index]; 719 g = &sc->sc_cmap_green[index]; 720 b = &sc->sc_cmap_blue[index]; 721 722 for (i = 0; i < count; i++) { 723 summitfb_putpalreg(sc, index, *r, *g, *b); 724 index++; 725 r++, g++, b++; 726 } 727 return 0; 728 } 729 730 static int 731 summitfb_getcmap(struct summitfb_softc *sc, struct wsdisplay_cmap *cm) 732 { 733 u_int index = cm->index; 734 u_int count = cm->count; 735 int error; 736 737 if (index >= 255 || count > 256 || index + count > 256) 738 return EINVAL; 739 740 error = copyout(&sc->sc_cmap_red[index], cm->red, count); 741 if (error) 742 return error; 743 error = copyout(&sc->sc_cmap_green[index], cm->green, count); 744 if (error) 745 return error; 746 error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); 747 if (error) 748 return error; 749 750 return 0; 751 } 752 753 static void 754 summitfb_restore_palette(struct summitfb_softc *sc) 755 { 756 uint8_t cmap[768]; 757 int i, j; 758 759 j = 0; 760 rasops_get_cmap(&sc->sc_console_screen.scr_ri, cmap, sizeof(cmap)); 761 for (i = 0; i < 256; i++) { 762 sc->sc_cmap_red[i] = cmap[j]; 763 sc->sc_cmap_green[i] = cmap[j + 1]; 764 sc->sc_cmap_blue[i] = cmap[j + 2]; 765 summitfb_putpalreg(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]); 766 j += 3; 767 } 768 for (i = 0; i < 16; i++) { 769 sc->sc_palette[i] = (rasops_cmap[i * 3] << 16) | 770 (rasops_cmap[i * 3 + 1] << 8) | 771 rasops_cmap[i * 3 + 2]; 772 } 773 774 } 775 776 static int 777 summitfb_putpalreg(struct summitfb_softc *sc, uint8_t idx, 778 uint8_t r, uint8_t g, uint8_t b) 779 { 780 781 summitfb_write4(sc, VISFX_COLOR_INDEX, idx); 782 summitfb_write4(sc, VISFX_COLOR_VALUE, (r << 16) | ( g << 8) | b); 783 summitfb_write4(sc, VISFX_COLOR_MASK, 0xff); 784 return 0; 785 } 786 787 static inline void 788 summitfb_wait_fifo(struct summitfb_softc *sc, uint32_t slots) 789 { 790 uint32_t reg; 791 792 do { 793 reg = summitfb_read4(sc, VISFX_FIFO); 794 } while (reg < slots); 795 } 796 797 static void 798 summitfb_clearfb(struct summitfb_softc *sc) 799 { 800 summitfb_write_mode(sc, OTC32 | BIN8F | BUFBL | BUFFL | 0x8c0); 801 summitfb_wait_fifo(sc, 10); 802 summitfb_write4(sc, VISFX_IBO, RopSrc); 803 summitfb_write4(sc, VISFX_FG_COLOUR, 0); 804 summitfb_write4(sc, VISFX_START, 0); 805 summitfb_write4(sc, VISFX_SIZE, (sc->sc_width << 16) | sc->sc_height); 806 } 807 808 static void 809 summitfb_rectfill(struct summitfb_softc *sc, int x, int y, int wi, int he, 810 uint32_t bg) 811 { 812 813 summitfb_write_mode(sc, VISFX_WRITE_MODE_FILL); 814 summitfb_wait_fifo(sc, 10); 815 summitfb_write4(sc, VISFX_IBO, RopSrc); 816 summitfb_write4(sc, VISFX_FG_COLOUR, bg); 817 summitfb_write4(sc, VISFX_START, (x << 16) | y); 818 summitfb_write4(sc, VISFX_SIZE, (wi << 16) | he); 819 } 820 821 static void 822 summitfb_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi, 823 int he, int rop) 824 { 825 struct summitfb_softc *sc = cookie; 826 uint32_t read_mode, write_mode; 827 828 read_mode = OTC04 | BIN8I; 829 write_mode = OTC04 | BIN8I; 830 if (ys >= sc->sc_height) { 831 read_mode |= BUFBL; 832 ys -= sc->sc_height; 833 } 834 if (yd >= sc->sc_height) { 835 write_mode |= BUFBL; 836 yd -= sc->sc_height; 837 } 838 summitfb_write_mode(sc, write_mode); 839 summitfb_read_mode(sc, read_mode); 840 summitfb_wait_fifo(sc, 10); 841 summitfb_write4(sc, VISFX_IBO, rop); 842 summitfb_write4(sc, VISFX_COPY_SRC, (xs << 16) | ys); 843 summitfb_write4(sc, VISFX_COPY_WH, (wi << 16) | he); 844 summitfb_write4(sc, VISFX_COPY_DST, (xd << 16) | yd); 845 846 } 847 848 static void 849 summitfb_nuke_cursor(struct rasops_info *ri) 850 { 851 struct vcons_screen *scr = ri->ri_hw; 852 struct summitfb_softc *sc = scr->scr_cookie; 853 int wi, he, x, y; 854 855 if (ri->ri_flg & RI_CURSOR) { 856 wi = ri->ri_font->fontwidth; 857 he = ri->ri_font->fontheight; 858 x = ri->ri_ccol * wi + ri->ri_xorigin; 859 y = ri->ri_crow * he + ri->ri_yorigin; 860 summitfb_bitblt(sc, x, y, x, y, wi, he, RopInv); 861 ri->ri_flg &= ~RI_CURSOR; 862 } 863 } 864 865 static void 866 summitfb_cursor(void *cookie, int on, int row, int col) 867 { 868 struct rasops_info *ri = cookie; 869 struct vcons_screen *scr = ri->ri_hw; 870 struct summitfb_softc *sc = scr->scr_cookie; 871 int x, y, wi, he; 872 873 wi = ri->ri_font->fontwidth; 874 he = ri->ri_font->fontheight; 875 876 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 877 if (on) { 878 if (ri->ri_flg & RI_CURSOR) { 879 summitfb_nuke_cursor(ri); 880 } 881 x = col * wi + ri->ri_xorigin; 882 y = row * he + ri->ri_yorigin; 883 summitfb_bitblt(sc, x, y, x, y, wi, he, RopInv); 884 ri->ri_flg |= RI_CURSOR; 885 } 886 ri->ri_crow = row; 887 ri->ri_ccol = col; 888 } else { 889 ri->ri_crow = row; 890 ri->ri_ccol = col; 891 ri->ri_flg &= ~RI_CURSOR; 892 } 893 894 } 895 896 static void 897 summitfb_putchar(void *cookie, int row, int col, u_int c, long attr) 898 { 899 struct rasops_info *ri = cookie; 900 struct wsdisplay_font *font = PICK_FONT(ri, c); 901 struct vcons_screen *scr = ri->ri_hw; 902 struct summitfb_softc *sc = scr->scr_cookie; 903 void *data; 904 int i, x, y, wi, he; 905 uint32_t bg, fg, mask; 906 907 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) 908 return; 909 910 if (!CHAR_IN_FONT(c, font)) 911 return; 912 913 if (row == ri->ri_crow && col == ri->ri_ccol) { 914 ri->ri_flg &= ~RI_CURSOR; 915 } 916 917 wi = font->fontwidth; 918 he = font->fontheight; 919 920 x = ri->ri_xorigin + col * wi; 921 y = ri->ri_yorigin + row * he; 922 923 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 924 925 /* if we're drawing a space we're done here */ 926 if (c == 0x20) { 927 summitfb_rectfill(sc, x, y, wi, he, bg); 928 return; 929 } 930 931 fg = ri->ri_devcmap[(attr >> 24) & 0x0f]; 932 933 summitfb_write_mode(sc, VISFX_WRITE_MODE_EXPAND); 934 summitfb_wait_fifo(sc, 12); 935 summitfb_write4(sc, VISFX_IBO, RopSrc); 936 summitfb_write4(sc, VISFX_FG_COLOUR, fg); 937 summitfb_write4(sc, VISFX_BG_COLOUR, bg); 938 mask = 0xffffffff << (32 - wi); 939 summitfb_write4(sc, VISFX_PIXEL_MASK, mask); 940 /* not a tpyo, coordinates *are* backwards for this register */ 941 summitfb_write4(sc, VISFX_VRAM_WRITE_DEST, (y << 16) | x); 942 943 data = WSFONT_GLYPH(c, font); 944 945 if (ri->ri_font->stride == 1) { 946 uint8_t *data8 = data; 947 for (i = 0; i < he; i++) { 948 mask = *data8; 949 summitfb_write4(sc, VISFX_VRAM_WRITE_DATA_INCRY, 950 mask << 24); 951 data8++; 952 } 953 } else { 954 uint16_t *data16 = data; 955 for (i = 0; i < he; i++) { 956 mask = *data16; 957 summitfb_write4(sc, VISFX_VRAM_WRITE_DATA_INCRY, 958 mask << 16); 959 data16++; 960 } 961 } 962 } 963 964 static void 965 summitfb_putchar_aa(void *cookie, int row, int col, u_int c, long attr) 966 { 967 struct rasops_info *ri = cookie; 968 struct wsdisplay_font *font = PICK_FONT(ri, c); 969 struct vcons_screen *scr = ri->ri_hw; 970 struct summitfb_softc *sc = scr->scr_cookie; 971 int x, y, wi, he, rv = GC_NOPE, i, j; 972 uint32_t bg, fg, tmp; 973 uint8_t *data; 974 975 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) 976 return; 977 978 if (!CHAR_IN_FONT(c, font)) 979 return; 980 981 if (row == ri->ri_crow && col == ri->ri_ccol) { 982 ri->ri_flg &= ~RI_CURSOR; 983 } 984 985 wi = font->fontwidth; 986 he = font->fontheight; 987 988 x = ri->ri_xorigin + col * wi; 989 y = ri->ri_yorigin + row * he; 990 991 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 992 993 if (c == 0x20) { 994 summitfb_rectfill(sc, x, y, wi, he, bg); 995 return; 996 } 997 998 rv = glyphcache_try(&sc->sc_gc, c, x, y, attr); 999 if (rv == GC_OK) 1000 return; 1001 1002 /* 1003 * first we clear the background - we should be able to use the CBR 1004 * register as constant background but so far I couldn't make that work 1005 */ 1006 summitfb_rectfill(sc, x, y, wi, he, bg); 1007 1008 summitfb_write_mode(sc, OTC01 | BIN332F | BUFovl); 1009 /* we need the foreground colour as full RGB8 */ 1010 fg = sc->sc_palette[(attr >> 24) & 0xf]; 1011 1012 /* 1013 * set the blending equation to 1014 * src_color * src_alpha + dst_color * (1 - src_alpha) 1015 */ 1016 summitfb_write4(sc, VISFX_IBO, 1017 IBO_ADD | SRC(IBO_SRC) | DST(IBO_ONE_MINUS_SRC)); 1018 1019 /* get the glyph */ 1020 data = WSFONT_GLYPH(c, font); 1021 for (i = 0; i < he; i++) { 1022 /* 1023 * make some room in the pipeline 1024 * with just plain ROPs we can just hammer the FIFO without 1025 * having to worry about overflowing it but I suspect with 1026 * alpha blending enabled things may be a little slower 1027 */ 1028 summitfb_wait_fifo(sc, wi * 2); 1029 /* start a new line */ 1030 summitfb_write4(sc, VISFX_VRAM_WRITE_DEST, ((y + i) << 16) | x); 1031 for (j = 0; j < wi; j++) { 1032 tmp = *data; 1033 /* alpha & RGB -> ARGB */ 1034 summitfb_write4(sc, VISFX_VRAM_WRITE_DATA_INCRX, 1035 (tmp << 24) | fg); 1036 data++; 1037 } 1038 } 1039 1040 if (rv == GC_ADD) 1041 glyphcache_add(&sc->sc_gc, c, x, y); 1042 } 1043 1044 static void 1045 summitfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) 1046 { 1047 struct rasops_info *ri = cookie; 1048 struct vcons_screen *scr = ri->ri_hw; 1049 struct summitfb_softc *sc = scr->scr_cookie; 1050 int32_t xs, xd, y, width, height; 1051 1052 if (sc->sc_locked == 0 && sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1053 1054 if (ri->ri_crow == row && 1055 ri->ri_ccol >= srccol && ri->ri_ccol < (srccol + ncols) && 1056 (ri->ri_flg & RI_CURSOR)) { 1057 summitfb_nuke_cursor(ri); 1058 } 1059 1060 xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; 1061 xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; 1062 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1063 width = ri->ri_font->fontwidth * ncols; 1064 height = ri->ri_font->fontheight; 1065 summitfb_bitblt(sc, xs, y, xd, y, width, height, RopSrc); 1066 1067 if (ri->ri_crow == row && 1068 ri->ri_ccol >= dstcol && ri->ri_ccol < (dstcol + ncols)) 1069 ri->ri_flg &= ~RI_CURSOR; 1070 } 1071 } 1072 1073 static void 1074 summitfb_erasecols(void *cookie, int row, int startcol, int ncols, 1075 long fillattr) 1076 { 1077 struct rasops_info *ri = cookie; 1078 struct vcons_screen *scr = ri->ri_hw; 1079 struct summitfb_softc *sc = scr->scr_cookie; 1080 int32_t x, y, width, height, fg, bg, ul; 1081 1082 if (sc->sc_locked == 0 && sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1083 x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; 1084 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1085 width = ri->ri_font->fontwidth * ncols; 1086 height = ri->ri_font->fontheight; 1087 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 1088 1089 summitfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 1090 1091 if (ri->ri_crow == row && 1092 ri->ri_ccol >= startcol && 1093 ri->ri_ccol < (startcol + ncols)) 1094 ri->ri_flg &= ~RI_CURSOR; 1095 } 1096 } 1097 1098 static void 1099 summitfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) 1100 { 1101 struct rasops_info *ri = cookie; 1102 struct vcons_screen *scr = ri->ri_hw; 1103 struct summitfb_softc *sc = scr->scr_cookie; 1104 int32_t x, ys, yd, width, height; 1105 1106 if (sc->sc_locked == 0 && sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1107 1108 if (ri->ri_crow >= srcrow && ri->ri_crow < (srcrow + nrows) && 1109 (ri->ri_flg & RI_CURSOR)) { 1110 summitfb_nuke_cursor(ri); 1111 } 1112 1113 x = ri->ri_xorigin; 1114 ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; 1115 yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; 1116 width = ri->ri_emuwidth; 1117 height = ri->ri_font->fontheight * nrows; 1118 summitfb_bitblt(sc, x, ys, x, yd, width, height, RopSrc); 1119 1120 if (ri->ri_crow >= dstrow && ri->ri_crow < (dstrow + nrows)) 1121 ri->ri_flg &= ~RI_CURSOR; 1122 } 1123 } 1124 1125 static void 1126 summitfb_eraserows(void *cookie, int row, int nrows, long fillattr) 1127 { 1128 struct rasops_info *ri = cookie; 1129 struct vcons_screen *scr = ri->ri_hw; 1130 struct summitfb_softc *sc = scr->scr_cookie; 1131 int32_t x, y, width, height, fg, bg, ul; 1132 1133 if (sc->sc_locked == 0 && sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1134 x = ri->ri_xorigin; 1135 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1136 width = ri->ri_emuwidth; 1137 height = ri->ri_font->fontheight * nrows; 1138 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 1139 1140 summitfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 1141 1142 if (ri->ri_crow >= row && ri->ri_crow < (row + nrows)) 1143 ri->ri_flg &= ~RI_CURSOR; 1144 } 1145 } 1146 1147 static void 1148 summitfb_move_cursor(struct summitfb_softc *sc, int x, int y) 1149 { 1150 uint32_t pos; 1151 1152 sc->sc_cursor_x = x; 1153 x -= sc->sc_hot_x; 1154 sc->sc_cursor_y = y; 1155 y -= sc->sc_hot_y; 1156 1157 if (x < 0) 1158 x = 0x1000 - x; 1159 if (y < 0) 1160 y = 0x1000 - y; 1161 pos = (x << 16) | y; 1162 if (sc->sc_enabled) 1163 pos |= 0x80000000; 1164 summitfb_write4(sc, VISFX_CURSOR_POS, pos); 1165 } 1166 1167 static int 1168 summitfb_do_cursor(struct summitfb_softc *sc, struct wsdisplay_cursor *cur) 1169 { 1170 1171 if (cur->which & WSDISPLAY_CURSOR_DOCUR) { 1172 sc->sc_enabled = cur->enable; 1173 cur->which |= WSDISPLAY_CURSOR_DOPOS; 1174 } 1175 if (cur->which & WSDISPLAY_CURSOR_DOHOT) { 1176 sc->sc_hot_x = cur->hot.x; 1177 sc->sc_hot_y = cur->hot.y; 1178 cur->which |= WSDISPLAY_CURSOR_DOPOS; 1179 } 1180 if (cur->which & WSDISPLAY_CURSOR_DOPOS) { 1181 summitfb_move_cursor(sc, cur->pos.x, cur->pos.y); 1182 } 1183 if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { 1184 uint32_t rgb; 1185 uint8_t r[2], g[2], b[2]; 1186 1187 copyin(cur->cmap.blue, b, 2); 1188 copyin(cur->cmap.green, g, 2); 1189 copyin(cur->cmap.red, r, 2); 1190 summitfb_write4(sc, VISFX_CURSOR_INDEX, 0); 1191 rgb = r[0] << 16 | g[0] << 8 | b[0]; 1192 summitfb_write4(sc, VISFX_CURSOR_BG, rgb); 1193 rgb = r[1] << 16 | g[1] << 8 | b[1]; 1194 summitfb_write4(sc, VISFX_CURSOR_FG, rgb); 1195 1196 } 1197 if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { 1198 1199 uint32_t buffer[128], latch, tmp; 1200 int i; 1201 1202 copyin(cur->mask, buffer, 512); 1203 summitfb_write4(sc, VISFX_CURSOR_INDEX, 0); 1204 for (i = 0; i < 128; i += 2) { 1205 latch = 0; 1206 tmp = buffer[i] & 0x80808080; 1207 latch |= tmp >> 7; 1208 tmp = buffer[i] & 0x40404040; 1209 latch |= tmp >> 5; 1210 tmp = buffer[i] & 0x20202020; 1211 latch |= tmp >> 3; 1212 tmp = buffer[i] & 0x10101010; 1213 latch |= tmp >> 1; 1214 tmp = buffer[i] & 0x08080808; 1215 latch |= tmp << 1; 1216 tmp = buffer[i] & 0x04040404; 1217 latch |= tmp << 3; 1218 tmp = buffer[i] & 0x02020202; 1219 latch |= tmp << 5; 1220 tmp = buffer[i] & 0x01010101; 1221 latch |= tmp << 7; 1222 summitfb_write4(sc, VISFX_CURSOR_DATA, latch); 1223 latch = 0; 1224 tmp = buffer[i + 1] & 0x80808080; 1225 latch |= tmp >> 7; 1226 tmp = buffer[i + 1] & 0x40404040; 1227 latch |= tmp >> 5; 1228 tmp = buffer[i + 1] & 0x20202020; 1229 latch |= tmp >> 3; 1230 tmp = buffer[i + 1] & 0x10101010; 1231 latch |= tmp >> 1; 1232 tmp = buffer[i + 1] & 0x08080808; 1233 latch |= tmp << 1; 1234 tmp = buffer[i + 1] & 0x04040404; 1235 latch |= tmp << 3; 1236 tmp = buffer[i + 1] & 0x02020202; 1237 latch |= tmp << 5; 1238 tmp = buffer[i + 1] & 0x01010101; 1239 latch |= tmp << 7; 1240 summitfb_write4(sc, VISFX_CURSOR_DATA, latch); 1241 } 1242 1243 summitfb_write4(sc, VISFX_CURSOR_INDEX, 0x80); 1244 copyin(cur->image, buffer, 512); 1245 for (i = 0; i < 128; i += 2) { 1246 latch = 0; 1247 tmp = buffer[i] & 0x80808080; 1248 latch |= tmp >> 7; 1249 tmp = buffer[i] & 0x40404040; 1250 latch |= tmp >> 5; 1251 tmp = buffer[i] & 0x20202020; 1252 latch |= tmp >> 3; 1253 tmp = buffer[i] & 0x10101010; 1254 latch |= tmp >> 1; 1255 tmp = buffer[i] & 0x08080808; 1256 latch |= tmp << 1; 1257 tmp = buffer[i] & 0x04040404; 1258 latch |= tmp << 3; 1259 tmp = buffer[i] & 0x02020202; 1260 latch |= tmp << 5; 1261 tmp = buffer[i] & 0x01010101; 1262 latch |= tmp << 7; 1263 summitfb_write4(sc, VISFX_CURSOR_DATA, latch); 1264 latch = 0; 1265 tmp = buffer[i + 1] & 0x80808080; 1266 latch |= tmp >> 7; 1267 tmp = buffer[i + 1] & 0x40404040; 1268 latch |= tmp >> 5; 1269 tmp = buffer[i + 1] & 0x20202020; 1270 latch |= tmp >> 3; 1271 tmp = buffer[i + 1] & 0x10101010; 1272 latch |= tmp >> 1; 1273 tmp = buffer[i + 1] & 0x08080808; 1274 latch |= tmp << 1; 1275 tmp = buffer[i + 1] & 0x04040404; 1276 latch |= tmp << 3; 1277 tmp = buffer[i + 1] & 0x02020202; 1278 latch |= tmp << 5; 1279 tmp = buffer[i + 1] & 0x01010101; 1280 latch |= tmp << 7; 1281 summitfb_write4(sc, VISFX_CURSOR_DATA, latch); 1282 } 1283 } 1284 1285 return 0; 1286 } 1287 1288 static void 1289 summitfb_set_video(struct summitfb_softc *sc, int on) 1290 { 1291 1292 if (sc->sc_video_on == on) 1293 return; 1294 1295 sc->sc_video_on = on; 1296 1297 summitfb_wait(sc); 1298 if (on) { 1299 summitfb_write4(sc, VISFX_MPC, MPC_VIDEO_ON); 1300 } else { 1301 summitfb_write4(sc, VISFX_MPC, MPC_VSYNC_OFF | MPC_HSYNC_OFF); 1302 } 1303 } 1304 1305 static void 1306 summitfb_copyfont(struct summitfb_softc *sc) 1307 { 1308 struct sti_font *fp = &sc->sc_scr.scr_curfont; 1309 uint8_t *font = sc->sc_scr.scr_romfont; 1310 uint8_t *fontbuf, *fontdata, *src, *dst; 1311 struct wsdisplay_font *f; 1312 int bufsize, i, si; 1313 1314 if (font == NULL) 1315 return; 1316 1317 bufsize = sizeof(struct wsdisplay_font) + 32 + fp->bpc * (fp->last - fp->first); 1318 DPRINTF(("%s: %dx%d %d\n", __func__, fp->width, fp->height, bufsize)); 1319 fontbuf = kmem_alloc(bufsize, KM_SLEEP); 1320 f = (struct wsdisplay_font *)fontbuf; 1321 f->name = fontbuf + sizeof(struct wsdisplay_font); 1322 fontdata = fontbuf + sizeof(struct wsdisplay_font) + 32; 1323 strcpy(fontbuf + sizeof(struct wsdisplay_font), "HP ROM"); 1324 f->firstchar = fp->first; 1325 f->numchars = (fp->last + 1) - fp->first; 1326 f->encoding = WSDISPLAY_FONTENC_ISO; 1327 f->fontwidth = fp->width; 1328 f->fontheight = fp->height; 1329 f->stride = (fp->width + 7) >> 3; 1330 f->bitorder = WSDISPLAY_FONTORDER_L2R; 1331 f->byteorder = WSDISPLAY_FONTORDER_L2R; 1332 f->data = fontdata; 1333 /* skip over font struct */ 1334 font += sizeof(struct sti_font); 1335 /* now copy and rearrange the glyphs into ISO order */ 1336 /* first, copy the characters up to 0x7f */ 1337 memcpy(fontdata, font, (0x80 - fp->first) * fp->bpc); 1338 /* zero 0x80 to 0x9f */ 1339 memset(fontdata + 0x80 * fp->bpc, 0, 0x20 * fp->bpc); 1340 /* rearrange 0xa0 till last */ 1341 for (i = 0xa0; i < (fp->last + 1); i++) { 1342 dst = fontdata + fp->bpc * i; 1343 si = sti_unitoroman[i - 0xa0]; 1344 if (si != 0) { 1345 src = font + fp->bpc * si; 1346 memcpy(dst, src, fp->bpc); 1347 } else { 1348 /* no mapping - zero this cell */ 1349 memset(dst, 0, fp->bpc); 1350 } 1351 } 1352 wsfont_add(f, 0); 1353 } 1354