Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc/dev use SX for basic hardware acceleration



details:   https://anonhg.NetBSD.org/src/rev/a4b319a66a0e
branches:  trunk
changeset: 784700:a4b319a66a0e
user:      macallan <macallan%NetBSD.org@localhost>
date:      Wed Feb 06 04:10:54 2013 +0000

description:
use SX for basic hardware acceleration
not quite complete yet but good enough to be useful
missing things include:
- backwards blits
- ROP support
- the cursor is still drawn by software

diffstat:

 sys/arch/sparc/dev/cgfourteen.c    |  478 ++++++++++++++++++++++++++++++++++++-
 sys/arch/sparc/dev/cgfourteenvar.h |    6 +-
 2 files changed, 478 insertions(+), 6 deletions(-)

diffs (truncated from 568 to 300 lines):

diff -r 3193d4253e20 -r a4b319a66a0e sys/arch/sparc/dev/cgfourteen.c
--- a/sys/arch/sparc/dev/cgfourteen.c   Wed Feb 06 04:06:29 2013 +0000
+++ b/sys/arch/sparc/dev/cgfourteen.c   Wed Feb 06 04:10:54 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cgfourteen.c,v 1.69 2013/02/05 21:45:39 macallan Exp $ */
+/*     $NetBSD: cgfourteen.c,v 1.70 2013/02/06 04:10:54 macallan Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -53,8 +53,6 @@
 
 /*
  * Driver for Campus-II on-board mbus-based video (cgfourteen).
- * Provides minimum emulation of a Sun cgthree 8-bit framebuffer to
- * allow X to run.
  *
  * Does not handle interrupts, even though they can occur.
  *
@@ -68,6 +66,9 @@
  */
 #undef CG14_MAP_REGS
 
+#include "opt_wsemul.h"
+#include "sx.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/buf.h>
@@ -96,10 +97,11 @@
 
 #include <dev/wscons/wsdisplay_vconsvar.h>
 
+#include <sparc/sparc/asm.h>
 #include <sparc/dev/cgfourteenreg.h>
 #include <sparc/dev/cgfourteenvar.h>
-
-#include "opt_wsemul.h"
+#include <sparc/dev/sxreg.h>
+#include <sparc/dev/sxvar.h>
 
 /* autoconfiguration driver */
 static int     cgfourteenmatch(device_t, struct cfdata *, void *);
@@ -145,6 +147,23 @@
 static void cg14_move_cursor(struct cgfourteen_softc *, int, int);
 static int  cg14_do_cursor(struct cgfourteen_softc *,
                            struct wsdisplay_cursor *);
+
+#if NSX > 0
+static void cg14_wait_idle(struct cgfourteen_softc *);
+static void cg14_rectfill(struct cgfourteen_softc *, int, int, int, int, uint32_t);
+static void cg14_bitblt(void *, int, int, int, int, int, int, int);
+
+#if 0
+static void cg14_cursor(void *, int, int, int);
+static void cg14_putchar_aa(void *, int, int, u_int, long);
+#endif
+static void cg14_putchar(void *, int, int, u_int, long);
+static void cg14_copycols(void *, int, int, int, int);
+static void cg14_erasecols(void *, int, int, int, long);
+static void cg14_copyrows(void *, int, int, int);
+static void cg14_eraserows(void *, int, int, long);
+#endif /* NSX > 0 */
+
 #endif
 
 /*
@@ -212,6 +231,10 @@
        int i, isconsole, items;
        uint32_t fbva[2] = {0, 0};
        uint32_t *ptr = fbva;
+#if NSX > 0
+       device_t dv;
+       deviter_t di;
+#endif
 
        sc->sc_dev = self;
        sc->sc_opens = 0;
@@ -320,6 +343,32 @@
                printf("\n");
 
        sc->sc_depth = 8;
+
+#if NSX > 0
+       /* see if we've got an SX to help us */
+       sc->sc_sx = NULL;
+       for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
+           dv != NULL;
+           dv = deviter_next(&di)) {
+               if (device_is_a(dv, "sx")) {
+                       sc->sc_sx = device_private(dv);
+               }
+       }
+       deviter_release(&di);
+       if (sc->sc_sx != NULL) {
+               sc->sc_fb_paddr = bus_space_mmap(sc->sc_bustag,
+                   sc->sc_fbaddr, 0, 0, 0) & 0xfffff000;
+               aprint_normal_dev(sc->sc_dev, "using %s\n", 
+                   device_xname(sc->sc_sx->sc_dev));
+               aprint_normal_dev(sc->sc_dev, "fb paddr: %08x\n",
+                   sc->sc_fb_paddr);
+#if 0
+               sx_write(sc->sc_sx, SX_PAGE_BOUND_LOWER, sc->sc_fb_paddr);
+               sx_write(sc->sc_sx, SX_PAGE_BOUND_UPPER,
+                   sc->sc_fb_paddr + 0x03ffffff);
+#endif
+       }
+#endif
        cg14_setup_wsdisplay(sc, isconsole);
 #endif
 
@@ -962,6 +1011,9 @@
        ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
 
        ri->ri_bits = (char *)sc->sc_fb.fb_pixels;
+#if NSX > 0
+       if (sc->sc_sx == NULL)
+#endif
        scr->scr_flags |= VCONS_DONT_READ;
 
        if (existing) {
@@ -976,6 +1028,21 @@
            sc->sc_fb.fb_type.fb_width / ri->ri_font->fontwidth);
 
        ri->ri_hw = scr;
+#if NSX > 0
+       if (sc->sc_sx != NULL) {
+               ri->ri_ops.copyrows = cg14_copyrows;
+               ri->ri_ops.copycols = cg14_copycols;
+               ri->ri_ops.eraserows = cg14_eraserows;
+               ri->ri_ops.erasecols = cg14_erasecols;
+#if 0
+               ri->ri_ops.cursor = cg14_cursor;
+               if (FONT_IS_ALPHA(ri->ri_font)) {
+                       ri->ri_ops.putchar = cg14_putchar_aa;
+               } else
+#endif
+                       ri->ri_ops.putchar = cg14_putchar;
+       }
+#endif /* NSX > 0 */
 }
 
 static void
@@ -1104,4 +1171,405 @@
        }
        return 0;
 }
+
+#if NSX > 0
+
+static void
+cg14_wait_idle(struct cgfourteen_softc *sc)
+{
+}
+
+static void
+cg14_rectfill(struct cgfourteen_softc *sc, int x, int y, int wi, int he,
+     uint32_t colour)
+{
+       uint32_t addr, pptr;
+       int line, cnt;
+       int stride = sc->sc_fb.fb_type.fb_width;
+
+       addr = sc->sc_fb_paddr + x + stride * y;
+       sx_write(sc->sc_sx, SX_QUEUED(8), colour);
+       sx_write(sc->sc_sx, SX_QUEUED(9), colour);
+       for (line = 0; line < he; line++) {
+               pptr = addr;
+               cnt = wi;
+               while(cnt > 32) {
+                       sta(pptr, ASI_SX, SX_STBS(8, 31, pptr & 7));
+                       pptr += 32;
+                       cnt -= 32;
+               }
+               if (cnt > 0)
+                       sta(pptr, ASI_SX, SX_STBS(8, cnt - 1, pptr & 7));
+               addr += stride;
+       }
+       cg14_wait_idle(sc);
+}
+
+static void
+cg14_bitblt(void *cookie, int xs, int ys, int xd, int yd,
+    int wi, int he, int rop)
+{
+       struct cgfourteen_softc *sc = cookie;
+       uint32_t saddr, daddr, sptr, dptr;
+       int line, cnt, stride = sc->sc_fb.fb_type.fb_width;
+
+       saddr = sc->sc_fb_paddr + xs + stride * ys;
+       daddr = sc->sc_fb_paddr + xd + stride * yd;
+       if ((saddr & 3) == (daddr & 3)) {
+               int pre = saddr & 3;    /* pixels to copy byte-wise */
+               if (pre != 0) pre = 4 - pre;
+               for (line = 0; line < he; line++) {
+                       sptr = saddr;
+                       dptr = daddr;
+                       cnt = wi;
+                       if (pre > 0) {
+                               sta(sptr, ASI_SX, SX_LDB(32, pre - 1, sptr & 7));
+                               sta(dptr, ASI_SX, SX_STB(32, pre - 1, dptr & 7));
+                               cnt -= pre;
+                               sptr += pre;
+                               dptr += pre;
+                       }
+                       while(cnt > 128) {
+                               sta(sptr, ASI_SX, SX_LD(32, 31, sptr & 7));
+                               sta(dptr, ASI_SX, SX_ST(32, 31, dptr & 7));
+                               sptr += 128;
+                               dptr += 128;
+                               cnt -= 128;
+                       }
+                       if (cnt > 3) {
+                               int words = cnt >> 2;
+                               sta(sptr, ASI_SX, SX_LD(32, words - 1, sptr & 7));
+                               sta(dptr, ASI_SX, SX_ST(32, words - 1, dptr & 7));
+                               sptr += words << 2;
+                               dptr += words << 2;
+                               cnt -= words << 2;
+                       }
+                       if (cnt > 0) {
+                               sta(sptr, ASI_SX, SX_LDB(32, cnt - 1, sptr & 7));
+                               sta(dptr, ASI_SX, SX_STB(32, cnt - 1, dptr & 7));
+                       }
+                       saddr += stride;
+                       daddr += stride;
+               }
+       } else {
+               /* unaligned, have to use byte mode */
+               for (line = 0; line < he; line++) {
+                       sptr = saddr;
+                       dptr = daddr;
+                       cnt = wi;
+                       while(cnt > 32) {
+                               sta(sptr, ASI_SX, SX_LDB(32, 31, sptr & 7));
+                               sta(dptr, ASI_SX, SX_STB(32, 31, dptr & 7));
+                               sptr += 32;
+                               dptr += 32;
+                               cnt -= 32;
+                       }
+                       if (cnt > 0) {
+                               sta(sptr, ASI_SX, SX_LDB(32, cnt - 1, sptr & 7));
+                               sta(dptr, ASI_SX, SX_STB(32, cnt - 1, dptr & 7));
+                       }
+                       saddr += stride;
+                       daddr += stride;
+               }
+       }
+       cg14_wait_idle(sc);
+}
+
+
+static void
+cg14_putchar(void *cookie, int row, int col, u_int c, long attr)
+{
+       struct rasops_info *ri = cookie;
+       struct wsdisplay_font *font = PICK_FONT(ri, c);
+       struct vcons_screen *scr = ri->ri_hw;
+       struct cgfourteen_softc *sc = scr->scr_cookie;
+       void *data;
+       uint32_t fg, bg;
+       int i, x, y, wi, he;
+       uint32_t addr;
+       int stride = sc->sc_fb.fb_type.fb_width;
+
+       if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) 
+               return;
+
+       if (!CHAR_IN_FONT(c, font))
+               return;
+
+       wi = font->fontwidth;
+       he = font->fontheight;
+
+       bg = ri->ri_devcmap[(attr >> 16) & 0xf];
+       fg = ri->ri_devcmap[(attr >> 24) & 0xf];
+       sx_write(sc->sc_sx, SX_QUEUED(8), bg);
+       sx_write(sc->sc_sx, SX_QUEUED(9), fg);
+
+       x = ri->ri_xorigin + col * wi;
+       y = ri->ri_yorigin + row * he;
+
+       if (c == 0x20) {
+               cg14_rectfill(sc, x, y, wi, he, bg);
+               return;
+       }
+
+       data = WSFONT_GLYPH(c, font);
+       addr = sc->sc_fb_paddr + x + stride * y;
+
+       switch (font->stride) {
+               case 1: {
+                       uint8_t *data8 = data;
+                       uint32_t reg;
+                       for (i = 0; i < he; i++) {
+                               reg = *data8;
+                               sx_write(sc->sc_sx, SX_QUEUED(R_MASK), reg << 24);
+                               sta(addr, ASI_SX, SX_STBS(8, wi - 1, addr & 7));
+                               data8++;
+                               addr += stride;
+                       }



Home | Main Index | Thread Index | Old Index