Annotation of sys/arch/sparc/dev/cgsix.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cgsix.c,v 1.38 2007/02/18 18:40:35 miod Exp $ */
2: /* $NetBSD: cgsix.c,v 1.33 1997/08/07 19:12:30 pk Exp $ */
3:
4: /*
5: * Copyright (c) 2002 Miodrag Vallat. All rights reserved.
6: * Copyright (c) 2001 Jason L. Wright (jason@thought.net)
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28: * POSSIBILITY OF SUCH DAMAGE.
29: *
30: * Effort sponsored in part by the Defense Advanced Research Projects
31: * Agency (DARPA) and Air Force Research Laboratory, Air Force
32: * Materiel Command, USAF, under agreement number F30602-01-2-0537.
33: *
34: *
35: * Copyright (c) 1993
36: * The Regents of the University of California. All rights reserved.
37: *
38: * This software was developed by the Computer Systems Engineering group
39: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
40: * contributed to Berkeley.
41: *
42: * All advertising materials mentioning features or use of this software
43: * must display the following acknowledgement:
44: * This product includes software developed by the University of
45: * California, Lawrence Berkeley Laboratory.
46: *
47: * Redistribution and use in source and binary forms, with or without
48: * modification, are permitted provided that the following conditions
49: * are met:
50: * 1. Redistributions of source code must retain the above copyright
51: * notice, this list of conditions and the following disclaimer.
52: * 2. Redistributions in binary form must reproduce the above copyright
53: * notice, this list of conditions and the following disclaimer in the
54: * documentation and/or other materials provided with the distribution.
55: * 3. Neither the name of the University nor the names of its contributors
56: * may be used to endorse or promote products derived from this software
57: * without specific prior written permission.
58: *
59: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69: * SUCH DAMAGE.
70: *
71: * @(#)cgsix.c 8.4 (Berkeley) 1/21/94
72: */
73:
74: /*
75: * color display (cgsix) driver.
76: */
77:
78: #include <sys/param.h>
79: #include <sys/systm.h>
80: #include <sys/buf.h>
81: #include <sys/device.h>
82: #include <sys/ioctl.h>
83: #include <sys/malloc.h>
84: #include <sys/mman.h>
85: #include <sys/tty.h>
86: #include <sys/conf.h>
87:
88: #include <uvm/uvm_extern.h>
89:
90: #include <machine/autoconf.h>
91: #include <machine/pmap.h>
92: #include <machine/cpu.h>
93: #if defined(SUN4)
94: #include <machine/eeprom.h>
95: #endif
96: #include <machine/conf.h>
97:
98: #include <dev/wscons/wsconsio.h>
99: #include <dev/wscons/wsdisplayvar.h>
100: #include <dev/rasops/rasops.h>
101: #include <machine/fbvar.h>
102:
103: #include <sparc/dev/btreg.h>
104: #include <sparc/dev/btvar.h>
105: #include <sparc/dev/cgsixreg.h>
106: #include <sparc/dev/sbusvar.h>
107: #if defined(SUN4)
108: #include <sparc/dev/pfourreg.h>
109: #endif
110:
111: /* per-display variables */
112: struct cgsix_softc {
113: struct sunfb sc_sunfb; /* common base part */
114: struct rom_reg sc_phys; /* phys addr of h/w */
115: volatile struct bt_regs *sc_bt; /* Brooktree registers */
116: volatile int *sc_fhc; /* FHC register */
117: volatile struct cgsix_thc *sc_thc; /* THC registers */
118: volatile struct cgsix_fbc *sc_fbc; /* FBC registers */
119: volatile struct cgsix_tec_xxx *sc_tec; /* TEC registers */
120: union bt_cmap sc_cmap; /* Brooktree color map */
121: struct intrhand sc_ih;
122: };
123:
124: void cgsix_burner(void *, u_int, u_int);
125: int cgsix_intr(void *);
126: int cgsix_ioctl(void *, u_long, caddr_t, int, struct proc *);
127: static __inline__
128: void cgsix_loadcmap_deferred(struct cgsix_softc *, u_int, u_int);
129: paddr_t cgsix_mmap(void *, off_t, int);
130: void cgsix_reset(struct cgsix_softc *, u_int);
131: void cgsix_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
132:
133: void cgsix_ras_copyrows(void *, int, int, int);
134: void cgsix_ras_copycols(void *, int, int, int, int);
135: void cgsix_ras_do_cursor(struct rasops_info *);
136: void cgsix_ras_erasecols(void *, int, int, int, long);
137: void cgsix_ras_eraserows(void *, int, int, long);
138: void cgsix_ras_init(struct cgsix_softc *);
139:
140: struct wsdisplay_accessops cgsix_accessops = {
141: cgsix_ioctl,
142: cgsix_mmap,
143: NULL, /* alloc_screen */
144: NULL, /* free_screen */
145: NULL, /* show_screen */
146: NULL, /* load_font */
147: NULL, /* scrollback */
148: NULL, /* getchar */
149: cgsix_burner,
150: NULL /* pollc */
151: };
152:
153: int cgsixmatch(struct device *, void *, void *);
154: void cgsixattach(struct device *, struct device *, void *);
155:
156: struct cfattach cgsix_ca = {
157: sizeof(struct cgsix_softc), cgsixmatch, cgsixattach
158: };
159:
160: struct cfdriver cgsix_cd = {
161: NULL, "cgsix", DV_DULL
162: };
163:
164: int
165: cgsixmatch(struct device *parent, void *vcf, void *aux)
166: {
167: struct cfdata *cf = vcf;
168: struct confargs *ca = aux;
169: struct romaux *ra = &ca->ca_ra;
170:
171: if (strcmp(ra->ra_name, cf->cf_driver->cd_name) &&
172: strcmp(ra->ra_name, "SUNW,cgsix"))
173: return (0);
174:
175: switch (ca->ca_bustype) {
176: case BUS_SBUS:
177: return (1);
178: case BUS_OBIO:
179: #if defined(SUN4)
180: if (CPU_ISSUN4) {
181: void *tmp;
182:
183: /*
184: * Check for a pfour framebuffer. This is done
185: * somewhat differently on the cgsix than other
186: * pfour framebuffers.
187: */
188: bus_untmp();
189: tmp = (caddr_t)mapdev(ra->ra_reg, TMPMAP_VA,
190: CGSIX_FHC_OFFSET, NBPG);
191: if (probeget(tmp, 4) == -1)
192: return (0);
193:
194: if (fb_pfour_id(tmp) == PFOUR_ID_FASTCOLOR)
195: return (1);
196: }
197: #endif
198: /* FALLTHROUGH */
199: default:
200: return (0);
201: }
202: }
203:
204: void
205: cgsixattach(struct device *parent, struct device *self, void *args)
206: {
207: struct cgsix_softc *sc = (struct cgsix_softc *)self;
208: struct confargs *ca = args;
209: int node, pri;
210: int isconsole = 0, sbus = 1;
211: char *nam;
212: u_int fhcrev;
213:
214: pri = ca->ca_ra.ra_intr[0].int_pri;
215: printf(" pri %d: ", pri);
216:
217: /*
218: * Map just BT, FHC, FBC, THC, and video RAM.
219: */
220: sc->sc_phys = ca->ca_ra.ra_reg[0];
221: sc->sc_bt = (volatile struct bt_regs *)
222: mapiodev(ca->ca_ra.ra_reg, CGSIX_BT_OFFSET, CGSIX_BT_SIZE);
223: sc->sc_fhc = (volatile int *)
224: mapiodev(ca->ca_ra.ra_reg, CGSIX_FHC_OFFSET, CGSIX_FHC_SIZE);
225: sc->sc_thc = (volatile struct cgsix_thc *)
226: mapiodev(ca->ca_ra.ra_reg, CGSIX_THC_OFFSET, CGSIX_THC_SIZE);
227: sc->sc_fbc = (volatile struct cgsix_fbc *)
228: mapiodev(ca->ca_ra.ra_reg, CGSIX_FBC_OFFSET, CGSIX_FBC_SIZE);
229: sc->sc_tec = (volatile struct cgsix_tec_xxx *)
230: mapiodev(ca->ca_ra.ra_reg, CGSIX_TEC_OFFSET, CGSIX_TEC_SIZE);
231:
232: switch (ca->ca_bustype) {
233: case BUS_OBIO:
234: sbus = node = 0;
235: SET(sc->sc_sunfb.sf_flags, FB_PFOUR);
236: nam = "p4";
237: break;
238: case BUS_SBUS:
239: node = ca->ca_ra.ra_node;
240: nam = getpropstring(node, "model");
241: break;
242: }
243:
244: if (*nam != '\0')
245: printf("%s, ", nam);
246:
247: #if defined(SUN4)
248: if (CPU_ISSUN4) {
249: struct eeprom *eep = (struct eeprom *)eeprom_va;
250: int constype = ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR) ?
251: EE_CONS_P4OPT : EE_CONS_COLOR;
252: /*
253: * Assume this is the console if there's no eeprom info
254: * to be found.
255: */
256: if (eep == NULL || eep->eeConsole == constype)
257: isconsole = 1;
258: }
259: #endif
260:
261: if (CPU_ISSUN4COR4M)
262: isconsole = node == fbnode;
263:
264: fhcrev = (*sc->sc_fhc >> FHC_REV_SHIFT) &
265: (FHC_REV_MASK >> FHC_REV_SHIFT);
266:
267: sc->sc_ih.ih_fun = cgsix_intr;
268: sc->sc_ih.ih_arg = sc;
269: intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname);
270:
271: /* reset cursor & frame buffer controls */
272: cgsix_reset(sc, fhcrev);
273:
274: /* enable video */
275: cgsix_burner(sc, 1, 0);
276:
277: fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
278: sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg,
279: CGSIX_VID_OFFSET, round_page(sc->sc_sunfb.sf_fbsize));
280: sc->sc_sunfb.sf_ro.ri_hw = sc;
281:
282: /*
283: * If the framebuffer width is under 1024x768, we will switch from the
284: * PROM font to the more adequate 8x16 font here.
285: * However, we need to adjust two things in this case:
286: * - the display row should be overrided from the current PROM metrics,
287: * to prevent us from overwriting the last few lines of text.
288: * - if the 80x34 screen would make a large margin appear around it,
289: * choose to clear the screen rather than keeping old prom output in
290: * the margins.
291: * XXX there should be a rasops "clear margins" feature
292: */
293: fbwscons_init(&sc->sc_sunfb, isconsole &&
294: (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR);
295: fbwscons_setcolormap(&sc->sc_sunfb, cgsix_setcolor);
296:
297: /*
298: * Old rev. cg6 cards do not like the current acceleration code.
299: *
300: * Some hints from Sun point out at timing and cache problems, which
301: * will be investigated later.
302: */
303: if (fhcrev >= 5) {
304: sc->sc_sunfb.sf_ro.ri_ops.copyrows = cgsix_ras_copyrows;
305: sc->sc_sunfb.sf_ro.ri_ops.copycols = cgsix_ras_copycols;
306: sc->sc_sunfb.sf_ro.ri_ops.eraserows = cgsix_ras_eraserows;
307: sc->sc_sunfb.sf_ro.ri_ops.erasecols = cgsix_ras_erasecols;
308: sc->sc_sunfb.sf_ro.ri_do_cursor = cgsix_ras_do_cursor;
309: cgsix_ras_init(sc);
310: }
311:
312: printf("%dx%d, rev %d\n", sc->sc_sunfb.sf_width,
313: sc->sc_sunfb.sf_height, fhcrev);
314:
315: if (isconsole) {
316: fbwscons_console_init(&sc->sc_sunfb,
317: sc->sc_sunfb.sf_width >= 1024 ? -1 : 0);
318: }
319:
320: fbwscons_attach(&sc->sc_sunfb, &cgsix_accessops, isconsole);
321: }
322:
323: int
324: cgsix_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
325: {
326: struct cgsix_softc *sc = dev;
327: struct wsdisplay_cmap *cm;
328: struct wsdisplay_fbinfo *wdf;
329: int error;
330:
331: switch (cmd) {
332: case WSDISPLAYIO_GTYPE:
333: *(u_int *)data = WSDISPLAY_TYPE_SUNCG6;
334: break;
335: case WSDISPLAYIO_GINFO:
336: wdf = (struct wsdisplay_fbinfo *)data;
337: wdf->height = sc->sc_sunfb.sf_height;
338: wdf->width = sc->sc_sunfb.sf_width;
339: wdf->depth = sc->sc_sunfb.sf_depth;
340: wdf->cmsize = 256;
341: break;
342: case WSDISPLAYIO_LINEBYTES:
343: *(u_int *)data = sc->sc_sunfb.sf_linebytes;
344: break;
345:
346: case WSDISPLAYIO_GETCMAP:
347: cm = (struct wsdisplay_cmap *)data;
348: error = bt_getcmap(&sc->sc_cmap, cm);
349: if (error)
350: return (error);
351: break;
352:
353: case WSDISPLAYIO_PUTCMAP:
354: cm = (struct wsdisplay_cmap *)data;
355: error = bt_putcmap(&sc->sc_cmap, cm);
356: if (error)
357: return (error);
358: cgsix_loadcmap_deferred(sc, cm->index, cm->count);
359: break;
360:
361: case WSDISPLAYIO_SVIDEO:
362: case WSDISPLAYIO_GVIDEO:
363: break;
364:
365: case WSDISPLAYIO_GCURPOS:
366: case WSDISPLAYIO_SCURPOS:
367: case WSDISPLAYIO_GCURMAX:
368: case WSDISPLAYIO_GCURSOR:
369: case WSDISPLAYIO_SCURSOR:
370: default:
371: return (-1); /* not supported yet */
372: }
373:
374: return (0);
375: }
376:
377: /*
378: * Clean up hardware state (e.g., after bootup or after X crashes).
379: */
380: void
381: cgsix_reset(struct cgsix_softc *sc, u_int fhcrev)
382: {
383: volatile struct cgsix_tec_xxx *tec;
384: int fhc;
385: volatile struct bt_regs *bt;
386:
387: /* hide the cursor, just in case */
388: sc->sc_thc->thc_cursxy = THC_CURSOFF;
389:
390: /* turn off frobs in transform engine (makes X11 work) */
391: tec = sc->sc_tec;
392: tec->tec_mv = 0;
393: tec->tec_clip = 0;
394: tec->tec_vdc = 0;
395:
396: /* take care of hardware bugs in old revisions */
397: if (fhcrev < 5) {
398: /*
399: * Keep current resolution; set cpu to 68020, set test
400: * window (size 1Kx1K), and for rev 1, disable dest cache.
401: */
402: fhc = (*sc->sc_fhc & FHC_RES_MASK) | FHC_CPU_68020 |
403: FHC_TEST |
404: (11 << FHC_TESTX_SHIFT) | (11 << FHC_TESTY_SHIFT);
405: if (fhcrev < 2)
406: fhc |= FHC_DST_DISABLE;
407: *sc->sc_fhc = fhc;
408: }
409:
410: /* Enable cursor in Brooktree DAC. */
411: bt = sc->sc_bt;
412: bt->bt_addr = 0x06 << 24;
413: bt->bt_ctrl |= 0x03 << 24;
414: }
415:
416: paddr_t
417: cgsix_mmap(void *v, off_t offset, int prot)
418: {
419: struct cgsix_softc *sc = v;
420:
421: if (offset & PGOFSET)
422: return (-1);
423:
424: /* Allow mapping as a dumb framebuffer from offset 0 */
425: if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
426: return (REG2PHYS(&sc->sc_phys, offset + CGSIX_VID_OFFSET) |
427: PMAP_NC);
428: }
429:
430: return (-1);
431: }
432:
433: void
434: cgsix_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
435: {
436: struct cgsix_softc *sc = v;
437:
438: bt_setcolor(&sc->sc_cmap, sc->sc_bt, index, r, g, b, 1);
439: }
440:
441: static __inline__ void
442: cgsix_loadcmap_deferred(struct cgsix_softc *sc, u_int start, u_int ncolors)
443: {
444: u_int32_t thcm;
445:
446: thcm = sc->sc_thc->thc_misc;
447: thcm &= ~THC_MISC_RESET;
448: thcm |= THC_MISC_INTEN;
449: sc->sc_thc->thc_misc = thcm;
450: }
451:
452: void
453: cgsix_burner(void *v, u_int on, u_int flags)
454: {
455: struct cgsix_softc *sc = v;
456: int s;
457: u_int32_t thcm;
458:
459: s = splhigh();
460: thcm = sc->sc_thc->thc_misc;
461: if (on)
462: thcm |= THC_MISC_VIDEN | THC_MISC_SYNCEN;
463: else {
464: thcm &= ~THC_MISC_VIDEN;
465: if (flags & WSDISPLAY_BURN_VBLANK)
466: thcm &= ~THC_MISC_SYNCEN;
467: }
468: sc->sc_thc->thc_misc = thcm;
469: splx(s);
470: }
471:
472: int
473: cgsix_intr(void *v)
474: {
475: struct cgsix_softc *sc = v;
476: u_int32_t thcm;
477:
478: thcm = sc->sc_thc->thc_misc;
479: if ((thcm & (THC_MISC_INTEN | THC_MISC_INTR)) !=
480: (THC_MISC_INTEN | THC_MISC_INTR)) {
481: /* Not expecting an interrupt, it's not for us. */
482: return (0);
483: }
484:
485: /* Acknowledge the interrupt and disable it. */
486: thcm &= ~(THC_MISC_RESET | THC_MISC_INTEN);
487: thcm |= THC_MISC_INTR;
488: sc->sc_thc->thc_misc = thcm;
489: bt_loadcmap(&sc->sc_cmap, sc->sc_bt, 0, 256, 1);
490: return (1);
491: }
492:
493: /*
494: * Specifics rasops handlers for accelerated console
495: */
496:
497: #define CG6_BLIT_WAIT(fbc) \
498: while (((fbc)->fbc_blit & (FBC_BLIT_UNKNOWN | FBC_BLIT_GXFULL)) == \
499: (FBC_BLIT_UNKNOWN | FBC_BLIT_GXFULL))
500: #define CG6_DRAW_WAIT(fbc) \
501: while (((fbc)->fbc_draw & (FBC_DRAW_UNKNOWN | FBC_DRAW_GXFULL)) == \
502: (FBC_DRAW_UNKNOWN | FBC_DRAW_GXFULL))
503: #define CG6_DRAIN(fbc) \
504: while ((fbc)->fbc_s & FBC_S_GXINPROGRESS)
505:
506: void
507: cgsix_ras_init(struct cgsix_softc *sc)
508: {
509: u_int32_t m;
510:
511: CG6_DRAIN(sc->sc_fbc);
512: m = sc->sc_fbc->fbc_mode;
513: m &= ~FBC_MODE_MASK;
514: m |= FBC_MODE_VAL;
515: sc->sc_fbc->fbc_mode = m;
516: }
517:
518: void
519: cgsix_ras_copyrows(void *cookie, int src, int dst, int n)
520: {
521: struct rasops_info *ri = cookie;
522: struct cgsix_softc *sc = ri->ri_hw;
523: volatile struct cgsix_fbc *fbc = sc->sc_fbc;
524:
525: if (dst == src)
526: return;
527: if (src < 0) {
528: n += src;
529: src = 0;
530: }
531: if (src + n > ri->ri_rows)
532: n = ri->ri_rows - src;
533: if (dst < 0) {
534: n += dst;
535: dst = 0;
536: }
537: if (dst + n > ri->ri_rows)
538: n = ri->ri_rows - dst;
539: if (n <= 0)
540: return;
541: n *= ri->ri_font->fontheight;
542: src *= ri->ri_font->fontheight;
543: dst *= ri->ri_font->fontheight;
544:
545: fbc->fbc_clip = 0;
546: fbc->fbc_s = 0;
547: fbc->fbc_offx = 0;
548: fbc->fbc_offy = 0;
549: fbc->fbc_clipminx = 0;
550: fbc->fbc_clipminy = 0;
551: fbc->fbc_clipmaxx = ri->ri_width - 1;
552: fbc->fbc_clipmaxy = ri->ri_height - 1;
553: fbc->fbc_alu = FBC_ALU_COPY;
554: fbc->fbc_x0 = ri->ri_xorigin;
555: fbc->fbc_y0 = ri->ri_yorigin + src;
556: fbc->fbc_x1 = ri->ri_xorigin + ri->ri_emuwidth - 1;
557: fbc->fbc_y1 = ri->ri_yorigin + src + n - 1;
558: fbc->fbc_x2 = ri->ri_xorigin;
559: fbc->fbc_y2 = ri->ri_yorigin + dst;
560: fbc->fbc_x3 = ri->ri_xorigin + ri->ri_emuwidth - 1;
561: fbc->fbc_y3 = ri->ri_yorigin + dst + n - 1;
562: CG6_BLIT_WAIT(fbc);
563: CG6_DRAIN(fbc);
564: }
565:
566: void
567: cgsix_ras_copycols(void *cookie, int row, int src, int dst, int n)
568: {
569: struct rasops_info *ri = cookie;
570: struct cgsix_softc *sc = ri->ri_hw;
571: volatile struct cgsix_fbc *fbc = sc->sc_fbc;
572:
573: if (dst == src)
574: return;
575: if ((row < 0) || (row >= ri->ri_rows))
576: return;
577: if (src < 0) {
578: n += src;
579: src = 0;
580: }
581: if (src + n > ri->ri_cols)
582: n = ri->ri_cols - src;
583: if (dst < 0) {
584: n += dst;
585: dst = 0;
586: }
587: if (dst + n > ri->ri_cols)
588: n = ri->ri_cols - dst;
589: if (n <= 0)
590: return;
591: n *= ri->ri_font->fontwidth;
592: src *= ri->ri_font->fontwidth;
593: dst *= ri->ri_font->fontwidth;
594: row *= ri->ri_font->fontheight;
595:
596: fbc->fbc_clip = 0;
597: fbc->fbc_s = 0;
598: fbc->fbc_offx = 0;
599: fbc->fbc_offy = 0;
600: fbc->fbc_clipminx = 0;
601: fbc->fbc_clipminy = 0;
602: fbc->fbc_clipmaxx = ri->ri_width - 1;
603: fbc->fbc_clipmaxy = ri->ri_height - 1;
604: fbc->fbc_alu = FBC_ALU_COPY;
605: fbc->fbc_x0 = ri->ri_xorigin + src;
606: fbc->fbc_y0 = ri->ri_yorigin + row;
607: fbc->fbc_x1 = ri->ri_xorigin + src + n - 1;
608: fbc->fbc_y1 = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
609: fbc->fbc_x2 = ri->ri_xorigin + dst;
610: fbc->fbc_y2 = ri->ri_yorigin + row;
611: fbc->fbc_x3 = ri->ri_xorigin + dst + n - 1;
612: fbc->fbc_y3 = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
613: CG6_BLIT_WAIT(fbc);
614: CG6_DRAIN(fbc);
615: }
616:
617: void
618: cgsix_ras_erasecols(void *cookie, int row, int col, int n, long attr)
619: {
620: struct rasops_info *ri = cookie;
621: struct cgsix_softc *sc = ri->ri_hw;
622: volatile struct cgsix_fbc *fbc = sc->sc_fbc;
623: int fg, bg;
624:
625: if ((row < 0) || (row >= ri->ri_rows))
626: return;
627: if (col < 0) {
628: n += col;
629: col = 0;
630: }
631: if (col + n > ri->ri_cols)
632: n = ri->ri_cols - col;
633: if (n <= 0)
634: return;
635: n *= ri->ri_font->fontwidth;
636: col *= ri->ri_font->fontwidth;
637: row *= ri->ri_font->fontheight;
638:
639: ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
640:
641: fbc->fbc_clip = 0;
642: fbc->fbc_s = 0;
643: fbc->fbc_offx = 0;
644: fbc->fbc_offy = 0;
645: fbc->fbc_clipminx = 0;
646: fbc->fbc_clipminy = 0;
647: fbc->fbc_clipmaxx = ri->ri_width - 1;
648: fbc->fbc_clipmaxy = ri->ri_height - 1;
649: fbc->fbc_alu = FBC_ALU_FILL;
650: fbc->fbc_fg = ri->ri_devcmap[bg];
651: fbc->fbc_arecty = ri->ri_yorigin + row;
652: fbc->fbc_arectx = ri->ri_xorigin + col;
653: fbc->fbc_arecty = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
654: fbc->fbc_arectx = ri->ri_xorigin + col + n - 1;
655: CG6_DRAW_WAIT(fbc);
656: CG6_DRAIN(fbc);
657: }
658:
659: void
660: cgsix_ras_eraserows(void *cookie, int row, int n, long attr)
661: {
662: struct rasops_info *ri = cookie;
663: struct cgsix_softc *sc = ri->ri_hw;
664: volatile struct cgsix_fbc *fbc = sc->sc_fbc;
665: int fg, bg;
666:
667: if (row < 0) {
668: n += row;
669: row = 0;
670: }
671: if (row + n > ri->ri_rows)
672: n = ri->ri_rows - row;
673: if (n <= 0)
674: return;
675:
676: ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
677:
678: fbc->fbc_clip = 0;
679: fbc->fbc_s = 0;
680: fbc->fbc_offx = 0;
681: fbc->fbc_offy = 0;
682: fbc->fbc_clipminx = 0;
683: fbc->fbc_clipminy = 0;
684: fbc->fbc_clipmaxx = ri->ri_width - 1;
685: fbc->fbc_clipmaxy = ri->ri_height - 1;
686: fbc->fbc_alu = FBC_ALU_FILL;
687: fbc->fbc_fg = ri->ri_devcmap[bg];
688: if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
689: fbc->fbc_arecty = 0;
690: fbc->fbc_arectx = 0;
691: fbc->fbc_arecty = ri->ri_height - 1;
692: fbc->fbc_arectx = ri->ri_width - 1;
693: } else {
694: row *= ri->ri_font->fontheight;
695: fbc->fbc_arecty = ri->ri_yorigin + row;
696: fbc->fbc_arectx = ri->ri_xorigin;
697: fbc->fbc_arecty =
698: ri->ri_yorigin + row + (n * ri->ri_font->fontheight) - 1;
699: fbc->fbc_arectx =
700: ri->ri_xorigin + ri->ri_emuwidth - 1;
701: }
702: CG6_DRAW_WAIT(fbc);
703: CG6_DRAIN(fbc);
704: }
705:
706: void
707: cgsix_ras_do_cursor(struct rasops_info *ri)
708: {
709: struct cgsix_softc *sc = ri->ri_hw;
710: int row, col;
711: volatile struct cgsix_fbc *fbc = sc->sc_fbc;
712:
713: row = ri->ri_crow * ri->ri_font->fontheight;
714: col = ri->ri_ccol * ri->ri_font->fontwidth;
715: fbc->fbc_clip = 0;
716: fbc->fbc_s = 0;
717: fbc->fbc_offx = 0;
718: fbc->fbc_offy = 0;
719: fbc->fbc_clipminx = 0;
720: fbc->fbc_clipminy = 0;
721: fbc->fbc_clipmaxx = ri->ri_width - 1;
722: fbc->fbc_clipmaxy = ri->ri_height - 1;
723: fbc->fbc_alu = FBC_ALU_FLIP;
724: fbc->fbc_arecty = ri->ri_yorigin + row;
725: fbc->fbc_arectx = ri->ri_xorigin + col;
726: fbc->fbc_arecty = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
727: fbc->fbc_arectx = ri->ri_xorigin + col + ri->ri_font->fontwidth - 1;
728: CG6_DRAW_WAIT(fbc);
729: CG6_DRAIN(fbc);
730: }
CVSweb