/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Paul Kranenburg.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* color display (cgthree) driver.
*
* Does not handle interrupts, even though they can occur.
*
* XXX should defer colormap updates to vertical retrace interrupts
*/
/* Transfer video magic to board, if it's not running */
if ((fbc->fbc_ctrl & FBC_TIMING) == 0) {
int sense = (fbc->fbc_status & FBS_MSENSE);
/* Search table for video timings fitting this monitor */
for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]);
i++) {
int j;
if (sense != cg3_videoctrl[i].sense)
continue;
if(isconsole) {
/* we mess with cg3_console_screen only once */
vcons_init_screen(&sc->vd, &cg3_console_screen, 1,
&defattr);
memset(sc->sc_fb.fb_pixels, (defattr >> 16) & 0xff,
sc->sc_stride * sc->sc_height);
cg3_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
cgthree_defaultscreen.textops = &ri->ri_ops;
cgthree_defaultscreen.capabilities = ri->ri_caps;
cgthree_defaultscreen.nrows = ri->ri_rows;
cgthree_defaultscreen.ncols = ri->ri_cols;
sc->vd.active = &cg3_console_screen;
wsdisplay_cnattach(&cgthree_defaultscreen, ri, 0, 0, defattr);
vcons_replay_msgbuf(&cg3_console_screen);
} else {
/*
* we're not the console so we just clear the screen and don't
* set up any sort of text display
*/
}
/* Initialize the default color map. */
cg3_setup_palette(sc);
case FBIOGETCMAP:
#define p ((struct fbcmap *)data)
return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
case FBIOPUTCMAP:
/* copy to software map */
error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
if (error)
return (error);
/* now blast them into the chip */
/* XXX should use retrace interrupt */
cgthreeloadcmap(sc, p->index, p->count);
#undef p
break;
case FBIOGVIDEO:
*(int *)data = cgthree_get_video(sc);
break;
case FBIOSVIDEO:
cgthree_set_video(sc, *(int *)data);
break;
default:
return (ENOTTY);
}
return (0);
}
/*
* Undo the effect of an FBIOSVIDEO that turns the video off.
*/
static void
cgthreeunblank(device_t self)
{
struct cgthree_softc *sc = device_private(self);
cgthree_set_video(sc, 1);
}
static void
cgthree_set_video(struct cgthree_softc *sc, int enable)
{
if (enable)
sc->sc_fbc->fbc_ctrl |= FBC_VENAB;
else
sc->sc_fbc->fbc_ctrl &= ~FBC_VENAB;
}
static int
cgthree_get_video(struct cgthree_softc *sc)
{
/*
* Load a subset of the current (new) colormap into the Brooktree DAC.
*/
static void
cgthreeloadcmap(struct cgthree_softc *sc, int start, int ncolors)
{
volatile struct bt_regs *bt;
u_int *ip;
int count;
/*
* Return the address that would map the given device at the given
* offset, allowing for the given protection, or return -1 for error.
*
* The cg3 is mapped starting at 256KB, for pseudo-compatibility with
* the cg4 (which had an overlay plane in the first 128K and an enable
* plane in the next 128K). X11 uses only 256k+ region but tries to
* map the whole thing, so we repeatedly map the first 256K to the
* first page of the color screen. If someone tries to use the overlay
* and enable regions, they will get a surprise....
*
* As well, mapping at an offset of 0x04000000 causes the cg3 to be
* mapped in flat mode without the cg4 emulation.
*/
paddr_t
cgthreemmap(dev_t dev, off_t off, int prot)
{
struct cgthree_softc *sc = device_lookup_private(&cgthree_cd,
minor(dev));
if (off & PGOFSET)
panic("cgthreemmap");
if (off < 0)
return (-1);
if ((u_int)off >= NOOVERLAY)
off -= NOOVERLAY;
else if ((u_int)off >= START)
off -= START;
else
off = 0;
if (off >= sc->sc_fb.fb_type.fb_size)
return (-1);