These devices will never be found on sun4u machines.
This commit is contained in:
parent
b86b5d0346
commit
317a570728
|
@ -1,8 +1,8 @@
|
|||
# $NetBSD: GENERIC32,v 1.4 2000/08/13 01:31:21 itojun Exp $
|
||||
# $NetBSD: GENERIC32,v 1.5 2000/08/22 21:43:36 pk Exp $
|
||||
|
||||
include "arch/sparc64/conf/std.sparc64"
|
||||
|
||||
#ident "GENERIC-$Revision: 1.4 $"
|
||||
#ident "GENERIC-$Revision: 1.5 $"
|
||||
|
||||
maxusers 32
|
||||
|
||||
|
@ -435,9 +435,6 @@ cgsix* at sbus? slot ? offset ?
|
|||
#tcx0 at sbus? slot ? offset ?
|
||||
#tcx* at sbus? slot ? offset ?
|
||||
|
||||
# Sun "cgfourteen" accelerated 24-bit framebuffer.
|
||||
#cgfourteen0 at obio0 # sun4m
|
||||
|
||||
## Sun FFB not supported
|
||||
#ffb* at upa?
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.sparc64,v 1.35 2000/08/22 21:35:45 pk Exp $
|
||||
# $NetBSD: files.sparc64,v 1.36 2000/08/22 21:43:35 pk Exp $
|
||||
|
||||
# @(#)files.sparc64 8.1 (Berkeley) 7/19/93
|
||||
# sparc64-specific configuration info
|
||||
|
@ -169,18 +169,6 @@ major { wd = 12 }
|
|||
# RAIDframe
|
||||
major { raid = 25 }
|
||||
|
||||
device cgtwo
|
||||
attach cgtwo at sbus
|
||||
file arch/sparc64/dev/cgtwo.c cgtwo needs-flag
|
||||
|
||||
device cgfour: bt_dac, pfour
|
||||
attach cgfour at sbus
|
||||
file arch/sparc64/dev/cgfour.c cgfour needs-flag
|
||||
|
||||
device cgeight: bt_dac, pfour
|
||||
attach cgeight at sbus
|
||||
file arch/sparc64/dev/cgeight.c cgeight needs-flag
|
||||
|
||||
device cgfourteen
|
||||
attach cgfourteen at sbus
|
||||
file arch/sparc64/dev/cgfourteen.c cgfourteen needs-flag
|
||||
|
|
|
@ -1,523 +0,0 @@
|
|||
/* $NetBSD: cgeight.c,v 1.6 2000/06/29 07:37:54 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
|
||||
* Copyright (c) 1995 Theo de Raadt
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from @(#)cgthree.c 8.2 (Berkeley) 10/30/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* color display (cgeight) driver.
|
||||
*
|
||||
* Does not handle interrupts, even though they can occur.
|
||||
*
|
||||
* XXX should defer colormap updates to vertical retrace interrupts
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/fbvar.h>
|
||||
#include <machine/eeprom.h>
|
||||
#include <machine/conf.h>
|
||||
|
||||
#include <sparc64/dev/btreg.h>
|
||||
#include <sparc64/dev/btvar.h>
|
||||
#include <sparc64/dev/pfourreg.h>
|
||||
|
||||
/* per-display variables */
|
||||
struct cgeight_softc {
|
||||
struct device sc_dev; /* base device */
|
||||
struct fbdevice sc_fb; /* frame buffer device */
|
||||
struct rom_reg sc_phys; /* display RAM (phys addr) */
|
||||
volatile struct fbcontrol *sc_fbc; /* Brooktree registers */
|
||||
int sc_bustype; /* type of bus we live on */
|
||||
union bt_cmap sc_cmap; /* Brooktree color map */
|
||||
};
|
||||
|
||||
/* autoconfiguration driver */
|
||||
static void cgeightattach(struct device *, struct device *, void *);
|
||||
static int cgeightmatch(struct device *, struct cfdata *, void *);
|
||||
#if defined(SUN4)
|
||||
static void cgeightunblank __P((struct device *));
|
||||
#endif
|
||||
|
||||
/* cdevsw prototypes */
|
||||
cdev_decl(cgeight);
|
||||
|
||||
struct cfattach cgeight_ca = {
|
||||
sizeof(struct cgeight_softc), cgeightmatch, cgeightattach
|
||||
};
|
||||
|
||||
struct cfdriver cgeight_cd = {
|
||||
NULL, "cgeight", DV_DULL
|
||||
};
|
||||
|
||||
#if defined(SUN4)
|
||||
/* frame buffer generic driver */
|
||||
static struct fbdriver cgeightfbdriver = {
|
||||
cgeightunblank, cgeightopen, cgeightclose, cgeightioctl,
|
||||
cgeightpoll, cgeightmmap
|
||||
};
|
||||
|
||||
extern int fbnode;
|
||||
extern struct tty *fbconstty;
|
||||
|
||||
static void cgeightloadcmap __P((struct cgeight_softc *, int, int));
|
||||
static int cgeight_get_video __P((struct cgeight_softc *));
|
||||
static void cgeight_set_video __P((struct cgeight_softc *, int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Match a cgeight.
|
||||
*/
|
||||
int
|
||||
cgeightmatch(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
{
|
||||
struct confargs *ca = aux;
|
||||
struct romaux *ra = &ca->ca_ra;
|
||||
|
||||
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Mask out invalid flags from the user.
|
||||
*/
|
||||
cf->cf_flags &= FB_USERMASK;
|
||||
|
||||
/*
|
||||
* Only exists on a sun4.
|
||||
*/
|
||||
if (!CPU_ISSUN4)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Only exists on obio.
|
||||
*/
|
||||
if (ca->ca_bustype != BUS_OBIO)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Make sure there's hardware there.
|
||||
*/
|
||||
if (probeget(ra->ra_vaddr, ASI_PRIMARY, 4) == -1)
|
||||
return (0);
|
||||
|
||||
#if defined(SUN4)
|
||||
/*
|
||||
* Check the pfour register.
|
||||
*/
|
||||
if (fb_pfour_id(ra->ra_vaddr) == PFOUR_ID_COLOR24) {
|
||||
cf->cf_flags |= FB_PFOUR;
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach a display. We need to notice if it is the console, too.
|
||||
*/
|
||||
void
|
||||
cgeightattach(parent, self, args)
|
||||
struct device *parent, *self;
|
||||
void *args;
|
||||
{
|
||||
#if defined(SUN4)
|
||||
register struct cgeight_softc *sc = (struct cgeight_softc *)self;
|
||||
register struct confargs *ca = args;
|
||||
register int node = 0, ramsize, i;
|
||||
register volatile struct bt_regs *bt;
|
||||
struct fbdevice *fb = &sc->sc_fb;
|
||||
int isconsole;
|
||||
|
||||
fb->fb_driver = &cgeightfbdriver;
|
||||
fb->fb_device = &sc->sc_dev;
|
||||
fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
|
||||
fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
|
||||
|
||||
/*
|
||||
* Only pfour cgfours, thank you...
|
||||
*/
|
||||
if ((ca->ca_bustype != BUS_OBIO) ||
|
||||
((fb->fb_flags & FB_PFOUR) == 0)) {
|
||||
printf("%s: ignoring; not a pfour\n", sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Map the pfour register. */
|
||||
fb->fb_pfour = (volatile u_int32_t *)
|
||||
mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
|
||||
|
||||
ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
|
||||
|
||||
fb->fb_type.fb_depth = 24;
|
||||
fb_setsize(fb, fb->fb_type.fb_depth, 1152, 900, node, ca->ca_bustype);
|
||||
|
||||
sc->sc_fb.fb_type.fb_cmsize = 256;
|
||||
sc->sc_fb.fb_type.fb_size = ramsize;
|
||||
printf(": cgeight/p4, %d x %d", fb->fb_type.fb_width,
|
||||
fb->fb_type.fb_height);
|
||||
|
||||
isconsole = 0;
|
||||
|
||||
if (cputyp == CPU_SUN4) {
|
||||
struct eeprom *eep = (struct eeprom *)eeprom_va;
|
||||
|
||||
/*
|
||||
* Assume this is the console if there's no eeprom info
|
||||
* to be found.
|
||||
*/
|
||||
if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT)
|
||||
isconsole = (fbconstty != NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* We don't do any of the console handling here. Instead,
|
||||
* we let the bwtwo driver pick up the overlay plane and
|
||||
* use it instead. Rconsole should have better performance
|
||||
* with the 1-bit depth.
|
||||
* -- Jason R. Thorpe <thorpej@NetBSD.ORG>
|
||||
*/
|
||||
|
||||
/*
|
||||
* When the ROM has mapped in a cgfour display, the address
|
||||
* maps only the video RAM, so in any case we have to map the
|
||||
* registers ourselves. We only need the video RAM if we are
|
||||
* going to print characters via rconsole.
|
||||
*/
|
||||
|
||||
if (isconsole) {
|
||||
/* XXX this is kind of a waste */
|
||||
fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
|
||||
PFOUR_COLOR_OFF_OVERLAY, ramsize);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Map the Brooktree. */
|
||||
sc->sc_fbc = (volatile struct fbcontrol *)
|
||||
mapiodev(ca->ca_ra.ra_reg,
|
||||
PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol));
|
||||
|
||||
sc->sc_phys = ca->ca_ra.ra_reg[0];
|
||||
sc->sc_bustype = ca->ca_bustype;
|
||||
|
||||
#if 0 /* XXX thorpej ??? */
|
||||
/* tell the enable plane to look at the mono image */
|
||||
memset(ca->ca_ra.ra_vaddr, 0xff,
|
||||
sc->sc_fb.fb_type.fb_width * sc->sc_fb.fb_type.fb_height / 8);
|
||||
#endif
|
||||
|
||||
/* grab initial (current) color map */
|
||||
bt = &sc->sc_fbc->fbc_dac;
|
||||
bt->bt_addr = 0;
|
||||
for (i = 0; i < 256 * 3 / 4; i++)
|
||||
sc->sc_cmap.cm_chip[i] = bt->bt_cmap;
|
||||
|
||||
BT_INIT(bt, 0);
|
||||
|
||||
#if 0 /* see above */
|
||||
if (isconsole) {
|
||||
printf(" (console)\n");
|
||||
#if defined(RASTERCONSOLE) && 0 /* XXX been told it doesn't work well. */
|
||||
fbrcons_init(fb);
|
||||
#endif
|
||||
} else
|
||||
#endif /* 0 */
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* Even though we're not using rconsole, we'd still like
|
||||
* to notice if we're the console framebuffer.
|
||||
*/
|
||||
fb_attach(&sc->sc_fb, isconsole);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
cgeightopen(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
int unit = minor(dev);
|
||||
|
||||
if (unit >= cgeight_cd.cd_ndevs || cgeight_cd.cd_devs[unit] == NULL)
|
||||
return (ENXIO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgeightclose(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgeightioctl(dev, cmd, data, flags, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
register caddr_t data;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
#if defined(SUN4)
|
||||
register struct cgeight_softc *sc = cgeight_cd.cd_devs[minor(dev)];
|
||||
register struct fbgattr *fba;
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case FBIOGTYPE:
|
||||
*(struct fbtype *)data = sc->sc_fb.fb_type;
|
||||
break;
|
||||
|
||||
case FBIOGATTR:
|
||||
fba = (struct fbgattr *)data;
|
||||
fba->real_type = sc->sc_fb.fb_type.fb_type;
|
||||
fba->owner = 0; /* XXX ??? */
|
||||
fba->fbtype = sc->sc_fb.fb_type;
|
||||
fba->sattr.flags = 0;
|
||||
fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
|
||||
fba->sattr.dev_specific[0] = -1;
|
||||
fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
|
||||
fba->emu_types[1] = -1;
|
||||
break;
|
||||
|
||||
case FBIOGETCMAP:
|
||||
return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
|
||||
|
||||
case FBIOPUTCMAP:
|
||||
/* copy to software map */
|
||||
#define p ((struct fbcmap *)data)
|
||||
error = bt_putcmap(p, &sc->sc_cmap, 256);
|
||||
if (error)
|
||||
return (error);
|
||||
/* now blast them into the chip */
|
||||
/* XXX should use retrace interrupt */
|
||||
cgeightloadcmap(sc, p->index, p->count);
|
||||
#undef p
|
||||
break;
|
||||
|
||||
case FBIOGVIDEO:
|
||||
*(int *)data = cgeight_get_video(sc);
|
||||
break;
|
||||
|
||||
case FBIOSVIDEO:
|
||||
cgeight_set_video(sc, *(int *)data);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgeightpoll(dev, events, p)
|
||||
dev_t dev;
|
||||
int events;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (seltrue(dev, events, p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the address that would map the given device at the given
|
||||
* offset, allowing for the given protection, or return -1 for error.
|
||||
*
|
||||
* The cg8 maps it's overlay plane at 0 for 128K, followed by the
|
||||
* enable plane for 128K, followed by the colour for as long as it
|
||||
* goes. Starting at 8MB, it maps the ramdac for NBPG, then the p4
|
||||
* register for NBPG, then the bootrom for 0x40000.
|
||||
*/
|
||||
paddr_t
|
||||
cgeightmmap(dev, off, prot)
|
||||
dev_t dev;
|
||||
off_t off;
|
||||
int prot;
|
||||
{
|
||||
register struct cgeight_softc *sc = cgeight_cd.cd_devs[minor(dev)];
|
||||
off_t poff;
|
||||
|
||||
#define START_ENABLE (128*1024)
|
||||
#define START_COLOR ((128*1024) + (128*1024))
|
||||
#define COLOR_SIZE (sc->sc_fb.fb_type.fb_width * \
|
||||
sc->sc_fb.fb_type.fb_height * 3)
|
||||
#define END_COLOR (START_COLOR + COLOR_SIZE)
|
||||
#define START_SPECIAL 0x800000
|
||||
#define PROMSIZE 0x40000
|
||||
#define NOOVERLAY (0x04000000)
|
||||
|
||||
if (off & PGOFSET)
|
||||
panic("cgeightmap");
|
||||
|
||||
if (off < 0)
|
||||
return (-1);
|
||||
else if ((u_int)off >= NOOVERLAY) {
|
||||
off -= NOOVERLAY;
|
||||
|
||||
/*
|
||||
* X11 maps a huge chunk of the frame buffer; far more than
|
||||
* there really is. We compensate by double-mapping the
|
||||
* first page for as many other pages as it wants
|
||||
*/
|
||||
while (off >= COLOR_SIZE)
|
||||
off -= COLOR_SIZE; /* XXX thorpej ??? */
|
||||
|
||||
poff = off + PFOUR_COLOR_OFF_COLOR;
|
||||
} else if ((u_int)off < START_ENABLE) {
|
||||
/*
|
||||
* in overlay plane
|
||||
*/
|
||||
poff = PFOUR_COLOR_OFF_OVERLAY + off;
|
||||
} else if ((u_int)off < START_COLOR) {
|
||||
/*
|
||||
* in enable plane
|
||||
*/
|
||||
poff = (off - START_ENABLE) + PFOUR_COLOR_OFF_ENABLE;
|
||||
} else if ((u_int)off < sc->sc_fb.fb_type.fb_size) {
|
||||
/*
|
||||
* in colour plane
|
||||
*/
|
||||
poff = (off - START_COLOR) + PFOUR_COLOR_OFF_COLOR;
|
||||
} else if ((u_int)off < START_SPECIAL) {
|
||||
/*
|
||||
* hole
|
||||
*/
|
||||
poff = 0; /* XXX */
|
||||
} else if ((u_int)off == START_SPECIAL) {
|
||||
/*
|
||||
* colour map (Brooktree)
|
||||
*/
|
||||
poff = PFOUR_COLOR_OFF_CMAP;
|
||||
} else if ((u_int)off == START_SPECIAL + NBPG) {
|
||||
/*
|
||||
* p4 register
|
||||
*/
|
||||
poff = 0;
|
||||
} else if ((u_int)off > (START_SPECIAL + (NBPG * 2)) &&
|
||||
(u_int) off < (START_SPECIAL + (NBPG * 2) + PROMSIZE)) {
|
||||
/*
|
||||
* rom
|
||||
*/
|
||||
poff = 0x8000 + (off - (START_SPECIAL + (NBPG * 2)));
|
||||
} else
|
||||
return (-1);
|
||||
/*
|
||||
* I turned on PMAP_NC here to disable the cache as I was
|
||||
* getting horribly broken behaviour with it on.
|
||||
*/
|
||||
return (REG2PHYS(&sc->sc_phys, poff) | PMAP_NC);
|
||||
}
|
||||
|
||||
#if defined(SUN4)
|
||||
/*
|
||||
* Undo the effect of an FBIOSVIDEO that turns the video off.
|
||||
*/
|
||||
static void
|
||||
cgeightunblank(dev)
|
||||
struct device *dev;
|
||||
{
|
||||
|
||||
cgeight_set_video((struct cgeight_softc *)dev, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
cgeight_get_video(sc)
|
||||
struct cgeight_softc *sc;
|
||||
{
|
||||
|
||||
return (fb_pfour_get_video(&sc->sc_fb));
|
||||
}
|
||||
|
||||
static void
|
||||
cgeight_set_video(sc, enable)
|
||||
struct cgeight_softc *sc;
|
||||
int enable;
|
||||
{
|
||||
|
||||
fb_pfour_set_video(&sc->sc_fb, enable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load a subset of the current (new) colormap into the Brooktree DAC.
|
||||
*/
|
||||
static void
|
||||
cgeightloadcmap(sc, start, ncolors)
|
||||
register struct cgeight_softc *sc;
|
||||
register int start, ncolors;
|
||||
{
|
||||
register volatile struct bt_regs *bt;
|
||||
register u_int *ip;
|
||||
register 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_fbc->fbc_dac;
|
||||
bt->bt_addr = BT_D4M4(start);
|
||||
while (--count >= 0)
|
||||
bt->bt_cmap = *ip++;
|
||||
}
|
||||
#endif
|
|
@ -1,503 +0,0 @@
|
|||
/* $NetBSD: cgfour.c,v 1.7 2000/06/29 07:37:54 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
|
||||
* Copyright (c) 1995 Theo de Raadt. All rights reserved.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Theo de Raadt.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from @(#)cgthree.c 8.2 (Berkeley) 10/30/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* color display (cgfour) driver.
|
||||
*
|
||||
* Does not handle interrupts, even though they can occur.
|
||||
*
|
||||
* XXX should defer colormap updates to vertical retrace interrupts
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/fbvar.h>
|
||||
#include <machine/eeprom.h>
|
||||
#include <machine/conf.h>
|
||||
|
||||
#include <sparc64/dev/btreg.h>
|
||||
#include <sparc64/dev/btvar.h>
|
||||
#include <sparc64/dev/pfourreg.h>
|
||||
|
||||
/* per-display variables */
|
||||
struct cgfour_softc {
|
||||
struct device sc_dev; /* base device */
|
||||
struct fbdevice sc_fb; /* frame buffer device */
|
||||
struct rom_reg sc_phys; /* display RAM (phys addr) */
|
||||
volatile struct fbcontrol *sc_fbc; /* Brooktree registers */
|
||||
int sc_bustype; /* type of bus we live on */
|
||||
union bt_cmap sc_cmap; /* Brooktree color map */
|
||||
};
|
||||
|
||||
/* autoconfiguration driver */
|
||||
static void cgfourattach __P((struct device *, struct device *, void *));
|
||||
static int cgfourmatch __P((struct device *, struct cfdata *, void *));
|
||||
#if defined(SUN4)
|
||||
static void cgfourunblank __P((struct device *));
|
||||
#endif
|
||||
|
||||
/* cdevsw prototypes */
|
||||
cdev_decl(cgfour);
|
||||
|
||||
struct cfattach cgfour_ca = {
|
||||
sizeof(struct cgfour_softc), cgfourmatch, cgfourattach
|
||||
};
|
||||
|
||||
struct cfdriver cgfour_cd = {
|
||||
NULL, "cgfour", DV_DULL
|
||||
};
|
||||
|
||||
#if defined(SUN4)
|
||||
/* frame buffer generic driver */
|
||||
static struct fbdriver cgfourfbdriver = {
|
||||
cgfourunblank, cgfouropen, cgfourclose, cgfourioctl, cgfourpoll,
|
||||
cgfourmmap
|
||||
};
|
||||
|
||||
extern int fbnode;
|
||||
extern struct tty *fbconstty;
|
||||
|
||||
static void cgfourloadcmap __P((struct cgfour_softc *, int, int));
|
||||
static int cgfour_get_video __P((struct cgfour_softc *));
|
||||
static void cgfour_set_video __P((struct cgfour_softc *, int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Match a cgfour.
|
||||
*/
|
||||
int
|
||||
cgfourmatch(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
{
|
||||
struct confargs *ca = aux;
|
||||
struct romaux *ra = &ca->ca_ra;
|
||||
|
||||
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Mask out invalid flags from the user.
|
||||
*/
|
||||
cf->cf_flags &= FB_USERMASK;
|
||||
|
||||
/*
|
||||
* Only exists on a sun4.
|
||||
*/
|
||||
if (!CPU_ISSUN4)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Only exists on obio.
|
||||
*/
|
||||
if (ca->ca_bustype != BUS_OBIO)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Make sure there's hardware there.
|
||||
*/
|
||||
if (probeget(ra->ra_vaddr, ASI_PRIMARY, 4) == -1)
|
||||
return (0);
|
||||
|
||||
#if defined(SUN4)
|
||||
/*
|
||||
* Check the pfour register.
|
||||
*/
|
||||
if (fb_pfour_id(ra->ra_vaddr) == PFOUR_ID_COLOR8P1) {
|
||||
cf->cf_flags |= FB_PFOUR;
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach a display. We need to notice if it is the console, too.
|
||||
*/
|
||||
void
|
||||
cgfourattach(parent, self, args)
|
||||
struct device *parent, *self;
|
||||
void *args;
|
||||
{
|
||||
#if defined(SUN4)
|
||||
register struct cgfour_softc *sc = (struct cgfour_softc *)self;
|
||||
register struct confargs *ca = args;
|
||||
register int node = 0, ramsize, i;
|
||||
register volatile struct bt_regs *bt;
|
||||
struct fbdevice *fb = &sc->sc_fb;
|
||||
int isconsole;
|
||||
|
||||
fb->fb_driver = &cgfourfbdriver;
|
||||
fb->fb_device = &sc->sc_dev;
|
||||
fb->fb_type.fb_type = FBTYPE_SUN4COLOR;
|
||||
fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
|
||||
|
||||
/*
|
||||
* Only pfour cgfours, thank you...
|
||||
*/
|
||||
if ((ca->ca_bustype != BUS_OBIO) ||
|
||||
((fb->fb_flags & FB_PFOUR) == 0)) {
|
||||
printf("%s: ignoring; not a pfour\n", sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Map the pfour register. */
|
||||
fb->fb_pfour = (volatile u_int32_t *)
|
||||
mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
|
||||
|
||||
ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
|
||||
|
||||
fb->fb_type.fb_depth = 8;
|
||||
fb_setsize(fb, fb->fb_type.fb_depth, 1152, 900, node, ca->ca_bustype);
|
||||
|
||||
fb->fb_type.fb_cmsize = 256;
|
||||
fb->fb_type.fb_size = ramsize;
|
||||
printf(": cgfour/p4, %d x %d", fb->fb_type.fb_width,
|
||||
fb->fb_type.fb_height);
|
||||
|
||||
isconsole = 0;
|
||||
|
||||
if (CPU_ISSUN4) {
|
||||
struct eeprom *eep = (struct eeprom *)eeprom_va;
|
||||
|
||||
/*
|
||||
* Assume this is the console if there's no eeprom info
|
||||
* to be found.
|
||||
*/
|
||||
if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT)
|
||||
isconsole = (fbconstty != NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* We don't do any of the console handling here. Instead,
|
||||
* we let the bwtwo driver pick up the overlay plane and
|
||||
* use it instead. Rconsole should have better performance
|
||||
* with the 1-bit depth.
|
||||
* -- Jason R. Thorpe <thorpej@NetBSD.ORG>
|
||||
*/
|
||||
|
||||
/*
|
||||
* When the ROM has mapped in a cgfour display, the address
|
||||
* maps only the video RAM, so in any case we have to map the
|
||||
* registers ourselves. We only need the video RAM if we are
|
||||
* going to print characters via rconsole.
|
||||
*/
|
||||
|
||||
if (isconsole) {
|
||||
/* XXX this is kind of a waste */
|
||||
fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
|
||||
PFOUR_COLOR_OFF_OVERLAY, ramsize);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Map the Brooktree. */
|
||||
sc->sc_fbc = (volatile struct fbcontrol *)
|
||||
mapiodev(ca->ca_ra.ra_reg,
|
||||
PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol));
|
||||
|
||||
sc->sc_phys = ca->ca_ra.ra_reg[0];
|
||||
sc->sc_bustype = ca->ca_bustype;
|
||||
|
||||
/* grab initial (current) color map */
|
||||
bt = &sc->sc_fbc->fbc_dac;
|
||||
bt->bt_addr = 0;
|
||||
for (i = 0; i < 256 * 3 / 4; i++)
|
||||
((char *)&sc->sc_cmap)[i] = bt->bt_cmap >> 24;
|
||||
|
||||
BT_INIT(bt, 24);
|
||||
|
||||
#if 0 /* See above. */
|
||||
if (isconsole) {
|
||||
printf(" (console)\n");
|
||||
#if defined(RASTERCONSOLE) && 0 /* XXX been told it doesn't work well. */
|
||||
fbrcons_init(fb);
|
||||
#endif
|
||||
} else
|
||||
#endif /* 0 */
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* Even though we're not using rconsole, we'd still like
|
||||
* to notice if we're the console framebuffer.
|
||||
*/
|
||||
fb_attach(fb, isconsole);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
cgfouropen(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
int unit = minor(dev);
|
||||
|
||||
if (unit >= cgfour_cd.cd_ndevs || cgfour_cd.cd_devs[unit] == NULL)
|
||||
return (ENXIO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgfourclose(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgfourioctl(dev, cmd, data, flags, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
register caddr_t data;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
#if defined(SUN4)
|
||||
register struct cgfour_softc *sc = cgfour_cd.cd_devs[minor(dev)];
|
||||
register struct fbgattr *fba;
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case FBIOGTYPE:
|
||||
*(struct fbtype *)data = sc->sc_fb.fb_type;
|
||||
break;
|
||||
|
||||
case FBIOGATTR:
|
||||
fba = (struct fbgattr *)data;
|
||||
fba->real_type = sc->sc_fb.fb_type.fb_type;
|
||||
fba->owner = 0; /* XXX ??? */
|
||||
fba->fbtype = sc->sc_fb.fb_type;
|
||||
fba->sattr.flags = 0;
|
||||
fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
|
||||
fba->sattr.dev_specific[0] = -1;
|
||||
fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
|
||||
fba->emu_types[1] = -1;
|
||||
break;
|
||||
|
||||
case FBIOGETCMAP:
|
||||
return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
|
||||
|
||||
case FBIOPUTCMAP:
|
||||
/* copy to software map */
|
||||
#define p ((struct fbcmap *)data)
|
||||
error = bt_putcmap(p, &sc->sc_cmap, 256);
|
||||
if (error)
|
||||
return (error);
|
||||
/* now blast them into the chip */
|
||||
/* XXX should use retrace interrupt */
|
||||
cgfourloadcmap(sc, p->index, p->count);
|
||||
#undef p
|
||||
break;
|
||||
|
||||
case FBIOGVIDEO:
|
||||
*(int *)data = cgfour_get_video(sc);
|
||||
break;
|
||||
|
||||
case FBIOSVIDEO:
|
||||
cgfour_set_video(sc, *(int *)data);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgfourpoll(dev, events, p)
|
||||
dev_t dev;
|
||||
int events;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (seltrue(dev, events, p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the address that would map the given device at the given
|
||||
* offset, allowing for the given protection, or return -1 for error.
|
||||
*
|
||||
* the cg4 maps it's overlay plane for 128K, followed by the enable
|
||||
* plane for 128K, followed by the colour plane (for as much colour
|
||||
* as their is.)
|
||||
*
|
||||
* As well, mapping at an offset of 0x04000000 causes the cg4 to map
|
||||
* only it's colour plane, at 0.
|
||||
*/
|
||||
paddr_t
|
||||
cgfourmmap(dev, off, prot)
|
||||
dev_t dev;
|
||||
off_t off;
|
||||
int prot;
|
||||
{
|
||||
register struct cgfour_softc *sc = cgfour_cd.cd_devs[minor(dev)];
|
||||
off_t poff;
|
||||
|
||||
#define START_ENABLE (128*1024)
|
||||
#define START_COLOR ((128*1024) + (128*1024))
|
||||
#define COLOR_SIZE (sc->sc_fb.fb_type.fb_width * \
|
||||
sc->sc_fb.fb_type.fb_height)
|
||||
#define END_COLOR (START_COLOR + COLOR_SIZE)
|
||||
#define NOOVERLAY (0x04000000)
|
||||
|
||||
if (off & PGOFSET)
|
||||
panic("cgfourmap");
|
||||
|
||||
if (off < 0)
|
||||
return (-1);
|
||||
else if ((u_int)off >= NOOVERLAY) {
|
||||
off -= NOOVERLAY;
|
||||
|
||||
/*
|
||||
* X11 maps a huge chunk of the frame buffer; far more than
|
||||
* there really is. We compensate by double-mapping the
|
||||
* first page for as many other pages as it wants
|
||||
*/
|
||||
while ((u_int)off >= COLOR_SIZE)
|
||||
off -= COLOR_SIZE; /* XXX thorpej ??? */
|
||||
|
||||
poff = off + PFOUR_COLOR_OFF_COLOR;
|
||||
} else if ((u_int)off < START_ENABLE) {
|
||||
/*
|
||||
* in overlay plane
|
||||
*/
|
||||
poff = PFOUR_COLOR_OFF_OVERLAY + off;
|
||||
} else if ((u_int)off < START_COLOR) {
|
||||
/*
|
||||
* in enable plane
|
||||
*/
|
||||
poff = (off - START_ENABLE) + PFOUR_COLOR_OFF_ENABLE;
|
||||
} else if ((u_int)off < sc->sc_fb.fb_type.fb_size) {
|
||||
/*
|
||||
* in colour plane
|
||||
*/
|
||||
poff = (off - START_COLOR) + PFOUR_COLOR_OFF_COLOR;
|
||||
} else
|
||||
return (-1);
|
||||
|
||||
return (REG2PHYS(&sc->sc_phys, poff) | PMAP_NC);
|
||||
}
|
||||
|
||||
#if defined(SUN4)
|
||||
/*
|
||||
* Undo the effect of an FBIOSVIDEO that turns the video off.
|
||||
*/
|
||||
static void
|
||||
cgfourunblank(dev)
|
||||
struct device *dev;
|
||||
{
|
||||
|
||||
cgfour_set_video((struct cgfour_softc *)dev, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
cgfour_get_video(sc)
|
||||
struct cgfour_softc *sc;
|
||||
{
|
||||
|
||||
return (fb_pfour_get_video(&sc->sc_fb));
|
||||
}
|
||||
|
||||
static void
|
||||
cgfour_set_video(sc, enable)
|
||||
struct cgfour_softc *sc;
|
||||
int enable;
|
||||
{
|
||||
|
||||
fb_pfour_set_video(&sc->sc_fb, enable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load a subset of the current (new) colormap into the Brooktree DAC.
|
||||
*/
|
||||
static void
|
||||
cgfourloadcmap(sc, start, ncolors)
|
||||
register struct cgfour_softc *sc;
|
||||
register int start, ncolors;
|
||||
{
|
||||
register volatile struct bt_regs *bt;
|
||||
register u_int *ip, i;
|
||||
register 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_fbc->fbc_dac;
|
||||
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;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,896 +0,0 @@
|
|||
/* $NetBSD: cgfourteen.c,v 1.6 2000/06/29 07:37:54 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
* The President and Fellows of Harvard College. All rights reserved.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Harvard University.
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* This product includes software developed by Harvard University and
|
||||
* its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Based on:
|
||||
* NetBSD: cgthree.c,v 1.28 1996/05/31 09:59:22 pk Exp
|
||||
* NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver for Campus-II on-board mbus-based video (cgfourteen).
|
||||
* Provides minimum emulation of a Sun cgthree 8-bit framebuffer to
|
||||
* allow X to run.
|
||||
*
|
||||
* Does not handle interrupts, even though they can occur.
|
||||
*
|
||||
* XXX should defer colormap updates to vertical retrace interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following is for debugging only; it opens up a security hole
|
||||
* enabled by allowing any user to map the control registers for the
|
||||
* cg14 into their space.
|
||||
*/
|
||||
#undef 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/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/fbvar.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/conf.h>
|
||||
|
||||
#include <sparc64/dev/cgfourteenreg.h>
|
||||
#include <sparc64/dev/cgfourteenvar.h>
|
||||
|
||||
/* autoconfiguration driver */
|
||||
static void cgfourteenattach(struct device *, struct device *, void *);
|
||||
static int cgfourteenmatch(struct device *, struct cfdata *, void *);
|
||||
static void cgfourteenunblank(struct device *);
|
||||
|
||||
/* cdevsw prototypes */
|
||||
cdev_decl(cgfourteen);
|
||||
|
||||
struct cfattach cgfourteen_ca = {
|
||||
sizeof(struct cgfourteen_softc), cgfourteenmatch, cgfourteenattach
|
||||
};
|
||||
|
||||
struct cfdriver cgfourteen_cd = {
|
||||
NULL, "cgfourteen", DV_DULL
|
||||
};
|
||||
|
||||
/* frame buffer generic driver */
|
||||
static struct fbdriver cgfourteenfbdriver = {
|
||||
cgfourteenunblank, cgfourteenopen, cgfourteenclose, cgfourteenioctl,
|
||||
cgfourteenpoll, cgfourteenmmap
|
||||
};
|
||||
|
||||
extern int fbnode;
|
||||
extern struct tty *fbconstty;
|
||||
|
||||
static void cg14_set_video __P((struct cgfourteen_softc *, int));
|
||||
static int cg14_get_video __P((struct cgfourteen_softc *));
|
||||
static int cg14_get_cmap __P((struct fbcmap *, union cg14cmap *, int));
|
||||
static int cg14_put_cmap __P((struct fbcmap *, union cg14cmap *, int));
|
||||
static void cg14_load_hwcmap __P((struct cgfourteen_softc *, int, int));
|
||||
static void cg14_init __P((struct cgfourteen_softc *));
|
||||
static void cg14_reset __P((struct cgfourteen_softc *));
|
||||
static void cg14_loadomap __P((struct cgfourteen_softc *));/* cursor overlay */
|
||||
static void cg14_setcursor __P((struct cgfourteen_softc *));/* set position */
|
||||
static void cg14_loadcursor __P((struct cgfourteen_softc *));/* set shape */
|
||||
|
||||
/*
|
||||
* Match a cgfourteen.
|
||||
*/
|
||||
int
|
||||
cgfourteenmatch(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
{
|
||||
struct confargs *ca = aux;
|
||||
struct romaux *ra = &ca->ca_ra;
|
||||
|
||||
/*
|
||||
* Mask out invalid flags from the user.
|
||||
*/
|
||||
cf->cf_flags &= FB_USERMASK;
|
||||
|
||||
/* Check driver name */
|
||||
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* The cgfourteen is a local-bus video adaptor, accessed directly
|
||||
* via the processor, and not through device space or an external
|
||||
* bus. Thus we look _only_ at the obio bus.
|
||||
* Additionally, these things exist only on the Sun4m.
|
||||
*/
|
||||
if (CPU_ISSUN4M && ca->ca_bustype == BUS_OBIO)
|
||||
return(1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach a display. We need to notice if it is the console, too.
|
||||
*/
|
||||
void
|
||||
cgfourteenattach(parent, self, args)
|
||||
struct device *parent, *self;
|
||||
void *args;
|
||||
{
|
||||
register struct cgfourteen_softc *sc = (struct cgfourteen_softc *)self;
|
||||
register struct confargs *ca = args;
|
||||
register int node = 0, ramsize;
|
||||
register u_int32_t *lut;
|
||||
int i, isconsole;
|
||||
|
||||
sc->sc_fb.fb_driver = &cgfourteenfbdriver;
|
||||
sc->sc_fb.fb_device = &sc->sc_dev;
|
||||
sc->sc_fb.fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
|
||||
|
||||
/*
|
||||
* We're emulating a cg3/8, so represent ourselves as one
|
||||
*/
|
||||
#ifdef CG14_CG8
|
||||
sc->sc_fb.fb_type.fb_type = FBTYPE_MEMCOLOR;
|
||||
#else
|
||||
sc->sc_fb.fb_type.fb_type = FBTYPE_SUN3COLOR;
|
||||
#endif
|
||||
|
||||
node = ca->ca_ra.ra_node;
|
||||
#ifdef CG14_CG8
|
||||
sc->sc_fb.fb_type.fb_depth = 32;
|
||||
#else
|
||||
sc->sc_fb.fb_type.fb_depth = 8;
|
||||
#endif
|
||||
fb_setsize(&sc->sc_fb, sc->sc_fb.fb_type.fb_depth,
|
||||
1152, 900, node, ca->ca_bustype);
|
||||
|
||||
ramsize = roundup(sc->sc_fb.fb_type.fb_height * sc->sc_fb.fb_linebytes,
|
||||
NBPG);
|
||||
|
||||
sc->sc_fb.fb_type.fb_cmsize = CG14_CLUT_SIZE;
|
||||
sc->sc_fb.fb_type.fb_size = ramsize;
|
||||
|
||||
/*
|
||||
* Now map in the 8 useful pages of registers
|
||||
*/
|
||||
if (ca->ca_ra.ra_len < 0x10000) {
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("warning: can't find all cgfourteen registers...\n");
|
||||
#endif
|
||||
ca->ca_ra.ra_len = 0x10000;
|
||||
}
|
||||
sc->sc_ctl = (struct cg14ctl *) mapiodev(ca->ca_ra.ra_reg, 0,
|
||||
ca->ca_ra.ra_len);
|
||||
|
||||
sc->sc_hwc = (struct cg14curs *) ((u_int)sc->sc_ctl +
|
||||
CG14_OFFSET_CURS);
|
||||
sc->sc_dac = (struct cg14dac *) ((u_int)sc->sc_ctl +
|
||||
CG14_OFFSET_DAC);
|
||||
sc->sc_xlut = (struct cg14xlut *) ((u_int)sc->sc_ctl +
|
||||
CG14_OFFSET_XLUT);
|
||||
sc->sc_clut1 = (struct cg14clut *) ((u_int)sc->sc_ctl +
|
||||
CG14_OFFSET_CLUT1);
|
||||
sc->sc_clut2 = (struct cg14clut *) ((u_int)sc->sc_ctl +
|
||||
CG14_OFFSET_CLUT2);
|
||||
sc->sc_clut3 = (struct cg14clut *) ((u_int)sc->sc_ctl +
|
||||
CG14_OFFSET_CLUT3);
|
||||
sc->sc_clutincr = (u_int *) ((u_int)sc->sc_ctl +
|
||||
CG14_OFFSET_CLUTINCR);
|
||||
|
||||
/*
|
||||
* Stash the physical address of the framebuffer for use by mmap
|
||||
*/
|
||||
if (ca->ca_ra.ra_nreg < 2)
|
||||
panic("cgfourteen with only one register set; can't find"
|
||||
" framebuffer");
|
||||
sc->sc_phys = ca->ca_ra.ra_reg[1];
|
||||
|
||||
#if defined(DEBUG) && defined(CG14_MAP_REGS)
|
||||
/* Store the physical address of the control registers */
|
||||
sc->sc_regphys = ca->ca_ra.ra_reg[0];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Let the user know that we're here
|
||||
*/
|
||||
#ifdef CG14_CG8
|
||||
printf(": cgeight emulated at %dx%dx24bpp",
|
||||
sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
|
||||
#else
|
||||
printf(": cgthree emulated at %dx%dx8bpp",
|
||||
sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
|
||||
#endif
|
||||
/*
|
||||
* Enable the video, but don't change the pixel depth.
|
||||
*/
|
||||
cg14_set_video(sc, 1);
|
||||
|
||||
/*
|
||||
* Grab the initial colormap
|
||||
*/
|
||||
lut = (u_int32_t *) sc->sc_clut1->clut_lut;
|
||||
for (i = 0; i < CG14_CLUT_SIZE; i++)
|
||||
sc->sc_cmap.cm_chip[i] = lut[i];
|
||||
|
||||
/* See if we're the console */
|
||||
isconsole = (node == fbnode);
|
||||
|
||||
/*
|
||||
* We don't use the raster console since the cg14 is fast enough
|
||||
* already.
|
||||
*/
|
||||
#ifdef notdef
|
||||
/*
|
||||
* When the ROM has mapped in a cgfourteen display, the address
|
||||
* maps only the video RAM, so in any case we have to map the
|
||||
* registers ourselves. We only need the video RAM if we are
|
||||
* going to print characters via rconsole.
|
||||
*/
|
||||
if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
|
||||
/* this probably cannot happen, but what the heck */
|
||||
sc->sc_fb.fb_pixels = mapiodev(ca->ca_ra.ra_reg, CG3REG_MEM,
|
||||
ramsize);
|
||||
}
|
||||
#endif /* notdef */
|
||||
|
||||
|
||||
if (isconsole) {
|
||||
printf(" (console)\n");
|
||||
#ifdef notdef
|
||||
#ifdef RASTERCONSOLE
|
||||
fbrcons_init(&sc->sc_fb);
|
||||
#endif
|
||||
#endif /* notdef */
|
||||
} else
|
||||
printf("\n");
|
||||
|
||||
/* Attach to /dev/fb */
|
||||
if (node == fbnode)
|
||||
fb_attach(&sc->sc_fb, isconsole);
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep track of the number of opens made. In the 24-bit driver, we need to
|
||||
* switch to 24-bit mode on the first open, and switch back to 8-bit on
|
||||
* the last close. This kind of nonsense is needed to give screenblank
|
||||
* a fighting chance of working.
|
||||
*/
|
||||
static int cg14_opens = 0;
|
||||
|
||||
int
|
||||
cgfourteenopen(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
|
||||
int unit = minor(dev);
|
||||
int s, oldopens;
|
||||
|
||||
if (unit >= cgfourteen_cd.cd_ndevs ||
|
||||
cgfourteen_cd.cd_devs[unit] == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
s = splhigh();
|
||||
oldopens = cg14_opens++;
|
||||
splx(s);
|
||||
|
||||
/* Setup the cg14 as we want it, and save the original PROM state */
|
||||
if (oldopens == 0) /* first open only, to make screenblank work */
|
||||
cg14_init(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgfourteenclose(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
|
||||
int s, opens;
|
||||
|
||||
s = splhigh();
|
||||
opens = --cg14_opens;
|
||||
if (cg14_opens < 0)
|
||||
opens = cg14_opens = 0;
|
||||
splx(s);
|
||||
|
||||
/*
|
||||
* Restore video state to make the PROM happy, on last close.
|
||||
*/
|
||||
if (opens == 0)
|
||||
cg14_reset(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgfourteenioctl(dev, cmd, data, flags, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
register caddr_t data;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
|
||||
struct fbgattr fba;
|
||||
union cg14cursor_cmap tcm;
|
||||
int v, error;
|
||||
u_int count;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case FBIOGTYPE:
|
||||
copyout(sc->sc_fb.fb_type, data, sizeof (sc->sc_fb.fb_type));
|
||||
break;
|
||||
|
||||
case FBIOGATTR:
|
||||
fba->real_type = FBTYPE_MDICOLOR;
|
||||
fba->owner = 0; /* XXX ??? */
|
||||
fba->fbtype = sc->sc_fb.fb_type;
|
||||
fba->sattr.flags = 0;
|
||||
fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
|
||||
fba->sattr.dev_specific[0] = -1;
|
||||
fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
|
||||
fba->emu_types[1] = -1;
|
||||
copyout(&fba, data, sizeof (fba));
|
||||
break;
|
||||
|
||||
case FBIOGETCMAP:
|
||||
return (cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap,
|
||||
CG14_CLUT_SIZE));
|
||||
|
||||
case FBIOPUTCMAP:
|
||||
/* copy to software map */
|
||||
#define p ((struct fbcmap *)data)
|
||||
#ifdef CG14_CG8
|
||||
suword(&p->index,fuword(&p->index) & 0xffffff);
|
||||
#endif
|
||||
error = cg14_put_cmap(p, &sc->sc_cmap, CG14_CLUT_SIZE);
|
||||
if (error)
|
||||
return (error);
|
||||
/* now blast them into the chip */
|
||||
/* XXX should use retrace interrupt */
|
||||
cg14_load_hwcmap(sc, fuword(&p->index), fuword(&p->count));
|
||||
#undef p
|
||||
break;
|
||||
|
||||
case FBIOGVIDEO:
|
||||
*(int *)data = cg14_get_video(sc);
|
||||
break;
|
||||
|
||||
case FBIOSVIDEO:
|
||||
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:
|
||||
{
|
||||
caddr_t image;
|
||||
|
||||
/* do not quite want everything here... */
|
||||
susword(&p->set, FB_CUR_SETALL); /* close enough, anyway */
|
||||
susword(&p->enable, cc->cc_enable);
|
||||
suword(&p->pos, cc->cc_pos);
|
||||
suword(&p->hot, cc->cc_hot);
|
||||
suword(&p->size, cc->cc_size);
|
||||
|
||||
/* begin ugh ... can we lose some of this crap?? */
|
||||
image = fuword(&p->image);
|
||||
if (image != NULL) {
|
||||
count = cc->cc_size.y * 32 / NBBY;
|
||||
error = copyout((caddr_t)cc->cc_cplane,
|
||||
(caddr_t)image, count);
|
||||
if (error)
|
||||
return (error);
|
||||
error = copyout((caddr_t)cc->cc_eplane,
|
||||
(caddr_t)fuword(p->mask), count);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
if (fuword(&p->cmap.red) != NULL) {
|
||||
error = cg14_get_cmap(&p->cmap,
|
||||
(union cg14cmap *)&cc->cc_color, 2);
|
||||
if (error)
|
||||
return (error);
|
||||
} else {
|
||||
suword(&p->cmap.index, 0);
|
||||
suword(&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 = fusword(&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) {
|
||||
struct fbcurpos size;
|
||||
|
||||
size = fuword(&p->size);
|
||||
if ((u_int)size.x > 32 || (u_int)size.y > 32)
|
||||
return (EINVAL);
|
||||
count = size.y * 32 / NBBY;
|
||||
if (!useracc(fuword(&p->image), count, B_READ) ||
|
||||
!useracc(fuword(&p->mask), count, B_READ))
|
||||
return (EFAULT);
|
||||
}
|
||||
|
||||
/* parameters are OK; do it */
|
||||
if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
|
||||
if (v & FB_CUR_SETCUR)
|
||||
cc->cc_enable = fusword(&p->enable);
|
||||
if (v & FB_CUR_SETPOS)
|
||||
cc->cc_pos = fuword(&p->pos);
|
||||
if (v & FB_CUR_SETHOT)
|
||||
cc->cc_hot = fuword(&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 = fuword(&p->size);
|
||||
count = cc->cc_size.y * 32 / NBBY;
|
||||
bzero((caddr_t)cc->cc_eplane, sizeof cc->cc_eplane);
|
||||
bzero((caddr_t)cc->cc_cplane, sizeof cc->cc_cplane);
|
||||
copyin(fuword(&p->mask), (caddr_t)cc->cc_eplane, count);
|
||||
copyin(fuword(&p->image), (caddr_t)cc->cc_cplane, count);
|
||||
cg14_loadcursor(sc);
|
||||
}
|
||||
break;
|
||||
|
||||
#undef cc
|
||||
#undef p
|
||||
case FBIOGCURPOS:
|
||||
suword(data, sc->sc_cursor.cc_pos);
|
||||
break;
|
||||
|
||||
case FBIOSCURPOS:
|
||||
sc->sc_cursor.cc_pos = *(struct fbcurpos *)fuword(data);
|
||||
cg14_setcursor(sc);
|
||||
break;
|
||||
|
||||
case FBIOGCURMAX:
|
||||
/* max cursor size is 32x32 */
|
||||
susword(&((struct fbcurpos *)data)->x, 32);
|
||||
susword(&((struct fbcurpos *)data)->y, 32);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Undo the effect of an FBIOSVIDEO that turns the video off.
|
||||
*/
|
||||
static void
|
||||
cgfourteenunblank(dev)
|
||||
struct device *dev;
|
||||
{
|
||||
|
||||
cg14_set_video((struct cgfourteen_softc *)dev, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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?
|
||||
*/
|
||||
paddr_t
|
||||
cgfourteenmmap(dev, off, prot)
|
||||
dev_t dev;
|
||||
off_t off;
|
||||
int prot;
|
||||
{
|
||||
register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
|
||||
|
||||
#define CG3START (128*1024 + 128*1024)
|
||||
#define CG8START (256*1024)
|
||||
#define NOOVERLAY (0x04000000)
|
||||
|
||||
if (off & PGOFSET)
|
||||
panic("cgfourteenmmap");
|
||||
|
||||
if (off < 0)
|
||||
return (-1);
|
||||
|
||||
#if defined(DEBUG) && 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;
|
||||
return (REG2PHYS(&sc->sc_regphys, off, 0) | PMAP_NC);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((u_int)off >= NOOVERLAY)
|
||||
off -= NOOVERLAY;
|
||||
#ifdef CG14_CG8
|
||||
else if ((u_int)off >= CG8START) {
|
||||
off -= CG8START;
|
||||
}
|
||||
#else
|
||||
else if ((u_int)off >= CG3START)
|
||||
off -= CG3START;
|
||||
#endif
|
||||
else
|
||||
off = 0;
|
||||
|
||||
if (off >= sc->sc_fb.fb_type.fb_size *
|
||||
sc->sc_fb.fb_type.fb_depth/8) {
|
||||
#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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use PMAP_NC to disable the cache, since otherwise refresh is
|
||||
* very confused.
|
||||
*/
|
||||
return (REG2PHYS(&sc->sc_phys, off) | PMAP_NC);
|
||||
}
|
||||
|
||||
int
|
||||
cgfourteenpoll(dev, events, p)
|
||||
dev_t dev;
|
||||
int events;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (seltrue(dev, events, p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Miscellaneous helper functions
|
||||
*/
|
||||
|
||||
/* Initialize the framebuffer, storing away useful state for later reset */
|
||||
static void
|
||||
cg14_init(sc)
|
||||
struct cgfourteen_softc *sc;
|
||||
{
|
||||
register u_int32_t *clut;
|
||||
register u_int8_t *xlut;
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* We stash away the following to restore on close:
|
||||
*
|
||||
* color look-up table 1 (sc->sc_saveclut)
|
||||
* x look-up table (sc->sc_savexlut)
|
||||
* control register (sc->sc_savectl)
|
||||
* cursor control register (sc->sc_savehwc)
|
||||
*/
|
||||
sc->sc_savectl = sc->sc_ctl->ctl_mctl;
|
||||
sc->sc_savehwc = sc->sc_hwc->curs_ctl;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
#ifdef CG14_CG8
|
||||
/*
|
||||
* Enable the video, and put in 24 bit mode.
|
||||
*/
|
||||
sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_32 |
|
||||
CG14_MCTL_POWERCTL;
|
||||
|
||||
/*
|
||||
* Zero the xlut to enable direct-color mode
|
||||
*/
|
||||
bzero(sc->sc_xlut, CG14_CLUT_SIZE);
|
||||
#else
|
||||
/*
|
||||
* Enable the video and put it in 8 bit mode
|
||||
*/
|
||||
sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_8 |
|
||||
CG14_MCTL_POWERCTL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
cg14_reset(sc) /* Restore the state saved on cg14_init */
|
||||
struct cgfourteen_softc *sc;
|
||||
{
|
||||
register u_int32_t *clut;
|
||||
register u_int8_t *xlut;
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* We restore the following, saved in cg14_init:
|
||||
*
|
||||
* color look-up table 1 (sc->sc_saveclut)
|
||||
* x look-up table (sc->sc_savexlut)
|
||||
* control register (sc->sc_savectl)
|
||||
* cursor control register (sc->sc_savehwc)
|
||||
*
|
||||
* Note that we don't touch the video enable bits in the
|
||||
* control register; otherwise, screenblank wouldn't work.
|
||||
*/
|
||||
sc->sc_ctl->ctl_mctl = (sc->sc_ctl->ctl_mctl & (CG14_MCTL_ENABLEVID |
|
||||
CG14_MCTL_POWERCTL)) |
|
||||
(sc->sc_savectl & ~(CG14_MCTL_ENABLEVID |
|
||||
CG14_MCTL_POWERCTL));
|
||||
sc->sc_hwc->curs_ctl = sc->sc_savehwc;
|
||||
|
||||
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++) {
|
||||
clut[i] = sc->sc_saveclut.cm_chip[i];
|
||||
xlut[i] = sc->sc_savexlut[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable/disable video display; power down monitor if DPMS-capable */
|
||||
static void
|
||||
cg14_set_video(sc, enable)
|
||||
struct cgfourteen_softc *sc;
|
||||
int enable;
|
||||
{
|
||||
/*
|
||||
* We can only use DPMS to power down the display if the chip revision
|
||||
* is greater than 0.
|
||||
*/
|
||||
if (enable) {
|
||||
if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0)
|
||||
sc->sc_ctl->ctl_mctl |= (CG14_MCTL_ENABLEVID |
|
||||
CG14_MCTL_POWERCTL);
|
||||
else
|
||||
sc->sc_ctl->ctl_mctl |= CG14_MCTL_ENABLEVID;
|
||||
} else {
|
||||
if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0)
|
||||
sc->sc_ctl->ctl_mctl &= ~(CG14_MCTL_ENABLEVID |
|
||||
CG14_MCTL_POWERCTL);
|
||||
else
|
||||
sc->sc_ctl->ctl_mctl &= ~CG14_MCTL_ENABLEVID;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get status of video display */
|
||||
static int
|
||||
cg14_get_video(sc)
|
||||
struct cgfourteen_softc *sc;
|
||||
{
|
||||
return ((sc->sc_ctl->ctl_mctl & CG14_MCTL_ENABLEVID) != 0);
|
||||
}
|
||||
|
||||
/* Read the software shadow colormap */
|
||||
static int
|
||||
cg14_get_cmap(p, cm, cmsize)
|
||||
register struct fbcmap *p;
|
||||
union cg14cmap *cm;
|
||||
int cmsize;
|
||||
{
|
||||
register u_int i, start, count;
|
||||
register u_char *cp;
|
||||
|
||||
start = fuword(&p->index);
|
||||
count = fuword(&p->count);
|
||||
if (start >= cmsize || start + count > cmsize)
|
||||
#ifdef DEBUG
|
||||
{
|
||||
printf("putcmaperror: start %d cmsize %d count %d\n",
|
||||
start,cmsize,count);
|
||||
#endif
|
||||
return (EINVAL);
|
||||
#ifdef DEBUG
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!useracc(fuword(&p->red), count, B_WRITE) ||
|
||||
!useracc(fuword(&p->green), count, B_WRITE) ||
|
||||
!useracc(fuword(&p->blue), count, B_WRITE))
|
||||
return (EFAULT);
|
||||
for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
|
||||
if (subyte(&p->red[i], cp[3]) ||
|
||||
subyte(&p->green[i], cp[2]) ||
|
||||
subyte(&p->blue[i], cp[1]))
|
||||
return (EFAULT);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Write the software shadow colormap */
|
||||
static int
|
||||
cg14_put_cmap(p, cm, cmsize)
|
||||
register struct fbcmap *p;
|
||||
union cg14cmap *cm;
|
||||
int cmsize;
|
||||
{
|
||||
register u_int i, start, count;
|
||||
register u_char *cp;
|
||||
|
||||
start = fuword(&p->index);
|
||||
count = fuword(&p->count);
|
||||
if (start >= cmsize || start + count > cmsize)
|
||||
#ifdef DEBUG
|
||||
{
|
||||
printf("putcmaperror: start %d cmsize %d count %d\n",
|
||||
start,cmsize,count);
|
||||
#endif
|
||||
return (EINVAL);
|
||||
#ifdef DEBUG
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!useracc(fuword(&p->red), count, B_READ) ||
|
||||
!useracc(fuword(&p->green), count, B_READ) ||
|
||||
!useracc(fuword(&p->blue), count, B_READ))
|
||||
return (EFAULT);
|
||||
for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
|
||||
cp[3] = fubyte(&p->red[i]);
|
||||
cp[2] = fubyte(&p->green[i]);
|
||||
cp[1] = fubyte(&p->blue[i]);
|
||||
cp[0] = 0; /* no alpha channel */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
cg14_load_hwcmap(sc, start, ncolors)
|
||||
register struct cgfourteen_softc *sc;
|
||||
register int start, ncolors;
|
||||
{
|
||||
/* XXX switch to auto-increment, and on retrace intr */
|
||||
|
||||
/* Setup pointers to source and dest */
|
||||
register u_int32_t *colp = &sc->sc_cmap.cm_chip[start];
|
||||
volatile register u_int32_t *lutp = &sc->sc_clut1->clut_lut[start];
|
||||
|
||||
/* Copy by words */
|
||||
while (--ncolors >= 0)
|
||||
*lutp++ = *colp++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the cursor (overlay `foreground' and `background') colors.
|
||||
*/
|
||||
static void
|
||||
cg14_setcursor(sc)
|
||||
register 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(sc)
|
||||
register struct cgfourteen_softc *sc;
|
||||
{
|
||||
register volatile struct cg14curs *hwc;
|
||||
register u_int edgemask, m;
|
||||
register 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(sc)
|
||||
register 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];
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
/* $NetBSD: cgfourteenreg.h,v 1.1.1.1 1998/06/20 04:58:50 eeh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
* The President and Fellows of Harvard College. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Harvard University and
|
||||
* its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Register/dac/clut/cursor definitions for cgfourteen frame buffer
|
||||
*/
|
||||
|
||||
/* Locations of control registers in cg14 register set */
|
||||
#define CG14_OFFSET_CURS 0x1000
|
||||
#define CG14_OFFSET_DAC 0x2000
|
||||
#define CG14_OFFSET_XLUT 0x3000
|
||||
#define CG14_OFFSET_CLUT1 0x4000
|
||||
#define CG14_OFFSET_CLUT2 0x5000
|
||||
#define CG14_OFFSET_CLUT3 0x6000
|
||||
#define CG14_OFFSET_CLUTINCR 0xf000
|
||||
|
||||
/* Main control register set */
|
||||
struct cg14ctl {
|
||||
volatile u_int8_t ctl_mctl; /* main control register */
|
||||
#define CG14_MCTL_ENABLEINTR 0x80 /* interrupts */
|
||||
#define CG14_MCTL_ENABLEVID 0x40 /* enable video */
|
||||
#define CG14_MCTL_PIXMODE_MASK 0x30
|
||||
#define CG14_MCTL_PIXMODE_8 0x00 /* data is 16 8-bit pixels */
|
||||
#define CG14_MCTL_PIXMODE_16 0x20 /* data is 8 16-bit pixels */
|
||||
#define CG14_MCTL_PIXMODE_32 0x30 /* data is 4 32-bit pixels */
|
||||
#define CG14_MCTL_PIXMODE_SHIFT 4
|
||||
#define CG14_MCTL_TMR 0x0c
|
||||
#define CG14_MCTL_ENABLETMR 0x02
|
||||
#define CG14_MCTL_rev0RESET 0x01
|
||||
#define CG14_MCTL_POWERCTL 0x01
|
||||
|
||||
volatile u_int8_t ctl_ppr; /* packed pixel register */
|
||||
volatile u_int8_t ctl_tmsr0; /* test status reg. 0 */
|
||||
volatile u_int8_t ctl_tmsr1; /* test status reg. 1 */
|
||||
volatile u_int8_t ctl_msr; /* master status register */
|
||||
volatile u_int8_t ctl_fsr; /* fault status register */
|
||||
volatile u_int8_t ctl_rsr; /* revision status register */
|
||||
#define CG14_RSR_REVMASK 0xf0 /* mask to get revision */
|
||||
#define CG14_RSR_IMPLMASK 0x0f /* mask to get impl. code */
|
||||
volatile u_int8_t ctl_ccr; /* clock control register */
|
||||
/* XXX etc. */
|
||||
};
|
||||
|
||||
/* Hardware cursor map */
|
||||
#define CG14_CURS_SIZE 32
|
||||
struct cg14curs {
|
||||
volatile u_int32_t curs_plane0[CG14_CURS_SIZE]; /* plane 0 */
|
||||
volatile u_int32_t curs_plane1[CG14_CURS_SIZE];
|
||||
volatile u_int8_t curs_ctl; /* control register */
|
||||
#define CG14_CURS_ENABLE 0x4
|
||||
#define CG14_CURS_DOUBLEBUFFER 0x2 /* use X-channel for curs */
|
||||
volatile u_int8_t pad0[3];
|
||||
volatile u_int16_t curs_x; /* x position */
|
||||
volatile u_int16_t curs_y; /* y position */
|
||||
volatile u_int32_t curs_color1; /* color register 1 */
|
||||
volatile u_int32_t curs_color2; /* color register 2 */
|
||||
volatile u_int32_t pad[444]; /* pad to 2KB boundary */
|
||||
volatile u_int32_t curs_plane0incr[CG14_CURS_SIZE]; /* autoincr */
|
||||
volatile u_int32_t curs_plane1incr[CG14_CURS_SIZE]; /* autoincr */
|
||||
};
|
||||
|
||||
/* DAC */
|
||||
struct cg14dac {
|
||||
volatile u_int8_t dac_addr; /* address register */
|
||||
volatile u_int8_t pad0[255];
|
||||
volatile u_int8_t dac_gammalut; /* gamma LUT */
|
||||
volatile u_int8_t pad1[255];
|
||||
volatile u_int8_t dac_regsel; /* register select */
|
||||
volatile u_int8_t pad2[255];
|
||||
volatile u_int8_t dac_mode; /* mode register */
|
||||
};
|
||||
|
||||
#define CG14_CLUT_SIZE 256
|
||||
|
||||
/* XLUT registers */
|
||||
struct cg14xlut {
|
||||
volatile u_int8_t xlut_lut[CG14_CLUT_SIZE]; /* the LUT */
|
||||
volatile u_int8_t xlut_lutd[CG14_CLUT_SIZE]; /* ??? */
|
||||
volatile u_int8_t pad0[0x600];
|
||||
volatile u_int8_t xlut_lutinc[CG14_CLUT_SIZE]; /* autoincrLUT*/
|
||||
volatile u_int8_t xlut_lutincd[CG14_CLUT_SIZE];
|
||||
};
|
||||
|
||||
/* Color Look-Up Table (CLUT) */
|
||||
struct cg14clut {
|
||||
volatile u_int32_t clut_lut[CG14_CLUT_SIZE]; /* the LUT */
|
||||
volatile u_int32_t clut_lutd[CG14_CLUT_SIZE]; /* ??? */
|
||||
volatile u_int32_t clut_lutinc[CG14_CLUT_SIZE]; /* autoincr */
|
||||
volatile u_int32_t clut_lutincd[CG14_CLUT_SIZE];
|
||||
};
|
|
@ -1,93 +0,0 @@
|
|||
/* $NetBSD: cgfourteenvar.h,v 1.1.1.1 1998/06/20 04:58:50 eeh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
* The President and Fellows of Harvard College. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Harvard University and
|
||||
* its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Layout of cg14 hardware colormap
|
||||
*/
|
||||
union cg14cmap {
|
||||
u_char cm_map[256][4]; /* 256 R/G/B/A entries (B is high)*/
|
||||
u_int32_t cm_chip[256]; /* the way the chip gets loaded */
|
||||
};
|
||||
|
||||
/*
|
||||
* cg14 hardware cursor colormap
|
||||
*/
|
||||
union cg14cursor_cmap { /* colormap, like bt_cmap, but tiny */
|
||||
u_char cm_map[2][4]; /* 2 R/G/B/A entries */
|
||||
u_int32_t cm_chip[2]; /* 2 chip equivalents */
|
||||
};
|
||||
|
||||
/*
|
||||
* cg14 hardware cursor status
|
||||
*/
|
||||
struct cg14_cursor { /* cg14 hardware cursor status */
|
||||
short cc_enable; /* cursor is enabled */
|
||||
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 */
|
||||
union cg14cursor_cmap cc_color; /* cursor colormap */
|
||||
};
|
||||
|
||||
/*
|
||||
* per-cg14 variables/state
|
||||
*/
|
||||
struct cgfourteen_softc {
|
||||
struct device sc_dev; /* base device */
|
||||
struct fbdevice sc_fb; /* frame buffer device */
|
||||
|
||||
struct rom_reg sc_phys; /* phys address of frame buffer */
|
||||
#if defined(DEBUG) && defined(CG14_MAP_REGS)
|
||||
struct rom_reg sc_regphys; /* phys addr of fb regs; for debug */
|
||||
#endif
|
||||
union cg14cmap sc_cmap; /* current colormap */
|
||||
|
||||
struct cg14_cursor sc_cursor; /* Hardware cursor state */
|
||||
|
||||
union cg14cmap sc_saveclut; /* a place to stash PROM state */
|
||||
u_int8_t sc_savexlut[256];
|
||||
u_int8_t sc_savectl;
|
||||
u_int8_t sc_savehwc;
|
||||
|
||||
struct cg14ctl *sc_ctl; /* various registers */
|
||||
struct cg14curs *sc_hwc;
|
||||
struct cg14dac *sc_dac;
|
||||
struct cg14xlut *sc_xlut;
|
||||
struct cg14clut *sc_clut1;
|
||||
struct cg14clut *sc_clut2;
|
||||
struct cg14clut *sc_clut3;
|
||||
u_int *sc_clutincr;
|
||||
};
|
|
@ -1,444 +0,0 @@
|
|||
/* $NetBSD: cgtwo.c,v 1.6 2000/06/29 07:37:54 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)cgthree.c 8.2 (Berkeley) 10/30/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* color display (cgtwo) driver.
|
||||
*
|
||||
* Does not handle interrupts, even though they can occur.
|
||||
*
|
||||
* XXX should defer colormap updates to vertical retrace interrupts
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/fbvar.h>
|
||||
#if defined(SUN4)
|
||||
#include <machine/eeprom.h>
|
||||
#endif
|
||||
#include <machine/conf.h>
|
||||
#include <machine/cgtworeg.h>
|
||||
|
||||
|
||||
/* per-display variables */
|
||||
struct cgtwo_softc {
|
||||
struct device sc_dev; /* base device */
|
||||
struct fbdevice sc_fb; /* frame buffer device */
|
||||
struct rom_reg sc_phys; /* display RAM (phys addr) */
|
||||
int sc_bustype; /* type of bus we live on */
|
||||
volatile struct cg2statusreg *sc_reg; /* CG2 control registers */
|
||||
volatile u_short *sc_cmap;
|
||||
#define sc_redmap(sc) ((sc)->sc_cmap)
|
||||
#define sc_greenmap(sc) ((sc)->sc_cmap + CG2_CMSIZE)
|
||||
#define sc_bluemap(sc) ((sc)->sc_cmap + 2 * CG2_CMSIZE)
|
||||
};
|
||||
|
||||
/* autoconfiguration driver */
|
||||
static void cgtwoattach __P((struct device *, struct device *, void *));
|
||||
static int cgtwomatch __P((struct device *, struct cfdata *, void *));
|
||||
static void cgtwounblank __P((struct device *));
|
||||
int cgtwogetcmap __P((struct cgtwo_softc *, struct fbcmap *));
|
||||
int cgtwoputcmap __P((struct cgtwo_softc *, struct fbcmap *));
|
||||
|
||||
/* cdevsw prototypes */
|
||||
cdev_decl(cgtwo);
|
||||
|
||||
struct cfattach cgtwo_ca = {
|
||||
sizeof(struct cgtwo_softc), cgtwomatch, cgtwoattach
|
||||
};
|
||||
|
||||
struct cfdriver cgtwo_cd = {
|
||||
NULL, "cgtwo", DV_DULL
|
||||
};
|
||||
|
||||
/* frame buffer generic driver */
|
||||
static struct fbdriver cgtwofbdriver = {
|
||||
cgtwounblank, cgtwoopen, cgtwoclose, cgtwoioctl, cgtwopoll, cgtwommap
|
||||
};
|
||||
|
||||
extern int fbnode;
|
||||
extern struct tty *fbconstty;
|
||||
|
||||
/*
|
||||
* Match a cgtwo.
|
||||
*/
|
||||
int
|
||||
cgtwomatch(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
{
|
||||
struct confargs *ca = aux;
|
||||
struct romaux *ra = &ca->ca_ra;
|
||||
#if defined(SUN4)
|
||||
caddr_t tmp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mask out invalid flags from the user.
|
||||
*/
|
||||
cf->cf_flags &= FB_USERMASK;
|
||||
|
||||
if (ca->ca_bustype != BUS_VME16)
|
||||
return (0);
|
||||
|
||||
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
|
||||
return (0);
|
||||
|
||||
#if defined(SUN4)
|
||||
if (!CPU_ISSUN4 || cf->cf_unit != 0)
|
||||
return (0);
|
||||
|
||||
/* XXX - Must do our own mapping at CG2_CTLREG_OFF */
|
||||
bus_untmp();
|
||||
tmp = (caddr_t)mapdev(ra->ra_reg, TMPMAP_VA, CG2_CTLREG_OFF, NBPG);
|
||||
if (probeget(tmp, ASI_PRIMARY, 2) != -1)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach a display. We need to notice if it is the console, too.
|
||||
*/
|
||||
void
|
||||
cgtwoattach(parent, self, args)
|
||||
struct device *parent, *self;
|
||||
void *args;
|
||||
{
|
||||
register struct cgtwo_softc *sc = (struct cgtwo_softc *)self;
|
||||
register struct confargs *ca = args;
|
||||
register int node = 0;
|
||||
int isconsole = 0;
|
||||
char *nam = NULL;
|
||||
|
||||
sc->sc_fb.fb_driver = &cgtwofbdriver;
|
||||
sc->sc_fb.fb_device = &sc->sc_dev;
|
||||
sc->sc_fb.fb_type.fb_type = FBTYPE_SUN2COLOR;
|
||||
sc->sc_fb.fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
|
||||
|
||||
switch (ca->ca_bustype) {
|
||||
case BUS_VME16:
|
||||
node = 0;
|
||||
nam = "cgtwo";
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("cgtwoattach: impossible bustype");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
sc->sc_fb.fb_type.fb_depth = 8;
|
||||
fb_setsize(&sc->sc_fb, sc->sc_fb.fb_type.fb_depth,
|
||||
1152, 900, node, ca->ca_bustype);
|
||||
|
||||
sc->sc_fb.fb_type.fb_cmsize = 256;
|
||||
sc->sc_fb.fb_type.fb_size = roundup(CG2_MAPPED_SIZE, NBPG);
|
||||
printf(": %s, %d x %d", nam,
|
||||
sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
|
||||
|
||||
/*
|
||||
* When the ROM has mapped in a cgtwo display, the address
|
||||
* maps only the video RAM, so in any case we have to map the
|
||||
* registers ourselves. We only need the video RAM if we are
|
||||
* going to print characters via rconsole.
|
||||
*/
|
||||
#if defined(SUN4)
|
||||
if (CPU_ISSUN4) {
|
||||
struct eeprom *eep = (struct eeprom *)eeprom_va;
|
||||
/*
|
||||
* Assume this is the console if there's no eeprom info
|
||||
* to be found.
|
||||
*/
|
||||
if (eep == NULL || eep->eeConsole == EE_CONS_COLOR)
|
||||
isconsole = (fbconstty != NULL);
|
||||
else
|
||||
isconsole = 0;
|
||||
}
|
||||
#endif
|
||||
sc->sc_phys = ca->ca_ra.ra_reg[0];
|
||||
/* Apparently, the pixels are 32-bit data space */
|
||||
sc->sc_phys.rr_iospace = PMAP_VME32;
|
||||
sc->sc_bustype = ca->ca_bustype;
|
||||
|
||||
if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
|
||||
/* this probably cannot happen, but what the heck */
|
||||
sc->sc_fb.fb_pixels = mapiodev(&sc->sc_phys, CG2_PIXMAP_OFF,
|
||||
CG2_PIXMAP_SIZE);
|
||||
}
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
|
||||
#endif
|
||||
|
||||
sc->sc_reg = (volatile struct cg2statusreg *)
|
||||
mapiodev(ca->ca_ra.ra_reg,
|
||||
CG2_ROPMEM_OFF + offsetof(struct cg2fb, status.reg),
|
||||
sizeof(struct cg2statusreg));
|
||||
|
||||
sc->sc_cmap = (volatile u_short *)
|
||||
mapiodev(ca->ca_ra.ra_reg,
|
||||
CG2_ROPMEM_OFF + offsetof(struct cg2fb, redmap[0]),
|
||||
3 * CG2_CMSIZE);
|
||||
|
||||
if (isconsole) {
|
||||
printf(" (console)\n");
|
||||
#ifdef RASTERCONSOLE
|
||||
fbrcons_init(&sc->sc_fb);
|
||||
#endif
|
||||
} else
|
||||
printf("\n");
|
||||
|
||||
if (node == fbnode || CPU_ISSUN4)
|
||||
fb_attach(&sc->sc_fb, isconsole);
|
||||
}
|
||||
|
||||
int
|
||||
cgtwoopen(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
int unit = minor(dev);
|
||||
|
||||
if (unit >= cgtwo_cd.cd_ndevs || cgtwo_cd.cd_devs[unit] == NULL)
|
||||
return (ENXIO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgtwoclose(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgtwoioctl(dev, cmd, data, flags, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
register caddr_t data;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct cgtwo_softc *sc = cgtwo_cd.cd_devs[minor(dev)];
|
||||
register struct fbgattr *fba;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case FBIOGTYPE:
|
||||
*(struct fbtype *)data = sc->sc_fb.fb_type;
|
||||
break;
|
||||
|
||||
case FBIOGATTR:
|
||||
fba = (struct fbgattr *)data;
|
||||
fba->real_type = sc->sc_fb.fb_type.fb_type;
|
||||
fba->owner = 0; /* XXX ??? */
|
||||
fba->fbtype = sc->sc_fb.fb_type;
|
||||
fba->sattr.flags = 0;
|
||||
fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
|
||||
fba->sattr.dev_specific[0] = -1;
|
||||
fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
|
||||
fba->emu_types[1] = -1;
|
||||
break;
|
||||
|
||||
case FBIOGETCMAP:
|
||||
return cgtwogetcmap(sc, (struct fbcmap *) data);
|
||||
|
||||
case FBIOPUTCMAP:
|
||||
return cgtwoputcmap(sc, (struct fbcmap *) data);
|
||||
|
||||
case FBIOGVIDEO:
|
||||
*(int *)data = sc->sc_reg->video_enab;
|
||||
break;
|
||||
|
||||
case FBIOSVIDEO:
|
||||
sc->sc_reg->video_enab = (*(int*)data) & 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cgtwopoll(dev, events, p)
|
||||
dev_t dev;
|
||||
int events;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (seltrue(dev, events, p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Undo the effect of an FBIOSVIDEO that turns the video off.
|
||||
*/
|
||||
static void
|
||||
cgtwounblank(dev)
|
||||
struct device *dev;
|
||||
{
|
||||
struct cgtwo_softc *sc = (struct cgtwo_softc *)dev;
|
||||
sc->sc_reg->video_enab = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
int
|
||||
cgtwogetcmap(sc, cmap)
|
||||
register struct cgtwo_softc *sc;
|
||||
register struct fbcmap *cmap;
|
||||
{
|
||||
u_char red[CG2_CMSIZE], green[CG2_CMSIZE], blue[CG2_CMSIZE];
|
||||
int error, start, count, ecount;
|
||||
register u_int i;
|
||||
register volatile u_short *p;
|
||||
|
||||
start = cmap->index;
|
||||
count = cmap->count;
|
||||
ecount = start + count;
|
||||
if (start >= CG2_CMSIZE || ecount > CG2_CMSIZE)
|
||||
return (EINVAL);
|
||||
|
||||
/* XXX - Wait for retrace? */
|
||||
|
||||
/* Copy hardware to local arrays. */
|
||||
p = &sc_redmap(sc)[start];
|
||||
for (i = start; i < ecount; i++)
|
||||
red[i] = *p++;
|
||||
p = &sc_greenmap(sc)[start];
|
||||
for (i = start; i < ecount; i++)
|
||||
green[i] = *p++;
|
||||
p = &sc_bluemap(sc)[start];
|
||||
for (i = start; i < ecount; i++)
|
||||
blue[i] = *p++;
|
||||
|
||||
/* Copy local arrays to user space. */
|
||||
if ((error = copyout(red + start, cmap->red, count)) != 0)
|
||||
return (error);
|
||||
if ((error = copyout(green + start, cmap->green, count)) != 0)
|
||||
return (error);
|
||||
if ((error = copyout(blue + start, cmap->blue, count)) != 0)
|
||||
return (error);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
int
|
||||
cgtwoputcmap(sc, cmap)
|
||||
register struct cgtwo_softc *sc;
|
||||
register struct fbcmap *cmap;
|
||||
{
|
||||
u_char red[CG2_CMSIZE], green[CG2_CMSIZE], blue[CG2_CMSIZE];
|
||||
int error, start, count, ecount;
|
||||
register u_int i;
|
||||
register volatile u_short *p;
|
||||
|
||||
start = cmap->index;
|
||||
count = cmap->count;
|
||||
ecount = start + count;
|
||||
if (start >= CG2_CMSIZE || ecount > CG2_CMSIZE)
|
||||
return (EINVAL);
|
||||
|
||||
/* Copy from user space to local arrays. */
|
||||
if ((error = copyin(cmap->red, red + start, count)) != 0)
|
||||
return (error);
|
||||
if ((error = copyin(cmap->green, green + start, count)) != 0)
|
||||
return (error);
|
||||
if ((error = copyin(cmap->blue, blue + start, count)) != 0)
|
||||
return (error);
|
||||
|
||||
/* XXX - Wait for retrace? */
|
||||
|
||||
/* Copy from local arrays to hardware. */
|
||||
p = &sc_redmap(sc)[start];
|
||||
for (i = start; i < ecount; i++)
|
||||
*p++ = red[i];
|
||||
p = &sc_greenmap(sc)[start];
|
||||
for (i = start; i < ecount; i++)
|
||||
*p++ = green[i];
|
||||
p = &sc_bluemap(sc)[start];
|
||||
for (i = start; i < ecount; i++)
|
||||
*p++ = blue[i];
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the address that would map the given device at the given
|
||||
* offset, allowing for the given protection, or return -1 for error.
|
||||
*/
|
||||
paddr_t
|
||||
cgtwommap(dev, off, prot)
|
||||
dev_t dev;
|
||||
off_t off;
|
||||
int prot;
|
||||
{
|
||||
register struct cgtwo_softc *sc = cgtwo_cd.cd_devs[minor(dev)];
|
||||
|
||||
if (off & PGOFSET)
|
||||
panic("cgtwommap");
|
||||
|
||||
if (off >= sc->sc_fb.fb_type.fb_size)
|
||||
return (-1);
|
||||
|
||||
return (REG2PHYS(&sc->sc_phys, off) | PMAP_NC);
|
||||
}
|
Loading…
Reference in New Issue