Annotation of sys/arch/sparc/dev/p9000.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: p9000.c,v 1.20 2007/02/25 18:14:48 miod Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2003, Miodrag Vallat.
! 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: *
! 15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
! 18: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
! 19: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 20: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 21: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 22: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 23: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
! 24: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 25: * POSSIBILITY OF SUCH DAMAGE.
! 26: */
! 27:
! 28: /*
! 29: * Driver for the Tadpole SPARCbook 3 on-board display.
! 30: * Heavily based on the p9100 driver.
! 31: */
! 32:
! 33: #include <sys/param.h>
! 34: #include <sys/systm.h>
! 35: #include <sys/buf.h>
! 36: #include <sys/device.h>
! 37: #include <sys/ioctl.h>
! 38: #include <sys/malloc.h>
! 39: #include <sys/mman.h>
! 40: #include <sys/tty.h>
! 41: #include <sys/conf.h>
! 42:
! 43: #include <uvm/uvm_extern.h>
! 44:
! 45: #include <machine/autoconf.h>
! 46: #include <machine/pmap.h>
! 47: #include <machine/cpu.h>
! 48: #include <machine/conf.h>
! 49:
! 50: #include <dev/wscons/wsconsio.h>
! 51: #include <dev/wscons/wsdisplayvar.h>
! 52: #include <dev/rasops/rasops.h>
! 53: #include <machine/fbvar.h>
! 54:
! 55: #include <sparc/dev/btreg.h>
! 56: #include <sparc/dev/btvar.h>
! 57: #include <sparc/dev/bt445reg.h>
! 58: #include <sparc/dev/bt445var.h>
! 59: #include <sparc/dev/sbusvar.h>
! 60:
! 61: #include <dev/ic/p9000.h>
! 62:
! 63: #include "tctrl.h"
! 64: #if NTCTRL > 0
! 65: #include <sparc/dev/tctrlvar.h>
! 66: #endif
! 67:
! 68: /* per-display variables */
! 69: struct p9000_softc {
! 70: struct sunfb sc_sunfb; /* common base part */
! 71: struct rom_reg sc_phys; /* phys address description */
! 72: volatile u_int8_t *sc_cmd; /* command registers (dac, etc) */
! 73: volatile u_int8_t *sc_ctl; /* control registers (draw engine) */
! 74: union bt_cmap sc_cmap; /* Brooktree color map */
! 75: volatile u_int8_t *sc_ramdac; /* BT445 registers */
! 76: struct intrhand sc_ih;
! 77: u_int32_t sc_junk; /* throwaway value */
! 78: };
! 79:
! 80: int p9000_ioctl(void *, u_long, caddr_t, int, struct proc *);
! 81: static __inline__
! 82: void p9000_loadcmap_deferred(struct p9000_softc *, u_int, u_int);
! 83: void p9000_loadcmap_immediate(struct p9000_softc *, u_int, u_int);
! 84: paddr_t p9000_mmap(void *, off_t, int);
! 85: void p9000_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
! 86: void p9000_burner(void *, u_int, u_int);
! 87: int p9000_intr(void *);
! 88:
! 89: struct wsdisplay_accessops p9000_accessops = {
! 90: p9000_ioctl,
! 91: p9000_mmap,
! 92: NULL, /* alloc_screen */
! 93: NULL, /* free_screen */
! 94: NULL, /* show_screen */
! 95: NULL, /* load_font */
! 96: NULL, /* scrollback */
! 97: NULL, /* getchar */
! 98: p9000_burner,
! 99: NULL /* pollc */
! 100: };
! 101:
! 102: void p9000_ras_copycols(void *, int, int, int, int);
! 103: void p9000_ras_copyrows(void *, int, int, int);
! 104: void p9000_ras_do_cursor(struct rasops_info *);
! 105: void p9000_ras_erasecols(void *, int, int, int, long int);
! 106: void p9000_ras_eraserows(void *, int, int, long int);
! 107: void p9000_ras_init(struct p9000_softc *);
! 108:
! 109: int p9000match(struct device *, void *, void *);
! 110: void p9000attach(struct device *, struct device *, void *);
! 111:
! 112: struct cfattach pninek_ca = {
! 113: sizeof (struct p9000_softc), p9000match, p9000attach
! 114: };
! 115:
! 116: struct cfdriver pninek_cd = {
! 117: NULL, "pninek", DV_DULL
! 118: };
! 119:
! 120: /*
! 121: * SBus registers mappings
! 122: */
! 123: #define P9000_NREG 5 /* actually, 7 total */
! 124: #define P9000_REG_CTL 0
! 125: #define P9000_REG_CMD 1
! 126: #define P9000_REG_VRAM 4
! 127:
! 128: /*
! 129: * P9000 read/write macros
! 130: */
! 131:
! 132: #define P9000_READ_CTL(sc,reg) \
! 133: *(volatile u_int32_t *)((sc)->sc_ctl + (reg))
! 134: #define P9000_READ_CMD(sc,reg) \
! 135: *(volatile u_int32_t *)((sc)->sc_cmd + (reg))
! 136:
! 137: #define P9000_WRITE_CTL(sc,reg,value) \
! 138: *(volatile u_int32_t *)((sc)->sc_ctl + (reg)) = (value)
! 139: #define P9000_WRITE_CMD(sc,reg,value) \
! 140: *(volatile u_int32_t *)((sc)->sc_cmd + (reg)) = (value)
! 141:
! 142: /*
! 143: * On the Tadpole, the first write to a register group is ignored until
! 144: * the proper group address is latched, which can be done by reading from the
! 145: * register group first.
! 146: *
! 147: * Register groups are 0x80 bytes long (i.e. it is necessary to force a read
! 148: * when writing to an address which upper 25 bit differ from the previous
! 149: * read or write operation).
! 150: *
! 151: * This is specific to the Tadpole design, and not a limitation of the
! 152: * Power 9000 hardware.
! 153: */
! 154: #define P9000_SELECT_SCR(sc) \
! 155: (sc)->sc_junk = P9000_READ_CTL(sc, P9000_SYSTEM_CONFIG)
! 156: #define P9000_SELECT_VCR(sc) \
! 157: (sc)->sc_junk = P9000_READ_CTL(sc, P9000_HCR)
! 158: #define P9000_SELECT_VRAM(sc) \
! 159: (sc)->sc_junk = P9000_READ_CTL(sc, P9000_MCR)
! 160: #define P9000_SELECT_PE(sc) \
! 161: (sc)->sc_junk = P9000_READ_CMD(sc, P9000_PE_STATUS)
! 162: #define P9000_SELECT_DE_LOW(sc) \
! 163: (sc)->sc_junk = P9000_READ_CMD(sc, P9000_DE_FG_COLOR)
! 164: #define P9000_SELECT_DE_HIGH(sc) \
! 165: (sc)->sc_junk = P9000_READ_CMD(sc, P9000_DE_PATTERN(0))
! 166: #define P9000_SELECT_COORD(sc,field) \
! 167: (sc)->sc_junk = P9000_READ_CMD(sc, field)
! 168:
! 169:
! 170: int
! 171: p9000match(struct device *parent, void *vcf, void *aux)
! 172: {
! 173: struct confargs *ca = aux;
! 174: struct romaux *ra = &ca->ca_ra;
! 175:
! 176: if (strcmp("p9000", ra->ra_name))
! 177: return (0);
! 178:
! 179: return (1);
! 180: }
! 181:
! 182: void
! 183: p9000attach(struct device *parent, struct device *self, void *args)
! 184: {
! 185: struct p9000_softc *sc = (struct p9000_softc *)self;
! 186: struct confargs *ca = args;
! 187: int node, pri, row, isconsole, scr;
! 188: struct device *btdev;
! 189: extern struct cfdriver btcham_cd;
! 190:
! 191: pri = ca->ca_ra.ra_intr[0].int_pri;
! 192: printf(" pri %d", pri);
! 193:
! 194: #ifdef DIAGNOSTIC
! 195: if (ca->ca_ra.ra_nreg < P9000_NREG) {
! 196: printf(": expected %d registers, got only %d\n",
! 197: P9000_NREG, ca->ca_ra.ra_nreg);
! 198: return;
! 199: }
! 200: #endif
! 201:
! 202: /*
! 203: * Find the RAMDAC device. It should have attached before, since it
! 204: * attaches at obio. If, for some reason, it did not, it's not worth
! 205: * going any further.
! 206: *
! 207: * We rely upon the PROM to properly initialize the RAMDAC in a safe
! 208: * mode.
! 209: */
! 210: btdev = btcham_cd.cd_ndevs != 0 ? btcham_cd.cd_devs[0] : NULL;
! 211: if (btdev != NULL)
! 212: sc->sc_ramdac = ((struct bt445_softc *)btdev)->sc_regs;
! 213:
! 214: if (sc->sc_ramdac == NULL) {
! 215: printf(": bt445 did not attach previously\n");
! 216: return;
! 217: }
! 218:
! 219: sc->sc_phys = ca->ca_ra.ra_reg[P9000_REG_VRAM];
! 220:
! 221: sc->sc_ctl = mapiodev(&(ca->ca_ra.ra_reg[P9000_REG_CTL]), 0,
! 222: ca->ca_ra.ra_reg[0].rr_len);
! 223: sc->sc_cmd = mapiodev(&(ca->ca_ra.ra_reg[P9000_REG_CMD]), 0,
! 224: ca->ca_ra.ra_reg[1].rr_len);
! 225:
! 226: node = ca->ca_ra.ra_node;
! 227: isconsole = node == fbnode;
! 228:
! 229: fb_setsize(&sc->sc_sunfb, 8, 640, 480, node, ca->ca_bustype);
! 230: sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, 0,
! 231: round_page(sc->sc_sunfb.sf_fbsize));
! 232: sc->sc_sunfb.sf_ro.ri_hw = sc;
! 233:
! 234: P9000_SELECT_SCR(sc);
! 235: scr = P9000_READ_CTL(sc, P9000_SYSTEM_CONFIG);
! 236:
! 237: printf(": rev %x, %dx%d\n", scr & SCR_ID_MASK,
! 238: sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
! 239:
! 240: /* Disable frame buffer interrupts */
! 241: P9000_SELECT_SCR(sc);
! 242: P9000_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE, IER_MASTER_ENABLE | 0);
! 243:
! 244: sc->sc_ih.ih_fun = p9000_intr;
! 245: sc->sc_ih.ih_arg = sc;
! 246: intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname);
! 247:
! 248: /*
! 249: * If the framebuffer width is under 1024x768, we will switch from the
! 250: * PROM font to the more adequate 8x16 font here.
! 251: * However, we need to adjust two things in this case:
! 252: * - the display row should be overrided from the current PROM metrics,
! 253: * to prevent us from overwriting the last few lines of text.
! 254: * - if the 80x34 screen would make a large margin appear around it,
! 255: * choose to clear the screen rather than keeping old prom output in
! 256: * the margins.
! 257: * XXX there should be a rasops "clear margins" feature
! 258: */
! 259: fbwscons_init(&sc->sc_sunfb,
! 260: isconsole && (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR);
! 261: fbwscons_setcolormap(&sc->sc_sunfb, p9000_setcolor);
! 262:
! 263: /*
! 264: * Plug-in accelerated console operations.
! 265: */
! 266: if (sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags != 0)
! 267: p9000_ras_init(sc);
! 268:
! 269: /* enable video */
! 270: p9000_burner(sc, 1, 0);
! 271:
! 272: if (isconsole) {
! 273: if (sc->sc_sunfb.sf_width < 1024)
! 274: row = 0; /* screen has been cleared above */
! 275: else
! 276: row = -1;
! 277:
! 278: fbwscons_console_init(&sc->sc_sunfb, row);
! 279: }
! 280:
! 281: fbwscons_attach(&sc->sc_sunfb, &p9000_accessops, isconsole);
! 282: }
! 283:
! 284: int
! 285: p9000_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
! 286: {
! 287: struct p9000_softc *sc = v;
! 288: struct wsdisplay_fbinfo *wdf;
! 289: struct wsdisplay_cmap *cm;
! 290: #if NTCTRL > 0
! 291: struct wsdisplay_param *dp;
! 292: #endif
! 293: int error;
! 294:
! 295: switch (cmd) {
! 296:
! 297: case WSDISPLAYIO_GTYPE:
! 298: *(u_int *)data = WSDISPLAY_TYPE_SB_P9000;
! 299: break;
! 300:
! 301: case WSDISPLAYIO_SMODE:
! 302: /* Restore proper acceleration state upon leaving X11 */
! 303: if (*(u_int *)data == WSDISPLAYIO_MODE_EMUL) {
! 304: if (sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags != 0)
! 305: p9000_ras_init(sc);
! 306: }
! 307: break;
! 308:
! 309: case WSDISPLAYIO_GINFO:
! 310: wdf = (struct wsdisplay_fbinfo *)data;
! 311: wdf->height = sc->sc_sunfb.sf_height;
! 312: wdf->width = sc->sc_sunfb.sf_width;
! 313: wdf->depth = sc->sc_sunfb.sf_depth;
! 314: wdf->cmsize = 256;
! 315: break;
! 316:
! 317: case WSDISPLAYIO_LINEBYTES:
! 318: *(u_int *)data = sc->sc_sunfb.sf_linebytes;
! 319: break;
! 320:
! 321: case WSDISPLAYIO_GETCMAP:
! 322: cm = (struct wsdisplay_cmap *)data;
! 323: error = bt_getcmap(&sc->sc_cmap, cm);
! 324: if (error)
! 325: return (error);
! 326: break;
! 327:
! 328: case WSDISPLAYIO_PUTCMAP:
! 329: cm = (struct wsdisplay_cmap *)data;
! 330: error = bt_putcmap(&sc->sc_cmap, cm);
! 331: if (error)
! 332: return (error);
! 333: p9000_loadcmap_deferred(sc, cm->index, cm->count);
! 334: break;
! 335:
! 336: #if NTCTRL > 0
! 337: case WSDISPLAYIO_GETPARAM:
! 338: dp = (struct wsdisplay_param *)data;
! 339:
! 340: switch (dp->param) {
! 341: case WSDISPLAYIO_PARAM_BRIGHTNESS:
! 342: dp->min = 0;
! 343: dp->max = 255;
! 344: dp->curval = tadpole_get_brightness();
! 345: break;
! 346: case WSDISPLAYIO_PARAM_BACKLIGHT:
! 347: dp->min = 0;
! 348: dp->max = 1;
! 349: dp->curval = tadpole_get_video() & TV_ON ? 1 : 0;
! 350: break;
! 351: default:
! 352: return (-1);
! 353: }
! 354: break;
! 355:
! 356: case WSDISPLAYIO_SETPARAM:
! 357: dp = (struct wsdisplay_param *)data;
! 358:
! 359: switch (dp->param) {
! 360: case WSDISPLAYIO_PARAM_BRIGHTNESS:
! 361: tadpole_set_brightness(dp->curval);
! 362: break;
! 363: case WSDISPLAYIO_PARAM_BACKLIGHT:
! 364: tadpole_set_video(dp->curval);
! 365: break;
! 366: default:
! 367: return (-1);
! 368: }
! 369: break;
! 370: #endif /* NTCTRL > 0 */
! 371:
! 372: case WSDISPLAYIO_SVIDEO:
! 373: case WSDISPLAYIO_GVIDEO:
! 374: break;
! 375:
! 376: case WSDISPLAYIO_GCURPOS:
! 377: case WSDISPLAYIO_SCURPOS:
! 378: case WSDISPLAYIO_GCURMAX:
! 379: case WSDISPLAYIO_GCURSOR:
! 380: case WSDISPLAYIO_SCURSOR:
! 381: default:
! 382: return (-1); /* not supported yet */
! 383: }
! 384:
! 385: return (0);
! 386: }
! 387:
! 388: paddr_t
! 389: p9000_mmap(void *v, off_t offset, int prot)
! 390: {
! 391: struct p9000_softc *sc = v;
! 392:
! 393: if (offset & PGOFSET)
! 394: return (-1);
! 395:
! 396: if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
! 397: return (REG2PHYS(&sc->sc_phys, offset) | PMAP_NC);
! 398: }
! 399:
! 400: return (-1);
! 401: }
! 402:
! 403: void
! 404: p9000_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
! 405: {
! 406: struct p9000_softc *sc = v;
! 407: union bt_cmap *bcm = &sc->sc_cmap;
! 408:
! 409: bcm->cm_map[index][0] = r;
! 410: bcm->cm_map[index][1] = g;
! 411: bcm->cm_map[index][2] = b;
! 412: p9000_loadcmap_immediate(sc, index, 1);
! 413: }
! 414:
! 415: void
! 416: p9000_loadcmap_immediate(struct p9000_softc *sc, u_int start, u_int ncolors)
! 417: {
! 418: sc->sc_ramdac[BT445_ADDRESS] = start;
! 419: for (ncolors += start; start < ncolors; start++) {
! 420: sc->sc_ramdac[BT445_PALDATA] = sc->sc_cmap.cm_map[start][0];
! 421: sc->sc_ramdac[BT445_PALDATA] = sc->sc_cmap.cm_map[start][1];
! 422: sc->sc_ramdac[BT445_PALDATA] = sc->sc_cmap.cm_map[start][2];
! 423: }
! 424: }
! 425:
! 426: static __inline__ void
! 427: p9000_loadcmap_deferred(struct p9000_softc *sc, u_int start, u_int ncolors)
! 428: {
! 429: /* Schedule an interrupt for next retrace */
! 430: P9000_SELECT_SCR(sc);
! 431: P9000_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE,
! 432: IER_MASTER_ENABLE | IER_MASTER_INTERRUPT |
! 433: IER_VBLANK_ENABLE | IER_VBLANK_INTERRUPT);
! 434: }
! 435:
! 436: void
! 437: p9000_burner(void *v, u_int on, u_int flags)
! 438: {
! 439: struct p9000_softc *sc = v;
! 440: u_int32_t vcr;
! 441: int s;
! 442:
! 443: s = splhigh();
! 444: P9000_SELECT_VCR(sc);
! 445: vcr = P9000_READ_CTL(sc, P9000_SRTC1);
! 446: if (on)
! 447: vcr |= SRTC1_VIDEN;
! 448: else
! 449: vcr &= ~SRTC1_VIDEN;
! 450: P9000_WRITE_CTL(sc, P9000_SRTC1, vcr);
! 451: #if NTCTRL > 0
! 452: tadpole_set_video(on);
! 453: #endif
! 454: splx(s);
! 455: }
! 456:
! 457: int
! 458: p9000_intr(void *v)
! 459: {
! 460: struct p9000_softc *sc = v;
! 461:
! 462: if (P9000_READ_CTL(sc, P9000_INTERRUPT) & IER_VBLANK_INTERRUPT) {
! 463: p9000_loadcmap_immediate(sc, 0, 256);
! 464:
! 465: /* Disable further interrupts now */
! 466: /* P9000_SELECT_SCR(sc); */
! 467: P9000_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE,
! 468: IER_MASTER_ENABLE | 0);
! 469:
! 470: /* Clear interrupt condition */
! 471: P9000_WRITE_CTL(sc, P9000_INTERRUPT,
! 472: IER_VBLANK_ENABLE | 0);
! 473:
! 474: return (1);
! 475: }
! 476:
! 477: return (0);
! 478: }
! 479:
! 480: /*
! 481: * Accelerated text console code
! 482: */
! 483:
! 484: static int p9000_drain(struct p9000_softc *);
! 485:
! 486: static int
! 487: p9000_drain(struct p9000_softc *sc)
! 488: {
! 489: u_int i;
! 490:
! 491: for (i = 10000; i != 0; i--) {
! 492: if ((P9000_READ_CMD(sc, P9000_PE_STATUS) &
! 493: (STATUS_QUAD_BUSY | STATUS_BLIT_BUSY)) == 0)
! 494: break;
! 495: }
! 496:
! 497: return (i);
! 498: }
! 499:
! 500: void
! 501: p9000_ras_init(struct p9000_softc *sc)
! 502: {
! 503:
! 504: if (p9000_drain(sc) == 0)
! 505: return;
! 506:
! 507: sc->sc_sunfb.sf_ro.ri_ops.copycols = p9000_ras_copycols;
! 508: sc->sc_sunfb.sf_ro.ri_ops.copyrows = p9000_ras_copyrows;
! 509: sc->sc_sunfb.sf_ro.ri_ops.erasecols = p9000_ras_erasecols;
! 510: sc->sc_sunfb.sf_ro.ri_ops.eraserows = p9000_ras_eraserows;
! 511: sc->sc_sunfb.sf_ro.ri_do_cursor = p9000_ras_do_cursor;
! 512:
! 513: /*
! 514: * Setup safe defaults for the parameter and drawing engines, in
! 515: * order to minimize the operations to do for ri_ops.
! 516: */
! 517:
! 518: P9000_SELECT_DE_LOW(sc);
! 519: P9000_WRITE_CMD(sc, P9000_DE_DRAWMODE,
! 520: DM_PICK_CONTROL | 0 | DM_BUFFER_CONTROL | DM_BUFFER_ENABLE0);
! 521:
! 522: P9000_WRITE_CMD(sc, P9000_DE_PATTERN_ORIGIN_X, 0);
! 523: P9000_WRITE_CMD(sc, P9000_DE_PATTERN_ORIGIN_Y, 0);
! 524: /* enable all planes */
! 525: P9000_WRITE_CMD(sc, P9000_DE_PLANEMASK, 0xff);
! 526:
! 527: /* Unclip */
! 528: P9000_WRITE_CMD(sc, P9000_DE_WINMIN, 0);
! 529: P9000_WRITE_CMD(sc, P9000_DE_WINMAX,
! 530: P9000_COORDS(sc->sc_sunfb.sf_width - 1, sc->sc_sunfb.sf_height - 1));
! 531:
! 532: P9000_SELECT_PE(sc);
! 533: P9000_WRITE_CMD(sc, P9000_PE_WINOFFSET, 0);
! 534: P9000_WRITE_CMD(sc, P9000_PE_INDEX, 0);
! 535: P9000_WRITE_CMD(sc, P9000_PE_WINMIN, 0);
! 536: P9000_WRITE_CMD(sc, P9000_PE_WINMAX,
! 537: P9000_COORDS(sc->sc_sunfb.sf_width - 1, sc->sc_sunfb.sf_height - 1));
! 538: }
! 539:
! 540: void
! 541: p9000_ras_copycols(void *v, int row, int src, int dst, int n)
! 542: {
! 543: struct rasops_info *ri = v;
! 544: struct p9000_softc *sc = ri->ri_hw;
! 545:
! 546: n *= ri->ri_font->fontwidth;
! 547: n--;
! 548: src *= ri->ri_font->fontwidth;
! 549: src += ri->ri_xorigin;
! 550: dst *= ri->ri_font->fontwidth;
! 551: dst += ri->ri_xorigin;
! 552: row *= ri->ri_font->fontheight;
! 553: row += ri->ri_yorigin;
! 554:
! 555: p9000_drain(sc);
! 556: P9000_SELECT_DE_LOW(sc);
! 557: P9000_WRITE_CMD(sc, P9000_DE_RASTER,
! 558: P9000_RASTER_SRC & P9000_RASTER_MASK);
! 559:
! 560: P9000_SELECT_COORD(sc, P9000_DC_COORD(0));
! 561: P9000_WRITE_CMD(sc, P9000_DC_COORD(0) + P9000_COORD_XY,
! 562: P9000_COORDS(src, row));
! 563: P9000_WRITE_CMD(sc, P9000_DC_COORD(1) + P9000_COORD_XY,
! 564: P9000_COORDS(src + n, row + ri->ri_font->fontheight - 1));
! 565: P9000_SELECT_COORD(sc, P9000_DC_COORD(2));
! 566: P9000_WRITE_CMD(sc, P9000_DC_COORD(2) + P9000_COORD_XY,
! 567: P9000_COORDS(dst, row));
! 568: P9000_WRITE_CMD(sc, P9000_DC_COORD(3) + P9000_COORD_XY,
! 569: P9000_COORDS(dst + n, row + ri->ri_font->fontheight - 1));
! 570:
! 571: sc->sc_junk = P9000_READ_CMD(sc, P9000_PE_BLIT);
! 572:
! 573: p9000_drain(sc);
! 574: }
! 575:
! 576: void
! 577: p9000_ras_copyrows(void *v, int src, int dst, int n)
! 578: {
! 579: struct rasops_info *ri = v;
! 580: struct p9000_softc *sc = ri->ri_hw;
! 581:
! 582: n *= ri->ri_font->fontheight;
! 583: n--;
! 584: src *= ri->ri_font->fontheight;
! 585: src += ri->ri_yorigin;
! 586: dst *= ri->ri_font->fontheight;
! 587: dst += ri->ri_yorigin;
! 588:
! 589: p9000_drain(sc);
! 590: P9000_SELECT_DE_LOW(sc);
! 591: P9000_WRITE_CMD(sc, P9000_DE_RASTER,
! 592: P9000_RASTER_SRC & P9000_RASTER_MASK);
! 593:
! 594: P9000_SELECT_COORD(sc, P9000_DC_COORD(0));
! 595: P9000_WRITE_CMD(sc, P9000_DC_COORD(0) + P9000_COORD_XY,
! 596: P9000_COORDS(ri->ri_xorigin, src));
! 597: P9000_WRITE_CMD(sc, P9000_DC_COORD(1) + P9000_COORD_XY,
! 598: P9000_COORDS(ri->ri_xorigin + ri->ri_emuwidth - 1, src + n));
! 599: P9000_SELECT_COORD(sc, P9000_DC_COORD(2));
! 600: P9000_WRITE_CMD(sc, P9000_DC_COORD(2) + P9000_COORD_XY,
! 601: P9000_COORDS(ri->ri_xorigin, dst));
! 602: P9000_WRITE_CMD(sc, P9000_DC_COORD(3) + P9000_COORD_XY,
! 603: P9000_COORDS(ri->ri_xorigin + ri->ri_emuwidth - 1, dst + n));
! 604:
! 605: sc->sc_junk = P9000_READ_CMD(sc, P9000_PE_BLIT);
! 606:
! 607: p9000_drain(sc);
! 608: }
! 609:
! 610: void
! 611: p9000_ras_erasecols(void *v, int row, int col, int n, long int attr)
! 612: {
! 613: struct rasops_info *ri = v;
! 614: struct p9000_softc *sc = ri->ri_hw;
! 615: int fg, bg;
! 616:
! 617: ri->ri_ops.unpack_attr(v, attr, &fg, &bg, NULL);
! 618:
! 619: n *= ri->ri_font->fontwidth;
! 620: col *= ri->ri_font->fontwidth;
! 621: col += ri->ri_xorigin;
! 622: row *= ri->ri_font->fontheight;
! 623: row += ri->ri_yorigin;
! 624:
! 625: p9000_drain(sc);
! 626: P9000_SELECT_DE_LOW(sc);
! 627: P9000_WRITE_CMD(sc, P9000_DE_RASTER,
! 628: P9000_RASTER_PATTERN & P9000_RASTER_MASK);
! 629: P9000_WRITE_CMD(sc, P9000_DE_FG_COLOR, bg);
! 630:
! 631: P9000_SELECT_COORD(sc, P9000_LC_RECT);
! 632: P9000_WRITE_CMD(sc, P9000_LC_RECT + P9000_COORD_XY,
! 633: P9000_COORDS(col, row));
! 634: P9000_WRITE_CMD(sc, P9000_LC_RECT + P9000_COORD_XY,
! 635: P9000_COORDS(col + n, row + ri->ri_font->fontheight));
! 636:
! 637: sc->sc_junk = P9000_READ_CMD(sc, P9000_PE_QUAD);
! 638:
! 639: p9000_drain(sc);
! 640: }
! 641:
! 642: void
! 643: p9000_ras_eraserows(void *v, int row, int n, long int attr)
! 644: {
! 645: struct rasops_info *ri = v;
! 646: struct p9000_softc *sc = ri->ri_hw;
! 647: int fg, bg;
! 648:
! 649: ri->ri_ops.unpack_attr(v, attr, &fg, &bg, NULL);
! 650:
! 651: p9000_drain(sc);
! 652: P9000_SELECT_DE_LOW(sc);
! 653: P9000_WRITE_CMD(sc, P9000_DE_RASTER,
! 654: P9000_RASTER_PATTERN & P9000_RASTER_MASK);
! 655: P9000_WRITE_CMD(sc, P9000_DE_FG_COLOR, bg);
! 656:
! 657: P9000_SELECT_COORD(sc, P9000_LC_RECT);
! 658: if (n == ri->ri_rows && ISSET(ri->ri_flg, RI_FULLCLEAR)) {
! 659: P9000_WRITE_CMD(sc, P9000_LC_RECT + P9000_COORD_XY,
! 660: P9000_COORDS(0, 0));
! 661: P9000_WRITE_CMD(sc, P9000_LC_RECT + P9000_COORD_XY,
! 662: P9000_COORDS(ri->ri_width, ri->ri_height));
! 663: } else {
! 664: n *= ri->ri_font->fontheight;
! 665: row *= ri->ri_font->fontheight;
! 666: row += ri->ri_yorigin;
! 667:
! 668: P9000_WRITE_CMD(sc, P9000_LC_RECT + P9000_COORD_XY,
! 669: P9000_COORDS(ri->ri_xorigin, row));
! 670: P9000_WRITE_CMD(sc, P9000_LC_RECT + P9000_COORD_XY,
! 671: P9000_COORDS(ri->ri_xorigin + ri->ri_emuwidth, row + n));
! 672: }
! 673:
! 674: sc->sc_junk = P9000_READ_CMD(sc, P9000_PE_QUAD);
! 675:
! 676: p9000_drain(sc);
! 677: }
! 678:
! 679: void
! 680: p9000_ras_do_cursor(struct rasops_info *ri)
! 681: {
! 682: struct p9000_softc *sc = ri->ri_hw;
! 683: int row, col;
! 684:
! 685: row = ri->ri_crow * ri->ri_font->fontheight + ri->ri_yorigin;
! 686: col = ri->ri_ccol * ri->ri_font->fontwidth + ri->ri_xorigin;
! 687:
! 688: p9000_drain(sc);
! 689:
! 690: P9000_SELECT_DE_LOW(sc);
! 691: P9000_WRITE_CMD(sc, P9000_DE_RASTER,
! 692: (P9000_RASTER_PATTERN ^ P9000_RASTER_DST) & P9000_RASTER_MASK);
! 693: P9000_WRITE_CMD(sc, P9000_DE_FG_COLOR, ri->ri_devcmap[WSCOL_BLACK]);
! 694:
! 695: P9000_SELECT_COORD(sc, P9000_LC_RECT);
! 696: P9000_WRITE_CMD(sc, P9000_LC_RECT + P9000_COORD_XY,
! 697: P9000_COORDS(col, row));
! 698: P9000_WRITE_CMD(sc, P9000_LC_RECT + P9000_COORD_XY,
! 699: P9000_COORDS(col + ri->ri_font->fontwidth,
! 700: row + ri->ri_font->fontheight));
! 701:
! 702: sc->sc_junk = P9000_READ_CMD(sc, P9000_PE_QUAD);
! 703:
! 704: p9000_drain(sc);
! 705: }
CVSweb