Module Name:    src
Committed By:   macallan
Date:           Tue Jan 20 12:13:04 UTC 2015

Modified Files:
        src/sys/arch/sgimips/dev: crmfb.c crmfbreg.h

Log Message:
- 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


To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/sgimips/dev/crmfb.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/sgimips/dev/crmfbreg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sgimips/dev/crmfb.c
diff -u src/sys/arch/sgimips/dev/crmfb.c:1.38 src/sys/arch/sgimips/dev/crmfb.c:1.39
--- src/sys/arch/sgimips/dev/crmfb.c:1.38	Tue Sep  2 15:44:44 2014
+++ src/sys/arch/sgimips/dev/crmfb.c	Tue Jan 20 12:13:04 2015
@@ -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 <[email protected]>
@@ -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 @@ struct crmfb_softc {
 	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_copyrows(void *, int, 
 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 @@ crmfb_attach(device_t parent, device_t s
 	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 @@ crmfb_attach(device_t parent, device_t s
 	}
 	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 @@ crmfb_mmap(void *v, void *vs, off_t offs
 	/* 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 @@ crmfb_init_screen(void *c, struct vcons_
 	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 @@ crmfb_init_screen(void *c, struct vcons_
 	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 @@ crmfb_read_reg(struct crmfb_softc *sc, i
 	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 @@ crmfb_setup_video(struct crmfb_softc *sc
 		}
 		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 @@ crmfb_setup_video(struct crmfb_softc *sc
 			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 @@ crmfb_set_mte_direction(struct crmfb_sof
 	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 @@ crmfb_set_mte_direction(struct crmfb_sof
 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 @@ crmfb_setup_palette(struct crmfb_softc *
 		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 @@ crmfb_fill_rect(struct crmfb_softc *sc, 
 
 	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 @@ crmfb_bitblt(struct crmfb_softc *sc, int
 {
 	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 @@ crmfb_scroll(struct crmfb_softc *sc, int
 	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 @@ crmfb_scroll(struct crmfb_softc *sc, int
 		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,
@@ -1367,7 +1457,7 @@ crmfb_putchar(void *cookie, int row, int
 	if (c == 0x20) {
 		crmfb_fill_rect(sc, x, y, wi, he, bg);
 	} else {
-		crmfb_wait_idle(sc);
+		crmfb_make_room(sc, 6);
 		/* setup */
 		bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_DRAWMODE,
 		    DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK |
@@ -1382,14 +1472,13 @@ crmfb_putchar(void *cookie, int row, int
 		bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_STIPPLE_MODE,
 		    0x001f0000);
 		/* now let's feed the engine */
+		crmfb_make_room(sc, 30);
 		if (font->stride == 1) {
 			/* shovel in 8 bit quantities */
 			fd8 = fd;
 			for (i = 0; i < he; i++) {
-				/*
-				 * the pipeline should be long enough to
-				 * draw any character without having to wait
-				 */
+				if (i & 8)
+					crmfb_make_room(sc, 30); 
 				bus_space_write_4(sc->sc_iot, sc->sc_reh, 
 				    CRIME_DE_STIPPLE_PAT, *fd8 << 24);
 				bus_space_write_4(sc->sc_iot, sc->sc_reh,
@@ -1404,10 +1493,8 @@ crmfb_putchar(void *cookie, int row, int
 			/* shovel in 16 bit quantities */
 			fd16 = fd;
 			for (i = 0; i < he; i++) {
-				/*
-				 * the pipeline should be long enough to
-				 * draw any character without having to wait
-				 */
+				if (i & 8)
+					crmfb_make_room(sc, 30); 
 				bus_space_write_4(sc->sc_iot, sc->sc_reh, 
 				    CRIME_DE_STIPPLE_PAT, *fd16 << 16);
 				bus_space_write_4(sc->sc_iot, sc->sc_reh,
@@ -1423,6 +1510,97 @@ crmfb_putchar(void *cookie, int row, int
 }
 
 static void
+crmfb_putchar_aa(void *cookie, int row, int col, u_int c, long attr)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct crmfb_softc *sc = scr->scr_cookie;
+	struct wsdisplay_font *font = PICK_FONT(ri, c);
+	uint32_t bg, fg;
+	int x, y, wi, he, uc, xx;
+	void *fd;
+
+	wi = font->fontwidth;
+	he = font->fontheight;
+
+	x = ri->ri_xorigin + col * wi;
+	y = ri->ri_yorigin + row * he;
+
+	bg = ri->ri_devcmap[(attr >> 16) & 0xff];
+	fg = (attr >> 24);
+	uc = c - font->firstchar;
+	fd = (uint8_t *)font->data + uc * ri->ri_fontscale;
+
+	/* fill the cell with the background colour */
+	crmfb_fill_rect(sc, x, y, wi, he, bg);
+
+	/* if all we draw is a space we're done */
+	if (c == 0x20)
+		return;
+
+	/* copy the glyph into the linear buffer */
+	memcpy(sc->sc_lptr, fd, ri->ri_fontscale);
+	wbflush();
+
+	/* now blit it on top of the requested fg colour cell */
+	xx = fg * wi;
+	crmfb_make_room(sc, 2);
+	crmfb_src_mode(sc,
+	    DE_MODE_LIN_A |
+	    DE_MODE_BUFDEPTH_8 |
+	    DE_MODE_TYPE_CI |
+	    DE_MODE_PIXDEPTH_8);
+	crmfb_dst_mode(sc,
+	    DE_MODE_TLB_A |
+	    DE_MODE_BUFDEPTH_32 |
+	    DE_MODE_TYPE_CI |
+	    DE_MODE_PIXDEPTH_8);
+
+	crmfb_make_room(sc, 6);
+	/* only write into the alpha channel */
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_DRAWMODE,
+	    DE_DRAWMODE_PLANEMASK | 0x08 |
+	    DE_DRAWMODE_XFER_EN);
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_PRIMITIVE,
+	    DE_PRIM_RECTANGLE | DE_PRIM_TB);
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_STRD_SRC, 1);
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_ADDR_SRC, 0);
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_X_VERTEX_0,
+	    (xx << 16) | (sc->sc_height & 0xffff));
+	bus_space_write_4(sc->sc_iot, sc->sc_reh,
+	    CRIME_DE_X_VERTEX_1 | CRIME_DE_START,
+	    ((xx + wi - 1) << 16) | ((sc->sc_height + he - 1) & 0xffff));
+
+	/* now draw the actual character */
+	crmfb_make_room(sc, 2);
+	crmfb_src_mode(sc,
+	    DE_MODE_TLB_A |
+	    DE_MODE_BUFDEPTH_32 |
+	    DE_MODE_TYPE_RGBA |
+	    DE_MODE_PIXDEPTH_32);
+	crmfb_dst_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_ALPHA_BLEND |
+	    DE_DRAWMODE_XFER_EN);
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_ALPHA_FUNC, 
+	    DE_ALPHA_ADD |
+	    (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) |
+	    (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT));
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_PRIMITIVE,
+	    DE_PRIM_RECTANGLE | DE_PRIM_TB);
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_XFER_ADDR_SRC, 
+	    (xx << 16) | (sc->sc_height & 0xffff));
+	bus_space_write_4(sc->sc_iot, sc->sc_reh, CRIME_DE_X_VERTEX_0,
+	    (x << 16) | (y & 0xffff));
+	bus_space_write_4(sc->sc_iot, sc->sc_reh,
+	    CRIME_DE_X_VERTEX_1 | CRIME_DE_START,
+	    ((x + wi - 1) << 16) | ((y + he - 1) & 0xffff));
+}
+
+static void
 crmfb_setup_ddc(struct crmfb_softc *sc)
 {
 	int i;
@@ -1679,4 +1857,3 @@ crmfb_set_mode(struct crmfb_softc *sc, c
 
 	return TRUE;
 }
-

Index: src/sys/arch/sgimips/dev/crmfbreg.h
diff -u src/sys/arch/sgimips/dev/crmfbreg.h:1.15 src/sys/arch/sgimips/dev/crmfbreg.h:1.16
--- src/sys/arch/sgimips/dev/crmfbreg.h:1.15	Tue May 17 22:26:33 2011
+++ src/sys/arch/sgimips/dev/crmfbreg.h	Tue Jan 20 12:13:04 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: crmfbreg.h,v 1.15 2011/05/17 22:26:33 macallan Exp $ */
+/* $NetBSD: crmfbreg.h,v 1.16 2015/01/20 12:13:04 macallan Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <[email protected]>
@@ -68,6 +68,7 @@
 #define		CRMFB_DOTCLOCK_N_MASK		0x00003f00
 #define		CRMFB_DOTCLOCK_P_MASK		0x0000c000
 #define		CRMFB_DOTCLOCK_CLKRUN_SHIFT	20
+#define		CRMFB_DOTCLOCK_BYPASS		0x00100000 /* turn the clock off */
 #define		CRMFB_DOTCLOCK_OUT_OF_RANGE	0x00400000
 #define		CRMFB_DOTCLOCK_OUT_OF_LOCK	0x00800000
 #define		CRMFB_DOTCLOCK_TDWNI		0x01000000 /* ? */
@@ -328,6 +329,7 @@
 #define DE_MODE_TYPE_RGBA	0x00000020
 #define DE_MODE_TYPE_ABGR	0x00000030
 #define DE_MODE_TYPE_YCRCB	0x000000f0
+#define DE_MODE_TYPE_MASK	0x000000f0
 #define DE_MODE_PIXDEPTH_8	0x00000000
 #define DE_MODE_PIXDEPTH_16	0x00000004
 #define DE_MODE_PIXDEPTH_32	0x00000008
@@ -427,7 +429,12 @@
 #define CRIME_DE_BUF_START	0x0000003f
 
 #define CRIME_DE_LEVEL_SHIFT	18
-#define CRIME_DE_LEVEL_MAX	0x7f
+/*
+ * XXX
+ * The manual claims that the pipeline is 128 deep, in reality it seems to be
+ * 64, at least on my O2. Might be 128 deep on O2+
+ */ 
+#define CRIME_DE_LEVEL_MAX	0x3f
 #define CRIME_PIPE_LEVEL(x)	((x & CRIME_DE_LEVEL_MASK) >>  \
 				  CRIME_DE_LEVEL_SHIFT)
 

Reply via email to