1 /* $NetBSD: plumvideo.c,v 1.13 2000/06/29 08:17:59 mrg Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000 UCHIYAMA Yasushi. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 #define PLUMVIDEODEBUG 29 30 #include "opt_tx39_debug.h" 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/device.h> 35 36 #include <sys/ioctl.h> 37 #include <sys/buf.h> 38 #include <uvm/uvm_extern.h> 39 40 #include <dev/cons.h> /* consdev */ 41 42 #include <machine/bus.h> 43 #include <machine/intr.h> 44 45 #include <hpcmips/tx/tx39var.h> 46 #include <hpcmips/dev/plumvar.h> 47 #include <hpcmips/dev/plumicuvar.h> 48 #include <hpcmips/dev/plumpowervar.h> 49 #include <hpcmips/dev/plumvideoreg.h> 50 51 #include <machine/bootinfo.h> 52 53 #include <dev/wscons/wsdisplayvar.h> 54 #include <dev/rasops/rasops.h> 55 #include <arch/hpcmips/dev/video_subr.h> 56 57 #include <dev/wscons/wsconsio.h> 58 #include <arch/hpcmips/dev/hpcfbvar.h> 59 #include <arch/hpcmips/dev/hpcfbio.h> 60 61 #ifdef PLUMVIDEODEBUG 62 int plumvideo_debug = 1; 63 #define DPRINTF(arg) if (plumvideo_debug) printf arg; 64 #define DPRINTFN(n, arg) if (plumvideo_debug > (n)) printf arg; 65 #else 66 #define DPRINTF(arg) 67 #define DPRINTFN(n, arg) 68 #endif 69 70 struct plumvideo_softc { 71 struct device sc_dev; 72 tx_chipset_tag_t sc_tc; 73 plum_chipset_tag_t sc_pc; 74 75 /* control register */ 76 bus_space_tag_t sc_regt; 77 bus_space_handle_t sc_regh; 78 /* frame buffer */ 79 bus_space_tag_t sc_fbiot; 80 bus_space_handle_t sc_fbioh; 81 /* clut buffer (8bpp only) */ 82 bus_space_tag_t sc_clutiot; 83 bus_space_handle_t sc_clutioh; 84 /* bitblt */ 85 bus_space_tag_t sc_bitbltt; 86 bus_space_handle_t sc_bitblth; 87 88 struct video_chip sc_chip; 89 struct hpcfb_fbconf sc_fbconf; 90 struct hpcfb_dspconf sc_dspconf; 91 }; 92 93 int plumvideo_match __P((struct device*, struct cfdata*, void*)); 94 void plumvideo_attach __P((struct device*, struct device*, void*)); 95 96 int plumvideo_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); 97 paddr_t plumvideo_mmap __P((void *, off_t, int)); 98 99 struct cfattach plumvideo_ca = { 100 sizeof(struct plumvideo_softc), plumvideo_match, plumvideo_attach 101 }; 102 103 struct hpcfb_accessops plumvideo_ha = { 104 plumvideo_ioctl, plumvideo_mmap 105 }; 106 107 int plumvideo_init __P((struct plumvideo_softc*)); 108 void plumvideo_hpcfbinit __P((struct plumvideo_softc *)); 109 110 void plumvideo_clut_default __P((struct plumvideo_softc *)); 111 void plumvideo_clut_set __P((struct plumvideo_softc *, u_int32_t *, int, 112 int)); 113 void plumvideo_clut_get __P((struct plumvideo_softc *, u_int32_t *, int, 114 int)); 115 void __plumvideo_clut_access __P((struct plumvideo_softc *, 116 void (*) __P((bus_space_tag_t, 117 bus_space_handle_t)))); 118 static void _flush_cache __P((void)) __attribute__((__unused__)); /* !!! */ 119 120 #ifdef PLUMVIDEODEBUG 121 void plumvideo_dump __P((struct plumvideo_softc*)); 122 #endif 123 124 int 125 plumvideo_match(parent, cf, aux) 126 struct device *parent; 127 struct cfdata *cf; 128 void *aux; 129 { 130 /* 131 * VRAM area also uses as UHOSTC shared RAM. 132 */ 133 return (2); /* 1st attach group */ 134 } 135 136 void 137 plumvideo_attach(parent, self, aux) 138 struct device *parent; 139 struct device *self; 140 void *aux; 141 { 142 struct plum_attach_args *pa = aux; 143 struct plumvideo_softc *sc = (void*)self; 144 struct hpcfb_attach_args ha; 145 int console; 146 147 sc->sc_pc = pa->pa_pc; 148 sc->sc_regt = pa->pa_regt; 149 sc->sc_fbiot = sc->sc_clutiot = sc->sc_bitbltt = pa->pa_iot; 150 151 printf(": "); 152 /* 153 * map register area 154 */ 155 if (bus_space_map(sc->sc_regt, PLUM_VIDEO_REGBASE, 156 PLUM_VIDEO_REGSIZE, 0, &sc->sc_regh)) { 157 printf(": register map failed\n"); 158 return; 159 } 160 161 /* 162 * Power control 163 */ 164 #ifndef PLUMVIDEODEBUG 165 if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) { 166 /* LCD power on and display off */ 167 plum_power_disestablish(sc->sc_pc, PLUM_PWR_LCD); 168 /* power off V-RAM */ 169 plum_power_disestablish(sc->sc_pc, PLUM_PWR_EXTPW2); 170 /* power off LCD */ 171 plum_power_disestablish(sc->sc_pc, PLUM_PWR_EXTPW1); 172 /* power off RAMDAC */ 173 plum_power_disestablish(sc->sc_pc, PLUM_PWR_EXTPW0); 174 /* back-light off */ 175 plum_power_disestablish(sc->sc_pc, PLUM_PWR_BKL); 176 } else 177 #endif 178 { 179 /* LCD power on and display on */ 180 plum_power_establish(sc->sc_pc, PLUM_PWR_LCD); 181 /* supply power to V-RAM */ 182 plum_power_establish(sc->sc_pc, PLUM_PWR_EXTPW2); 183 /* supply power to LCD */ 184 plum_power_establish(sc->sc_pc, PLUM_PWR_EXTPW1); 185 /* back-light on */ 186 plum_power_establish(sc->sc_pc, PLUM_PWR_BKL); 187 } 188 189 /* 190 * Initialize LCD controller 191 * map V-RAM area. 192 * reinstall bootinfo structure. 193 * some OHCI shared-buffer hack. XXX 194 */ 195 if (plumvideo_init(sc) != 0) 196 return; 197 198 printf("\n"); 199 200 /* Attach frame buffer device */ 201 plumvideo_hpcfbinit(sc); 202 203 #ifdef PLUMVIDEODEBUG 204 if (plumvideo_debug > 1) 205 plumvideo_dump(sc); 206 /* attach debug draw routine (debugging use) */ 207 video_attach_drawfunc(&sc->sc_chip); 208 tx_conf_register_video(sc->sc_pc->pc_tc, &sc->sc_chip); 209 #endif /* PLUMVIDEODEBUG */ 210 211 console = cn_tab ? 0 : 1; 212 if(console && hpcfb_cnattach(&sc->sc_fbconf) != 0) { 213 panic("plumvideo_attach: can't init fb console"); 214 } 215 216 ha.ha_console = console; 217 ha.ha_accessops = &plumvideo_ha; 218 ha.ha_accessctx = sc; 219 ha.ha_curfbconf = 0; 220 ha.ha_nfbconf = 1; 221 ha.ha_fbconflist = &sc->sc_fbconf; 222 ha.ha_curdspconf = 0; 223 ha.ha_ndspconf = 1; 224 ha.ha_dspconflist = &sc->sc_dspconf; 225 226 config_found(self, &ha, hpcfbprint); 227 } 228 229 void 230 plumvideo_hpcfbinit(sc) 231 struct plumvideo_softc *sc; 232 { 233 struct hpcfb_fbconf *fb = &sc->sc_fbconf; 234 struct video_chip *chip = &sc->sc_chip; 235 vaddr_t fbvaddr = (vaddr_t)sc->sc_fbioh; 236 int height = chip->vc_fbheight; 237 int width = chip->vc_fbwidth; 238 int depth = chip->vc_fbdepth; 239 240 memset(fb, 0, sizeof(struct hpcfb_fbconf)); 241 242 fb->hf_conf_index = 0; /* configuration index */ 243 fb->hf_nconfs = 1; /* how many configurations */ 244 strncpy(fb->hf_name, "PLUM built-in video", HPCFB_MAXNAMELEN); 245 /* frame buffer name */ 246 strncpy(fb->hf_conf_name, "LCD", HPCFB_MAXNAMELEN); 247 /* configuration name */ 248 fb->hf_height = height; 249 fb->hf_width = width; 250 fb->hf_baseaddr = mips_ptob(mips_btop(fbvaddr)); 251 fb->hf_offset = (u_long)fbvaddr - fb->hf_baseaddr; 252 /* frame buffer start offset */ 253 fb->hf_bytes_per_line = (width * depth) / NBBY; 254 fb->hf_nplanes = 1; 255 fb->hf_bytes_per_plane = height * fb->hf_bytes_per_line; 256 257 fb->hf_access_flags |= HPCFB_ACCESS_BYTE; 258 fb->hf_access_flags |= HPCFB_ACCESS_WORD; 259 fb->hf_access_flags |= HPCFB_ACCESS_DWORD; 260 261 switch (depth) { 262 default: 263 panic("plumvideo_hpcfbinit: not supported color depth\n"); 264 /* NOTREACHED */ 265 case 16: 266 fb->hf_class = HPCFB_CLASS_RGBCOLOR; 267 fb->hf_access_flags |= HPCFB_ACCESS_STATIC; 268 fb->hf_pack_width = 16; 269 fb->hf_pixels_per_pack = 1; 270 fb->hf_pixel_width = 16; 271 272 fb->hf_class_data_length = sizeof(struct hf_rgb_tag); 273 /* reserved for future use */ 274 fb->hf_u.hf_rgb.hf_flags = 0; 275 276 fb->hf_u.hf_rgb.hf_red_width = 5; 277 fb->hf_u.hf_rgb.hf_red_shift = 11; 278 fb->hf_u.hf_rgb.hf_green_width = 6; 279 fb->hf_u.hf_rgb.hf_green_shift = 5; 280 fb->hf_u.hf_rgb.hf_blue_width = 5; 281 fb->hf_u.hf_rgb.hf_blue_shift = 0; 282 fb->hf_u.hf_rgb.hf_alpha_width = 0; 283 fb->hf_u.hf_rgb.hf_alpha_shift = 0; 284 break; 285 286 case 8: 287 fb->hf_class = HPCFB_CLASS_INDEXCOLOR; 288 fb->hf_access_flags |= HPCFB_ACCESS_STATIC; 289 fb->hf_pack_width = 8; 290 fb->hf_pixels_per_pack = 1; 291 fb->hf_pixel_width = 8; 292 fb->hf_class_data_length = sizeof(struct hf_indexed_tag); 293 /* reserved for future use */ 294 fb->hf_u.hf_indexed.hf_flags = 0; 295 break; 296 } 297 } 298 299 int 300 plumvideo_init(sc) 301 struct plumvideo_softc *sc; 302 { 303 bus_space_tag_t regt = sc->sc_regt; 304 bus_space_handle_t regh = sc->sc_regh; 305 plumreg_t reg; 306 size_t vram_size; 307 int bpp, width, height, vram_pitch; 308 struct video_chip *chip = &sc->sc_chip; 309 310 chip->vc_v = sc->sc_pc->pc_tc; 311 #if notyet 312 /* map BitBlt area */ 313 if (bus_space_map(sc->sc_bitbltt, 314 PLUM_VIDEO_BITBLT_IOBASE, 315 PLUM_VIDEO_BITBLT_IOSIZE, 0, 316 &sc->sc_bitblth)) { 317 printf(": BitBlt map failed\n"); 318 return (1); 319 } 320 #endif 321 reg = plum_conf_read(regt, regh, PLUM_VIDEO_PLGMD_REG); 322 switch (reg & PLUM_VIDEO_PLGMD_GMODE_MASK) { 323 case PLUM_VIDEO_PLGMD_16BPP: 324 #ifdef PLUM_BIG_OHCI_BUFFER 325 printf("(16bpp disabled) "); 326 /* FALLTHROUGH */ 327 #else /* PLUM_BIG_OHCI_BUFFER */ 328 bpp = 16; 329 break; 330 #endif /* PLUM_BIG_OHCI_BUFFER */ 331 default: 332 bootinfo->fb_type = BIFB_D8_FF; /* over ride */ 333 reg &= ~PLUM_VIDEO_PLGMD_GMODE_MASK; 334 plum_conf_write(regt, regh, PLUM_VIDEO_PLGMD_REG, reg); 335 reg |= PLUM_VIDEO_PLGMD_8BPP; 336 plum_conf_write(regt, regh, PLUM_VIDEO_PLGMD_REG, reg); 337 #if notyet 338 /* change BitBlt color depth */ 339 plum_conf_write(sc->sc_bitbltt, sc->sc_bitblth, 0x8, 0); 340 #endif 341 /* FALLTHROUGH */ 342 case PLUM_VIDEO_PLGMD_8BPP: 343 bpp = 8; 344 break; 345 } 346 chip->vc_fbdepth = bpp; 347 348 /* 349 * Get display size from WindowsCE setted. 350 */ 351 chip->vc_fbwidth = width = bootinfo->fb_width = 352 plum_conf_read(regt, regh, PLUM_VIDEO_PLHPX_REG) + 1; 353 chip->vc_fbheight = height = bootinfo->fb_height = 354 plum_conf_read(regt, regh, PLUM_VIDEO_PLVT_REG) - 355 plum_conf_read(regt, regh, PLUM_VIDEO_PLVDS_REG); 356 357 /* 358 * set line byte length to bootinfo and LCD controller. 359 */ 360 bootinfo->fb_line_bytes = (width * bpp) / NBBY; 361 362 vram_pitch = width / (8 / bpp); 363 plum_conf_write(regt, regh, PLUM_VIDEO_PLPIT1_REG, vram_pitch); 364 plum_conf_write(regt, regh, PLUM_VIDEO_PLPIT2_REG, 365 vram_pitch & PLUM_VIDEO_PLPIT2_MASK); 366 plum_conf_write(regt, regh, PLUM_VIDEO_PLOFS_REG, vram_pitch); 367 368 /* 369 * boot messages and map CLUT(if any). 370 */ 371 printf("display mode: "); 372 switch (bpp) { 373 default: 374 printf("disabled "); 375 break; 376 case 8: 377 printf("8bpp "); 378 /* map CLUT area */ 379 if (bus_space_map(sc->sc_clutiot, 380 PLUM_VIDEO_CLUT_LCD_IOBASE, 381 PLUM_VIDEO_CLUT_LCD_IOSIZE, 0, 382 &sc->sc_clutioh)) { 383 printf(": CLUT map failed\n"); 384 return (1); 385 } 386 /* install default CLUT */ 387 plumvideo_clut_default(sc); 388 break; 389 case 16: 390 printf("16bpp "); 391 break; 392 } 393 394 /* 395 * calcurate frame buffer size. 396 */ 397 reg = plum_conf_read(regt, regh, PLUM_VIDEO_PLGMD_REG); 398 vram_size = (width * height * bpp) / NBBY; 399 vram_size = mips_round_page(vram_size); 400 chip->vc_fbsize = vram_size; 401 402 /* 403 * map V-RAM area. 404 */ 405 if (bus_space_map(sc->sc_fbiot, PLUM_VIDEO_VRAM_IOBASE, 406 vram_size, 0, &sc->sc_fbioh)) { 407 printf(": V-RAM map failed\n"); 408 return (1); 409 } 410 411 bootinfo->fb_addr = (unsigned char *)sc->sc_fbioh; 412 chip->vc_fbvaddr = (vaddr_t)sc->sc_fbioh; 413 chip->vc_fbpaddr = PLUM_VIDEO_VRAM_IOBASE_PHYSICAL; 414 415 return (0); 416 } 417 418 int 419 plumvideo_ioctl(v, cmd, data, flag, p) 420 void *v; 421 u_long cmd; 422 caddr_t data; 423 int flag; 424 struct proc *p; 425 { 426 struct plumvideo_softc *sc = (struct plumvideo_softc *)v; 427 struct hpcfb_fbconf *fbconf; 428 struct hpcfb_dspconf *dspconf; 429 struct wsdisplay_cmap *cmap; 430 u_int8_t *r, *g, *b; 431 u_int32_t *rgb; 432 int idx, cnt, error; 433 434 switch (cmd) { 435 case WSDISPLAYIO_GETCMAP: 436 cmap = (struct wsdisplay_cmap*)data; 437 cnt = cmap->count; 438 idx = cmap->index; 439 440 if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR || 441 sc->sc_fbconf.hf_pack_width != 8 || 442 !LEGAL_CLUT_INDEX(idx) || 443 !LEGAL_CLUT_INDEX(idx + cnt -1)) { 444 return (EINVAL); 445 } 446 447 if (!uvm_useracc(cmap->red, cnt, B_WRITE) || 448 !uvm_useracc(cmap->green, cnt, B_WRITE) || 449 !uvm_useracc(cmap->blue, cnt, B_WRITE)) { 450 return (EFAULT); 451 } 452 453 error = cmap_work_alloc(&r, &g, &b, &rgb, cnt); 454 if (error != 0) { 455 cmap_work_free(r, g, b, rgb); 456 return (ENOMEM); 457 } 458 plumvideo_clut_get(sc, rgb, idx, cnt); 459 rgb24_decompose(rgb, r, g, b, cnt); 460 461 copyout(r, cmap->red, cnt); 462 copyout(g, cmap->green,cnt); 463 copyout(b, cmap->blue, cnt); 464 465 cmap_work_free(r, g, b, rgb); 466 467 return (0); 468 469 case WSDISPLAYIO_PUTCMAP: 470 cmap = (struct wsdisplay_cmap*)data; 471 cnt = cmap->count; 472 idx = cmap->index; 473 474 if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR || 475 sc->sc_fbconf.hf_pack_width != 8 || 476 !LEGAL_CLUT_INDEX(idx) || 477 !LEGAL_CLUT_INDEX(idx + cnt -1)) { 478 return (EINVAL); 479 } 480 481 if (!uvm_useracc(cmap->red, cnt, B_WRITE) || 482 !uvm_useracc(cmap->green, cnt, B_WRITE) || 483 !uvm_useracc(cmap->blue, cnt, B_WRITE)) { 484 return (EFAULT); 485 } 486 487 error = cmap_work_alloc(&r, &g, &b, &rgb, cnt); 488 if (error != 0) { 489 cmap_work_free(r, g, b, rgb); 490 return (ENOMEM); 491 } 492 rgb24_compose(rgb, r, g, b, cnt); 493 plumvideo_clut_set(sc, rgb, idx, cnt); 494 495 cmap_work_free(r, g, b, rgb); 496 497 return (0); 498 499 case HPCFBIO_GCONF: 500 fbconf = (struct hpcfb_fbconf *)data; 501 if (fbconf->hf_conf_index != 0 && 502 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) { 503 return (EINVAL); 504 } 505 *fbconf = sc->sc_fbconf; /* structure assignment */ 506 return (0); 507 508 case HPCFBIO_SCONF: 509 fbconf = (struct hpcfb_fbconf *)data; 510 if (fbconf->hf_conf_index != 0 && 511 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) { 512 return (EINVAL); 513 } 514 /* 515 * nothing to do because we have only one configration 516 */ 517 return (0); 518 519 case HPCFBIO_GDSPCONF: 520 dspconf = (struct hpcfb_dspconf *)data; 521 if ((dspconf->hd_unit_index != 0 && 522 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) || 523 (dspconf->hd_conf_index != 0 && 524 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) { 525 return (EINVAL); 526 } 527 *dspconf = sc->sc_dspconf; /* structure assignment */ 528 return (0); 529 530 case HPCFBIO_SDSPCONF: 531 dspconf = (struct hpcfb_dspconf *)data; 532 if ((dspconf->hd_unit_index != 0 && 533 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) || 534 (dspconf->hd_conf_index != 0 && 535 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) { 536 return (EINVAL); 537 } 538 /* 539 * nothing to do 540 * because we have only one unit and one configration 541 */ 542 return (0); 543 544 case HPCFBIO_GOP: 545 case HPCFBIO_SOP: 546 /* XXX not implemented yet */ 547 return (EINVAL); 548 } 549 550 return (ENOTTY); 551 } 552 553 paddr_t 554 plumvideo_mmap(ctx, offset, prot) 555 void *ctx; 556 off_t offset; 557 int prot; 558 { 559 struct plumvideo_softc *sc = (struct plumvideo_softc *)ctx; 560 561 if (offset < 0 || (sc->sc_fbconf.hf_bytes_per_plane + 562 sc->sc_fbconf.hf_offset) < offset) { 563 return (-1); 564 } 565 566 return (mips_btop(PLUM_VIDEO_VRAM_IOBASE_PHYSICAL + offset)); 567 } 568 569 void 570 plumvideo_clut_get(sc, rgb, beg, cnt) 571 struct plumvideo_softc *sc; 572 u_int32_t *rgb; 573 int beg, cnt; 574 { 575 static void __plumvideo_clut_get __P((bus_space_tag_t, 576 bus_space_handle_t)); 577 static void __plumvideo_clut_get(iot, ioh) 578 bus_space_tag_t iot; 579 bus_space_handle_t ioh; 580 { 581 int i; 582 583 for (i = 0, beg *= 4; i < cnt; i++, beg += 4) { 584 *rgb++ = bus_space_read_4(iot, ioh, beg) & 585 0x00ffffff; 586 } 587 } 588 589 KASSERT(rgb); 590 KASSERT(LEGAL_CLUT_INDEX(beg)); 591 KASSERT(LEGAL_CLUT_INDEX(beg + cnt - 1)); 592 __plumvideo_clut_access(sc, __plumvideo_clut_get); 593 } 594 595 void 596 plumvideo_clut_set(sc, rgb, beg, cnt) 597 struct plumvideo_softc *sc; 598 u_int32_t *rgb; 599 int beg, cnt; 600 { 601 static void __plumvideo_clut_set __P((bus_space_tag_t, 602 bus_space_handle_t)); 603 static void __plumvideo_clut_set(iot, ioh) 604 bus_space_tag_t iot; 605 bus_space_handle_t ioh; 606 { 607 int i; 608 609 for (i = 0, beg *= 4; i < cnt; i++, beg +=4) { 610 bus_space_write_4(iot, ioh, beg, 611 *rgb++ & 0x00ffffff); 612 } 613 } 614 615 KASSERT(rgb); 616 KASSERT(LEGAL_CLUT_INDEX(beg)); 617 KASSERT(LEGAL_CLUT_INDEX(beg + cnt - 1)); 618 __plumvideo_clut_access(sc, __plumvideo_clut_set); 619 } 620 621 void 622 plumvideo_clut_default(sc) 623 struct plumvideo_softc *sc; 624 { 625 static void __plumvideo_clut_default __P((bus_space_tag_t, 626 bus_space_handle_t)); 627 static void __plumvideo_clut_default(iot, ioh) 628 bus_space_tag_t iot; 629 bus_space_handle_t ioh; 630 { 631 const u_int8_t compo6[6] = { 0, 51, 102, 153, 204, 255 }; 632 const u_int32_t ansi_color[16] = { 633 0x000000, 0xff0000, 0x00ff00, 0xffff00, 634 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff, 635 0x000000, 0x800000, 0x008000, 0x808000, 636 0x000080, 0x800080, 0x008080, 0x808080, 637 }; 638 int i, r, g, b; 639 640 /* ANSI escape sequence */ 641 for (i = 0; i < 16; i++) { 642 bus_space_write_4(iot, ioh, i << 2, ansi_color[i]); 643 } 644 /* 16 - 31, gray scale */ 645 for ( ; i < 32; i++) { 646 int j = (i - 16) * 17; 647 bus_space_write_4(iot, ioh, i << 2, RGB24(j, j, j)); 648 } 649 /* 32 - 247, RGB color */ 650 for (r = 0; r < 6; r++) { 651 for (g = 0; g < 6; g++) { 652 for (b = 0; b < 6; b++) { 653 bus_space_write_4(iot, ioh, i << 2, 654 RGB24(compo6[r], 655 compo6[g], 656 compo6[b])); 657 i++; 658 } 659 } 660 } 661 /* 248 - 245, just white */ 662 for ( ; i < 256; i++) { 663 bus_space_write_4(iot, ioh, i << 2, 0xffffff); 664 } 665 } 666 667 __plumvideo_clut_access(sc, __plumvideo_clut_default); 668 } 669 670 void 671 __plumvideo_clut_access(sc, palette_func) 672 struct plumvideo_softc *sc; 673 void (*palette_func) __P((bus_space_tag_t, bus_space_handle_t)); 674 { 675 bus_space_tag_t regt = sc->sc_regt; 676 bus_space_handle_t regh = sc->sc_regh; 677 plumreg_t val, gmode; 678 679 /* display off */ 680 val = bus_space_read_4(regt, regh, PLUM_VIDEO_PLGMD_REG); 681 gmode = val & PLUM_VIDEO_PLGMD_GMODE_MASK; 682 val &= ~PLUM_VIDEO_PLGMD_GMODE_MASK; 683 bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val); 684 685 /* palette access disable */ 686 val &= ~PLUM_VIDEO_PLGMD_PALETTE_ENABLE; 687 bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val); 688 689 /* change palette mode to CPU */ 690 val &= ~PLUM_VIDEO_PLGMD_MODE_DISPLAY; 691 bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val); 692 693 /* palette access */ 694 (*palette_func) (sc->sc_clutiot, sc->sc_clutioh); 695 696 /* change palette mode to Display */ 697 val |= PLUM_VIDEO_PLGMD_MODE_DISPLAY; 698 bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val); 699 700 /* palette access enable */ 701 val |= PLUM_VIDEO_PLGMD_PALETTE_ENABLE; 702 bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val); 703 704 /* display on */ 705 val |= gmode; 706 bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val); 707 } 708 709 /* !!! */ 710 static void 711 _flush_cache() 712 { 713 MachFlushCache(); 714 } 715 716 #ifdef PLUMVIDEODEBUG 717 void 718 plumvideo_dump(sc) 719 struct plumvideo_softc *sc; 720 { 721 bus_space_tag_t regt = sc->sc_regt; 722 bus_space_handle_t regh = sc->sc_regh; 723 724 plumreg_t reg; 725 int i; 726 727 for (i = 0; i < 0x160; i += 4) { 728 reg = plum_conf_read(regt, regh, i); 729 printf("0x%03x %08x", i, reg); 730 bitdisp(reg); 731 } 732 } 733 #endif /* PLUMVIDEODEBUG */ 734