Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sgimips/dev - remove scratch area, it's been unused...



details:   https://anonhg.NetBSD.org/src/rev/d568e6b3b0a6
branches:  trunk
changeset: 805814:d568e6b3b0a6
user:      macallan <macallan%NetBSD.org@localhost>
date:      Tue Jan 20 12:13:04 2015 +0000

description:
- remove scratch area, it's been unused since we're drawing characters by
  hardware
- don't sync the rendering engine unless we have to, watch FIFO levels
  instead
- support anti-aliased fonts and let the drawing engine do all the work

diffstat:

 sys/arch/sgimips/dev/crmfb.c    |  267 +++++++++++++++++++++++++++++++++------
 sys/arch/sgimips/dev/crmfbreg.h |   11 +-
 2 files changed, 231 insertions(+), 47 deletions(-)

diffs (truncated from 482 to 300 lines):

diff -r f69b01e9bb19 -r d568e6b3b0a6 sys/arch/sgimips/dev/crmfb.c
--- a/sys/arch/sgimips/dev/crmfb.c      Tue Jan 20 07:12:41 2015 +0000
+++ b/sys/arch/sgimips/dev/crmfb.c      Tue Jan 20 12:13:04 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: crmfb.c,v 1.38 2014/09/02 15:44:44 macallan Exp $ */
+/* $NetBSD: crmfb.c,v 1.39 2015/01/20 12:13:04 macallan Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: crmfb.c,v 1.38 2014/09/02 15:44:44 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: crmfb.c,v 1.39 2015/01/20 12:13:04 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -154,7 +154,10 @@
        int                     sc_mte_x_shift;
        uint32_t                sc_mte_mode;
        uint32_t                sc_de_mode;
-       uint8_t                 *sc_scratch;
+       uint32_t                sc_src_mode;
+       uint32_t                sc_dst_mode;
+       int                     sc_needs_sync;
+       uint8_t                 *sc_lptr;
        paddr_t                 sc_linear;
        uint32_t                sc_vtflags;
        int                     sc_wsmode, sc_video_on;
@@ -198,6 +201,7 @@
 static void    crmfb_eraserows(void *, int, int, long);
 static void    crmfb_cursor(void *, int, int, int);
 static void    crmfb_putchar(void *, int, int, u_int, long);
+static void    crmfb_putchar_aa(void *, int, int, u_int, long);
 
 /* I2C glue */
 static int crmfb_i2c_acquire_bus(void *, int);
@@ -336,8 +340,8 @@
        if (rv)
                panic("crmfb_attach: can't load DMA map");
 
-       /* allocate an extra 64Kb for a linear buffer */
-       sc->sc_dma.size = 0x10000 * (16 * sc->sc_tiles_x + 1);
+       /* allocate an extra 128Kb for a linear buffer */
+       sc->sc_dma.size = 0x10000 * (16 * sc->sc_tiles_x + 2);
        rv = bus_dmamem_alloc(sc->sc_dmat, sc->sc_dma.size, 65536, 0,
            sc->sc_dma.segs,
            sizeof(sc->sc_dma.segs) / sizeof(sc->sc_dma.segs[0]),
@@ -365,8 +369,8 @@
        }
        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmai.map, 0, sc->sc_dmai.size,
            BUS_DMASYNC_PREWRITE);
-       sc->sc_scratch = (char *)KERNADDR(sc->sc_dma) + (0xf0000 * sc->sc_tiles_x);
        sc->sc_linear = (paddr_t)DMAADDR(sc->sc_dma) + 0x100000 * sc->sc_tiles_x;
+       sc->sc_lptr =  (char *)KERNADDR(sc->sc_dma) + (0x100000 * sc->sc_tiles_x);
 
        aprint_normal_dev(sc->sc_dev, "allocated %d byte fb @ %p (%p)\n", 
            sc->sc_fbsize, KERNADDR(sc->sc_dmai), KERNADDR(sc->sc_dma));
@@ -580,8 +584,8 @@
        /* now the actual engine registers */
        if ((offset >= 0x15002000) && (offset < 0x15005000))
                return bus_space_mmap(sc->sc_iot, offset, 0, prot, 0);
-       /* and now the scratch area */
-       if ((offset >= 0x15010000) && (offset < 0x15020000))
+       /* and now the linear area */
+       if ((offset >= 0x15010000) && (offset < 0x15030000))
                return bus_dmamem_mmap(sc->sc_dmat, sc->sc_dma.segs,
                     sc->sc_dma.nsegs,
                     offset + (0x100000 * sc->sc_tiles_x) - 0x15010000,
@@ -599,7 +603,7 @@
        sc = (struct crmfb_softc *)c;
        ri = &scr->scr_ri;
 
-       ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
+       ri->ri_flg = RI_CENTER | RI_FULLCLEAR | RI_ENABLE_ALPHA;
        ri->ri_depth = sc->sc_console_depth;
        ri->ri_width = sc->sc_width;
        ri->ri_height = sc->sc_height;
@@ -639,8 +643,11 @@
        ri->ri_ops.eraserows = crmfb_eraserows;
        ri->ri_ops.copycols  = crmfb_copycols;
        ri->ri_ops.erasecols = crmfb_erasecols;
-       ri->ri_ops.putchar   = crmfb_putchar;
-
+       if (FONT_IS_ALPHA(ri->ri_font)) {
+               ri->ri_ops.putchar   = crmfb_putchar_aa;
+       } else {
+               ri->ri_ops.putchar   = crmfb_putchar;
+       }
        return;
 }
 
@@ -831,6 +838,61 @@
        return bus_space_read_4(sc->sc_iot, sc->sc_ioh, offset);
 }
 
+static inline void
+crmfb_wait_idle(struct crmfb_softc *sc)
+{
+       int i = 0;
+
+       do {
+               i++;
+       } while (((bus_space_read_4(sc->sc_iot, sc->sc_reh, CRIME_DE_STATUS) &
+                  CRIME_DE_IDLE) == 0) && (i < 100000000));
+       if (i >= 100000000)
+               aprint_error("crmfb_wait_idle() timed out\n");
+       sc->sc_needs_sync = 0;
+}
+
+/* writes to CRIME_DE_MODE_* only take effect when the engine is idle */
+
+static inline void
+crmfb_src_mode(struct crmfb_softc *sc, uint32_t mode)
+{
+       if (mode == sc->sc_src_mode)
+               return;
+       bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_SRC, mode);
+       sc->sc_needs_sync = 1;
+       sc->sc_src_mode = mode;
+}
+
+static inline void
+crmfb_dst_mode(struct crmfb_softc *sc, uint32_t mode)
+{
+       if (mode == sc->sc_dst_mode)
+               return;
+       bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_DST, mode);
+       sc->sc_needs_sync = 1;
+       sc->sc_dst_mode = mode;
+}
+
+static inline void
+crmfb_make_room(struct crmfb_softc *sc, int num)
+{
+       int i = 0, slots;
+       uint32_t status;
+
+       if (sc->sc_needs_sync != 0) {
+               crmfb_wait_idle(sc);
+               return;
+       }
+
+       do {
+               i++;
+               status = bus_space_read_4(sc->sc_iot, sc->sc_reh,
+                   CRIME_DE_STATUS);
+               slots = 60 - CRIME_PIPE_LEVEL(status);
+       } while (slots <= num);
+}
+
 static int
 crmfb_wait_dma_idle(struct crmfb_softc *sc)
 {
@@ -1022,12 +1084,11 @@
                }
                tlbptr += 32;
        }
-       sc->sc_scratch = (char *)KERNADDR(sc->sc_dma) + (0xf0000 * tx);
 
-       /* now put the last 64kB into the 1st linear TLB */
+       /* now put the last 128kB into the 1st linear TLB */
        page = (sc->sc_linear >> 12) | 0x80000000;
        tlbptr = 0;
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < 16; i++) {
                reg = ((uint64_t)page << 32) | (page + 1);
                bus_space_write_8(sc->sc_iot, sc->sc_reh,
                    CRIME_RE_LINEAR_A + tlbptr, reg);
@@ -1081,10 +1142,13 @@
                        panic("%s: unsuported colour depth %d\n", __func__,
                            depth);
        }
-       bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_DST,
-           sc->sc_de_mode);
-       bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_SRC,
-           sc->sc_de_mode);
+       sc->sc_needs_sync = 0;
+       sc->sc_src_mode = 0xffffffff;
+       sc->sc_dst_mode = 0xffffffff;
+
+       crmfb_src_mode(sc, sc->sc_de_mode);
+       crmfb_dst_mode(sc, sc->sc_de_mode);
+
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_STEP_X, 1);
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_STEP_Y, 1);
 
@@ -1104,6 +1168,7 @@
        if (dir == sc->sc_mte_direction)
                return;
 
+       crmfb_make_room(sc, 2);
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_DST_Y_STEP, dir);
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_SRC_Y_STEP, dir);
        sc->sc_mte_direction = dir;
@@ -1112,7 +1177,9 @@
 static void
 crmfb_setup_palette(struct crmfb_softc *sc)
 {
-       int i;
+       int i, j, x;
+       uint32_t col;
+       struct rasops_info *ri = &crmfb_console_screen.scr_ri;
 
        for (i = 0; i < 256; i++) {
                crmfb_set_palette(sc, i, rasops_cmap[(i * 3) + 2],
@@ -1121,19 +1188,41 @@
                sc->sc_cmap_green[i] = rasops_cmap[(i * 3) + 1];
                sc->sc_cmap_blue[i] = rasops_cmap[(i * 3) + 0];
        }
-}
 
-static inline void
-crmfb_wait_idle(struct crmfb_softc *sc)
-{
-       int i = 0;
+       if (FONT_IS_ALPHA(ri->ri_font)) {       
+               sc->sc_de_mode =
+                   (sc->sc_de_mode & ~DE_MODE_TYPE_MASK) | DE_MODE_TYPE_RGB;
+       }
 
-       do {
-               i++;
-       } while (((bus_space_read_4(sc->sc_iot, sc->sc_reh, CRIME_DE_STATUS) &
-                  CRIME_DE_IDLE) == 0) && (i < 100000000));
-       if (i >= 100000000)
-               aprint_error("crmfb_wait_idle() timed out\n");
+       /* draw 16 character cells in 32bit RGBA for alpha blending */
+       crmfb_make_room(sc, 3);
+       crmfb_dst_mode(sc,
+           DE_MODE_TLB_A |
+           DE_MODE_BUFDEPTH_32 |
+           DE_MODE_TYPE_RGBA |
+           DE_MODE_PIXDEPTH_32);
+       bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_DRAWMODE,
+           DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK);
+       bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_PRIMITIVE,
+           DE_PRIM_RECTANGLE | DE_PRIM_TB);
+       j = 0;
+       x = 0;
+       for (i = 0; i < 16; i++) {
+               crmfb_make_room(sc, 2);
+               col = (rasops_cmap[j] << 24) | 
+                     (rasops_cmap[j + 1] << 16) | 
+                     (rasops_cmap[j + 2] << 8);
+               bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_FG, col);
+               bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_X_VERTEX_0,
+                   (x << 16) | ((sc->sc_height - 500) & 0xffff));
+               bus_space_write_4(sc->sc_iot, sc->sc_reh,
+                   CRIME_DE_X_VERTEX_1 | CRIME_DE_START,
+                   ((x + ri->ri_font->fontwidth - 1)  << 16) |
+                   ((sc->sc_height + ri->ri_font->fontheight - 1) & 0xffff));
+               j += 3;
+               x += ri->ri_font->fontwidth;
+       }
+       crmfb_dst_mode(sc, sc->sc_de_mode);
 }
 
 static void
@@ -1144,8 +1233,8 @@
 
        rxa = x << sc->sc_mte_x_shift;
        rxe = ((x + width) << sc->sc_mte_x_shift) - 1;
-       crmfb_wait_idle(sc);
        crmfb_set_mte_direction(sc, 1);
+       crmfb_make_room(sc, 4);
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_MODE,
            sc->sc_mte_mode | 0);
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_BG, colour);
@@ -1162,9 +1251,9 @@
 {
        uint32_t prim = DE_PRIM_RECTANGLE;
        int rxa, rya, rxe, rye, rxs, rys;
-       crmfb_wait_idle(sc);
-       bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_MODE_SRC,
-           sc->sc_de_mode);
+       crmfb_make_room(sc, 2);
+       crmfb_src_mode(sc, sc->sc_de_mode);
+       crmfb_make_room(sc, 6);
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_DRAWMODE,
            DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP |
            DE_DRAWMODE_XFER_EN);
@@ -1212,7 +1301,7 @@
        rxe = ((xs + wi) << sc->sc_mte_x_shift) - 1;
        rxde = ((xd + wi) << sc->sc_mte_x_shift) - 1;
 
-       crmfb_wait_idle(sc);
+       crmfb_make_room(sc, 1);
 
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_MODE,
            sc->sc_mte_mode | MTE_MODE_COPY);
@@ -1232,6 +1321,7 @@
                ryde = yd + he - 1;
                crmfb_set_mte_direction(sc, 1);
        }
+       crmfb_make_room(sc, 4);
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_SRC0,
            (rxa << 16) | rya);
        bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_MTE_SRC1,



Home | Main Index | Thread Index | Old Index