/*
* Copyright (c) 2012, 2016 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Lukas F. Hartmann.
* This code is derived from software contributed to The NetBSD Foundation
* by Radoslaw Kujawa.
*
* 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 AUTHOR ``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 AUTHOR 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.
*/
static paddr_t mntva_mmap(void *v, void *vs, off_t offset, int prot);
static int mntva_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
struct lwp *l);
static void mntva_init_screen(void *cookie, struct vcons_screen *scr,
int existing, long *defattr);
static void mntva_init_palette(struct mntva_softc *sc);
/* blitter support */
static void mntva_rectfill(struct mntva_softc *sc, int x, int y, int wi,
int he, uint32_t color);
static void mntva_bitblt(struct mntva_softc *sc, int xs, int ys, int xd,
int yd, int wi, int he);
/* accelerated raster ops */
static void mntva_eraserows(void *cookie, int row, int nrows, long fillattr);
static void mntva_copyrows(void *cookie, int srcrow, int dstrow, int nrows);
static void mntva_copycols(void *cookie, int row, int srccol, int dstcol,
int ncols);
static void mntva_erasecols(void *cookie, int row, int startcol, int ncols,
long fillattr);
#if 0
static void mntva_cursor(void *cookie, int on, int row, int col);
#endif
/*
* XXX: these will be called by console handling code, shouldn't they be
* included from somewhere else?
*/
void mntvacninit(struct consdev *cd);
void mntvacnprobe(struct consdev *cd);
void mntvacnputc(dev_t cd, int ch);
int mntvacngetc(dev_t cd);
void mntvacnpollc(dev_t cd, int on);
sc->sc_isconsole = false;
/* this should come from "opt_mntva.h" auto generated by kernel conf system */
#ifdef MNTVA_CONSOLE
sc->sc_isconsole = true;
#endif /* MNTVA_CONSOLE */
static void
mntva_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
{
struct mntva_softc *sc;
struct rasops_info *ri;
struct vcons_screen *scr;
int x, ys, yd, wi, he;
ri = cookie;
scr = ri->ri_hw;
sc = scr->scr_cookie;
if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
x = ri->ri_xorigin;
ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow;
yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow;
wi = ri->ri_emuwidth;
he = ri->ri_font->fontheight * nrows;
mntva_bitblt(sc, x, ys, x, yd, wi, he);
}
}
static void
mntva_eraserows(void *cookie, int row, int nrows, long fillattr)
{
struct mntva_softc *sc;
struct rasops_info *ri;
struct vcons_screen *scr;
int x, y, wi, he, fg, bg, ul;
ri = cookie;
scr = ri->ri_hw;
sc = scr->scr_cookie;
if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
rasops_unpack_attr(fillattr, &fg, &bg, &ul);
if ((row == 0) && (nrows == ri->ri_rows))
mntva_rectfill(sc, 0, 0, ri->ri_width,
ri->ri_height, ri->ri_devcmap[bg]);
else {
x = ri->ri_xorigin;
y = ri->ri_yorigin + ri->ri_font->fontheight * row;
wi = ri->ri_emuwidth;
he = ri->ri_font->fontheight * nrows;
mntva_rectfill(sc, x, y, wi, he, ri->ri_devcmap[bg]);
}
}
}
static void
mntva_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
{
struct mntva_softc *sc;
struct rasops_info *ri;
struct vcons_screen *scr;
int xs, xd, y, w, h;
ri = cookie;
scr = ri->ri_hw;
sc = scr->scr_cookie;
if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol;
xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol;
y = ri->ri_yorigin + ri->ri_font->fontheight * row;
w = ri->ri_font->fontwidth * ncols;
h = ri->ri_font->fontheight;
mntva_bitblt(sc, xs, y, xd, y, w, h);
}
}
static void
mntva_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
{
struct mntva_softc *sc;
struct rasops_info *ri;
struct vcons_screen *scr;
int x, y, w, h, fg, bg, ul;
ri = cookie;
scr = ri->ri_hw;
sc = scr->scr_cookie;
if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol;
y = ri->ri_yorigin + ri->ri_font->fontheight * row;
w = ri->ri_font->fontwidth * ncols;
h = ri->ri_font->fontheight;
rasops_unpack_attr(fillattr, &fg, &bg, &ul);
mntva_rectfill(sc, x, y, w, h, ri->ri_devcmap[bg & 0xf]);
}
}
case WSDISPLAYIO_LINEBYTES:
*(u_int *) data = sc->sc_linebytes;
return 0;
case WSDISPLAYIO_SMODE:
{
int new_mode = *(int *) data;
if (new_mode != sc->sc_mode) {
sc->sc_mode = new_mode;
if (new_mode == WSDISPLAYIO_MODE_EMUL)
vcons_redraw_screen(ms);
}
return 0;
}
case WSDISPLAYIO_GET_FBINFO:
{
struct wsdisplayio_fbinfo *fbi = data;
struct rasops_info *ri;
int ret;
ri = &sc->vd.active->scr_ri;
ret = wsdisplayio_get_fbinfo(ri, fbi);
return ret;
}
}
return EPASSTHROUGH;
}
#if 0
static void
mntva_cursor(void *cookie, int on, int row, int col)
{
struct mntva_softc *sc;
struct rasops_info *ri;
struct vcons_screen *scr;
int x, y, wi, he;
ri = cookie;
scr = ri->ri_hw;
sc = scr->scr_cookie;
wi = ri->ri_font->fontwidth;
he = ri->ri_font->fontheight;
if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
x = ri->ri_ccol * wi + ri->ri_xorigin;
y = ri->ri_crow * he + ri->ri_yorigin;
if (ri->ri_flg & RI_CURSOR) {
mntva_bitblt(sc, x, y, x, y, wi, he);
ri->ri_flg &= ~RI_CURSOR;
}
ri->ri_crow = row;
ri->ri_ccol = col;
if (on) {
x = ri->ri_ccol * wi + ri->ri_xorigin;
y = ri->ri_crow * he + ri->ri_yorigin;
mntva_bitblt(sc, x, y, x, y, wi, he);
ri->ri_flg |= RI_CURSOR;
}
} else {
scr->scr_ri.ri_crow = row;
scr->scr_ri.ri_ccol = col;
scr->scr_ri.ri_flg &= ~RI_CURSOR;
}
}
#endif
void
mntvacnprobe(struct consdev *cd)
{
#ifdef MNTVA_CONSOLE
/*
* This isn't exactly true, but cons.h does not define anything
* that would fit our case exactly.
*/
cd->cn_pri = CN_INTERNAL;
cd->cn_dev = NODEV; /* Filled later by wscons. */
#endif /* MNTVA_CONSOLE */
}
/* ARGSUSED */
void
mntvacnputc(dev_t cd, int ch)
{
}
/* ARGSUSED */
int
mntvacngetc(dev_t cd)
{
return(0);
}
/* ARGSUSED */
void
mntvacnpollc(dev_t cd, int on)
{
}