PR/32552: Antonio Bravo: cgfourteen 24-bit support

Original code from der Mouse, posted to the mailing lists by Jakob Menzi.
This commit is contained in:
christos 2006-01-17 04:22:08 +00:00
parent 589b108660
commit d07104a9ce
3 changed files with 190 additions and 329 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cgfourteen.c,v 1.41 2005/12/11 12:19:05 christos Exp $ */
/* $NetBSD: cgfourteen.c,v 1.42 2006/01/17 04:22:08 christos Exp $ */
/*
* Copyright (c) 1996
@ -66,19 +66,14 @@
* enabled by allowing any user to map the control registers for the
* cg14 into their space.
*/
#undef CG14_MAP_REGS
#define CG14_MAP_REGS
/*
* The following enables 24-bit operation: when opened, the framebuffer
* will switch to 24-bit mode (actually 32-bit mode), and provide a
* simple cg8 emulation.
*
* XXX Note that the code enabled by this define is currently untested/broken.
*/
#undef CG14_CG8
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cgfourteen.c,v 1.41 2005/12/11 12:19:05 christos Exp $");
#define CG14_CG8
#include <sys/param.h>
#include <sys/systm.h>
@ -92,13 +87,12 @@ __KERNEL_RCSID(0, "$NetBSD: cgfourteen.c,v 1.41 2005/12/11 12:19:05 christos Exp
#include <uvm/uvm_extern.h>
#include <machine/bus.h>
#include <machine/autoconf.h>
#include <dev/sbus/sbusvar.h>
#include <dev/sun/fbio.h>
#include <machine/autoconf.h>
#include <machine/pmap.h>
#include <dev/sun/fbvar.h>
#include <machine/cpu.h>
#include <dev/sbus/sbusvar.h>
#include <sparc/dev/cgfourteenreg.h>
#include <sparc/dev/cgfourteenvar.h>
@ -110,25 +104,28 @@ static void cgfourteenunblank(struct device *);
CFATTACH_DECL(cgfourteen, sizeof(struct cgfourteen_softc),
cgfourteenmatch, cgfourteenattach, NULL, NULL);
extern struct cfdriver cgfourteen_cd;
dev_type_open(cgfourteenopen);
dev_type_close(cgfourteenclose);
dev_type_ioctl(cgfourteenioctl);
dev_type_mmap(cgfourteenmmap);
dev_type_poll(cgfourteenpoll);
const struct cdevsw cgfourteen_cdevsw = {
cgfourteenopen, cgfourteenclose, noread, nowrite, cgfourteenioctl,
nostop, notty, nopoll, cgfourteenmmap, nokqfilter,
cgfourteenopen, cgfourteenclose, noread, nowrite, cgfourteenioctl,
nostop, notty, cgfourteenpoll, cgfourteenmmap, nokqfilter,
};
/* frame buffer generic driver */
static struct fbdriver cgfourteenfbdriver = {
cgfourteenunblank, cgfourteenopen, cgfourteenclose, cgfourteenioctl,
nopoll, cgfourteenmmap, nokqfilter
cgfourteenpoll, cgfourteenmmap, nokqfilter
};
extern struct tty *fbconstty;
static void cg14_set_video(struct cgfourteen_softc *, int);
static int cg14_get_video(struct cgfourteen_softc *);
static int cg14_get_cmap(struct fbcmap *, union cg14cmap *, int);
@ -136,24 +133,11 @@ static int cg14_put_cmap(struct fbcmap *, union cg14cmap *, int);
static void cg14_load_hwcmap(struct cgfourteen_softc *, int, int);
static void cg14_init(struct cgfourteen_softc *);
static void cg14_reset(struct cgfourteen_softc *);
static void cg14_loadomap(struct cgfourteen_softc *); /* cursor overlay */
static void cg14_setcursor(struct cgfourteen_softc *); /* set position */
static void cg14_loadcursor(struct cgfourteen_softc *); /* set shape */
/*
* We map the display memory with an offset of 256K when emulating the cg3 or
* cg8; the cg3 uses this offset for compatibility with the cg4, and both the
* cg4 and cg8 have a mono overlay plane and an overlay enable plane in the
* first 256K. Mapping at an offset of 0x04000000 causes only the color
* frame buffer to be mapped, without the overlay planes.
*/
#define START (128*1024 + 128*1024)
#define NOOVERLAY (0x04000000)
/*
* Match a cgfourteen.
*/
static int
int
cgfourteenmatch(struct device *parent, struct cfdata *cf, void *aux)
{
union obio_attach_args *uoba = aux;
@ -173,10 +157,28 @@ cgfourteenmatch(struct device *parent, struct cfdata *cf, void *aux)
return (strcmp(cf->cf_name, sa->sa_name) == 0);
}
/*
* Set COLOUR_OFFSET to the offset of the video RAM. This is to provide
* space for faked overlay junk for the cg8 emulation.
*
* As it happens, this value is correct for both cg3 and cg8 emulation!
*/
#define COLOUR_OFFSET (256*1024)
static void cg14_set_rcons_luts(struct cgfourteen_softc *sc)
{
int i;
for (i=0;i<CG14_CLUT_SIZE;i++) sc->sc_xlut->xlut_lut[i] = 0x22;
for (i=0;i<CG14_CLUT_SIZE;i++) sc->sc_clut2->clut_lut[i] = 0x00ffffff;
sc->sc_clut2->clut_lut[0] = 0x00ffffff;
sc->sc_clut2->clut_lut[255] = 0;
}
/*
* Attach a display. We need to notice if it is the console, too.
*/
static void
void
cgfourteenattach(struct device *parent, struct device *self, void *aux)
{
union obio_attach_args *uoba = aux;
@ -204,29 +206,16 @@ cgfourteenattach(struct device *parent, struct device *self, void *aux)
#ifdef CG14_CG8
fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
fb->fb_type.fb_depth = 32;
fb_setsize_obp(fb, sc->sc_fb.fb_type.fb_depth, 1152, 900, node);
ramsize = roundup(fb->fb_type.fb_height * 1152 * 4, NBPG);
#else
fb->fb_type.fb_type = FBTYPE_SUN3COLOR;
fb->fb_type.fb_depth = 8;
#endif
fb_setsize_obp(fb, sc->sc_fb.fb_type.fb_depth, 1152, 900, node);
#ifdef CG14_CG8
/*
* fb_setsize_obp set fb->fb_linebytes based on the current
* depth reported by obp, but that defaults to 8 bits (as
* reported by getpropint(). Update the value to reflect
* the depth that will be used after open.
* The display memory size returned by the cg8 driver includes
* the space used by the overlay planes, but the size returned
* by the cg3 driver does not; emulate the other drivers.
*/
fb->fb_linebytes = (fb->fb_type.fb_width * fb->fb_type.fb_depth) / 8;
ramsize = roundup(START + (fb->fb_type.fb_height * fb->fb_linebytes),
PAGE_SIZE);
#else
ramsize = roundup(fb->fb_type.fb_height * fb->fb_linebytes, PAGE_SIZE);
ramsize = roundup(fb->fb_type.fb_height * fb->fb_linebytes, NBPG);
#endif
fb->fb_type.fb_cmsize = CG14_CLUT_SIZE;
fb->fb_type.fb_size = ramsize;
fb->fb_type.fb_size = ramsize + COLOUR_OFFSET;
if (sa->sa_nreg < 2) {
printf("%s: only %d register sets\n",
@ -234,7 +223,7 @@ cgfourteenattach(struct device *parent, struct device *self, void *aux)
return;
}
bcopy(sa->sa_reg, sc->sc_physadr,
sa->sa_nreg * sizeof(struct openprom_addr));
sa->sa_nreg * sizeof(struct sbus_reg));
/*
* Now map in the 8 useful pages of registers
@ -245,9 +234,11 @@ cgfourteenattach(struct device *parent, struct device *self, void *aux)
#endif
sa->sa_size = 0x10000;
}
if (sbus_bus_map(sa->sa_bustag,
sa->sa_slot, sa->sa_offset, sa->sa_size,
BUS_SPACE_MAP_LINEAR, &bh) != 0) {
if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
sa->sa_offset,
sa->sa_size,
BUS_SPACE_MAP_LINEAR,
&bh) != 0) {
printf("%s: cannot map control registers\n", self->dv_xname);
return;
}
@ -272,7 +263,7 @@ cgfourteenattach(struct device *parent, struct device *self, void *aux)
fb->fb_type.fb_width, fb->fb_type.fb_height);
#endif
/*
* Enable the video, but don't change the pixel depth.
* Enable the video.
*/
cg14_set_video(sc, 1);
@ -284,19 +275,32 @@ cgfourteenattach(struct device *parent, struct device *self, void *aux)
sc->sc_cmap.cm_chip[i] = lut[i];
/* See if we're the console */
isconsole = fb_is_console(node);
isconsole = fb_is_console(node);
if (isconsole) {
printf(" (console)\n");
#ifdef notdef
/*
* We don't use the raster console since the cg14 is
* fast enough already.
*/
#ifdef RASTERCONSOLE
fbrcons_init(fb);
/* *sbus*_bus_map? but that's how we map the regs... */
if (sbus_bus_map( sc->sc_bustag,
sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
sc->sc_physadr[CG14_PXL_IDX].sbr_offset+0x03800000,
1152*900, BUS_SPACE_MAP_LINEAR,
&bh) != 0) {
printf("%s: cannot map pixels\n",&sc->sc_dev.dv_xname[0]);
} else {
sc->sc_rcfb = sc->sc_fb;
sc->sc_rcfb.fb_type.fb_type = FBTYPE_SUN3COLOR;
sc->sc_rcfb.fb_type.fb_depth = 8;
sc->sc_rcfb.fb_linebytes = 1152;
sc->sc_rcfb.fb_type.fb_size = roundup(1152*900,NBPG);
sc->sc_rcfb.fb_pixels = (void *)bh;
printf("vram at %p\n",(void *)bh);
for (i=0;i<1152*900;i++) ((unsigned char *)bh)[i] = 0;
fbrcons_init(&sc->sc_rcfb);
cg14_set_rcons_luts(sc);
sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_32 | CG14_MCTL_POWERCTL;
}
#endif
#endif /* notdef */
} else
printf("\n");
@ -315,14 +319,16 @@ static int cg14_opens = 0;
int
cgfourteenopen(dev_t dev, int flags, int mode, struct lwp *l)
{
struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
int unit = minor(dev);
struct cgfourteen_softc *sc;
int unit;
int s, oldopens;
if (unit >= cgfourteen_cd.cd_ndevs ||
cgfourteen_cd.cd_devs[unit] == NULL)
return (ENXIO);
unit = minor(dev);
if (unit >= cgfourteen_cd.cd_ndevs)
return(ENXIO);
sc = cgfourteen_cd.cd_devs[minor(dev)];
if (sc == NULL)
return(ENXIO);
s = splhigh();
oldopens = cg14_opens++;
splx(s);
@ -360,10 +366,7 @@ cgfourteenioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct lwp *l)
{
struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
struct fbgattr *fba;
union cg14cursor_cmap tcm;
int v, error;
u_int count;
u_int eplane[32], cplane[32];
int error;
switch (cmd) {
@ -384,7 +387,7 @@ cgfourteenioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct lwp *l)
break;
case FBIOGETCMAP:
return (cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap,
return(cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap,
CG14_CLUT_SIZE));
case FBIOPUTCMAP:
@ -410,112 +413,6 @@ cgfourteenioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct lwp *l)
cg14_set_video(sc, *(int *)data);
break;
/* these are for both FBIOSCURSOR and FBIOGCURSOR */
#define p ((struct fbcursor *)data)
#define cc (&sc->sc_cursor)
case FBIOGCURSOR:
/* do not quite want everything here... */
p->set = FB_CUR_SETALL; /* close enough, anyway */
p->enable = cc->cc_enable;
p->pos = cc->cc_pos;
p->hot = cc->cc_hot;
p->size = cc->cc_size;
/* begin ugh ... can we lose some of this crap?? */
if (p->image != NULL) {
count = cc->cc_size.y * 32 / NBBY;
error = copyout(cc->cc_cplane, p->image, count);
if (error)
return (error);
error = copyout(cc->cc_eplane, p->mask, count);
if (error)
return (error);
}
if (p->cmap.red != NULL) {
error = cg14_get_cmap(&p->cmap,
(union cg14cmap *)&cc->cc_color, 2);
if (error)
return (error);
} else {
p->cmap.index = 0;
p->cmap.count = 2;
}
/* end ugh */
break;
case FBIOSCURSOR:
/*
* For setcmap and setshape, verify parameters, so that
* we do not get halfway through an update and then crap
* out with the software state screwed up.
*/
v = p->set;
if (v & FB_CUR_SETCMAP) {
/*
* This use of a temporary copy of the cursor
* colormap is not terribly efficient, but these
* copies are small (8 bytes)...
*/
tcm = cc->cc_color;
error = cg14_put_cmap(&p->cmap, (union cg14cmap *)&tcm,
2);
if (error)
return (error);
}
if (v & FB_CUR_SETSHAPE) {
if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)
return (EINVAL);
count = p->size.y * 32 / NBBY;
error = copyin(p->mask, eplane, count);
if (error)
return error;
error = copyin(p->image, cplane, count);
if (error)
return error;
}
/* parameters are OK; do it */
if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
if (v & FB_CUR_SETCUR)
cc->cc_enable = p->enable;
if (v & FB_CUR_SETPOS)
cc->cc_pos = p->pos;
if (v & FB_CUR_SETHOT)
cc->cc_hot = p->hot;
cg14_setcursor(sc);
}
if (v & FB_CUR_SETCMAP) {
cc->cc_color = tcm;
cg14_loadomap(sc); /* XXX defer to vertical retrace */
}
if (v & FB_CUR_SETSHAPE) {
cc->cc_size = p->size;
count = p->size.y * 32 / NBBY;
memset(cc->cc_eplane, 0, sizeof cc->cc_eplane);
memcpy(cc->cc_eplane, eplane, count);
memset(cc->cc_cplane, 0, sizeof cc->cc_cplane);
memcpy(cc->cc_cplane, cplane, count);
cg14_loadcursor(sc);
}
break;
#undef cc
#undef p
case FBIOGCURPOS:
*(struct fbcurpos *)data = sc->sc_cursor.cc_pos;
break;
case FBIOSCURPOS:
sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;
cg14_setcursor(sc);
break;
case FBIOGCURMAX:
/* max cursor size is 32x32 */
((struct fbcurpos *)data)->x = 32;
((struct fbcurpos *)data)->y = 32;
break;
default:
return (ENOTTY);
}
@ -536,17 +433,27 @@ cgfourteenunblank(struct device *dev)
* Return the address that would map the given device at the given
* offset, allowing for the given protection, or return -1 for error.
*
* The cg14 frame buffer can be mapped in either 8-bit or 32-bit mode
* starting at the address stored in the PROM. In 8-bit mode, the X
* channel is not present, and can be ignored. In 32-bit mode, mapping
* at 0K delivers a 32-bpp buffer where the upper 8 bits select the X
* channel information. We hardwire the Xlut to all zeroes to insure
* that, regardless of this value, direct 24-bit color access will be
* used.
* Since we're pretending to be a cg8, we put the main video RAM at the
* same place the cg8 does, at offset 256k. The cg8 has an enable
* plane in the 256k space; our "enable" plane works differently. We
* can't emulate the enable plane very well, but all X uses it for is
* to clear it at startup - so we map the first page of video RAM over
* and over to fill that 256k space. We also map some other views of
* the video RAM space.
*
* Alternatively, mapping the frame buffer at an offset of 16M seems to
* tell the chip to ignore the X channel. XXX where does it get the X value
* to use?
* Our memory map thus looks like
*
* mmap range space base offset
* 00000000-00040000 vram 0 (multi-mapped - see above)
* 00040000-00434800 vram 00000000
* 01000000-01400000 vram 01000000
* 02000000-02200000 vram 02000000
* 02800000-02a00000 vram 02800000
* 03000000-03100000 vram 03000000
* 03400000-03500000 vram 03400000
* 03800000-03900000 vram 03800000
* 03c00000-03d00000 vram 03c00000
* 10000000-10010000 regs 00000000 (only if CG14_MAP_REGS)
*/
paddr_t
cgfourteenmmap(dev_t dev, off_t off, int prot)
@ -559,50 +466,52 @@ cgfourteenmmap(dev_t dev, off_t off, int prot)
if (off < 0)
return (-1);
#if defined(DEBUG) && defined(CG14_MAP_REGS) /* XXX: security hole */
#if defined(CG14_MAP_REGS) /* XXX: security hole */
/*
* Map the control registers into user space. Should only be
* used for debugging!
*/
if ((u_int)off >= 0x10000000 && (u_int)off < 0x10000000 + 16*4096) {
off -= 0x10000000;
if (bus_space_mmap(sc->sc_bustag,
return (bus_space_mmap(sc->sc_bustag,
BUS_ADDR(sc->sc_physadr[CG14_CTL_IDX].sbr_slot,
sc->sc_physadr[CG14_CTL_IDX].sbr_offset),
sc->sc_physadr[CG14_CTL_IDX].sbr_offset),
off, prot, BUS_SPACE_MAP_LINEAR));
}
#endif
if ((u_int)off >= NOOVERLAY)
off -= NOOVERLAY;
else if ((u_int)off >= START)
off -= START;
else
if (off < COLOUR_OFFSET)
off = 0;
/*
* fb_size includes the overlay space only for the CG8.
*/
#ifdef CG14_CG8
if (off >= sc->sc_fb.fb_type.fb_size - START)
#else
if (off >= sc->sc_fb.fb_type.fb_size)
#endif
{
#ifdef DEBUG
printf("\nmmap request out of bounds: request 0x%x, "
"bound 0x%x\n", (unsigned) off,
(unsigned)sc->sc_fb.fb_type.fb_size);
#endif
return (-1);
else if (off < COLOUR_OFFSET+(1152*900*4))
off -= COLOUR_OFFSET;
else {
switch (off >> 20) {
case 0x010: case 0x011: case 0x012: case 0x013:
case 0x020: case 0x021:
case 0x028: case 0x029:
case 0x030:
case 0x034:
case 0x038:
case 0x03c:
break;
default:
return(-1);
}
}
return (bus_space_mmap(sc->sc_bustag,
BUS_ADDR(sc->sc_physadr[CG14_PXL_IDX].oa_space,
sc->sc_physadr[CG14_PXL_IDX].oa_base),
BUS_ADDR(sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
sc->sc_physadr[CG14_PXL_IDX].sbr_offset),
off, prot, BUS_SPACE_MAP_LINEAR));
}
int
cgfourteenpoll(dev_t dev, int events, struct lwp *l)
{
return (seltrue(dev, events, l));
}
/*
* Miscellaneous helper functions
*/
@ -611,8 +520,8 @@ cgfourteenmmap(dev_t dev, off_t off, int prot)
static void
cg14_init(struct cgfourteen_softc *sc)
{
volatile uint32_t *clut;
volatile uint8_t *xlut;
u_int32_t *clut;
u_int8_t *xlut;
int i;
/*
@ -626,8 +535,8 @@ cg14_init(struct cgfourteen_softc *sc)
sc->sc_savectl = sc->sc_ctl->ctl_mctl;
sc->sc_savehwc = sc->sc_hwc->curs_ctl;
clut = sc->sc_clut1->clut_lut;
xlut = sc->sc_xlut->xlut_lut;
clut = (u_int32_t *) sc->sc_clut1->clut_lut;
xlut = (u_int8_t *) sc->sc_xlut->xlut_lut;
for (i = 0; i < CG14_CLUT_SIZE; i++) {
sc->sc_saveclut.cm_chip[i] = clut[i];
sc->sc_savexlut[i] = xlut[i];
@ -643,7 +552,8 @@ cg14_init(struct cgfourteen_softc *sc)
/*
* Zero the xlut to enable direct-color mode
*/
memset(sc->sc_xlut, 0, CG14_CLUT_SIZE);
for (i = 0; i < CG14_CLUT_SIZE; i++)
sc->sc_xlut->xlut_lut[i] = 0;
#else
/*
* Enable the video and put it in 8 bit mode
@ -653,8 +563,8 @@ cg14_init(struct cgfourteen_softc *sc)
#endif
}
/* Restore the state saved on cg14_init */
static void
/* Restore the state saved on cg14_init */
cg14_reset(struct cgfourteen_softc *sc)
{
volatile uint32_t *clut;
@ -690,7 +600,6 @@ cg14_reset(struct cgfourteen_softc *sc)
static void
cg14_set_video(struct cgfourteen_softc *sc, int enable)
{
/*
* We can only use DPMS to power down the display if the chip revision
* is greater than 0.
@ -714,7 +623,6 @@ cg14_set_video(struct cgfourteen_softc *sc, int enable)
static int
cg14_get_video(struct cgfourteen_softc *sc)
{
return ((sc->sc_ctl->ctl_mctl & CG14_MCTL_ENABLEVID) != 0);
}
@ -722,64 +630,63 @@ cg14_get_video(struct cgfourteen_softc *sc)
static int
cg14_get_cmap(struct fbcmap *p, union cg14cmap *cm, int cmsize)
{
u_int i, start, count;
u_char *cp;
int error;
u_int i, start, count;
u_char *cp;
int error;
start = p->index;
count = p->count;
if (start >= cmsize || count > cmsize - start)
return (EINVAL);
start = p->index;
count = p->count;
if (start >= cmsize || count > cmsize - start)
return (EINVAL);
for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
error = copyout(&cp[3], &p->red[i], 1);
if (error)
return error;
error = copyout(&cp[2], &p->green[i], 1);
if (error)
return error;
error = copyout(&cp[1], &p->blue[i], 1);
if (error)
return error;
}
return (0);
for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
error = copyout(&cp[3], &p->red[i], 1);
if (error)
return error;
error = copyout(&cp[2], &p->green[i], 1);
if (error)
return error;
error = copyout(&cp[1], &p->blue[i], 1);
if (error)
return error;
}
return (0);
}
/* Write the software shadow colormap */
static int
cg14_put_cmap(struct fbcmap *p, union cg14cmap *cm, int cmsize)
{
u_int i, start, count;
u_char *cp;
u_char cmap[256][4];
int error;
u_int i, start, count;
u_char *cp;
u_char cmap[256][4];
int error;
start = p->index;
count = p->count;
if (start >= cmsize || count > cmsize - start)
return (EINVAL);
start = p->index;
count = p->count;
if (start >= cmsize || count > cmsize - start)
return (EINVAL);
memcpy(&cmap, &cm->cm_map, sizeof cmap);
for (cp = &cmap[start][0], i = 0; i < count; cp += 4, i++) {
error = copyin(&p->red[i], &cp[3], 1);
if (error)
return error;
error = copyin(&p->green[i], &cp[2], 1);
if (error)
return error;
error = copyin(&p->blue[i], &cp[1], 1);
if (error)
return error;
cp[0] = 0; /* no alpha channel */
}
memcpy(&cm->cm_map, &cmap, sizeof cmap);
return (0);
memcpy(&cmap, &cm->cm_map, sizeof cmap);
for (cp = &cmap[start][0], i = 0; i < count; cp += 4, i++) {
error = copyin(&p->red[i], &cp[3], 1);
if (error)
return error;
error = copyin(&p->green[i], &cp[2], 1);
if (error)
return error;
error = copyin(&p->blue[i], &cp[1], 1);
if (error)
return error;
cp[0] = 0; /* no alpha channel */
}
memcpy(&cm->cm_map, &cmap, sizeof cmap);
return (0);
}
static void
cg14_load_hwcmap(struct cgfourteen_softc *sc, int start, int ncolors)
{
/* XXX switch to auto-increment, and on retrace intr */
/* Setup pointers to source and dest */
@ -790,56 +697,3 @@ cg14_load_hwcmap(struct cgfourteen_softc *sc, int start, int ncolors)
while (--ncolors >= 0)
*lutp++ = *colp++;
}
/*
* Load the cursor (overlay `foreground' and `background') colors.
*/
static void
cg14_setcursor(struct cgfourteen_softc *sc)
{
/* we need to subtract the hot-spot value here */
#define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
sc->sc_hwc->curs_ctl = (sc->sc_cursor.cc_enable ? CG14_CURS_ENABLE : 0);
sc->sc_hwc->curs_x = COORD(x);
sc->sc_hwc->curs_y = COORD(y);
#undef COORD
}
static void
cg14_loadcursor(struct cgfourteen_softc *sc)
{
volatile struct cg14curs *hwc;
u_int edgemask, m;
int i;
/*
* Keep the top size.x bits. Here we *throw out* the top
* size.x bits from an all-one-bits word, introducing zeros in
* the top size.x bits, then invert all the bits to get what
* we really wanted as our mask. But this fails if size.x is
* 32---a sparc uses only the low 5 bits of the shift count---
* so we have to special case that.
*/
edgemask = ~0;
if (sc->sc_cursor.cc_size.x < 32)
edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);
hwc = sc->sc_hwc;
for (i = 0; i < 32; i++) {
m = sc->sc_cursor.cc_eplane[i] & edgemask;
hwc->curs_plane0[i] = m;
hwc->curs_plane1[i] = m & sc->sc_cursor.cc_cplane[i];
}
}
static void
cg14_loadomap(struct cgfourteen_softc *sc)
{
/* set background color */
sc->sc_hwc->curs_color1 = sc->sc_cursor.cc_color.cm_chip[0];
/* set foreground color */
sc->sc_hwc->curs_color2 = sc->sc_cursor.cc_color.cm_chip[1];
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cgfourteenreg.h,v 1.2 2005/11/16 00:49:03 uwe Exp $ */
/* $NetBSD: cgfourteenreg.h,v 1.3 2006/01/17 04:22:09 christos Exp $ */
/*
* Copyright (c) 1996

View File

@ -1,4 +1,4 @@
/* $NetBSD: cgfourteenvar.h,v 1.5 2005/11/16 00:49:03 uwe Exp $ */
/* $NetBSD: cgfourteenvar.h,v 1.6 2006/01/17 04:22:09 christos Exp $ */
/*
* Copyright (c) 1996
@ -32,7 +32,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
struct sbus_reg {
uint32_t sbr_slot;
uint32_t sbr_offset;
uint32_t sbr_size;
};
/*
* Layout of cg14 hardware colormap
*/
@ -57,8 +61,8 @@ struct cg14_cursor { /* cg14 hardware cursor status */
struct fbcurpos cc_pos; /* position */
struct fbcurpos cc_hot; /* hot-spot */
struct fbcurpos cc_size; /* size of mask & image fields */
u_int cc_eplane[32]; /* enable plane */
u_int cc_cplane[32]; /* color plane */
uint cc_eplane[32]; /* enable plane */
uint cc_cplane[32]; /* color plane */
union cg14cursor_cmap cc_color; /* cursor colormap */
};
@ -68,17 +72,20 @@ struct cg14_cursor { /* cg14 hardware cursor status */
struct cgfourteen_softc {
struct device sc_dev; /* base device */
struct fbdevice sc_fb; /* frame buffer device */
#ifdef RASTERCONSOLE
struct fbdevice sc_rcfb; /* sc_fb variant for rcons */
#endif
bus_space_tag_t sc_bustag;
struct openprom_addr sc_physadr[2]; /* phys addrs of h/w */
struct sbus_reg sc_physadr[2]; /* phys addrs of h/w */
#define CG14_CTL_IDX 0
#define CG14_PXL_IDX 1
union cg14cmap sc_cmap; /* current colormap */
struct cg14_cursor sc_cursor; /* Hardware cursor state */
union cg14cmap sc_saveclut; /* a place to stash PROM state */
uint8_t sc_savexlut[256];
uint8_t sc_savectl;
uint8_t sc_savehwc;
uint8_t sc_savexlut[256];
uint8_t sc_savectl;
uint8_t sc_savehwc;
struct cg14ctl *sc_ctl; /* various registers */
struct cg14curs *sc_hwc;
@ -87,5 +94,5 @@ struct cgfourteen_softc {
struct cg14clut *sc_clut1;
struct cg14clut *sc_clut2;
struct cg14clut *sc_clut3;
u_int *sc_clutincr;
uint *sc_clutincr;
};