Annotation of sys/arch/sparc/dev/p9000.c, Revision 1.1.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