Module Name: src Committed By: macallan Date: Thu Feb 7 16:14:30 UTC 2013
Modified Files: src/sys/arch/sparc/dev: cgfourteen.c Log Message: - implement buttom-up copies in cg14_bitblt() so scrolling down works now - use more registers when copying - use hardware to draw the cursor - use putchar() for horizontal scrolling since byte-wise overlapping copy ops wouldn't be any faster anyway To generate a diff of this commit: cvs rdiff -u -r1.70 -r1.71 src/sys/arch/sparc/dev/cgfourteen.c 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.70 src/sys/arch/sparc/dev/cgfourteen.c:1.71 --- src/sys/arch/sparc/dev/cgfourteen.c:1.70 Wed Feb 6 04:10:54 2013 +++ src/sys/arch/sparc/dev/cgfourteen.c Thu Feb 7 16:14:30 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: cgfourteen.c,v 1.70 2013/02/06 04:10:54 macallan Exp $ */ +/* $NetBSD: cgfourteen.c,v 1.71 2013/02/07 16:14:30 macallan Exp $ */ /* * Copyright (c) 1996 @@ -151,12 +151,13 @@ static int cg14_do_cursor(struct cgfour #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_invert(struct cgfourteen_softc *, int, int, int, int); 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_cursor(void *, int, int, int); 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); @@ -360,14 +361,13 @@ 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_normal_dev(sc->sc_dev, "fb paddr: %08x\n", + aprint_debug_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 } + cg14_wait_idle(sc); #endif cg14_setup_wsdisplay(sc, isconsole); #endif @@ -1012,7 +1012,13 @@ cg14_init_screen(void *cookie, struct vc ri->ri_bits = (char *)sc->sc_fb.fb_pixels; #if NSX > 0 - if (sc->sc_sx == NULL) + /* + * unaligned copies with horizontal overlap are slow, so don't bother + * handling them in cg14_bitblt() and use putchar() instead + */ + if (sc->sc_sx != NULL) { + scr->scr_flags |= VCONS_NO_COPYCOLS; + } else #endif scr->scr_flags |= VCONS_DONT_READ; @@ -1034,8 +1040,8 @@ cg14_init_screen(void *cookie, struct vc 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 0 if (FONT_IS_ALPHA(ri->ri_font)) { ri->ri_ops.putchar = cg14_putchar_aa; } else @@ -1184,25 +1190,112 @@ cg14_rectfill(struct cgfourteen_softc *s uint32_t colour) { uint32_t addr, pptr; - int line, cnt; + int line, cnt, pre, words; 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); + /* + * Calculate the number of pixels we need to do one by one + * until we're 32bit aligned, then do the rest in 32bit + * mode. Assumes that stride is always a multiple of 4. + */ + pre = addr & 3; + if (pre != 0) pre = 4 - pre; 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 (pre) { + sta(pptr, ASI_SX, SX_STBS(8, pre - 1, pptr & 7)); + pptr += pre; + cnt -= pre; } + /* now do the aligned pixels in 32bit chunks */ + while(cnt > 31) { + words = min(32, cnt >> 2); + sta(pptr, ASI_SX, SX_STS(8, words - 1, pptr & 7)); + pptr += words << 2; + cnt -= words << 2; + } + /* do any remaining pixels byte-wise again */ if (cnt > 0) sta(pptr, ASI_SX, SX_STBS(8, cnt - 1, pptr & 7)); addr += stride; } - cg14_wait_idle(sc); +} + +static void +cg14_invert(struct cgfourteen_softc *sc, int x, int y, int wi, int he) +{ + uint32_t addr, pptr; + int line, cnt, pre, words; + int stride = sc->sc_fb.fb_type.fb_width; + + addr = sc->sc_fb_paddr + x + stride * y; + sx_write(sc->sc_sx, SX_ROP_CONTROL, 0x33); /* ~src a */ + /* + * Calculate the number of pixels we need to do one by one + * until we're 32bit aligned, then do the rest in 32bit + * mode. Assumes that stride is always a multiple of 4. + */ + pre = addr & 3; + if (pre != 0) pre = 4 - pre; + for (line = 0; line < he; line++) { + pptr = addr; + cnt = wi; + if (pre) { + sta(pptr, ASI_SX, SX_LDB(8, pre - 1, pptr & 7)); + sx_write(sc->sc_sx, SX_INSTRUCTIONS, + SX_ROP(8, 8, 32, pre - 1)); + sta(pptr, ASI_SX, SX_STB(32, pre - 1, pptr & 7)); + pptr += pre; + cnt -= pre; + } + /* now do the aligned pixels in 32bit chunks */ + while(cnt > 15) { + words = min(16, cnt >> 2); + sta(pptr, ASI_SX, SX_LD(8, words - 1, pptr & 7)); + sx_write(sc->sc_sx, SX_INSTRUCTIONS, + SX_ROP(8, 8, 32, words - 1)); + sta(pptr, ASI_SX, SX_ST(32, words - 1, pptr & 7)); + pptr += words << 2; + cnt -= words << 2; + } + /* do any remaining pixels byte-wise again */ + if (cnt > 0) + sta(pptr, ASI_SX, SX_LDB(8, cnt - 1, pptr & 7)); + sx_write(sc->sc_sx, SX_INSTRUCTIONS, + SX_ROP(8, 8, 32, cnt - 1)); + sta(pptr, ASI_SX, SX_STB(32, cnt - 1, pptr & 7)); + addr += stride; + } +} + +static inline void +cg14_slurp(int reg, uint32_t addr, int cnt) +{ + int num; + while (cnt > 0) { + num = min(32, cnt); + sta(addr, ASI_SX, SX_LD(reg, num - 1, addr & 7)); + cnt -= num; + reg += num; + addr += (num << 2); + } +} + +static inline void +cg14_spit(int reg, uint32_t addr, int cnt) +{ + int num; + while (cnt > 0) { + num = min(32, cnt); + sta(addr, ASI_SX, SX_ST(reg, num - 1, addr & 7)); + cnt -= num; + reg += num; + addr += (num << 2); + } } static void @@ -1212,9 +1305,19 @@ cg14_bitblt(void *cookie, int xs, int ys struct cgfourteen_softc *sc = cookie; uint32_t saddr, daddr, sptr, dptr; int line, cnt, stride = sc->sc_fb.fb_type.fb_width; + int num, words, skip; + + if (ys < yd) { + /* need to go bottom-up */ + saddr = sc->sc_fb_paddr + xs + stride * (ys + he - 1); + daddr = sc->sc_fb_paddr + xd + stride * (yd + he - 1); + skip = -stride; + } else { + saddr = sc->sc_fb_paddr + xs + stride * ys; + daddr = sc->sc_fb_paddr + xd + stride * yd; + skip = stride; + } - 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; @@ -1229,27 +1332,21 @@ cg14_bitblt(void *cookie, int xs, int ys 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; + words = cnt >> 2; + while(cnt > 3) { + num = min(120, words); + cg14_slurp(8, sptr, num); + cg14_spit(8, dptr, num); + sptr += num << 2; + dptr += num << 2; + cnt -= num << 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; + saddr += skip; + daddr += skip; } } else { /* unaligned, have to use byte mode */ @@ -1257,7 +1354,7 @@ cg14_bitblt(void *cookie, int xs, int ys sptr = saddr; dptr = daddr; cnt = wi; - while(cnt > 32) { + while(cnt > 31) { sta(sptr, ASI_SX, SX_LDB(32, 31, sptr & 7)); sta(dptr, ASI_SX, SX_STB(32, 31, dptr & 7)); sptr += 32; @@ -1268,11 +1365,10 @@ cg14_bitblt(void *cookie, int xs, int ys 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; + saddr += skip; + daddr += skip; } } - cg14_wait_idle(sc); } @@ -1342,13 +1438,12 @@ cg14_putchar(void *cookie, int row, int } } -#if 0 static void -r128fb_cursor(void *cookie, int on, int row, int col) +cg14_cursor(void *cookie, int on, int row, int col) { struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; - struct r128fb_softc *sc = scr->scr_cookie; + struct cgfourteen_softc *sc = scr->scr_cookie; int x, y, wi, he; wi = ri->ri_font->fontwidth; @@ -1358,7 +1453,7 @@ r128fb_cursor(void *cookie, int on, int x = ri->ri_ccol * wi + ri->ri_xorigin; y = ri->ri_crow * he + ri->ri_yorigin; if (ri->ri_flg & RI_CURSOR) { - r128fb_bitblt(sc, x, y, x, y, wi, he, R128_ROP3_Dn); + cg14_invert(sc, x, y, wi, he); ri->ri_flg &= ~RI_CURSOR; } ri->ri_crow = row; @@ -1366,7 +1461,7 @@ r128fb_cursor(void *cookie, int on, int if (on) { x = ri->ri_ccol * wi + ri->ri_xorigin; y = ri->ri_crow * he + ri->ri_yorigin; - r128fb_bitblt(sc, x, y, x, y, wi, he, R128_ROP3_Dn); + cg14_invert(sc, x, y, wi, he); ri->ri_flg |= RI_CURSOR; } } else { @@ -1377,6 +1472,7 @@ r128fb_cursor(void *cookie, int on, int } +#if 0 static void r128fb_putchar_aa(void *cookie, int row, int col, u_int c, long attr) {