Module Name: src Committed By: rkujawa Date: Fri Jul 20 21:31:28 UTC 2012
Modified Files: src/sys/dev/pci: tdvfb.c tdvfbreg.h Log Message: Preliminary blitter support for Voodoo2. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/tdvfb.c src/sys/dev/pci/tdvfbreg.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/dev/pci/tdvfb.c diff -u src/sys/dev/pci/tdvfb.c:1.2 src/sys/dev/pci/tdvfb.c:1.3 --- src/sys/dev/pci/tdvfb.c:1.2 Fri Jul 20 12:03:32 2012 +++ src/sys/dev/pci/tdvfb.c Fri Jul 20 21:31:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: tdvfb.c,v 1.2 2012/07/20 12:03:32 rkujawa Exp $ */ +/* $NetBSD: tdvfb.c,v 1.3 2012/07/20 21:31:28 rkujawa Exp $ */ /* * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tdvfb.c,v 1.2 2012/07/20 12:03:32 rkujawa Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tdvfb.c,v 1.3 2012/07/20 21:31:28 rkujawa Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -75,7 +75,7 @@ static void tdvfb_cvg_set(struct tdvfb_s static void tdvfb_cvg_unset(struct tdvfb_softc *sc, uint32_t reg, uint32_t bits); static uint8_t tdvfb_cvg_dac_read(struct tdvfb_softc *sc, uint32_t reg); -void tdvfb_cvg_dac_write(struct tdvfb_softc *sc, uint32_t reg, +static void tdvfb_cvg_dac_write(struct tdvfb_softc *sc, uint32_t reg, uint32_t val); static void tdvfb_wait(struct tdvfb_softc *sc); @@ -96,6 +96,15 @@ static void tdvfb_gendac_set_vid_timing( static void tdvfb_init_screen(void *cookie, struct vcons_screen *scr, int existing, long *defattr); static void tdvfb_init_palette(struct tdvfb_softc *sc); +/* blitter support */ +static void tdvfb_rectfill(struct tdvfb_softc *sc, int x, int y, int wi, + int he, uint32_t color); +static void tdvfb_bitblt(struct tdvfb_softc *sc, int xs, int ys, int xd, + int yd, int wi, int he); +/* accelerated raster ops */ +static void tdvfb_eraserows(void *cookie, int row, int nrows, + long fillattr); +static void tdvfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows); CFATTACH_DECL_NEW(tdvfb, sizeof(struct tdvfb_softc), tdvfb_match, tdvfb_attach, NULL, NULL); @@ -180,7 +189,7 @@ tdvfb_attach(device_t parent, device_t s /* Select video mode, 800x600 32bpp 60Hz by default... */ sc->sc_width = 800; sc->sc_height = 600; - sc->sc_bpp = 32; + sc->sc_bpp = 32; /* XXX: 16 would allow blitter use. */ sc->sc_linebytes = 1024 * (sc->sc_bpp / 8); sc->sc_videomode = pick_mode_by_ref(sc->sc_width, sc->sc_height, 60); @@ -263,6 +272,14 @@ tdvfb_init_screen(void *cookie, struct v ri->ri_height = sc->sc_height; ri->ri_stride = sc->sc_linebytes; ri->ri_flg = RI_CENTER; + +#if BYTE_ORDER == BIG_ENDIAN +#if 0 /* XXX: not yet :( */ + if (sc->sc_bpp == 16) + ri->ri_flg |= RI_BITSWAP; +#endif +#endif + ri->ri_bits = (char *) bus_space_vaddr(sc->sc_cvgt, sc->sc_fbh); scr->scr_flags |= VCONS_DONT_READ; @@ -273,6 +290,13 @@ tdvfb_init_screen(void *cookie, struct v sc->sc_width / ri->ri_font->fontwidth); ri->ri_hw = scr; + + /* If we are a Voodoo2 and running in 16 bits try to use blitter. */ + if ((sc->sc_voodootype == TDV_VOODOO_2) && (sc->sc_bpp == 16)) { + aprint_normal_dev(sc->sc_dev, "using CVG blitter\n"); + ri->ri_ops.eraserows = tdvfb_eraserows; + ri->ri_ops.copyrows = tdvfb_copyrows; + } } static bool @@ -372,7 +396,12 @@ tdvfb_videomode_set(struct tdvfb_softc * TDV_INITENABLE_EN_FIFO); tdvfb_wait(sc); - lfbmode = TDV_LFBMODE_8888; + if (sc->sc_bpp == 16) + lfbmode = TDV_LFBMODE_565; + else if (sc->sc_bpp == 32) + lfbmode = TDV_LFBMODE_8888; + else + return false; #if BYTE_ORDER == BIG_ENDIAN lfbmode |= TDV_LFBMODE_BSW_WR | TDV_LFBMODE_BSW_RD; @@ -759,7 +788,7 @@ tdvfb_cvg_dac_read(struct tdvfb_softc *s return rv & 0xFF; } -void +static void tdvfb_cvg_dac_write(struct tdvfb_softc *sc, uint32_t reg, uint32_t val) { uint32_t wreg; @@ -775,3 +804,88 @@ tdvfb_cvg_dac_write(struct tdvfb_softc * tdvfb_wait(sc); } +static void +tdvfb_rectfill(struct tdvfb_softc *sc, int x, int y, int wi, int he, + uint32_t color) +{ + tdvfb_cvg_write(sc, TDV_OFF_BLTSRC, 0); + tdvfb_cvg_write(sc, TDV_OFF_BLTDST, 0); + tdvfb_cvg_write(sc, TDV_OFF_BLTROP, TDV_BLTROP_COPY); + tdvfb_cvg_write(sc, TDV_OFF_BLTXYSTRIDE, + sc->sc_linebytes | (sc->sc_linebytes << 16)); + tdvfb_cvg_write(sc, TDV_OFF_BLTDSTXY, x | (y << 16)); + tdvfb_cvg_write(sc, TDV_OFF_BLTSIZE, wi | (he << 16)); + tdvfb_cvg_write(sc, TDV_OFF_BLTCMD, TDV_BLTCMD_RECTFILL | + TDV_BLTCMD_LAUNCH | TDV_BLTCMD_FMT_565 << 3 | TDV_BLTCMD_DSTTILED | + TDV_BLTCMD_CLIPRECT ); + tdvfb_wait(sc); +} + +static void +tdvfb_bitblt(struct tdvfb_softc *sc, int xs, int ys, int xd, int yd, int wi, + int he) +{ + tdvfb_cvg_write(sc, TDV_OFF_BLTSRC, 0); + tdvfb_cvg_write(sc, TDV_OFF_BLTDST, 0); + tdvfb_cvg_write(sc, TDV_OFF_BLTROP, TDV_BLTROP_COPY); + tdvfb_cvg_write(sc, TDV_OFF_BLTXYSTRIDE, + sc->sc_linebytes | (sc->sc_linebytes << 16)); + tdvfb_cvg_write(sc, TDV_OFF_BLTSRCXY, xs | (ys << 16)); + tdvfb_cvg_write(sc, TDV_OFF_BLTDSTXY, xd | (yd << 16)); + tdvfb_cvg_write(sc, TDV_OFF_BLTSIZE, wi | (he << 16)); + tdvfb_cvg_write(sc, TDV_OFF_BLTCMD, TDV_BLTCMD_SCR2SCR | + TDV_BLTCMD_LAUNCH | TDV_BLTCMD_FMT_565 << 3); + + tdvfb_wait(sc); +} + +static void +tdvfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) +{ + struct tdvfb_softc *sc; + struct rasops_info *ri; + struct vcons_screen *scr; + int x, ys, yd, wi, he; + + ri = cookie; + scr = ri->ri_hw; + sc = scr->scr_cookie; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + x = ri->ri_xorigin; + ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; + yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; + wi = ri->ri_emuwidth; + he = ri->ri_font->fontheight * nrows; + tdvfb_bitblt(sc, x, ys, x, yd, wi, he); + } +} + +static void +tdvfb_eraserows(void *cookie, int row, int nrows, long fillattr) +{ + + struct tdvfb_softc *sc; + struct rasops_info *ri; + struct vcons_screen *scr; + int x, y, wi, he, fg, bg, ul; + + ri = cookie; + scr = ri->ri_hw; + sc = scr->scr_cookie; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + rasops_unpack_attr(fillattr, &fg, &bg, &ul); + if ((row == 0) && (nrows == ri->ri_rows)) + tdvfb_rectfill(sc, 0, 0, ri->ri_width, + ri->ri_height, ri->ri_devcmap[bg]); + else { + x = ri->ri_xorigin; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + wi = ri->ri_emuwidth; + he = ri->ri_font->fontheight * nrows; + tdvfb_rectfill(sc, x, y, wi, he, ri->ri_devcmap[bg]); + } + } +} + Index: src/sys/dev/pci/tdvfbreg.h diff -u src/sys/dev/pci/tdvfbreg.h:1.2 src/sys/dev/pci/tdvfbreg.h:1.3 --- src/sys/dev/pci/tdvfbreg.h:1.2 Fri Jul 20 12:03:32 2012 +++ src/sys/dev/pci/tdvfbreg.h Fri Jul 20 21:31:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: tdvfbreg.h,v 1.2 2012/07/20 12:03:32 rkujawa Exp $ */ +/* $NetBSD: tdvfbreg.h,v 1.3 2012/07/20 21:31:28 rkujawa Exp $ */ /* * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -133,6 +133,31 @@ #define TDV_OFF_FBIINIT6 0x0248 #define TDV_FBIINIT6_TILES_X_LSB 30 +#define TDV_OFF_BLTSRC 0x02C0 +#define TDV_OFF_BLTDST 0x02C4 +#define TDV_OFF_BLTXYSTRIDE 0x02C8 +#define TDV_OFF_BLTSRCCHROMA 0x02CC +#define TDV_OFF_BLTDSTCHROMA 0x02D0 +#define TDV_OFF_BLTCLIPX 0x02D4 +#define TDV_OFF_BLTCLIPY 0x02D8 +#define TDV_OFF_BLTSRCXY 0x02E0 +#define TDV_OFF_BLTDSTXY 0x02E4 +#define TDV_OFF_BLTSIZE 0x02E8 +#define TDV_OFF_BLTROP 0x02EC +#define TDV_BLTROP_COPY 0x0CCCC +#define TDV_BLTROP_INVERT 0x05555 +#define TDV_BLTROP_XOR 0x06666 +#define TDV_OFF_BLTCOLOR 0x02F0 +#define TDV_OFF_BLTCMD 0x02F8 +#define TDV_BLTCMD_SCR2SCR 0 +#define TDV_BLTCMD_CPU2SCR 1 +#define TDV_BLTCMD_RECTFILL 2 +#define TDV_BLTCMD_LAUNCH __BIT(31) +#define TDV_BLTCMD_FMT_565 2 +#define TDV_BLTCMD_CLIPRECT __BIT(16) +#define TDV_BLTCMD_DSTTILED __BIT(15) +#define TDV_OFF_DATA 0x02FC /* CPU2SCR */ + /* DAC */ #define TDV_GENDAC_REFFREQ 14318 #define TDV_GENDAC_MAXVCO 250000 /* not sure about that */