Module Name: src
Committed By: macallan
Date: Thu Aug 6 18:26:03 UTC 2009
Modified Files:
src/sys/dev/sbus: files.sbus tcx.c tcxreg.h
Log Message:
make the tcx driver do something useful:
- attach a wsdisplay
- make it work with an S24
- accelerate scrolling and character drawing
This isn't quite finished yet, it works fine as a console but most things
X will need are not functional right now.
To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/sbus/files.sbus
cvs rdiff -u -r1.31 -r1.32 src/sys/dev/sbus/tcx.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/sbus/tcxreg.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/sbus/files.sbus
diff -u src/sys/dev/sbus/files.sbus:1.32 src/sys/dev/sbus/files.sbus:1.33
--- src/sys/dev/sbus/files.sbus:1.32 Thu Apr 23 20:46:49 2009
+++ src/sys/dev/sbus/files.sbus Thu Aug 6 18:26:03 2009
@@ -1,4 +1,4 @@
-# $NetBSD: files.sbus,v 1.32 2009/04/23 20:46:49 macallan Exp $
+# $NetBSD: files.sbus,v 1.33 2009/08/06 18:26:03 macallan Exp $
#
# Config file and device description for machine-independent SBUS code.
# Included by ports that need it.
@@ -115,7 +115,7 @@
file dev/sbus/cgthree_sbus.c cgthree_sbus
# framebuffer devices implemented only on SBus
-device tcx: bt_dac, fb, rasops8, rasops24
+device tcx: bt_dac, fb, rasops8, wsemuldisplaydev, vcons
attach tcx at sbus
file dev/sbus/tcx.c tcx needs-flag
@@ -125,6 +125,7 @@
# Tadpole 3GX/3GS (P9100 -- P Nine One Zero Zero -> pnozz)
defflag opt_pnozz.h PNOZZ_DEBUG
+defflag opt_pnozz.h PNOZZ_EMUL_CG3
device pnozz: fb, rasops8, bt_dac, wsemuldisplaydev, vcons
attach pnozz at sbus
file dev/sbus/p9100.c pnozz needs-flag
Index: src/sys/dev/sbus/tcx.c
diff -u src/sys/dev/sbus/tcx.c:1.31 src/sys/dev/sbus/tcx.c:1.32
--- src/sys/dev/sbus/tcx.c:1.31 Tue May 12 14:43:59 2009
+++ src/sys/dev/sbus/tcx.c Thu Aug 6 18:26:03 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: tcx.c,v 1.31 2009/05/12 14:43:59 cegger Exp $ */
+/* $NetBSD: tcx.c,v 1.32 2009/08/06 18:26:03 macallan Exp $ */
/*
* Copyright (c) 1996,1998 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.31 2009/05/12 14:43:59 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.32 2009/08/06 18:26:03 macallan Exp $");
/*
* define for cg8 emulation on S24 (24-bit version of tcx) for the SS5;
@@ -72,6 +72,15 @@
#include <dev/sbus/sbusvar.h>
#include <dev/sbus/tcxreg.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wsfont/wsfont.h>
+#include <dev/rasops/rasops.h>
+
+#include <dev/wscons/wsdisplay_vconsvar.h>
+
+#include "opt_wsemul.h"
+
/* per-display variables */
struct tcx_softc {
struct device sc_dev; /* base device */
@@ -80,14 +89,41 @@
bus_space_tag_t sc_bustag;
struct openprom_addr sc_physadr[TCX_NREG];/* phys addr of h/w */
- volatile struct bt_regs *sc_bt; /* Brooktree registers */
- volatile struct tcx_thc *sc_thc;/* THC registers */
-#ifdef TCX_CG8
- volatile ulong *sc_cplane; /* framebuffer with control planes */
-#endif
+ bus_space_handle_t sc_bt; /* Brooktree registers */
+ bus_space_handle_t sc_thc; /* THC registers */
+ uint8_t *sc_fbaddr; /* framebuffer */
+ uint64_t *sc_rblit; /* blitspace */
+ uint64_t *sc_rstip; /* stipple space */
+
short sc_8bit; /* true if 8-bit hardware */
short sc_blanked; /* true if blanked */
- union bt_cmap sc_cmap; /* Brooktree color map */
+ u_char sc_cmap_red[256];
+ u_char sc_cmap_green[256];
+ u_char sc_cmap_blue[256];
+ int sc_mode, sc_bg;
+ struct vcons_data vd;
+};
+
+static struct vcons_screen tcx_console_screen;
+
+extern const u_char rasops_cmap[768];
+
+struct wsscreen_descr tcx_defscreendesc = {
+ "default",
+ 0, 0,
+ NULL,
+ 8, 16,
+ WSSCREEN_WSCOLORS,
+};
+
+const struct wsscreen_descr *_tcx_scrlist[] = {
+ &tcx_defscreendesc,
+ /* XXX other formats, graphics screen? */
+};
+
+struct wsscreen_list tcx_screenlist = {
+ sizeof(_tcx_scrlist) / sizeof(struct wsscreen_descr *),
+ _tcx_scrlist
};
/*
@@ -134,6 +170,26 @@
static void tcx_reset(struct tcx_softc *);
static void tcx_loadcmap(struct tcx_softc *, int, int);
+static int tcx_ioctl(void *, void *, u_long, void *, int, struct lwp *);
+static paddr_t tcx_mmap(void *, void *, off_t, int);
+
+static void tcx_init_screen(void *, struct vcons_screen *, int, long *);
+static void tcx_clearscreen(struct tcx_softc *);
+static void tcx_copyrows(void *, int, int, int);
+static void tcx_eraserows(void *, int, int, long);
+static void tcx_putchar(void *, int, int, u_int, long);
+
+struct wsdisplay_accessops tcx_accessops = {
+ tcx_ioctl,
+ tcx_mmap,
+ NULL, /* vcons_alloc_screen */
+ NULL, /* vcons_free_screen */
+ NULL, /* vcons_show_screen */
+ NULL, /* load_font */
+ NULL, /* polls */
+ NULL, /* scroll */
+};
+
#define OBPNAME "SUNW,tcx"
#ifdef TCX_CG8
@@ -168,11 +224,14 @@
{
struct tcx_softc *sc = device_private(self);
struct sbus_attach_args *sa = args;
+ struct wsemuldisplaydev_attach_args aa;
+ struct rasops_info *ri;
+ unsigned long defattr;
int node, ramsize;
- volatile struct bt_regs *bt;
struct fbdevice *fb = &sc->sc_fb;
bus_space_handle_t bh;
- int isconsole;
+ int isconsole, i, j;
+ uint32_t confreg;
sc->sc_bustag = sa->sa_bustag;
node = sa->sa_node;
@@ -187,65 +246,27 @@
* presence of the "tcx-8-bit" attribute on the SS4 version.
*/
sc->sc_8bit = node_has_property(node, "tcx-8-bit");
-#ifdef TCX_CG8
- if (sc->sc_8bit) {
-#endif
- /*
- * cg8 emulation is either not compiled in or not supported
- * on this hardware. Report values for the 8-bit framebuffer
- * so cg3 emulation works. (If this hardware supports
- * 24-bit mode, the 24-bit framebuffer will also be available)
- */
- fb->fb_type.fb_depth = 8;
- fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node);
+ fb->fb_type.fb_depth = 8;
+ fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node);
- ramsize = fb->fb_type.fb_height * fb->fb_linebytes;
-#ifdef TCX_CG8
+ if (sc->sc_8bit) {
+ printf(" {8bit only TCX)");
+ ramsize = 1024 * 1024;
+ /* XXX - fix THC and TEC offsets */
+ sc->sc_physadr[TCX_REG_TEC].oa_base += 0x1000;
+ sc->sc_physadr[TCX_REG_THC].oa_base += 0x1000;
} else {
- /*
- * for cg8 emulation, unconditionally report the depth as
- * 32 bits, but use the height and width reported by the
- * boot prom. cg8 users want to see the full size of
- * overlay planes plus color planes included in the
- * reported framebuffer size.
- */
- fb->fb_type.fb_depth = 32;
- fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node);
- fb->fb_linebytes =
- (fb->fb_type.fb_width * fb->fb_type.fb_depth) / 8;
- ramsize = TCX_CG8OVERLAY +
- (fb->fb_type.fb_height * fb->fb_linebytes);
+ printf(" (S24)\n");
+ ramsize = 4 * 1024 * 1024;
}
-#endif
+
fb->fb_type.fb_cmsize = 256;
fb->fb_type.fb_size = ramsize;
printf(": %s, %d x %d", OBPNAME,
fb->fb_type.fb_width,
fb->fb_type.fb_height);
-#ifdef TCX_CG8
- /*
- * if cg8 emulation is enabled, say so; but if hardware can't
- * emulate cg8, explain that instead
- */
- printf( (sc->sc_8bit)?
- " (8-bit only)" :
- " (emulating cg8)");
-#endif
- /*
- * XXX - should be set to FBTYPE_TCX.
- * XXX For CG3 emulation to work in current (96/6) X11 servers,
- * XXX `fbtype' must point to an "unregocnised" entry.
- */
-#ifdef TCX_CG8
- if (sc->sc_8bit) {
- fb->fb_type.fb_type = FBTYPE_RESERVED3;
- } else {
- fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
- }
-#else
- fb->fb_type.fb_type = FBTYPE_RESERVED3;
-#endif
+ fb->fb_type.fb_type = FBTYPE_SUNTCX;
if (sa->sa_nreg != TCX_NREG) {
@@ -256,73 +277,135 @@
memcpy(sc->sc_physadr, sa->sa_reg,
sa->sa_nreg * sizeof(struct openprom_addr));
- /* XXX - fix THC and TEC offsets */
- sc->sc_physadr[TCX_REG_TEC].oa_base += 0x1000;
- sc->sc_physadr[TCX_REG_THC].oa_base += 0x1000;
-
/* Map the register banks we care about */
if (sbus_bus_map(sa->sa_bustag,
sc->sc_physadr[TCX_REG_THC].oa_space,
sc->sc_physadr[TCX_REG_THC].oa_base,
- sizeof (struct tcx_thc),
- BUS_SPACE_MAP_LINEAR, &bh) != 0) {
+ 0x1000,
+ BUS_SPACE_MAP_LINEAR, &sc->sc_thc) != 0) {
printf("tcxattach: cannot map thc registers\n");
return;
}
- sc->sc_thc = (volatile struct tcx_thc *)
- bus_space_vaddr(sa->sa_bustag, bh);
if (sbus_bus_map(sa->sa_bustag,
sc->sc_physadr[TCX_REG_CMAP].oa_space,
sc->sc_physadr[TCX_REG_CMAP].oa_base,
- sizeof (struct bt_regs),
- BUS_SPACE_MAP_LINEAR, &bh) != 0) {
+ 0x1000,
+ BUS_SPACE_MAP_LINEAR, &sc->sc_bt) != 0) {
printf("tcxattach: cannot map bt registers\n");
return;
}
- sc->sc_bt = bt = (volatile struct bt_regs *)
- bus_space_vaddr(sa->sa_bustag, bh);
-#ifdef TCX_CG8
- if (!sc->sc_8bit) {
- if (sbus_bus_map(sa->sa_bustag,
- sc->sc_physadr[TCX_REG_RDFB32].oa_space,
- sc->sc_physadr[TCX_REG_RDFB32].oa_base,
- TCX_SIZE_DFB32,
+ /* map the 8bit dumb FB for the console */
+ if (sbus_bus_map(sa->sa_bustag,
+ sc->sc_physadr[TCX_REG_DFB8].oa_space,
+ sc->sc_physadr[TCX_REG_DFB8].oa_base,
+ 1024 * 1024,
BUS_SPACE_MAP_LINEAR,
&bh) != 0) {
- printf("tcxattach: cannot map control planes\n");
- return;
- }
- sc->sc_cplane = (volatile ulong *)bh;
+ printf("tcxattach: cannot map framebuffer\n");
+ return;
}
-#endif
+ sc->sc_fbaddr = bus_space_vaddr(sa->sa_bustag, bh);
+
+ /* RBLIT space */
+ if (sbus_bus_map(sa->sa_bustag,
+ sc->sc_physadr[TCX_REG_RBLIT].oa_space,
+ sc->sc_physadr[TCX_REG_RBLIT].oa_base,
+ 8 * 1024 * 1024,
+ BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
+ &bh) != 0) {
+ printf("tcxattach: cannot map RBLIT space\n");
+ return;
+ }
+ sc->sc_rblit = bus_space_vaddr(sa->sa_bustag, bh);
+
+ /* RSTIP space */
+ if (sbus_bus_map(sa->sa_bustag,
+ sc->sc_physadr[TCX_REG_RSTIP].oa_space,
+ sc->sc_physadr[TCX_REG_RSTIP].oa_base,
+ 8 * 1024 * 1024,
+ BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
+ &bh) != 0) {
+ printf("tcxattach: cannot map RSTIP space\n");
+ return;
+ }
+ sc->sc_rstip = bus_space_vaddr(sa->sa_bustag, bh);
isconsole = fb_is_console(node);
+ confreg = bus_space_read_4(sa->sa_bustag, sc->sc_thc, THC_CONFIG);
printf(", id %d, rev %d, sense %d",
- (sc->sc_thc->thc_config & THC_CFG_FBID) >> THC_CFG_FBID_SHIFT,
- (sc->sc_thc->thc_config & THC_CFG_REV) >> THC_CFG_REV_SHIFT,
- (sc->sc_thc->thc_config & THC_CFG_SENSE) >> THC_CFG_SENSE_SHIFT
+ (confreg & THC_CFG_FBID) >> THC_CFG_FBID_SHIFT,
+ (confreg & THC_CFG_REV) >> THC_CFG_REV_SHIFT,
+ (confreg & THC_CFG_SENSE) >> THC_CFG_SENSE_SHIFT
);
/* reset cursor & frame buffer controls */
tcx_reset(sc);
/* Initialize the default color map. */
- bt_initcmap(&sc->sc_cmap, 256);
+ j = 0;
+ for (i = 0; i < 256; i++) {
+
+ sc->sc_cmap_red[i] = rasops_cmap[j];
+ sc->sc_cmap_green[i] = rasops_cmap[j + 1];
+ sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
+ j += 3;
+ }
tcx_loadcmap(sc, 0, 256);
/* enable video */
- sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
+ confreg = bus_space_read_4(sa->sa_bustag, sc->sc_thc, THC_MISC);
+ confreg |= THC_MISC_VIDEN;
+ bus_space_write_4(sa->sa_bustag, sc->sc_thc, THC_MISC, confreg);
if (isconsole) {
printf(" (console)\n");
} else
printf("\n");
+ bus_space_write_4(sa->sa_bustag, sc->sc_bt, DAC_ADDRESS, 0);
+ printf("DAC ID: %02x %02x\n",
+ bus_space_read_1(sa->sa_bustag, sc->sc_bt, DAC_CONTROL_1),
+ bus_space_read_1(sa->sa_bustag, sc->sc_bt, DAC_CONTROL_1));
sbus_establish(&sc->sc_sd, &sc->sc_dev);
fb_attach(&sc->sc_fb, isconsole);
+
+ sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
+ wsfont_init();
+
+ vcons_init(&sc->vd, sc, &tcx_defscreendesc, &tcx_accessops);
+ sc->vd.init_screen = tcx_init_screen;
+
+ vcons_init_screen(&sc->vd, &tcx_console_screen, 1, &defattr);
+ tcx_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+
+ sc->sc_bg = (defattr >> 16) & 0xff;
+ tcx_clearscreen(sc);
+
+ ri = &tcx_console_screen.scr_ri;
+
+ tcx_defscreendesc.nrows = ri->ri_rows;
+ tcx_defscreendesc.ncols = ri->ri_cols;
+ tcx_defscreendesc.textops = &ri->ri_ops;
+ tcx_defscreendesc.capabilities = ri->ri_caps;
+
+ if(isconsole) {
+ wsdisplay_cnattach(&tcx_defscreendesc, ri, 0, 0, defattr);
+ }
+
+ aa.console = isconsole;
+ aa.scrdata = &tcx_screenlist;
+ aa.accessops = &tcx_accessops;
+ aa.accesscookie = &sc->vd;
+
+ config_found(self, &aa, wsemuldisplaydevprint);
+ /*
+ * we need to do this again - something overwrites a handful
+ * palette registers and we end up with white in reg. 0
+ */
+ tcx_loadcmap(sc, 0, 256);
}
#ifdef TCX_CG8
@@ -407,7 +490,7 @@
tcxioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
{
struct tcx_softc *sc = device_lookup_private(&tcx_cd, minor(dev));
- int error;
+ //int error;
switch (cmd) {
@@ -428,7 +511,7 @@
fba->emu_types[2] = -1;
#undef fba
break;
-
+#if 0
case FBIOGETCMAP:
#define p ((struct fbcmap *)data)
return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
@@ -452,7 +535,7 @@
tcx_loadcmap(sc, p->index, p->count);
#undef p
break;
-
+#endif
case FBIOGVIDEO:
*(int *)data = sc->sc_blanked;
break;
@@ -462,10 +545,10 @@
tcx_unblank(&sc->sc_dev);
else if (!sc->sc_blanked) {
sc->sc_blanked = 1;
- sc->sc_thc->thc_hcmisc &= ~THC_MISC_VIDEN;
+ //sc->sc_thc->thc_hcmisc &= ~THC_MISC_VIDEN;
/* Put monitor in `power-saving mode' */
- sc->sc_thc->thc_hcmisc |= THC_MISC_VSYNC_DISABLE;
- sc->sc_thc->thc_hcmisc |= THC_MISC_HSYNC_DISABLE;
+ //sc->sc_thc->thc_hcmisc |= THC_MISC_VSYNC_DISABLE;
+ //sc->sc_thc->thc_hcmisc |= THC_MISC_HSYNC_DISABLE;
}
break;
@@ -485,12 +568,11 @@
static void
tcx_reset(struct tcx_softc *sc)
{
- volatile struct bt_regs *bt;
/* Enable cursor in Brooktree DAC. */
- bt = sc->sc_bt;
- bt->bt_addr = 0x06 << 24;
- bt->bt_ctrl |= 0x03 << 24;
+ /* TODO: bus_spacify */
+// bt->bt_addr = 0x06 << 24;
+// bt->bt_ctrl |= 0x03 << 24;
}
/*
@@ -499,22 +581,19 @@
static void
tcx_loadcmap(struct tcx_softc *sc, int start, int ncolors)
{
- volatile struct bt_regs *bt;
- u_int *ip, i;
- int count;
-
- ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)]; /* start/4 * 3 */
- count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
- bt = sc->sc_bt;
- bt->bt_addr = BT_D4M4(start) << 24;
- while (--count >= 0) {
- i = *ip++;
- /* hardware that makes one want to pound boards with hammers */
- bt->bt_cmap = i;
- bt->bt_cmap = i << 8;
- bt->bt_cmap = i << 16;
- bt->bt_cmap = i << 24;
+ int i;
+
+ for (i = 0; i < ncolors; i++) {
+ bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_ADDRESS,
+ (start + i) << 24);
+ bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_FB_LUT,
+ sc->sc_cmap_red[i + start] << 24);
+ bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_FB_LUT,
+ sc->sc_cmap_green[i + start] << 24);
+ bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_FB_LUT,
+ sc->sc_cmap_blue[i + start] << 24);
}
+ bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_ADDRESS, 0);
}
static void
@@ -523,10 +602,11 @@
struct tcx_softc *sc = device_private(dev);
if (sc->sc_blanked) {
+
sc->sc_blanked = 0;
- sc->sc_thc->thc_hcmisc &= ~THC_MISC_VSYNC_DISABLE;
- sc->sc_thc->thc_hcmisc &= ~THC_MISC_HSYNC_DISABLE;
- sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
+ //sc->sc_thc->thc_hcmisc &= ~THC_MISC_VSYNC_DISABLE;
+ //sc->sc_thc->thc_hcmisc &= ~THC_MISC_HSYNC_DISABLE;
+ //sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
}
}
@@ -581,7 +661,7 @@
{ TCX_USER_RBLIT, 1, TCX_REG_RBLIT },
{ TCX_USER_TEC, 1, TCX_REG_TEC },
{ TCX_USER_BTREGS, 8192 /* XXX */, TCX_REG_CMAP },
- { TCX_USER_THC, sizeof(struct tcx_thc), TCX_REG_THC },
+ { TCX_USER_THC, 0x1000, TCX_REG_THC },
{ TCX_USER_DHC, 1, TCX_REG_DHC },
{ TCX_USER_ALT, 1, TCX_REG_ALT },
{ TCX_USER_ROM, 65536, TCX_REG_ROM },
@@ -659,3 +739,341 @@
}
return (-1);
}
+
+int
+tcx_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
+ struct lwp *l)
+{
+ struct vcons_data *vd = v;
+ struct tcx_softc *sc = vd->cookie;
+ struct wsdisplay_fbinfo *wdf;
+ struct vcons_screen *ms = vd->active;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_SUNTCX;
+ return 0;
+
+#if 0
+ case FBIOGVIDEO:
+ case WSDISPLAYIO_GVIDEO:
+ *(int *)data = tcx_get_video(sc);
+ return 0;
+
+ case WSDISPLAYIO_SVIDEO:
+ case FBIOSVIDEO:
+ tcx_set_video(sc, *(int *)data);
+ return 0;
+#endif
+ case WSDISPLAYIO_GINFO:
+ wdf = (void *)data;
+ wdf->height = ms->scr_ri.ri_height;
+ wdf->width = ms->scr_ri.ri_width;
+ wdf->depth = ms->scr_ri.ri_depth;
+ wdf->cmsize = 256;
+ return 0;
+#if 0
+ case WSDISPLAYIO_GETCMAP:
+ return tcx_getcmap(sc, (struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_PUTCMAP:
+ return tcx_putcmap(sc, (struct wsdisplay_cmap *)data);
+#endif
+ case WSDISPLAYIO_SMODE:
+ {
+ int new_mode = *(int*)data;
+ if (new_mode != sc->sc_mode)
+ {
+ sc->sc_mode = new_mode;
+ if (new_mode == WSDISPLAYIO_MODE_EMUL)
+ {
+#if 0
+ tcxloadcmap(sc, 0, 256);
+ tcx_clearscreen(sc);
+#endif
+ vcons_redraw_screen(ms);
+ }
+ }
+ }
+ }
+ return EPASSTHROUGH;
+}
+
+static paddr_t
+tcx_mmap(void *v, void *vs, off_t offset, int prot)
+{
+#if 0
+ struct vcons_data *vd = v;
+ struct tcx_softc *sc = vd->cookie;
+ paddr_t pa;
+
+ /* 'regular' framebuffer mmap()ing */
+ if (offset < sc->sc_fb_psize) {
+ pa = bus_space_mmap(sc->sc_bustag, sc->sc_fb_paddr + offset, 0,
+ prot, BUS_SPACE_MAP_LINEAR);
+ return pa;
+ }
+
+ if ((offset >= sc->sc_fb_paddr) && (offset < (sc->sc_fb_paddr +
+ sc->sc_fb_psize))) {
+ pa = bus_space_mmap(sc->sc_bustag, offset, 0, prot,
+ BUS_SPACE_MAP_LINEAR);
+ return pa;
+ }
+
+ if ((offset >= sc->sc_ctl_paddr) && (offset < (sc->sc_ctl_paddr +
+ sc->sc_ctl_psize))) {
+ pa = bus_space_mmap(sc->sc_bustag, offset, 0, prot,
+ BUS_SPACE_MAP_LINEAR);
+ return pa;
+ }
+#endif
+ return -1;
+}
+
+static void
+tcx_init_screen(void *cookie, struct vcons_screen *scr,
+ int existing, long *defattr)
+{
+ struct tcx_softc *sc = cookie;
+ struct rasops_info *ri = &scr->scr_ri;
+
+ ri->ri_depth = 8;
+ ri->ri_width = sc->sc_fb.fb_type.fb_width;
+ ri->ri_height = sc->sc_fb.fb_type.fb_height;
+ ri->ri_stride = sc->sc_fb.fb_linebytes;
+ ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
+
+ ri->ri_bits = sc->sc_fbaddr;
+
+ rasops_init(ri, ri->ri_height/8, ri->ri_width/8);
+ ri->ri_caps = WSSCREEN_WSCOLORS;
+ rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
+ ri->ri_width / ri->ri_font->fontwidth);
+
+ /* enable acceleration */
+ ri->ri_ops.copyrows = tcx_copyrows;
+ ri->ri_ops.eraserows = tcx_eraserows;
+ ri->ri_ops.putchar = tcx_putchar;
+#if 0
+ ri->ri_ops.cursor = tcx_cursor;
+ ri->ri_ops.copycols = tcx_copycols;
+ ri->ri_ops.erasecols = tcx_erasecols;
+#endif
+}
+
+static void
+tcx_clearscreen(struct tcx_softc *sc)
+{
+ uint64_t bg = ((uint64_t)sc->sc_bg << 32) | 0xffffffffLL;
+ int i;
+
+ for (i = 0; i < 1024 * 1024; i += 32)
+ sc->sc_rstip[i] = bg;
+}
+
+static void
+tcx_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
+{
+ struct rasops_info *ri = cookie;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct tcx_softc *sc = scr->scr_cookie;
+ int i, last, first, len, dest, leftover;
+
+ i = ri->ri_width * ri->ri_font->fontheight * nrows;
+ len = i & 0xffffe0;
+ leftover = i & 0x1f;
+ if (srcrow < dstrow) {
+ /* we must go bottom to top */
+ first = ri->ri_width *
+ (ri->ri_font->fontheight * srcrow + ri->ri_yorigin);
+ last = first + len;
+ dest = ri->ri_width *
+ (ri->ri_font->fontheight * dstrow + ri->ri_yorigin) + len;
+ if (leftover > 0) {
+ sc->sc_rblit[dest + 32] =
+ (uint64_t)((leftover - 1) << 24) |
+ (uint64_t)(i + 32);
+ }
+ for (i = last; i >= first; i -= 32) {
+ sc->sc_rblit[dest] = 0x300000001f000000LL | (uint64_t)i;
+ dest -= 32;
+ }
+ } else {
+ /* top to bottom */
+ first = ri->ri_width *
+ (ri->ri_font->fontheight * srcrow + ri->ri_yorigin);
+ dest = ri->ri_width *
+ (ri->ri_font->fontheight * dstrow + ri->ri_yorigin);
+ last = first + len;
+ for (i = first; i <= last; i+= 32) {
+ sc->sc_rblit[dest] = 0x300000001f000000LL | (uint64_t)i;
+ dest += 32;
+ }
+ if (leftover > 0) {
+ sc->sc_rblit[dest] =
+ (uint64_t)((leftover - 1) << 24) | (uint64_t)i;
+ }
+ }
+}
+
+static void
+tcx_eraserows(void *cookie, int start, int nrows, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct tcx_softc *sc = scr->scr_cookie;
+ uint64_t temp;
+ int i, last, first, len, leftover;
+
+ i = ri->ri_width * ri->ri_font->fontheight * nrows;
+ len = i & 0xffffe0;
+ leftover = i & 0x1f;
+ first = ri->ri_width *
+ (ri->ri_font->fontheight * start + ri->ri_yorigin);
+ last = first + len;
+ temp = 0x30000000ffffffffLL |
+ ((uint64_t)ri->ri_devcmap[(attr >> 16) & 0xff] << 32);
+
+ for (i = first; i <= last; i+= 32)
+ sc->sc_rblit[i] = temp;
+
+ if (leftover > 0) {
+ temp &= 0xffffffffffffffffLL << (32 - leftover);
+ sc->sc_rblit[i] = temp;
+ }
+}
+/*
+ * The stipple engine is 100% retarded. All drawing operations have to start
+ * at 32 pixel boundaries so we'll have to deal with characters being split.
+ */
+
+static void
+tcx_putchar(void *cookie, int row, int col, u_int c, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct tcx_softc *sc = scr->scr_cookie;
+ uint64_t bg, fg, temp, mask;
+ int addr, i, uc, shift;
+ uint32_t fmask;
+ uint8_t *cdata;
+ uint16_t *wdata;
+
+ addr = ri->ri_xorigin +
+ col * ri->ri_font->fontwidth +
+ (ri->ri_yorigin + row * ri->ri_font->fontheight) * ri->ri_width;
+
+ /* check if the character is crossing a 32 pixel boundary */
+ if ((addr & 0xffffe0) ==
+ ((addr + ri->ri_font->fontwidth - 1) & 0xffffe0)) {
+ /* phew, not split */
+ shift = addr & 0x1f;
+ addr &= 0xffffe0;
+ fmask = 0xffffffff >> (32 - ri->ri_font->fontwidth);
+ fmask = fmask << (32 - ri->ri_font->fontwidth - shift);
+ mask = fmask;
+ bg = 0x3000000000000000LL |
+ ((uint64_t)ri->ri_devcmap[(attr >> 16) & 0xff] &
+ 0xff) << 32;
+ bg |= mask;
+ temp = 0x3000000000000000LL |
+ ((uint64_t)ri->ri_devcmap[(attr >> 24) & 0xff] & 0xff) <<
+ 32;
+ uc = c - ri->ri_font->firstchar;
+ cdata = (uint8_t *)ri->ri_font->data + uc * ri->ri_fontscale;
+
+ if (ri->ri_font->fontwidth < 9) {
+ /* byte by byte */
+ for (i = 0; i < ri->ri_font->fontheight; i++) {
+ sc->sc_rstip[addr] = bg;
+ if (*cdata != 0) {
+ if (shift > 24) {
+ fg = (uint64_t)*cdata >>
+ (shift - 24);
+ } else {
+ fg = (uint64_t)*cdata <<
+ (24 - shift);
+ }
+ sc->sc_rstip[addr] = fg | temp;
+ }
+ cdata++;
+ addr += ri->ri_width;
+ }
+ } else if (ri->ri_font->fontwidth < 17) {
+ /* short by short */
+ wdata = (uint16_t *)cdata;
+ for (i = 0; i < ri->ri_font->fontheight; i++) {
+ sc->sc_rstip[addr] = bg;
+ if (*wdata != 0) {
+ if (shift > 16) {
+ fg = temp | (uint64_t)*wdata >>
+ (shift - 16);
+ } else {
+ fg = temp | (uint64_t)*wdata <<
+ (16 - shift);
+ }
+ sc->sc_rstip[addr] = fg;
+ }
+ wdata++;
+ addr += ri->ri_width;
+ }
+ }
+ } else {
+ /* and now the split case ( man this hardware is dumb ) */
+ uint64_t bgr, maskr, fgr;
+ uint32_t bork;
+
+ shift = addr & 0x1f;
+ addr &= 0xffffe0;
+ mask = 0xffffffff >> shift;
+ maskr = (uint64_t)(0xffffffffUL <<
+ (32 - (ri->ri_font->fontwidth + shift - 32)));
+ bg = 0x3000000000000000LL |
+ ((uint64_t)ri->ri_devcmap[(attr >> 16) & 0xff] &
+ 0xff) << 32;
+ bgr = bg | maskr;
+ bg |= mask;
+ temp = 0x3000000000000000LL |
+ ((uint64_t)ri->ri_devcmap[(attr >> 24) & 0xff] & 0xff) <<
+ 32;
+
+ uc = c - ri->ri_font->firstchar;
+ cdata = (uint8_t *)ri->ri_font->data + uc * ri->ri_fontscale;
+
+ if (ri->ri_font->fontwidth < 9) {
+ /* byte by byte */
+ for (i = 0; i < ri->ri_font->fontheight; i++) {
+ sc->sc_rstip[addr] = bg;
+ sc->sc_rstip[addr + 32] = bgr;
+ bork = *cdata;
+ if (bork != 0) {
+ fg = (uint64_t)bork >> (shift - 24);
+ sc->sc_rstip[addr] = fg | temp;
+ fgr = (uint64_t)(bork << (52 - shift));
+ sc->sc_rstip[addr] = fgr | temp;
+ }
+ cdata++;
+ addr += ri->ri_width;
+ }
+ } else if (ri->ri_font->fontwidth < 17) {
+ /* short by short */
+ wdata = (uint16_t *)cdata;
+ for (i = 0; i < ri->ri_font->fontheight; i++) {
+ sc->sc_rstip[addr] = bg;
+ sc->sc_rstip[addr + 32] = bgr;
+ bork = *wdata;
+ if (bork != 0) {
+ fg = (uint64_t)bork >> (shift - 16);
+ sc->sc_rstip[addr] = fg | temp;
+ fgr = (uint64_t)(bork << (48 - shift));
+ sc->sc_rstip[addr + 32] = fgr | temp;
+ }
+ wdata++;
+ addr += ri->ri_width;
+ }
+ }
+
+ }
+}
+
Index: src/sys/dev/sbus/tcxreg.h
diff -u src/sys/dev/sbus/tcxreg.h:1.4 src/sys/dev/sbus/tcxreg.h:1.5
--- src/sys/dev/sbus/tcxreg.h:1.4 Mon Apr 28 20:23:57 2008
+++ src/sys/dev/sbus/tcxreg.h Thu Aug 6 18:26:03 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: tcxreg.h,v 1.4 2008/04/28 20:23:57 martin Exp $ */
+/* $NetBSD: tcxreg.h,v 1.5 2009/08/06 18:26:03 macallan Exp $ */
/*
* Copyright (c) 1996 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -64,23 +64,22 @@
/*
* The layout of the THC.
*/
-struct tcx_thc {
- u_int thc_config;
- u_int thc_xxx1[31];
- u_int thc_sensebus;
- u_int thc_xxx2[3];
- u_int thc_delay;
- u_int thc_strapping;
- u_int thc_xxx3[1];
- u_int thc_linecount;
- u_int thc_xxx4[478];
- u_int thc_hcmisc;
- u_int thc_xxx5[56];
- u_int thc_cursoraddr;
- u_int thc_cursorAdata[32];
- u_int thc_cursorBdata[32];
-};
+#define THC_CONFIG 0x00000000
+#define THC_SENSEBUS 0x00000080
+#define THC_DELAY 0x00000090
+#define THC_STRAPPING 0x00000094
+#define THC_LINECOUNTER 0x0000009c
+#define THC_HSYNC_START 0x000000a0
+#define THC_HSYNC_END 0x000000a4
+#define THC_HDISP_START 0x000000a8
+#define THC_HDISP_VSYNC 0x000000ac
+#define THC_HDISP_END 0x000000b0
+#define THC_MISC 0x00000818
+#define THC_CURSOR_POS 0x000008fc
+#define THC_CURSOR_1 0x00000900 /* bitmap bit 1 */
+#define THC_CURSOR_0 0x00000980 /* bitmap bit 0 */
+
/* bits in thc_config ??? */
#define THC_CFG_FBID 0xf0000000 /* id mask */
#define THC_CFG_FBID_SHIFT 28
@@ -141,3 +140,15 @@
u_int tec_vde; /* */
};
+/* DAC registers */
+#define DAC_ADDRESS 0x00000000
+#define DAC_FB_LUT 0x00000004 /* palette / gamma table */
+#define DAC_CONTROL_1 0x00000008
+#define DAC_CURSOR_LUT 0x0000000c /* cursor sprite colours */
+#define DAC_CONTROL_2 0x00000018
+
+#define DAC_C1_ID 0
+#define DAC_C1_REVISION 1
+#define DAC_C1_READ_MASK 4
+#define DAC_C1_BLINK_MASK 5
+#define DAC_C1_CONTROL_0 6