Module Name:    src
Committed By:   martin
Date:           Wed Jul  5 16:09:50 UTC 2023

Modified Files:
        src/sys/arch/sparc/dev [netbsd-10]: cgfourteen.c sx.c sxvar.h
        src/sys/dev/sbus [netbsd-10]: mgx.c
        src/sys/dev/wscons [netbsd-10]: wsdisplay_glyphcache.c
            wsdisplay_glyphcachevar.h wsdisplay_vcons.c wsdisplay_vconsvar.h

Log Message:
Pull up following revision(s) (requested by abs in ticket #224):

        sys/dev/wscons/wsdisplay_vconsvar.h: revision 1.34
        sys/dev/wscons/wsdisplay_glyphcachevar.h: revision 1.6
        sys/arch/sparc/dev/cgfourteen.c: revision 1.94
        sys/arch/sparc/dev/cgfourteen.c: revision 1.95
        sys/dev/sbus/mgx.c: revision 1.21
        sys/dev/sbus/mgx.c: revision 1.22
        sys/dev/sbus/mgx.c: revision 1.23
        sys/dev/wscons/wsdisplay_vcons.c: revision 1.65
        sys/dev/wscons/wsdisplay_vcons.c: revision 1.66
        sys/dev/wscons/wsdisplay_glyphcache.c: revision 1.12
        sys/arch/sparc/dev/sxvar.h: revision 1.5
        sys/arch/sparc/dev/sx.c: revision 1.6
        sys/arch/sparc/dev/sx.c: revision 1.7

make vcons_putchar_buffer() return a flag indicating if anything actually
changed, skip the actual drawing op if nothing did

add flags for drivers to requesr R2L bit/byte-ordered fonts, default to
L2R, chack them in vcons_load_font() instead of just trusting that we'd get
what we need

initialize the diagnostic register with the value suggested by the SunOS
header. This sets a bunch of undocumented bits and yields a 10% speed increase
when rendering antialiased text.

use macros compatible with xf86-video-suncg14 to issue SX instructions
much more readable, alignment weirdness is handled automatically and code is
interchangable

allow drivers to specify horizontal alignment of glyph cache cells
for things like SX which have alignment restrictions

add counter to periodically drain the instruction queue in order to avoid
stalling the MBus during long SX operations

adapted from xf86-video-suncg14
- use sx_wait() to avoid stalling the MBus
- request 32bit alignment for glyphcache cells

wait for the engine to go idle before issuing rectfill commands
we get occasional overlap with blit commands if we just wait for fifo slots
needs further investigation, it is possible that not all writes to drawing
engine registers are pipelined and of course we don't have docs

following a hunch...
- cache DEC and FG registers, only write them if the value actually changes
- wait for the engine to go idle before writing DEC
- wait for FIFO slots on everything else
with this we avoid waiting if possible and still avoid overlapping blit and
fill commands


To generate a diff of this commit:
cvs rdiff -u -r1.93 -r1.93.4.1 src/sys/arch/sparc/dev/cgfourteen.c
cvs rdiff -u -r1.5 -r1.5.4.1 src/sys/arch/sparc/dev/sx.c
cvs rdiff -u -r1.4 -r1.4.30.1 src/sys/arch/sparc/dev/sxvar.h
cvs rdiff -u -r1.20 -r1.20.4.1 src/sys/dev/sbus/mgx.c
cvs rdiff -u -r1.11 -r1.11.30.1 src/sys/dev/wscons/wsdisplay_glyphcache.c
cvs rdiff -u -r1.5 -r1.5.42.1 src/sys/dev/wscons/wsdisplay_glyphcachevar.h
cvs rdiff -u -r1.64 -r1.64.4.1 src/sys/dev/wscons/wsdisplay_vcons.c
cvs rdiff -u -r1.33 -r1.33.4.1 src/sys/dev/wscons/wsdisplay_vconsvar.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/sparc/dev/cgfourteen.c
diff -u src/sys/arch/sparc/dev/cgfourteen.c:1.93 src/sys/arch/sparc/dev/cgfourteen.c:1.93.4.1
--- src/sys/arch/sparc/dev/cgfourteen.c:1.93	Wed May 25 21:01:04 2022
+++ src/sys/arch/sparc/dev/cgfourteen.c	Wed Jul  5 16:09:50 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: cgfourteen.c,v 1.93 2022/05/25 21:01:04 macallan Exp $ */
+/*	$NetBSD: cgfourteen.c,v 1.93.4.1 2023/07/05 16:09:50 martin Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -168,6 +168,21 @@ static void cg14_copycols(void *, int, i
 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);
+
+/* 
+ * issue ALU instruction:
+ * sxi(OPCODE, srcA, srcB, dest, count)
+ */
+#define sxi(inst, a, b, d, cnt) \
+	sx_wait(sc->sc_sx); \
+	sx_write(sc->sc_sx, SX_INSTRUCTIONS, inst((a), (b), (d), (cnt)))
+
+/*
+ * issue memory referencing instruction:
+ * sxm(OPCODE, address, start register, count)
+ */
+#define sxm(inst, addr, reg, count) sta((addr) & ~7, ASI_SX, inst((reg), (count), (addr) & 7))
+
 #endif /* NSX > 0 */
 
 #endif
@@ -358,7 +373,7 @@ cgfourteenattach(device_t parent, device
 		    sc->sc_fbaddr, 0, 0, 0) & 0xfffff000;
 		aprint_normal_dev(sc->sc_dev, "using %s\n", 
 		    device_xname(sc->sc_sx->sc_dev));
-		aprint_debug_dev(sc->sc_dev, "fb paddr: %08x\n",
+		aprint_normal_dev(sc->sc_dev, "fb paddr: %08x\n",
 		    sc->sc_fb_paddr);
 		sx_write(sc->sc_sx, SX_PAGE_BOUND_LOWER, sc->sc_fb_paddr);
 		sx_write(sc->sc_sx, SX_PAGE_BOUND_UPPER,
@@ -379,7 +394,7 @@ cgfourteenattach(device_t parent, device
  * the last close. This kind of nonsense is needed to give screenblank
  * a fighting chance of working.
  */
-
+ 
 int
 cgfourteenopen(dev_t dev, int flags, int mode, struct lwp *l)
 {
@@ -567,8 +582,9 @@ cgfourteenmmap(dev_t dev, off_t off, int
 			0, prot, BUS_SPACE_MAP_LINEAR));
 	} else if (off >= CG14_SXIO_VOFF &&
 		   off < (CG14_SXIO_VOFF + 0x03ffffff)) {
+		off -= CG14_SXIO_VOFF;
 		return (bus_space_mmap(sc->sc_sx->sc_tag, 0x800000000LL,
-			sc->sc_fb_paddr + (off - CG14_SXIO_VOFF),
+			sc->sc_fb_paddr + off,
 			prot, BUS_SPACE_MAP_LINEAR));
 #endif
 	} else
@@ -756,13 +772,13 @@ cg14_setup_wsdisplay(struct cgfourteen_s
 		sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
 		sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
 		sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
-		glyphcache_init(&sc->sc_gc, sc->sc_fb.fb_type.fb_height + 5,
+		glyphcache_init_align(&sc->sc_gc, sc->sc_fb.fb_type.fb_height + 5,
 			(sc->sc_vramsize / sc->sc_fb.fb_type.fb_width) - 
 			 sc->sc_fb.fb_type.fb_height - 5,
 			sc->sc_fb.fb_type.fb_width,
 			ri->ri_font->fontwidth,
 			ri->ri_font->fontheight,
-			defattr);
+			defattr, 4);
 	if (is_cons) {
 		wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
 		    defattr);
@@ -1204,20 +1220,20 @@ cg14_rectfill(struct cgfourteen_softc *s
 		pptr = addr;
 		cnt = wi;
 		if (pre) {
-			sta(pptr & ~7, ASI_SX, SX_STBS(8, pre - 1, pptr & 7));
+			sxm(SX_STBS, pptr, 8, pre - 1);
 			pptr += pre;
 			cnt -= pre;
 		}
 		/* now do the aligned pixels in 32bit chunks */
 		while(cnt > 3) {
 			words = uimin(32, cnt >> 2);
-			sta(pptr & ~7, ASI_SX, SX_STS(8, words - 1, pptr & 7));
+			sxm(SX_STS, pptr, 8, words - 1);
 			pptr += words << 2;
 			cnt -= words << 2;
 		}
 		/* do any remaining pixels byte-wise again */
 		if (cnt > 0)
-			sta(pptr & ~7, ASI_SX, SX_STBS(8, cnt - 1, pptr & 7));
+			sxm(SX_STBS, pptr, 8, cnt - 1);
 		addr += stride;
 	}
 }
@@ -1275,28 +1291,25 @@ cg14_invert(struct cgfourteen_softc *sc,
 	for (line = 0; line < he; line++) {
 		pptr = addr;
 		/* load a whole scanline */
-		sta(pptr & ~7, ASI_SX, SX_LD(8, words - 1, pptr & 7));
+		sxm(SX_LD, pptr, 8, words - 1);
 		reg = 8;
 		if (pre) {
 			cg14_set_mask(sc, lmask);
-			sx_write(sc->sc_sx, SX_INSTRUCTIONS,
-			    SX_ROPB(8, 8, 40, 0));
+			sxi(SX_ROPB, 8, 8, 40, 0);
 			reg++;
 		}
 		if (cnt > 0) {
 			cg14_set_mask(sc, 0xffffffff);
 			/* XXX handle cnt > 16 */
-			sx_write(sc->sc_sx, SX_INSTRUCTIONS,
-			    SX_ROP(reg, reg, reg + 32, cnt - 1));
+			sxi(SX_ROP, reg, reg, reg + 32, cnt - 1);
 			reg += cnt;
 		}
 		if (post) {
 			cg14_set_mask(sc, rmask);
-			sx_write(sc->sc_sx, SX_INSTRUCTIONS,
-			    SX_ROPB(reg, 7, reg + 32, 0));
+			sxi(SX_ROPB, reg, 7, reg + 32, 0);
 			reg++;
 		}
-		sta(pptr & ~7, ASI_SX, SX_ST(40, words - 1, pptr & 7));		
+		sxm(SX_ST, pptr, 40, words - 1);		
 		addr += stride;
 	}
 }
@@ -1307,7 +1320,7 @@ cg14_slurp(int reg, uint32_t addr, int c
 	int num;
 	while (cnt > 0) {
 		num = uimin(32, cnt);
-		sta(addr & ~7, ASI_SX, SX_LD(reg, num - 1, addr & 7));
+		sxm(SX_LD, addr, reg, num - 1);
 		cnt -= num;
 		reg += num;
 		addr += (num << 2);
@@ -1320,7 +1333,7 @@ cg14_spit(int reg, uint32_t addr, int cn
 	int num;
 	while (cnt > 0) {
 		num = uimin(32, cnt);
-		sta(addr & ~7, ASI_SX, SX_ST(reg, num - 1, addr & 7));
+		sxm(SX_ST, addr, reg, num - 1);
 		cnt -= num;
 		reg += num;
 		addr += (num << 2);
@@ -1355,10 +1368,8 @@ cg14_bitblt(void *cookie, int xs, int ys
 			dptr = daddr;
 			cnt = wi;
 			if (pre > 0) {
-				sta(sptr & ~7, ASI_SX,
-				    SX_LDB(32, pre - 1, sptr & 7));
-				sta(dptr & ~7, ASI_SX,
-				    SX_STB(32, pre - 1, dptr & 7));
+				sxm(SX_LDB, sptr, 32, pre - 1);
+				sxm(SX_STB, dptr, 32, pre - 1);
 				cnt -= pre;
 				sptr += pre;
 				dptr += pre;
@@ -1373,10 +1384,8 @@ cg14_bitblt(void *cookie, int xs, int ys
 				cnt -= num << 2;
 			}
 			if (cnt > 0) {
-				sta(sptr & ~7, ASI_SX,
-				    SX_LDB(32, cnt - 1, sptr & 7));
-				sta(dptr & ~7, ASI_SX,
-				    SX_STB(32, cnt - 1, dptr & 7));
+				sxm(SX_LDB, sptr, 32, cnt - 1);
+				sxm(SX_STB, dptr, 32, cnt - 1);
 			}
 			saddr += skip;
 			daddr += skip;
@@ -1389,17 +1398,15 @@ cg14_bitblt(void *cookie, int xs, int ys
 			dptr = daddr;
 			cnt = wi;
 			while(cnt > 31) {
-				sta(sptr & ~7, ASI_SX, SX_LDB(32, 31, sptr & 7));
-				sta(dptr & ~7, ASI_SX, SX_STB(32, 31, dptr & 7));
+				sxm(SX_LDB, sptr, 32, 31);
+				sxm(SX_STB, dptr, 32, 31);
 				sptr += 32;
 				dptr += 32;
 				cnt -= 32;
 			}
 			if (cnt > 0) {
-				sta(sptr & ~7, ASI_SX,
-				    SX_LDB(32, cnt - 1, sptr & 7));
-				sta(dptr & ~7, ASI_SX,
-				    SX_STB(32, cnt - 1, dptr & 7));
+				sxm(SX_LDB, sptr, 32, cnt - 1);
+				sxm(SX_STB, dptr, 32, cnt - 1);
 			}
 			saddr += skip;
 			daddr += skip;
@@ -1444,22 +1451,22 @@ cg14_bitblt_gc(void *cookie, int xs, int
 	
 	for (line = 0; line < he; line++) {
 		/* read source line, in all quads */
-		sta(saddr & ~7, ASI_SX, SX_LDUQ0(8, swi - 1, saddr & 7));
+		sxm(SX_LDUQ0, saddr, 8, swi - 1);
 		/* now write it out */
 		dd = daddr;
 		r = dreg;
 		if (in > 0) {
-			sta(dd & ~7, ASI_SX, SX_STB(r, in - 1, dd & 7));
+			sxm(SX_STB, dd, r, in - 1);
 			dd += in;
 			r += in;
 		}
 		if (q > 0) {
-			sta(dd & ~7, ASI_SX, SX_STUQ0(r, q - 1, dd & 7));
+			sxm(SX_STUQ0, dd, r, q - 1);
 			r += q << 2;
 			dd += q << 2;
 		}
 		if (out > 0) {
-			sta(dd & ~7, ASI_SX, SX_STB(r, out - 1, dd & 7));
+			sxm(SX_STB, dd, r, out - 1);
 		}
 		saddr += stride;
 		daddr += stride;
@@ -1518,7 +1525,7 @@ cg14_putchar(void *cookie, int row, int 
 			for (i = 0; i < he; i++) {
 				reg = *data8;
 				cg14_set_mask(sc, reg << 24);
-				sta(addr & ~7, ASI_SX, SX_STBS(8, wi - 1, addr & 7));
+				sxm(SX_STBS, addr, 8, wi - 1);
 				data8++;
 				addr += stride;
 			}
@@ -1530,7 +1537,7 @@ cg14_putchar(void *cookie, int row, int 
 			for (i = 0; i < he; i++) {
 				reg = *data16;
 				cg14_set_mask(sc, reg << 16);
-				sta(addr & ~7, ASI_SX, SX_STBS(8, wi - 1, addr & 7));
+				sxm(SX_STBS, addr, 8, wi - 1);
 				data16++;
 				addr += stride;
 			}
@@ -1679,20 +1686,20 @@ cg14_putchar_aa(void *cookie, int row, i
 		cnt = wi;
 		if (in != 0) {
 			in = 4 - in;	/* pixels to write until aligned */
-			sta(next & ~7, ASI_SX, SX_STB(8, in - 1, next & 7));
+			sxm(SX_STB, next, 8, in - 1);
 			next += in;
 			reg = 8 + in;
 			cnt -= in;
 		}
 		q = cnt >> 2;	/* number of writes we can do in quads */
 		if (q > 0) {
-			sta(next & ~7, ASI_SX, SX_STUQ0(reg, q - 1, next & 7));
+			sxm(SX_STUQ0, next, reg, q - 1);
 			next += (q << 2);
 			cnt -= (q << 2);
 			reg += (q << 2);
 		}
 		if (cnt > 0) {
-			sta(next & ~7, ASI_SX, SX_STB(reg, cnt - 1, next & 7));
+			sxm(SX_STB, next, reg, cnt - 1);
 		}
 			
 		addr += stride;

Index: src/sys/arch/sparc/dev/sx.c
diff -u src/sys/arch/sparc/dev/sx.c:1.5 src/sys/arch/sparc/dev/sx.c:1.5.4.1
--- src/sys/arch/sparc/dev/sx.c:1.5	Sat Sep 11 20:28:05 2021
+++ src/sys/arch/sparc/dev/sx.c	Wed Jul  5 16:09:50 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: sx.c,v 1.5 2021/09/11 20:28:05 andvar Exp $	*/
+/*	$NetBSD: sx.c,v 1.5.4.1 2023/07/05 16:09:50 martin Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sx.c,v 1.5 2021/09/11 20:28:05 andvar Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sx.c,v 1.5.4.1 2023/07/05 16:09:50 martin Exp $");
 
 #include "locators.h"
 
@@ -84,6 +84,7 @@ sx_attach(device_t parent, device_t self
 	sc->sc_dev = self;
 	sc->sc_tag = ma->ma_bustag;
 	sc->sc_uregs = ma->ma_paddr + 0x1000;
+	sc->sc_cnt = 0;
 
 	if (bus_space_map(sc->sc_tag, ma->ma_paddr, 0x1000, 0, &sc->sc_regh)) {
 		aprint_error_dev(self, "failed to map registers\n");
@@ -104,7 +105,7 @@ sx_attach(device_t parent, device_t self
 	sx_write(sc, SX_PAGE_BOUND_LOWER, 0xfc000000);
 	/* cg14 takes up the whole 64MB chunk */
 	sx_write(sc, SX_PAGE_BOUND_UPPER, 0xffffffff);
-	sx_write(sc, SX_DIAGNOSTICS, 0);
+	sx_write(sc, SX_DIAGNOSTICS, SX_DIAG_INIT);
 	sx_write(sc, SX_PLANEMASK, 0xffffffff);
 
 	/*

Index: src/sys/arch/sparc/dev/sxvar.h
diff -u src/sys/arch/sparc/dev/sxvar.h:1.4 src/sys/arch/sparc/dev/sxvar.h:1.4.30.1
--- src/sys/arch/sparc/dev/sxvar.h:1.4	Fri Mar  1 02:30:42 2019
+++ src/sys/arch/sparc/dev/sxvar.h	Wed Jul  5 16:09:50 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: sxvar.h,v 1.4 2019/03/01 02:30:42 macallan Exp $	*/
+/*	$NetBSD: sxvar.h,v 1.4.30.1 2023/07/05 16:09:50 martin Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -32,11 +32,14 @@
 #ifndef SXVAR_H
 #define SXVAR_H
 
+#include <sparc/dev/sxreg.h>
+
 struct sx_softc {
 	device_t		sc_dev;
 	bus_addr_t		sc_uregs;
 	bus_space_tag_t		sc_tag;
 	bus_space_handle_t	sc_regh;
+	int			sc_cnt;
 };
 
 static inline void
@@ -51,6 +54,26 @@ sx_read(struct sx_softc *sc, int addr)
 	return bus_space_read_4(sc->sc_tag, sc->sc_regh, addr);
 }
 
+/*
+ * to be used before issuing SX instructions
+ * this will periodically allow the instruction queue to drain in order
+ * to avoid excessive MBus relinquish & retry cycles during long SX ops
+ * which may cause us to lose interrupts
+ */
+static inline void
+sx_wait(struct sx_softc *sc)
+{
+	uint32_t reg;
+	if (sc->sc_cnt > 6) {
+		do {
+			reg = bus_space_read_4(sc->sc_tag, sc->sc_regh,
+						 SX_CONTROL_STATUS);
+		} while ((reg & SX_MT) == 0);
+		sc->sc_cnt = 0;
+	} else
+		sc->sc_cnt++;
+}
+
 void sx_dump(void);
 
 #endif

Index: src/sys/dev/sbus/mgx.c
diff -u src/sys/dev/sbus/mgx.c:1.20 src/sys/dev/sbus/mgx.c:1.20.4.1
--- src/sys/dev/sbus/mgx.c:1.20	Thu Nov 11 19:37:30 2021
+++ src/sys/dev/sbus/mgx.c	Wed Jul  5 16:09:50 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: mgx.c,v 1.20 2021/11/11 19:37:30 macallan Exp $ */
+/*	$NetBSD: mgx.c,v 1.20.4.1 2023/07/05 16:09:50 martin Exp $ */
 
 /*-
  * Copyright (c) 2014 Michael Lorenz
@@ -29,7 +29,7 @@
 /* a console driver for the SSB 4096V-MGX graphics card */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.20 2021/11/11 19:37:30 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.20.4.1 2023/07/05 16:09:50 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -80,7 +80,7 @@ struct mgx_softc {
 	int		sc_fbsize;
 	int		sc_mode;
 	char		sc_name[8];
-	uint32_t	sc_dec;
+	uint32_t	sc_dec, sc_r_dec, sc_r_fg;
 	u_char		sc_cmap_red[256];
 	u_char		sc_cmap_green[256];
 	u_char		sc_cmap_blue[256];
@@ -216,6 +216,24 @@ mgx_write_4(struct mgx_softc *sc, uint32
 	bus_space_write_4(sc->sc_tag, sc->sc_blith, reg, val);
 }
 
+static inline void
+mgx_set_dec(struct mgx_softc *sc, uint32_t dec)
+{
+	if (dec == sc->sc_r_dec) return;
+	sc->sc_r_dec = dec;
+	mgx_wait_engine(sc);
+	mgx_write_4(sc, ATR_DEC, dec);
+}
+
+static inline void
+mgx_set_fg(struct mgx_softc *sc, uint32_t fg)
+{
+	if (fg == sc->sc_r_fg) return;
+	sc->sc_r_fg = fg;
+	mgx_wait_fifo(sc, 1);	
+	mgx_write_4(sc, ATR_FG, fg);
+}
+
 static int
 mgx_match(device_t parent, cfdata_t cf, void *aux)
 {
@@ -342,7 +360,7 @@ mgx_attach(device_t parent, device_t sel
 	 * leave some room between visible screen and glyph cache for upload
 	 * buffers used by putchar_mono()
 	 */
-	bsize = (32 * 1024 * sc->sc_stride - 1) / sc->sc_stride;
+	bsize = (32 * 1024 + sc->sc_stride - 1) / sc->sc_stride;
 	glyphcache_init(&sc->sc_gc,
 	    sc->sc_height + bsize,
 	    (0x400000 / sc->sc_stride) - (sc->sc_height + bsize),
@@ -531,6 +549,8 @@ mgx_setup(struct mgx_softc *sc, int dept
 	int i;
 	uint8_t reg;
 
+	sc->sc_r_dec = 0xffffffff;
+	sc->sc_r_fg = 0x12345678;
 	/* wait for everything to go idle */
 	if (mgx_wait_engine(sc) == 0)
 		return;
@@ -643,9 +663,9 @@ mgx_bitblt(void *cookie, int xs, int ys,
 		yd += he - 1;
 		dec |= DEC_DIR_Y_REVERSE;
 	}
-	mgx_wait_fifo(sc, 5);
+	mgx_set_dec(sc, dec);
+	mgx_wait_fifo(sc, 4);
 	mgx_write_1(sc, ATR_ROP, rop);
-	mgx_write_4(sc, ATR_DEC, dec);
 	mgx_write_4(sc, ATR_SRC_XY, (ys << 16) | xs);
 	mgx_write_4(sc, ATR_DST_XY, (yd << 16) | xd);
 	mgx_write_4(sc, ATR_WH, (he << 16) | wi);
@@ -666,10 +686,10 @@ mgx_rectfill(void *cookie, int x, int y,
 	dec = sc->sc_dec;
 	dec |= (DEC_COMMAND_RECT << DEC_COMMAND_SHIFT) |
 	       (DEC_START_DIMX << DEC_START_SHIFT);
-	mgx_wait_fifo(sc, 5);
+	mgx_set_dec(sc, dec);
+	mgx_set_fg(sc, col);
+	mgx_wait_fifo(sc, 3);
 	mgx_write_1(sc, ATR_ROP, ROP_SRC);
-	mgx_write_4(sc, ATR_FG, col);
-	mgx_write_4(sc, ATR_DEC, dec);
 	mgx_write_4(sc, ATR_DST_XY, (y << 16) | x);
 	mgx_write_4(sc, ATR_WH, (he << 16) | wi);
 }
@@ -753,8 +773,8 @@ mgx_putchar_mono(void *cookie, int row, 
 		return;
 	}
 
-	mgx_wait_fifo(sc, 3);
-	mgx_write_4(sc, ATR_FG, ri->ri_devcmap[fg]);
+	mgx_set_fg(sc, ri->ri_devcmap[fg]);
+	mgx_wait_fifo(sc, 2);
 	mgx_write_4(sc, ATR_BG, ri->ri_devcmap[bg]);
 	mgx_write_1(sc, ATR_ROP, ROP_SRC);
 
@@ -789,10 +809,10 @@ mgx_putchar_mono(void *cookie, int row, 
 		for (i = 0; i < ri->ri_fontscale; i++)
 			d[i] = s[i];
 	}
-	mgx_wait_fifo(sc, 5);
-	mgx_write_4(sc, ATR_DEC, sc->sc_dec | (DEC_COMMAND_BLT << DEC_COMMAND_SHIFT) |
+	mgx_set_dec(sc, sc->sc_dec | (DEC_COMMAND_BLT << DEC_COMMAND_SHIFT) |
 	       (DEC_START_DIMX << DEC_START_SHIFT) |
 	       DEC_SRC_LINEAR | DEC_SRC_CONTIGUOUS | DEC_MONOCHROME);
+	mgx_wait_fifo(sc, 3);
 	mgx_write_4(sc, ATR_SRC_XY, ((scratch & 0xfff000) << 4) | (scratch & 0xfff));
 	mgx_write_4(sc, ATR_DST_XY, (y << 16) | x);
 	mgx_write_4(sc, ATR_WH, (he << 16) | wi);

Index: src/sys/dev/wscons/wsdisplay_glyphcache.c
diff -u src/sys/dev/wscons/wsdisplay_glyphcache.c:1.11 src/sys/dev/wscons/wsdisplay_glyphcache.c:1.11.30.1
--- src/sys/dev/wscons/wsdisplay_glyphcache.c:1.11	Mon Sep  3 16:29:34 2018
+++ src/sys/dev/wscons/wsdisplay_glyphcache.c	Wed Jul  5 16:09:50 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_glyphcache.c,v 1.11 2018/09/03 16:29:34 riastradh Exp $	*/
+/*	$NetBSD: wsdisplay_glyphcache.c,v 1.11.30.1 2023/07/05 16:09:50 martin Exp $	*/
 
 /*
  * Copyright (c) 2012 Michael Lorenz
@@ -53,17 +53,24 @@
 static inline int
 attr2idx(long attr)
 {
-	if ((attr & 0xf0f0fff8) != 0)
+	if ((attr & 0xf0f00ff8) != 0)
 		return -1;
 	
 	return (((attr >> 16) & 0x0f) | ((attr >> 20) & 0xf0));
 }
 
-/* first line, lines, width, attr */
 int
 glyphcache_init(glyphcache *gc, int first, int lines, int width,
     int cellwidth, int cellheight, long attr)
 {
+	return glyphcache_init_align(gc, first, lines, width, cellwidth, cellheight,
+	    attr, 0);
+}
+
+int
+glyphcache_init_align(glyphcache *gc, int first, int lines, int width,
+    int cellwidth, int cellheight, long attr, int alignment)
+{
 
 	/* first the geometry stuff */
 	if (lines < 0) lines = 0;
@@ -72,6 +79,7 @@ glyphcache_init(glyphcache *gc, int firs
 	gc->gc_cellheight = -1;
 	gc->gc_firstline = first;
 	gc->gc_lines = lines;
+	gc->gc_cellalign = alignment;
 	gc->gc_buckets = NULL;
 	gc->gc_numbuckets = 0;
 	// XXX: Never free?
@@ -97,9 +105,16 @@ glyphcache_reconfig(glyphcache *gc, int 
 	}
 
 	gc->gc_cellwidth = cellwidth;
+	if (gc->gc_cellalign != 0) {
+		/* alignment in bytes */
+		gc->gc_cellstride = 
+		    (gc->gc_cellwidth + gc->gc_cellalign - 1) &
+		    ~(gc->gc_cellalign - 1);
+	} else
+		gc->gc_cellstride = cellwidth;
 	gc->gc_cellheight = cellheight;
 
-	gc->gc_cellsperline = gc->gc_width / cellwidth;
+	gc->gc_cellsperline = gc->gc_width / gc->gc_cellstride;
 
 	cache_lines = gc->gc_lines / cellheight;
 	gc->gc_numcells = cache_lines * gc->gc_cellsperline;
@@ -144,6 +159,8 @@ glyphcache_reconfig(glyphcache *gc, int 
 	glyphcache_wipe(gc);
 	DPRINTF("%s: using %d cells total, from %d width %d\n", __func__,
 	    gc->gc_numcells, gc->gc_firstline, gc->gc_cellsperline);
+	DPRINTF("%s: cell size %d x %d, stride %d\n", __func__,
+	    gc->gc_cellwidth, gc->gc_cellheight, gc->gc_cellstride);
 	return 0;
 }
 
@@ -209,7 +226,7 @@ glyphcache_add(glyphcache *gc, int c, in
 	cell += b->gb_firstcell;
 	cy = gc->gc_firstline +
 	    (cell / gc->gc_cellsperline) * gc->gc_cellheight;
-	cx = (cell % gc->gc_cellsperline) * gc->gc_cellwidth;
+	cx = (cell % gc->gc_cellsperline) * gc->gc_cellstride;
 	b->gb_map[c - 33] = (cx << 16) | cy;
 	gc->gc_bitblt(gc->gc_blitcookie, x, y, cx, cy,
 	    gc->gc_cellwidth, gc->gc_cellheight, gc->gc_rop);

Index: src/sys/dev/wscons/wsdisplay_glyphcachevar.h
diff -u src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.5 src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.5.42.1
--- src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.5	Fri Jun  2 19:30:10 2017
+++ src/sys/dev/wscons/wsdisplay_glyphcachevar.h	Wed Jul  5 16:09:50 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_glyphcachevar.h,v 1.5 2017/06/02 19:30:10 macallan Exp $	*/
+/*	$NetBSD: wsdisplay_glyphcachevar.h,v 1.5.42.1 2023/07/05 16:09:50 martin Exp $	*/
 
 /*
  * Copyright (c) 2012 Michael Lorenz
@@ -45,6 +45,8 @@ typedef struct _glyphcache {
 	/* geometry */
 	int gc_numcells;
 	int gc_cellwidth;
+	int gc_cellstride;
+	int gc_cellalign;
 	int gc_cellheight;
 	int gc_cellsperline;
 	int gc_firstline;	/* first line in vram to use for glyphs */
@@ -71,6 +73,9 @@ typedef struct _glyphcache {
 /* first line, lines, width, cellwidth, cellheight, attr */
 int glyphcache_init(glyphcache *, int, int, int, int, int, long);
 
+/* first line, lines, width, cellwidth, cellheight, attr, alignment */
+int glyphcache_init_align(glyphcache *, int, int, int, int, int, long, int);
+
 /* adapt to changed font */
 int glyphcache_reconfig(glyphcache *, int, int, long);
 

Index: src/sys/dev/wscons/wsdisplay_vcons.c
diff -u src/sys/dev/wscons/wsdisplay_vcons.c:1.64 src/sys/dev/wscons/wsdisplay_vcons.c:1.64.4.1
--- src/sys/dev/wscons/wsdisplay_vcons.c:1.64	Mon Jul 18 11:09:22 2022
+++ src/sys/dev/wscons/wsdisplay_vcons.c	Wed Jul  5 16:09:50 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_vcons.c,v 1.64 2022/07/18 11:09:22 martin Exp $ */
+/*	$NetBSD: wsdisplay_vcons.c,v 1.64.4.1 2023/07/05 16:09:50 martin Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.64 2022/07/18 11:09:22 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.64.4.1 2023/07/05 16:09:50 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -121,7 +121,7 @@ static void vcons_copycols_buffer(void *
 static void vcons_erasecols_buffer(void *, int, int, int, long);
 static void vcons_copyrows_buffer(void *, int, int, int);
 static void vcons_eraserows_buffer(void *, int, int, long);
-static void vcons_putchar_buffer(void *, int, int, u_int, long);
+static int vcons_putchar_buffer(void *, int, int, u_int, long);
 
 /*
  * actual wrapper methods which call both the _buffer ones above and the
@@ -478,7 +478,14 @@ vcons_load_font(void *v, void *cookie, s
 		flags |= WSFONT_FIND_ALPHA;
 	}
 
-	fcookie = wsfont_find(f->name, 0, 0, 0, 0, 0, flags);
+	fcookie = wsfont_find(f->name, 0, 0, 0,
+	    /* bitorder */
+	    scr->scr_flags & VCONS_FONT_BITS_R2L ?
+	      WSDISPLAY_FONTORDER_R2L : WSDISPLAY_FONTORDER_L2R,
+	    /* byteorder */
+	    scr->scr_flags & VCONS_FONT_BYTES_R2L ?
+	      WSDISPLAY_FONTORDER_R2L : WSDISPLAY_FONTORDER_L2R,
+	    flags);
 	if (fcookie == -1)
 		return EINVAL;
 
@@ -1237,22 +1244,25 @@ vcons_eraserows(void *cookie, int row, i
 	vcons_unlock(scr);
 }
 
-static void
+static int
 vcons_putchar_buffer(void *cookie, int row, int col, u_int c, long attr)
 {
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
 	int offset = vcons_offset_to_zero(scr);
-	int pos;
+	int pos, ret = 0;
 
 	if ((row >= 0) && (row < ri->ri_rows) && (col >= 0) &&
 	     (col < ri->ri_cols)) {
 		pos = col + row * ri->ri_cols;
+		ret = (scr->scr_attrs[pos + offset] != attr) ||
+		      (scr->scr_chars[pos + offset] != c);
 		scr->scr_attrs[pos + offset] = attr;
 		scr->scr_chars[pos + offset] = c;
 	}
 
-	vcons_dirty(scr);
+	if (ret) vcons_dirty(scr);
+	return ret;
 }
 
 #ifdef VCONS_DRAW_INTR
@@ -1282,8 +1292,9 @@ vcons_putchar(void *cookie, int row, int
 {
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
-
-	vcons_putchar_buffer(cookie, row, col, c, attr);
+	int need_draw;
+	
+	need_draw = vcons_putchar_buffer(cookie, row, col, c, attr);
 
 	if (vcons_use_intr(scr))
 		return;
@@ -1291,12 +1302,13 @@ vcons_putchar(void *cookie, int row, int
 	vcons_lock(scr);
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
 #ifdef VCONS_DRAW_INTR
-		vcons_putchar_cached(cookie, row, col, c, attr);
+		if (need_draw) vcons_putchar_cached(cookie, row, col, c, attr);
 #else
 		if (row == ri->ri_crow && col == ri->ri_ccol) {
 			ri->ri_flg &= ~RI_CURSOR;
-		}
-		scr->putchar(cookie, row, col, c, attr);
+			scr->putchar(cookie, row, col, c, attr);
+		} else if (need_draw)
+			scr->putchar(cookie, row, col, c, attr);
 #endif
 	}
 	vcons_unlock(scr);

Index: src/sys/dev/wscons/wsdisplay_vconsvar.h
diff -u src/sys/dev/wscons/wsdisplay_vconsvar.h:1.33 src/sys/dev/wscons/wsdisplay_vconsvar.h:1.33.4.1
--- src/sys/dev/wscons/wsdisplay_vconsvar.h:1.33	Sun Jul 17 20:23:17 2022
+++ src/sys/dev/wscons/wsdisplay_vconsvar.h	Wed Jul  5 16:09:50 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_vconsvar.h,v 1.33 2022/07/17 20:23:17 riastradh Exp $ */
+/*	$NetBSD: wsdisplay_vconsvar.h,v 1.33.4.1 2023/07/05 16:09:50 martin Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -70,6 +70,11 @@ struct vcons_screen {
 #define VCONS_LOADFONT		0x40	/* driver can load_font() */
 #define VCONS_NO_CURSOR		0x80	/* use putchar() based cursor(), to
 					 * avoid fb reads */
+#define VCONS_FONT_BITS_R2L	0x100	/* request right-to-left bitorder in
+					 * wsfont_find() */
+#define VCONS_FONT_BYTES_R2L	0x200	/* request right-to-left byteorder in
+					 * wsfont_find() */
+					 
 	/* status flags used by vcons */
 	uint32_t scr_status;
 #define VCONS_IS_VISIBLE	1	/* this screen is currently visible */

Reply via email to