Module Name: src
Committed By: macallan
Date: Wed Aug 19 03:35:33 UTC 2009
Modified Files:
src/sys/dev/sbus: tcx.c
Log Message:
- some cosmetic fixes
- add support for screen blanking via /dev/fb*
- reimplement colour map ioctl()s for /dev/fb*
- implement mmap and ioctl for wscons, map 8 or 24bit framebuffer depending
on hardware
With this X works with the wsfb driver in 24bit.
TODO:
- fix wsfb to use the right pixel format for S24
- implement wsdisplay colour map ioctl()s
- add hardware cursor support for wscons and /dev/fb*
To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/sys/dev/sbus/tcx.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/dev/sbus/tcx.c
diff -u src/sys/dev/sbus/tcx.c:1.33 src/sys/dev/sbus/tcx.c:1.34
--- src/sys/dev/sbus/tcx.c:1.33 Tue Aug 18 20:45:42 2009
+++ src/sys/dev/sbus/tcx.c Wed Aug 19 03:35:32 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: tcx.c,v 1.33 2009/08/18 20:45:42 macallan Exp $ */
+/* $NetBSD: tcx.c,v 1.34 2009/08/19 03:35:32 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.33 2009/08/18 20:45:42 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.34 2009/08/19 03:35:32 macallan Exp $");
/*
* define for cg8 emulation on S24 (24-bit version of tcx) for the SS5;
@@ -87,7 +87,7 @@
struct sbusdev sc_sd; /* sbus device */
struct fbdevice sc_fb; /* frame buffer device */
bus_space_tag_t sc_bustag;
- struct openprom_addr sc_physadr[TCX_NREG];/* phys addr of h/w */
+ struct openprom_addr sc_physaddr[TCX_NREG];/* phys addr of h/w */
bus_space_handle_t sc_bt; /* Brooktree registers */
bus_space_handle_t sc_thc; /* THC registers */
@@ -251,11 +251,11 @@
fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node);
if (sc->sc_8bit) {
- printf(" {8bit only TCX)");
+ 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;
+ sc->sc_physaddr[TCX_REG_TEC].oa_base += 0x1000;
+ sc->sc_physaddr[TCX_REG_THC].oa_base += 0x1000;
} else {
printf(" (S24)\n");
ramsize = 4 * 1024 * 1024;
@@ -275,13 +275,13 @@
device_xname(self), sa->sa_nreg);
return;
}
- memcpy(sc->sc_physadr, sa->sa_reg,
+ memcpy(sc->sc_physaddr, sa->sa_reg,
sa->sa_nreg * sizeof(struct openprom_addr));
/* 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,
+ sc->sc_physaddr[TCX_REG_THC].oa_space,
+ sc->sc_physaddr[TCX_REG_THC].oa_base,
0x1000,
BUS_SPACE_MAP_LINEAR, &sc->sc_thc) != 0) {
printf("tcxattach: cannot map thc registers\n");
@@ -289,8 +289,8 @@
}
if (sbus_bus_map(sa->sa_bustag,
- sc->sc_physadr[TCX_REG_CMAP].oa_space,
- sc->sc_physadr[TCX_REG_CMAP].oa_base,
+ sc->sc_physaddr[TCX_REG_CMAP].oa_space,
+ sc->sc_physaddr[TCX_REG_CMAP].oa_base,
0x1000,
BUS_SPACE_MAP_LINEAR, &sc->sc_bt) != 0) {
printf("tcxattach: cannot map bt registers\n");
@@ -299,8 +299,8 @@
/* 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,
+ sc->sc_physaddr[TCX_REG_DFB8].oa_space,
+ sc->sc_physaddr[TCX_REG_DFB8].oa_base,
1024 * 1024,
BUS_SPACE_MAP_LINEAR,
&bh) != 0) {
@@ -311,8 +311,8 @@
/* 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,
+ sc->sc_physaddr[TCX_REG_RBLIT].oa_space,
+ sc->sc_physaddr[TCX_REG_RBLIT].oa_base,
8 * 1024 * 1024,
BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
&bh) != 0) {
@@ -323,8 +323,8 @@
/* 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,
+ sc->sc_physaddr[TCX_REG_RSTIP].oa_space,
+ sc->sc_physaddr[TCX_REG_RSTIP].oa_base,
8 * 1024 * 1024,
BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
&bh) != 0) {
@@ -405,46 +405,9 @@
tcx_loadcmap(sc, 0, 256);
}
-#ifdef TCX_CG8
-/*
- * keep track of the number of opens, so we can switch to 24-bit mode
- * when the device is first opened, and return to 8-bit mode on the
- * last close. (stolen from cgfourteen driver...) There can only be
- * one TCX per system, so we only need one flag.
- */
-static int tcx_opens = 0;
-#endif
-
int
tcxopen(dev_t dev, int flags, int mode, struct lwp *l)
{
-#ifdef TCX_CG8
- int unit = minor(dev);
- struct tcx_softc *sc;
- int i, s, oldopens;
- volatile ulong *cptr;
- struct fbdevice *fb;
-
- sc = device_lookup_private(&tcx_cd, unit);
- if (!sc)
- return (ENXIO);
- if (!sc->sc_8bit) {
- s = splhigh();
- oldopens = tcx_opens++;
- splx(s);
- if (oldopens == 0) {
- /*
- * rewrite the control planes to select 24-bit mode
- * and clear the screen
- */
- fb = &sc->sc_fb;
- i = fb->fb_type.fb_height * fb->fb_type.fb_width;
- cptr = sc->sc_cplane;
- while (--i >= 0)
- *cptr++ = TCX_CTL_24_LEVEL;
- }
- }
-#endif
return (0);
}
@@ -452,34 +415,9 @@
tcxclose(dev_t dev, int flags, int mode, struct lwp *l)
{
struct tcx_softc *sc = device_lookup_private(&tcx_cd, minor(dev));
-#ifdef TCX_CG8
- int i, s, opens;
- volatile ulong *cptr;
- struct fbdevice *fb;
-#endif
tcx_reset(sc);
-#ifdef TCX_CG8
- if (!sc->sc_8bit) {
- s = splhigh();
- opens = --tcx_opens;
- if (tcx_opens <= 0)
- opens = tcx_opens = 0;
- splx(s);
- if (opens == 0) {
- /*
- * rewrite the control planes to select 8-bit mode,
- * preserving the contents of the screen.
- * (or we could just bzero the whole thing...)
- */
- fb = &sc->sc_fb;
- i = fb->fb_type.fb_height * fb->fb_type.fb_width;
- cptr = sc->sc_cplane;
- while (--i >= 0)
- *cptr++ &= TCX_CTL_PIXELMASK;
- }
- }
-#endif
+ /* we may want to clear and redraw the console here */
return (0);
}
@@ -508,31 +446,31 @@
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));
+ if (copyout(&sc->sc_cmap_red[p->index], p->red, p->count) != 0)
+ return EINVAL;
+ if (copyout(&sc->sc_cmap_green[p->index], p->green, p->count)
+ != 0)
+ return EINVAL;
+ if (copyout(&sc->sc_cmap_blue[p->index], p->blue, p->count)
+ != 0)
+ return EINVAL;
+ return 0;
case FBIOPUTCMAP:
/* copy to software map */
-#ifdef TCX_CG8
- if (!sc->sc_8bit) {
- /*
- * cg8 has extra bits in high-order byte of the index
- * that bt_putcmap doesn't recognize
- */
- p->index &= 0xffffff;
- }
-#endif
- error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
- if (error)
- return (error);
- /* now blast them into the chip */
- /* XXX should use retrace interrupt */
+ if (copyin(p->red, &sc->sc_cmap_red[p->index], p->count) != 0)
+ return EINVAL;
+ if (copyin(p->green, &sc->sc_cmap_green[p->index], p->count)
+ != 0)
+ return EINVAL;
+ if (copyin(p->blue, &sc->sc_cmap_blue[p->index], p->count) != 0)
+ return EINVAL;
tcx_loadcmap(sc, p->index, p->count);
#undef p
break;
-#endif
case FBIOGVIDEO:
*(int *)data = sc->sc_blanked;
break;
@@ -541,11 +479,16 @@
if (*(int *)data)
tcx_unblank(sc->sc_dev);
else if (!sc->sc_blanked) {
+ uint32_t reg;
sc->sc_blanked = 1;
- //sc->sc_thc->thc_hcmisc &= ~THC_MISC_VIDEN;
+ reg = bus_space_read_4(sc->sc_bustag, sc->sc_thc,
+ THC_MISC);
+ reg &= ~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;
+ reg |= THC_MISC_VSYNC_DISABLE;
+ reg |= THC_MISC_HSYNC_DISABLE;
+ bus_space_write_4(sc->sc_bustag, sc->sc_thc, THC_MISC,
+ reg);
}
break;
@@ -566,10 +509,10 @@
tcx_reset(struct tcx_softc *sc)
{
- /* Enable cursor in Brooktree DAC. */
- /* TODO: bus_spacify */
-// bt->bt_addr = 0x06 << 24;
-// bt->bt_ctrl |= 0x03 << 24;
+ /* Disable cursor in Brooktree DAC. */
+ bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_ADDRESS,
+ DAC_C1_CONTROL_0);
+ bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_CONTROL_1, 0);
}
/*
@@ -599,11 +542,13 @@
struct tcx_softc *sc = device_private(dev);
if (sc->sc_blanked) {
-
+ uint32_t reg;
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;
+ reg = bus_space_read_4(sc->sc_bustag, sc->sc_thc, THC_MISC);
+ reg &= ~THC_MISC_VSYNC_DISABLE;
+ reg &= ~THC_MISC_HSYNC_DISABLE;
+ reg |= THC_MISC_VIDEN;
+ bus_space_write_4(sc->sc_bustag, sc->sc_thc, THC_MISC, reg);
}
}
@@ -643,7 +588,7 @@
tcxmmap(dev_t dev, off_t off, int prot)
{
struct tcx_softc *sc = device_lookup_private(&tcx_cd, minor(dev));
- struct openprom_addr *rr = sc->sc_physadr;
+ struct openprom_addr *rr = sc->sc_physaddr;
struct mmo *mo, *mo_end;
u_int u, sz;
static struct mmo mmo[] = {
@@ -664,20 +609,6 @@
{ TCX_USER_ROM, 65536, TCX_REG_ROM },
};
#define NMMO (sizeof mmo / sizeof *mmo)
-#ifdef TCX_CG8
- /*
- * alternate mapping for CG8 emulation:
- * map part of the 8-bit-deep framebuffer into the cg8 overlay
- * space, just so there's something there, and map the 32-bit-deep
- * framebuffer where cg8 users expect to find it.
- */
- static struct mmo mmo_cg8[] = {
- { TCX_USER_RAM, TCX_CG8OVERLAY, TCX_REG_DFB8 },
- { TCX_CG8OVERLAY, TCX_SIZE_DFB32, TCX_REG_DFB24 },
- { TCX_USER_RAM_COMPAT, TCX_SIZE_DFB32, TCX_REG_DFB24 }
- };
-#define NMMO_CG8 (sizeof mmo_cg8 / sizeof *mmo_cg8)
-#endif
if (off & PGOFSET)
panic("tcxmmap");
@@ -691,18 +622,10 @@
* sizes are sometimes bizarre (e.g., 1) is effectively ignored:
* one byte is as good as one page.
*/
-#ifdef TCX_CG8
- if (sc->sc_8bit) {
- mo = mmo;
- mo_end = &mmo[NMMO];
- } else {
- mo = mmo_cg8;
- mo_end = &mmo_cg8[NMMO_CG8];
- }
-#else
+
mo = mmo;
mo_end = &mmo[NMMO];
-#endif
+
for (; mo < mo_end; mo++) {
if ((u_int)off < mo->mo_uaddr)
continue;
@@ -766,9 +689,20 @@
wdf = (void *)data;
wdf->height = ms->scr_ri.ri_height;
wdf->width = ms->scr_ri.ri_width;
- wdf->depth = ms->scr_ri.ri_depth;
+ if (sc->sc_8bit) {
+ wdf->depth = 8;
+ } else {
+ wdf->depth = 32;
+ }
wdf->cmsize = 256;
return 0;
+ case WSDISPLAYIO_LINEBYTES:
+ {
+ int *ret = (int *)data;
+ *ret = sc->sc_8bit ? ms->scr_ri.ri_width :
+ ms->scr_ri.ri_width << 2;
+ }
+ return 0;
#if 0
case WSDISPLAYIO_GETCMAP:
return tcx_getcmap(sc, (struct wsdisplay_cmap *)data);
@@ -784,10 +718,8 @@
sc->sc_mode = new_mode;
if (new_mode == WSDISPLAYIO_MODE_EMUL)
{
-#if 0
- tcxloadcmap(sc, 0, 256);
+ tcx_loadcmap(sc, 0, 256);
tcx_clearscreen(sc);
-#endif
vcons_redraw_screen(ms);
}
}
@@ -799,32 +731,25 @@
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,
+ if (sc->sc_8bit) {
+ /* on 8Bit boards hand over the 8 bit aperture */
+ if (offset > 1024 * 1024)
+ return -1;
+ return bus_space_mmap(sc->sc_bustag,
+ sc->sc_physaddr[TCX_REG_DFB8].oa_base + 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,
+ } else {
+ /* ... but if we have a 24bit aperture we use it */
+ if (offset > 1024 * 1024 * 4)
+ return -1;
+ return bus_space_mmap(sc->sc_bustag,
+ sc->sc_physaddr[TCX_REG_DFB24].oa_base + offset, 0, prot,
BUS_SPACE_MAP_LINEAR);
- return pa;
}
-#endif
return -1;
}