Pull up following revision(s) (requested by tsutsui in ticket #1162):

sys/dev/ic/stivar.h: revision 1.11
	sys/dev/ic/sti.c: revision 1.23
	sys/dev/ic/sti.c: revision 1.24
	sys/dev/ic/sti.c: revision 1.25
	sys/arch/hp300/dev/sti_sgc.c: revision 1.4

Pull the latest OpenBSD sti(4) changes for bitmap framebuffer support.
- bitmap and colormap ops based on old HP ngle X11 driver:
  http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/dev/ic/sti.c#rev1.76
  > Work-in-progress support for non-accelerated X11 on *some* sti(4)
  > frame buffers; based upon the old HP ngle X11 driver.
  > Currently limited to CRX (720/735/750), Timber (710, old 715),
  > Artist (712, 715) and EG (B-series), however the
  > colormap isn't set up correctly on Timber and EG yet.
  >
  > Joint work with Artem Falcon, now in good enough shape to be worked further
  > in the tree.
- misc other cosmetic changes to reduce diffs
No particular comments on port-hp300@ and port-hppa@:
 https://mail-index.netbsd.org/port-hp300/2020/12/19/msg000184.html
 https://mail-index.netbsd.org/port-hp300/2020/12/20/msg000185.html

The MD hp300 attachment for SGC CRX (A1659-66001) will be committed
separately.

Add bitmap access ops support for SGC CRX (A1659-66001) framebuffer.
Also modify existing 425e EVRX attachment to use updated MI sti(4) ops
more efficiently.

The Xorg server and mlterm-wscons (that support wsdisplay bitmap) work
fine on SGC hp425t.

No particular comments on port-hp300@ and port-hppa@:
 https://mail-index.netbsd.org/port-hp300/2020/12/19/msg000184.html
 https://mail-index.netbsd.org/port-hp300/2020/12/20/msg000185.html

Special thanks to Miod Vallat again, for contributing the SGC CRX
framebuffer with the SGC connector and flexible cable for HP9000/425t.

He also contributed DIO-II "Hyperion" monochrome framebuffer and
1 plane grayscale SGC GRX (A1924-66001), and I've confirmed hyper(4)
just works even with Xorg server.  I will try GRX as the next project.

Handle WSSCREEN_REVERSE properly.  Based on OpenBSD's sti(4).

Also remove WSSCREEN_UNDERLINE from capabilities that is not handled
by sti(4) ROM routines.

Tested on HP9000/425t with CRX.

Ignore WSDISPLAYIO_PUTCMAP in WSDISPLAYIO_MODE_EMUL, i.e. text mode.

The hardware palette settings are handled by the STI ROM in STI_TEXTMODE
and changing cmap could cause mangled text colors at least on CRX on 425t.

Updating CMAP in EMUL mode isn't expected anyway.

Fixes "red or invisible text" after exiting mlterm-wscons on A1659 CRX.
This commit is contained in:
martin 2020-12-28 20:10:04 +00:00
parent 43d32978d1
commit cbcf134c84
3 changed files with 549 additions and 270 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: sti_sgc.c,v 1.2.34.1 2020/05/18 17:52:22 martin Exp $ */
/* $NetBSD: sti_sgc.c,v 1.2.34.2 2020/12/28 20:10:04 martin Exp $ */
/* $OpenBSD: sti_sgc.c,v 1.14 2007/05/26 00:36:03 krw Exp $ */
/*
@ -27,7 +27,7 @@
*
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v 1.2.34.1 2020/05/18 17:52:22 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v 1.2.34.2 2020/12/28 20:10:04 martin Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -49,33 +49,40 @@ struct sti_sgc_softc {
struct sti_softc sc_sti;
paddr_t sc_bitmap;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_ramdach;
};
/*
* 425e EVRX specific hardware
*/
#define STI_EVRX_RAMDACOFFSET 0x060000
#define STI_EVRX_RAMDACSIZE 0x000800
/*
* EVRX RAMDAC (Bt458) is found at offset 0x060000 from SGC bus PA and
* offset 0x040000 length 0x1c0000 is mapped in MI sti via ROM region 2
*/
#define STI_EVRX_REGNO2OFFSET 0x020000
#define STI_EVRX_FBOFFSET 0x200000
#define EVRX_BT458_ADDR (0x200 + 2)
#define EVRX_BT458_CMAP (0x204 + 2)
#define EVRX_BT458_CTRL (0x208 + 2)
#define EVRX_BT458_OMAP (0x20C + 2)
#define EVRX_BT458_ADDR (STI_EVRX_REGNO2OFFSET + 0x200 + 2)
#define EVRX_BT458_CMAP (STI_EVRX_REGNO2OFFSET + 0x204 + 2)
#define EVRX_BT458_CTRL (STI_EVRX_REGNO2OFFSET + 0x208 + 2)
#define EVRX_BT458_OMAP (STI_EVRX_REGNO2OFFSET + 0x20C + 2)
/* from HP-UX /usr/lib/libddevrx.a */
#define EVRX_MAGIC00 0x600
#define EVRX_MAGIC04 0x604
#define EVRX_MAGIC08 0x608
#define EVRX_MAGIC0C 0x60c
#define EVRX_MAGIC10 0x610
#define EVRX_MAGIC00 (STI_EVRX_REGNO2OFFSET + 0x600)
#define EVRX_MAGIC04 (STI_EVRX_REGNO2OFFSET + 0x604)
#define EVRX_MAGIC08 (STI_EVRX_REGNO2OFFSET + 0x608)
#define EVRX_MAGIC0C (STI_EVRX_REGNO2OFFSET + 0x60c)
#define EVRX_MAGIC10 (STI_EVRX_REGNO2OFFSET + 0x610)
#define EVRX_MAGIC10_BSY 0x00010000
#define EVRX_MAGIC18 0x618
#define EVRX_MAGIC1C 0x61c
#define EVRX_MAGIC18 (STI_EVRX_REGNO2OFFSET + 0x618)
#define EVRX_MAGIC1C (STI_EVRX_REGNO2OFFSET + 0x61c)
/*
* HP A1659A CRX specific hardware
*/
#define STI_CRX_FBOFFSET 0x01000000
static int sticonslot = -1;
static struct bus_space_tag sticn_tag;
static struct sti_rom sticn_rom;
static struct sti_screen sticn_scr;
static bus_addr_t sticn_bases[STI_REGION_MAX];
@ -88,16 +95,16 @@ static int sti_sgc_probe(bus_space_tag_t, int);
CFATTACH_DECL_NEW(sti_sgc, sizeof(struct sti_sgc_softc),
sti_sgc_match, sti_sgc_attach, NULL, NULL);
/* 425e EVRX specific access functions */
static int sti_evrx_setcmap(struct sti_sgc_softc *, struct wsdisplay_cmap *);
static void sti_evrx_resetramdac(struct sti_sgc_softc *);
static void sti_evrx_resetcmap(struct sti_sgc_softc *);
static int sti_evrx_ioctl(void *, void *, u_long, void *, int, struct lwp *);
static paddr_t sti_evrx_mmap(void *, void *, off_t, int);
/* 425e EVRX/CRX specific access functions */
static int sti_evrx_putcmap(struct sti_screen *, u_int, u_int);
static void sti_evrx_resetramdac(struct sti_screen *);
static void sti_evrx_resetcmap(struct sti_screen *);
static void sti_evrx_setupfb(struct sti_screen *);
static paddr_t sti_m68k_mmap(void *, void *, off_t, int);
static const struct wsdisplay_accessops sti_evrx_accessops = {
sti_evrx_ioctl,
sti_evrx_mmap,
static const struct wsdisplay_accessops sti_m68k_accessops = {
sti_ioctl,
sti_m68k_mmap,
sti_alloc_screen,
sti_free_screen,
sti_show_screen,
@ -126,6 +133,7 @@ sti_sgc_attach(device_t parent, device_t self, void *aux)
struct sti_softc *ssc = &sc->sc_sti;
struct sgc_attach_args *saa = aux;
struct sti_screen *scr;
bus_space_tag_t bst;
bus_space_handle_t romh;
bus_addr_t base;
struct wsemuldisplaydev_attach_args waa;
@ -135,6 +143,7 @@ sti_sgc_attach(device_t parent, device_t self, void *aux)
int i;
ssc->sc_dev = self;
bst = saa->saa_iot;
base = (bus_addr_t)sgc_slottopa(saa->saa_slot);
if (saa->saa_slot == sticonslot) {
@ -147,18 +156,18 @@ sti_sgc_attach(device_t parent, device_t self, void *aux)
sti_describe(ssc);
} else {
if (bus_space_map(saa->saa_iot, base, PAGE_SIZE, 0, &romh)) {
if (bus_space_map(bst, base, PAGE_SIZE, 0, &romh)) {
aprint_error(": can't map ROM");
return;
}
/*
* Compute real PROM size
*/
romend = sti_rom_size(saa->saa_iot, romh);
romend = sti_rom_size(bst, romh);
bus_space_unmap(saa->saa_iot, romh, PAGE_SIZE);
bus_space_unmap(bst, romh, PAGE_SIZE);
if (bus_space_map(saa->saa_iot, base, romend, 0, &romh)) {
if (bus_space_map(bst, base, romend, 0, &romh)) {
aprint_error(": can't map frame buffer");
return;
}
@ -167,7 +176,7 @@ sti_sgc_attach(device_t parent, device_t self, void *aux)
for (i = 0; i < STI_REGION_MAX; i++)
ssc->bases[i] = base;
if (sti_attach_common(ssc, saa->saa_iot, saa->saa_iot, romh,
if (sti_attach_common(ssc, bst, bst, romh,
STI_CODEBASE_ALT) != 0)
return;
}
@ -185,29 +194,21 @@ sti_sgc_attach(device_t parent, device_t self, void *aux)
*/
sc->sc_bitmap = base + STI_EVRX_FBOFFSET;
/*
* Bt458 RAMDAC can be accessed at offset +0x60200 and
* unknown control registers are around +0x60600.
*/
sc->sc_bst = saa->saa_iot;
if (bus_space_map(sc->sc_bst, base + STI_EVRX_RAMDACOFFSET,
STI_EVRX_RAMDACSIZE, 0, &sc->sc_ramdach)) {
aprint_error_dev(self, "can't map RAMDAC\n");
return;
}
aprint_normal_dev(self, "Enable mmap support\n");
/*
* initialize Bt458 RAMDAC and preserve initial color map
*/
sti_evrx_resetramdac(sc);
sti_evrx_resetcmap(sc);
sti_evrx_resetramdac(scr);
sti_evrx_resetcmap(scr);
scr->setupfb = sti_evrx_setupfb;
scr->putcmap = sti_evrx_putcmap;
scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL;
waa.console = ssc->sc_flags & STI_CONSOLE ? 1 : 0;
waa.scrdata = &scr->scr_screenlist;
waa.accessops = &sti_evrx_accessops;
waa.accessops = &sti_m68k_accessops;
waa.accesscookie = scr;
config_found(ssc->sc_dev, &waa, wsemuldisplaydevprint);
@ -216,9 +217,20 @@ sti_sgc_attach(device_t parent, device_t self, void *aux)
case STI_DD_CRX:
/*
* HP A1659A CRX on some 425t variants.
* Not investigated yet; needs to check HP-UX libddgcrx.a etc.
* bitmap memory can be accessed at offset +0x1000000.
*/
/* FALLTHROUGH */
sc->sc_bitmap = base + STI_CRX_FBOFFSET;
aprint_normal_dev(self, "Enable mmap support\n");
scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL;
waa.console = ssc->sc_flags & STI_CONSOLE ? 1 : 0;
waa.scrdata = &scr->scr_screenlist;
waa.accessops = &sti_m68k_accessops;
waa.accesscookie = scr;
config_found(ssc->sc_dev, &waa, wsemuldisplaydevprint);
break;
default:
/*
* Unsupported variants.
@ -256,34 +268,12 @@ sti_sgc_probe(bus_space_tag_t iot, int slot)
}
static int
sti_evrx_setcmap(struct sti_sgc_softc *sc, struct wsdisplay_cmap *p)
sti_evrx_putcmap(struct sti_screen *scr, u_int index, u_int count)
{
struct sti_softc *ssc = &sc->sc_sti;
struct sti_screen *scr = ssc->sc_scr;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_ramdach;
uint8_t r[STI_NCMAP], g[STI_NCMAP], b[STI_NCMAP];
u_int index, count;
int i, error;
index = p->index;
count = p->count;
if (index >= STI_NCMAP || count > STI_NCMAP - index)
return EINVAL;
error = copyin(p->red, &r[index], count);
if (error)
return error;
error = copyin(p->green, &g[index], count);
if (error)
return error;
error = copyin(p->blue, &b[index], count);
if (error)
return error;
memcpy(&scr->scr_rcmap[index], &r[index], count);
memcpy(&scr->scr_gcmap[index], &g[index], count);
memcpy(&scr->scr_bcmap[index], &b[index], count);
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t bst = rom->memt;
bus_space_handle_t bsh = rom->regh[2];
int i;
/* magic setup from HP-UX */
bus_space_write_4(bst, bsh, EVRX_MAGIC08, 0x00000001);
@ -302,10 +292,11 @@ sti_evrx_setcmap(struct sti_sgc_softc *sc, struct wsdisplay_cmap *p)
}
static void
sti_evrx_resetramdac(struct sti_sgc_softc *sc)
sti_evrx_resetramdac(struct sti_screen *scr)
{
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_ramdach;
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t bst = rom->memt;
bus_space_handle_t bsh = rom->regh[2];
#if 0
int i;
#endif
@ -351,12 +342,11 @@ sti_evrx_resetramdac(struct sti_sgc_softc *sc)
}
static void
sti_evrx_resetcmap(struct sti_sgc_softc *sc)
sti_evrx_resetcmap(struct sti_screen *scr)
{
struct sti_softc *ssc = &sc->sc_sti;
struct sti_screen *scr = ssc->sc_scr;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_ramdach;
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t bst = rom->memt;
bus_space_handle_t bsh = rom->regh[2];
int i;
/* magic setup from HP-UX */
@ -376,68 +366,16 @@ sti_evrx_resetcmap(struct sti_sgc_softc *sc)
}
}
static int
sti_evrx_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
struct lwp *l)
static void
sti_evrx_setupfb(struct sti_screen *scr)
{
struct sti_screen *scr = (struct sti_screen *)v;
struct sti_rom *rom = scr->scr_rom;
struct sti_softc *ssc = rom->rom_softc;
struct sti_sgc_softc *sc = device_private(ssc->sc_dev);
struct wsdisplay_fbinfo *wdf;
struct wsdisplay_cmap *cmapp;
u_int idx, count;
int error, new_mode;
switch (cmd) {
case WSDISPLAYIO_GINFO:
wdf = (struct wsdisplay_fbinfo *)data;
wdf->height = scr->scr_cfg.scr_height;
wdf->width = scr->scr_cfg.scr_width;
wdf->depth = scr->scr_bpp;
wdf->cmsize = STI_NCMAP;
return 0;
case WSDISPLAYIO_GETCMAP:
cmapp = (struct wsdisplay_cmap *)data;
idx = cmapp->index;
count = cmapp->count;
if (idx >= STI_NCMAP || count > STI_NCMAP - idx)
return EINVAL;
error = copyout(&scr->scr_rcmap[idx], cmapp->red, count);
if (error != 0)
return error;
error = copyout(&scr->scr_gcmap[idx], cmapp->green, count);
if (error != 0)
return error;
error = copyout(&scr->scr_bcmap[idx], cmapp->blue, count);
if (error != 0)
return error;
return 0;
case WSDISPLAYIO_PUTCMAP:
cmapp = (struct wsdisplay_cmap *)data;
return sti_evrx_setcmap(sc, cmapp);
case WSDISPLAYIO_SMODE:
new_mode = *(int *)data;
if (new_mode != scr->scr_wsmode) {
scr->scr_wsmode = new_mode;
if (new_mode == WSDISPLAYIO_MODE_EMUL) {
sti_init(scr, STI_TEXTMODE);
} else if (new_mode == WSDISPLAYIO_MODE_DUMBFB) {
sti_init(scr, 0);
sti_evrx_resetramdac(sc);
}
}
return 0;
}
return sti_ioctl(v, vs, cmd, data, flag, l);
sti_init(scr, 0);
sti_evrx_resetramdac(scr);
}
static paddr_t
sti_evrx_mmap(void *v, void *vs, off_t offset, int prot)
sti_m68k_mmap(void *v, void *vs, off_t offset, int prot)
{
struct sti_screen *scr = (struct sti_screen *)v;
struct sti_rom *rom = scr->scr_rom;
@ -491,11 +429,13 @@ sti_sgc_cnattach(bus_space_tag_t bst, bus_addr_t addr, int slot)
{
int i;
sticn_tag = *bst;
/* sticn_bases[0] will be fixed in sti_cnattach() */
for (i = 0; i < STI_REGION_MAX; i++)
sticn_bases[i] = addr;
sti_cnattach(&sticn_rom, &sticn_scr, bst, sticn_bases,
sti_cnattach(&sticn_rom, &sticn_scr, &sticn_tag, sticn_bases,
STI_CODEBASE_ALT);
sticonslot = slot;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sti.c,v 1.19.12.1 2020/05/18 17:52:22 martin Exp $ */
/* $NetBSD: sti.c,v 1.19.12.2 2020/12/28 20:10:04 martin Exp $ */
/* $OpenBSD: sti.c,v 1.61 2009/09/05 14:09:35 miod Exp $ */
@ -31,11 +31,11 @@
* TODO:
* call sti procs asynchronously;
* implement console scroll-back;
* X11 support.
* X11 support on more models.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.19.12.1 2020/05/18 17:52:22 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.19.12.2 2020/12/28 20:10:04 martin Exp $");
#include "wsdisplay.h"
@ -79,33 +79,45 @@ void sti_copyrows(void *, int, int, int);
void sti_eraserows(void *, int, int, long);
int sti_alloc_attr(void *, int, int, int, long *);
/* pseudo attribute ops for sti ROM putchar function */
#define WSATTR_FG_SHIFT 24
#define WSATTR_BG_SHIFT 16
#define WSATTR_UNPACK_FG(attr) (((attr) >> WSATTR_FG_SHIFT) & 0xff)
#define WSATTR_UNPACK_BG(attr) (((attr) >> WSATTR_BG_SHIFT) & 0xff)
#define WSATTR_UNPACK_FLAG(attr) ((attr) & WSATTR_USERMASK)
#define WSATTR_PACK_FG(fg) ((fg) << WSATTR_FG_SHIFT)
#define WSATTR_PACK_BG(bg) ((bg) << WSATTR_BG_SHIFT)
#define WSATTR_PACK_FLAG(flag) ((flag))
#define WSATTR_PACK(fg, bg, flag) \
(WSATTR_PACK_FG(fg) | WSATTR_PACK_BG(bg) | WSATTR_PACK_FLAG(flag))
struct wsdisplay_emulops sti_emulops = {
sti_cursor,
sti_mapchar,
sti_putchar,
sti_copycols,
sti_erasecols,
sti_copyrows,
sti_eraserows,
sti_alloc_attr
.cursor = sti_cursor,
.mapchar = sti_mapchar,
.putchar = sti_putchar,
.copycols = sti_copycols,
.erasecols = sti_erasecols,
.copyrows = sti_copyrows,
.eraserows = sti_eraserows,
.allocattr = sti_alloc_attr
};
const struct wsdisplay_accessops sti_accessops = {
sti_ioctl,
sti_mmap,
sti_alloc_screen,
sti_free_screen,
sti_show_screen,
sti_load_font
.ioctl = sti_ioctl,
.mmap = sti_mmap,
.alloc_screen = sti_alloc_screen,
.free_screen = sti_free_screen,
.show_screen = sti_show_screen,
.load_font = sti_load_font
};
enum sti_bmove_funcs {
bmf_clear, bmf_copy, bmf_invert, bmf_underline
};
int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *);
void sti_bmove(struct sti_screen *, int, int, int, int, int, int,
enum sti_bmove_funcs);
int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *);
int sti_setcment(struct sti_screen *, u_int, u_char, u_char, u_char);
struct sti_screen *sti_attach_screen(struct sti_softc *, int);
@ -118,6 +130,15 @@ int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t,
bus_space_handle_t, bus_addr_t *, u_int);
int sti_screen_setup(struct sti_screen *, int);
int ngle_default_putcmap(struct sti_screen *, u_int, u_int);
#ifndef SMALL_KERNEL
void ngle_artist_setupfb(struct sti_screen *);
void ngle_elk_setupfb(struct sti_screen *);
void ngle_timber_setupfb(struct sti_screen *);
int ngle_putcmap(struct sti_screen *, u_int, u_int);
#endif
#if NSTI_PCI > 0
#define STI_ENABLE_ROM(sc) \
do { \
@ -220,51 +241,52 @@ sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt,
/*
* Get ROM header and code function pointers.
*/
dd = &rom->rom_dd;
rom->rom_devtype = bus_space_read_1(memt, romh, 3);
if (rom->rom_devtype == STI_DEVTYPE1) {
dd->dd_type = bus_space_read_1(memt, romh, 0x03);
dd->dd_nmon = bus_space_read_1(memt, romh, 0x07);
dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b);
dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f);
dd->dd_grid[0] = parseword(0x10);
dd->dd_grid[1] = parseword(0x20);
dd->dd_fntaddr = parseword(0x30) & ~3;
dd->dd_maxst = parseword(0x40);
dd->dd_romend = parseword(0x50) & ~3;
dd->dd_reglst = parseword(0x60) & ~3;
dd->dd_maxreent= parseshort(0x70);
dd->dd_maxtimo = parseshort(0x78);
dd->dd_montbl = parseword(0x80) & ~3;
dd->dd_udaddr = parseword(0x90) & ~3;
dd->dd_stimemreq=parseword(0xa0);
dd->dd_udsize = parseword(0xb0);
dd->dd_pwruse = parseshort(0xc0);
dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb);
dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf);
dd->dd_altcodet= bus_space_read_1(memt, romh, 0xd3);
dd->dd_eddst[0]= bus_space_read_1(memt, romh, 0xd7);
dd->dd_eddst[1]= bus_space_read_1(memt, romh, 0xdb);
dd->dd_eddst[2]= bus_space_read_1(memt, romh, 0xdf);
dd->dd_cfbaddr = parseword(0xe0) & ~3;
dd->dd_type = bus_space_read_1(memt, romh, 0x03);
dd->dd_nmon = bus_space_read_1(memt, romh, 0x07);
dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b);
dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f);
dd->dd_grid[0] = parseword(0x10);
dd->dd_grid[1] = parseword(0x20);
dd->dd_fntaddr = parseword(0x30) & ~3;
dd->dd_maxst = parseword(0x40);
dd->dd_romend = parseword(0x50) & ~3;
dd->dd_reglst = parseword(0x60) & ~3;
dd->dd_maxreent = parseshort(0x70);
dd->dd_maxtimo = parseshort(0x78);
dd->dd_montbl = parseword(0x80) & ~3;
dd->dd_udaddr = parseword(0x90) & ~3;
dd->dd_stimemreq = parseword(0xa0);
dd->dd_udsize = parseword(0xb0);
dd->dd_pwruse = parseshort(0xc0);
dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb);
dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf);
dd->dd_altcodet = bus_space_read_1(memt, romh, 0xd3);
dd->dd_eddst[0] = bus_space_read_1(memt, romh, 0xd7);
dd->dd_eddst[1] = bus_space_read_1(memt, romh, 0xdb);
dd->dd_eddst[2] = bus_space_read_1(memt, romh, 0xdf);
dd->dd_cfbaddr = parseword(0xe0) & ~3;
codebase <<= 2;
dd->dd_pacode[0x0] = parseword(codebase + 0x00) & ~3;
dd->dd_pacode[0x1] = parseword(codebase + 0x10) & ~3;
dd->dd_pacode[0x2] = parseword(codebase + 0x20) & ~3;
dd->dd_pacode[0x3] = parseword(codebase + 0x30) & ~3;
dd->dd_pacode[0x4] = parseword(codebase + 0x40) & ~3;
dd->dd_pacode[0x5] = parseword(codebase + 0x50) & ~3;
dd->dd_pacode[0x6] = parseword(codebase + 0x60) & ~3;
dd->dd_pacode[0x7] = parseword(codebase + 0x70) & ~3;
dd->dd_pacode[0x8] = parseword(codebase + 0x80) & ~3;
dd->dd_pacode[0x9] = parseword(codebase + 0x90) & ~3;
dd->dd_pacode[0xa] = parseword(codebase + 0xa0) & ~3;
dd->dd_pacode[0xb] = parseword(codebase + 0xb0) & ~3;
dd->dd_pacode[0xc] = parseword(codebase + 0xc0) & ~3;
dd->dd_pacode[0xd] = parseword(codebase + 0xd0) & ~3;
dd->dd_pacode[0xe] = parseword(codebase + 0xe0) & ~3;
dd->dd_pacode[0xf] = parseword(codebase + 0xf0) & ~3;
dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3;
dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3;
dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3;
dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3;
dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3;
dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3;
dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3;
dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3;
dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3;
dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3;
dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3;
dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3;
dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3;
dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3;
dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3;
dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3;
} else { /* STI_DEVTYPE4 */
bus_space_read_region_stream_4(memt, romh, 0, (uint32_t *)dd,
sizeof(*dd) / 4);
@ -298,7 +320,7 @@ sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt,
* Note there could be fewer than STI_END pointer entries
* populated, especially on older devices.
*/
for (i = STI_END; !dd->dd_pacode[i]; i--)
for (i = STI_END; dd->dd_pacode[i] == 0; i--)
;
size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN];
@ -310,13 +332,12 @@ sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt,
return EINVAL;
}
DPRINTF(("code size %x/%x\n", size, round_page(size)));
if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size), 0,
UVM_KMF_WIRED))) {
aprint_error(": cannot allocate %u bytes for code\n", size);
return ENOMEM;
}
DPRINTF(("code=0x%lx[%x]\n", rom->rom_code, size));
/*
* Copy code into memory and make it executable.
@ -332,8 +353,7 @@ sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt,
for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4;
addr < eaddr; addr += 4 ) {
*p++ = bus_space_read_4(memt, romh, addr)
& 0xff;
*p++ = bus_space_read_4(memt, romh, addr) & 0xff;
}
} else { /* STI_DEVTYPE4 */
bus_space_read_region_stream_4(memt, romh,
@ -359,26 +379,27 @@ sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt,
(dd->dd_pacode[(i)] == 0 ? 0 : \
(rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \
(rom->rom_devtype == STI_DEVTYPE1 ? 4 : 1)))
rom->init = (sti_init_t) O(STI_INIT_GRAPH);
rom->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT);
rom->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV);
rom->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE);
rom->test = (sti_test_t) O(STI_SELF_TEST);
rom->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR);
rom->init = (sti_init_t)O(STI_INIT_GRAPH);
rom->mgmt = (sti_mgmt_t)O(STI_STATE_MGMT);
rom->unpmv = (sti_unpmv_t)O(STI_FONT_UNPMV);
rom->blkmv = (sti_blkmv_t)O(STI_BLOCK_MOVE);
rom->test = (sti_test_t)O(STI_SELF_TEST);
rom->exhdl = (sti_exhdl_t)O(STI_EXCEP_HDLR);
rom->inqconf = (sti_inqconf_t)O(STI_INQ_CONF);
rom->scment = (sti_scment_t)O(STI_SCM_ENT);
rom->dmac = (sti_dmac_t) O(STI_DMA_CTRL);
rom->flowc = (sti_flowc_t) O(STI_FLOW_CTRL);
rom->dmac = (sti_dmac_t)O(STI_DMA_CTRL);
rom->flowc = (sti_flowc_t)O(STI_FLOW_CTRL);
rom->utiming = (sti_utiming_t)O(STI_UTIMING);
rom->pmgr = (sti_pmgr_t) O(STI_PROC_MGR);
rom->util = (sti_util_t) O(STI_UTIL);
rom->pmgr = (sti_pmgr_t)O(STI_PROC_MGR);
rom->util = (sti_util_t)O(STI_UTIL);
#undef O
/*
* Set colormap entry is not implemented until 8.04, so force
* a NULL pointer here.
*/
if (dd->dd_grrev < STI_REVISION(8, 4)) {
rom->scment = NULL;
}
@ -398,7 +419,6 @@ sti_region_setup(struct sti_screen *scr)
bus_addr_t *bases = rom->bases;
struct sti_dd *dd = &rom->rom_dd;
struct sti_cfg *cc = &scr->scr_cfg;
bus_space_handle_t bh;
struct sti_region regions[STI_REGION_MAX], *r;
u_int regno, regcnt;
bus_addr_t addr;
@ -459,14 +479,14 @@ sti_region_setup(struct sti_screen *scr)
continue;
}
/* XXXNH BUS_SPACE_MAP_CACHEABLE */
if (bus_space_map(memt, addr, r->length << PGSHIFT,
r->cache ? BUS_SPACE_MAP_CACHEABLE : 0, &bh)) {
BUS_SPACE_MAP_LINEAR | (r->cache ?
BUS_SPACE_MAP_CACHEABLE : 0), &rom->regh[regno]) != 0) {
rom->regh[regno] = romh; /* XXX */
DPRINTF((" - already mapped region\n"));
} else {
/* XXX should use bus_space_vaddr */
addr = (bus_addr_t)bh;
addr = (bus_addr_t)
bus_space_vaddr(memt, rom->regh[regno]);
if (regno == 1) {
DPRINTF((" - fb"));
scr->fbaddr = addr;
@ -625,12 +645,79 @@ sti_screen_setup(struct sti_screen *scr, int flags)
scr->scr_wsd.textops = &sti_emulops;
scr->scr_wsd.fontwidth = scr->scr_curfont.width;
scr->scr_wsd.fontheight = scr->scr_curfont.height;
scr->scr_wsd.capabilities = WSSCREEN_REVERSE | WSSCREEN_UNDERLINE;
scr->scr_wsd.capabilities = WSSCREEN_REVERSE;
scr->scr_scrlist[0] = &scr->scr_wsd;
scr->scr_screenlist.nscreens = 1;
scr->scr_screenlist.screens = scr->scr_scrlist;
#ifndef SMALL_KERNEL
/*
* Decide which board-specific routines to use.
*/
switch (dd->dd_grid[0]) {
case STI_DD_CRX:
scr->setupfb = ngle_elk_setupfb;
scr->putcmap = ngle_putcmap;
scr->reg10_value = 0x13601000;
if (scr->scr_bpp > 8)
scr->reg12_value = NGLE_BUFF1_CMAP3;
else
scr->reg12_value = NGLE_BUFF1_CMAP0;
scr->cmap_finish_register = NGLE_REG_1;
break;
case STI_DD_TIMBER:
scr->setupfb = ngle_timber_setupfb;
scr->putcmap = ngle_putcmap;
scr->reg10_value = 0x13602000;
scr->reg12_value = NGLE_BUFF1_CMAP0;
scr->cmap_finish_register = NGLE_REG_1;
break;
case STI_DD_ARTIST:
scr->setupfb = ngle_artist_setupfb;
scr->putcmap = ngle_putcmap;
scr->reg10_value = 0x13601000;
scr->reg12_value = NGLE_ARTIST_CMAP0;
scr->cmap_finish_register = NGLE_REG_26;
break;
case STI_DD_EG:
scr->setupfb = ngle_artist_setupfb;
scr->putcmap = ngle_putcmap;
scr->reg10_value = 0x13601000;
if (scr->scr_bpp > 8) {
scr->reg12_value = NGLE_BUFF1_CMAP3;
scr->cmap_finish_register = NGLE_REG_1;
} else {
scr->reg12_value = NGLE_ARTIST_CMAP0;
scr->cmap_finish_register = NGLE_REG_26;
}
break;
case STI_DD_GRX:
case STI_DD_CRX24:
case STI_DD_EVRX:
case STI_DD_3X2V:
case STI_DD_DUAL_CRX:
case STI_DD_HCRX:
case STI_DD_LEGO:
case STI_DD_SUMMIT:
case STI_DD_PINNACLE:
default:
scr->setupfb = NULL;
scr->putcmap =
rom->scment == NULL ? NULL : ngle_default_putcmap;
break;
}
#endif
return 0;
fail:
@ -671,6 +758,11 @@ sti_describe(struct sti_softc *sc)
sti_describe_screen(sc, sc->sc_scr);
}
/*
* Final part of attachment. On hppa where we use the PDC console
* during autoconf, this has to be postponed until autoconf has
* completed.
*/
void
sti_end_attach(struct sti_softc *sc)
{
@ -844,6 +936,7 @@ rescan:
/*
* Wrappers around STI code pointers
*/
int
sti_init(struct sti_screen *scr, int mode)
{
@ -972,11 +1065,10 @@ int
sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
{
struct sti_screen *scr = (struct sti_screen *)v;
struct sti_rom *rom = scr->scr_rom;
struct wsdisplay_fbinfo *wdf;
struct wsdisplay_cmap *cmapp;
u_int mode, idx, count;
int i, ret;
int ret;
ret = 0;
switch (cmd) {
@ -986,13 +1078,31 @@ sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
case WSDISPLAYIO_SMODE:
mode = *(u_int *)data;
if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL &&
mode == WSDISPLAYIO_MODE_DUMBFB)
ret = sti_init(scr, 0);
else if (scr->scr_wsmode == WSDISPLAYIO_MODE_DUMBFB &&
mode == WSDISPLAYIO_MODE_EMUL)
ret = sti_init(scr, STI_TEXTMODE);
scr->scr_wsmode = mode;
switch (mode) {
case WSDISPLAYIO_MODE_EMUL:
if (scr->scr_wsmode != WSDISPLAYIO_MODE_EMUL)
ret = sti_init(scr, STI_TEXTMODE);
break;
case WSDISPLAYIO_MODE_DUMBFB:
if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) {
sti_init(scr, 0);
if (scr->setupfb != NULL)
scr->setupfb(scr);
else
#if 0
ret = sti_init(scr, STI_FBMODE);
#else
ret = EINVAL;
#endif
}
break;
case WSDISPLAYIO_MODE_MAPPED:
default:
ret = EINVAL;
break;
}
if (ret == 0)
scr->scr_wsmode = mode;
break;
case WSDISPLAYIO_GTYPE:
@ -1004,19 +1114,22 @@ sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
wdf->height = scr->scr_cfg.scr_height;
wdf->width = scr->scr_cfg.scr_width;
wdf->depth = scr->scr_bpp;
if (rom->scment == NULL)
if (scr->putcmap == NULL || scr->scr_bpp > 8)
wdf->cmsize = 0;
else
wdf->cmsize = STI_NCMAP;
break;
case WSDISPLAYIO_LINEBYTES:
*(u_int *)data = scr->scr_cfg.fb_width;
if (scr->scr_bpp > 8)
*(u_int *)data = scr->scr_cfg.fb_width * 4;
else
*(u_int *)data = scr->scr_cfg.fb_width;
break;
case WSDISPLAYIO_GETCMAP:
if (rom->scment == NULL)
return ENOTTY;
if (scr->putcmap == NULL || scr->scr_bpp > 8)
return ENODEV;
cmapp = (struct wsdisplay_cmap *)data;
idx = cmapp->index;
count = cmapp->count;
@ -1031,8 +1144,18 @@ sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
break;
case WSDISPLAYIO_PUTCMAP:
if (rom->scment == NULL)
return ENOTTY;
if (scr->putcmap == NULL || scr->scr_bpp > 8)
return ENODEV;
if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL) {
/*
* The hardware palette settings are handled by
* the STI ROM in STI_TEXTMODE and changing cmap
* could cause mangled text colors at least on CRX.
* Updating CMAP in EMUL mode isn't expected anyway
* so just ignore it.
*/
return 0;
}
cmapp = (struct wsdisplay_cmap *)data;
idx = cmapp->index;
count = cmapp->count;
@ -1044,19 +1167,7 @@ sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
break;
if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count)))
break;
for (i = idx + count - 1; i >= idx; i--)
if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i],
scr->scr_gcmap[i], scr->scr_bcmap[i]))) {
DPRINTF(("sti_ioctl: "
"sti_setcment(%d, %u, %u, %u): %%d\n", i,
(u_int)scr->scr_rcmap[i],
(u_int)scr->scr_gcmap[i],
(u_int)scr->scr_bcmap[i]));
ret = EINVAL;
break;
}
ret = scr->putcmap(scr, idx, count);
break;
case WSDISPLAYIO_SVIDEO:
@ -1076,11 +1187,26 @@ sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
paddr_t
sti_mmap(void *v, void *vs, off_t offset, int prot)
{
#if 0
struct sti_screen *scr = (struct sti_screen *)v;
#if 0
struct sti_rom *rom = scr->scr_rom;
#endif
/* XXX not finished */
return -1;
paddr_t pa;
if ((offset & PAGE_MASK) != 0)
return -1;
if (offset < 0 || offset >= scr->fblen)
return -1;
#if 0 /* XXX not all platforms provide bus_space_mmap() yet */
pa = bus_space_mmap(rom->memt, scr->fbaddr, offset, prot,
BUS_SPACE_MAP_LINEAR);
#else
pa = scr->fbaddr + offset;
#endif
return pa;
}
int
@ -1097,7 +1223,6 @@ sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
*cyp = 0;
sti_alloc_attr(scr, 0, 0, 0, defattr);
scr->scr_nscreens++;
return 0;
}
@ -1139,8 +1264,10 @@ sti_cursor(void *v, int on, int row, int col)
struct sti_screen *scr = (struct sti_screen *)v;
struct sti_font *fp = &scr->scr_curfont;
sti_bmove(scr, col * fp->width, row * fp->height, col * fp->width,
row * fp->height, fp->height, fp->width, bmf_invert);
sti_bmove(scr,
col * fp->width, row * fp->height,
col * fp->width, row * fp->height,
fp->height, fp->width, bmf_invert);
}
/*
@ -1205,6 +1332,10 @@ sti_putchar(void *v, int row, int col, u_int uc, long attr)
struct sti_screen *scr = (struct sti_screen *)v;
struct sti_rom *rom = scr->scr_rom;
struct sti_font *fp = &scr->scr_curfont;
int bg, fg;
fg = WSATTR_UNPACK_FG(attr);
bg = WSATTR_UNPACK_BG(attr);
if (scr->scr_romfont != NULL) {
/*
@ -1219,9 +1350,8 @@ sti_putchar(void *v, int row, int col, u_int uc, long attr)
memset(&a, 0, sizeof(a));
a.flags.flags = STI_UNPMVF_WAIT;
/* XXX does not handle text attributes */
a.in.fg_colour = STI_COLOUR_WHITE;
a.in.bg_colour = STI_COLOUR_BLACK;
a.in.fg_colour = fg;
a.in.bg_colour = bg;
a.in.x = col * fp->width;
a.in.y = row * fp->height;
a.in.font_addr = scr->scr_romfont;
@ -1241,9 +1371,8 @@ sti_putchar(void *v, int row, int col, u_int uc, long attr)
memset(&a, 0, sizeof(a));
a.flags.flags = STI_BLKMVF_WAIT;
/* XXX does not handle text attributes */
a.in.fg_colour = STI_COLOUR_WHITE;
a.in.bg_colour = STI_COLOUR_BLACK;
a.in.fg_colour = fg;
a.in.bg_colour = bg;
a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) *
fp->width + scr->scr_fontbase;
@ -1264,8 +1393,10 @@ sti_copycols(void *v, int row, int srccol, int dstcol, int ncols)
struct sti_screen *scr = (struct sti_screen *)v;
struct sti_font *fp = &scr->scr_curfont;
sti_bmove(scr, srccol * fp->width, row * fp->height, dstcol * fp->width,
row * fp->height, fp->height, ncols * fp->width, bmf_copy);
sti_bmove(scr,
srccol * fp->width, row * fp->height,
dstcol * fp->width, row * fp->height,
fp->height, ncols * fp->width, bmf_copy);
}
void
@ -1274,9 +1405,10 @@ sti_erasecols(void *v, int row, int startcol, int ncols, long attr)
struct sti_screen *scr = (struct sti_screen *)v;
struct sti_font *fp = &scr->scr_curfont;
sti_bmove(scr, startcol * fp->width, row * fp->height,
startcol * fp->width, row * fp->height, fp->height,
ncols * fp->width, bmf_clear);
sti_bmove(scr,
startcol * fp->width, row * fp->height,
startcol * fp->width, row * fp->height,
fp->height, ncols * fp->width, bmf_clear);
}
void
@ -1306,8 +1438,18 @@ sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr)
struct sti_screen *scr = (struct sti_screen *)v;
#endif
*pattr = 0;
if ((flags & (WSATTR_HILIT | WSATTR_BLINK |
WSATTR_UNDERLINE | WSATTR_WSCOLORS)) != 0)
return EINVAL;
if ((flags & WSATTR_REVERSE) != 0) {
fg = STI_COLOUR_BLACK;
bg = STI_COLOUR_WHITE;
} else {
fg = STI_COLOUR_WHITE;
bg = STI_COLOUR_BLACK;
}
*pattr = WSATTR_PACK(fg, bg, flags);
return 0;
}
@ -1350,3 +1492,185 @@ sti_cnattach(struct sti_rom *rom, struct sti_screen *scr, bus_space_tag_t memt,
return 0;
}
#endif
int
ngle_default_putcmap(struct sti_screen *scr, u_int idx, u_int count)
{
int i, ret;
for (i = idx + count - 1; i >= (int)idx; i--)
if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i],
scr->scr_gcmap[i], scr->scr_bcmap[i])))
return EINVAL;
return 0;
}
#ifndef SMALL_KERNEL
void ngle_setup_hw(bus_space_tag_t, bus_space_handle_t);
void ngle_setup_fb(bus_space_tag_t, bus_space_handle_t, uint32_t);
void ngle_setup_attr_planes(struct sti_screen *scr);
void ngle_setup_bt458(struct sti_screen *scr);
#define ngle_bt458_write(memt, memh, r, v) \
bus_space_write_4(memt, memh, NGLE_REG_RAMDAC + ((r) << 2), (v) << 24)
void
ngle_artist_setupfb(struct sti_screen *scr)
{
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t memt = rom->memt;
bus_space_handle_t memh = rom->regh[2];
ngle_setup_bt458(scr);
ngle_setup_hw(memt, memh);
ngle_setup_fb(memt, memh, scr->reg10_value);
ngle_setup_attr_planes(scr);
ngle_setup_hw(memt, memh);
bus_space_write_4(memt, memh, NGLE_REG_21,
bus_space_read_4(memt, memh, NGLE_REG_21) | 0x0a000000);
bus_space_write_4(memt, memh, NGLE_REG_27,
bus_space_read_4(memt, memh, NGLE_REG_27) | 0x00800000);
}
void
ngle_elk_setupfb(struct sti_screen *scr)
{
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t memt = rom->memt;
bus_space_handle_t memh = rom->regh[2];
ngle_setup_bt458(scr);
ngle_setup_hw(memt, memh);
ngle_setup_fb(memt, memh, scr->reg10_value);
ngle_setup_attr_planes(scr);
ngle_setup_hw(memt, memh);
/* enable overlay planes in Bt458 command register */
ngle_bt458_write(memt, memh, 0x0c, 0x06);
ngle_bt458_write(memt, memh, 0x0e, 0x43);
}
void
ngle_timber_setupfb(struct sti_screen *scr)
{
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t memt = rom->memt;
bus_space_handle_t memh = rom->regh[2];
ngle_setup_bt458(scr);
ngle_setup_hw(memt, memh);
/* enable overlay planes in Bt458 command register */
ngle_bt458_write(memt, memh, 0x0c, 0x06);
ngle_bt458_write(memt, memh, 0x0e, 0x43);
}
void
ngle_setup_bt458(struct sti_screen *scr)
{
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t memt = rom->memt;
bus_space_handle_t memh = rom->regh[2];
ngle_setup_hw(memt, memh);
/* set Bt458 read mask register to all planes */
ngle_bt458_write(memt, memh, 0x08, 0x04);
ngle_bt458_write(memt, memh, 0x0a, 0xff);
}
void
ngle_setup_attr_planes(struct sti_screen *scr)
{
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t memt = rom->memt;
bus_space_handle_t memh = rom->regh[2];
ngle_setup_hw(memt, memh);
bus_space_write_4(memt, memh, NGLE_REG_11, 0x2ea0d000);
bus_space_write_4(memt, memh, NGLE_REG_14, 0x23000302);
bus_space_write_4(memt, memh, NGLE_REG_12, scr->reg12_value);
bus_space_write_4(memt, memh, NGLE_REG_8, 0xffffffff);
bus_space_write_4(memt, memh, NGLE_REG_6, 0x00000000);
bus_space_write_4(memt, memh, NGLE_REG_9,
(scr->scr_cfg.scr_width << 16) | scr->scr_cfg.scr_height);
bus_space_write_4(memt, memh, NGLE_REG_6, 0x05000000);
bus_space_write_4(memt, memh, NGLE_REG_9, 0x00040001);
ngle_setup_hw(memt, memh);
bus_space_write_4(memt, memh, NGLE_REG_12, 0x00000000);
ngle_setup_fb(memt, memh, scr->reg10_value);
}
int
ngle_putcmap(struct sti_screen *scr, u_int idx, u_int count)
{
struct sti_rom *rom = scr->scr_rom;
bus_space_tag_t memt = rom->memt;
bus_space_handle_t memh = rom->regh[2];
uint8_t *r, *g, *b;
uint32_t cmap_finish;
if (scr->scr_bpp > 8)
cmap_finish = 0x83000100;
else
cmap_finish = 0x80000100;
r = scr->scr_rcmap + idx;
g = scr->scr_gcmap + idx;
b = scr->scr_bcmap + idx;
ngle_setup_hw(memt, memh);
bus_space_write_4(memt, memh, NGLE_REG_10, 0xbbe0f000);
bus_space_write_4(memt, memh, NGLE_REG_14, 0x03000300);
bus_space_write_4(memt, memh, NGLE_REG_13, 0xffffffff);
while (count-- != 0) {
ngle_setup_hw(memt, memh);
bus_space_write_4(memt, memh, NGLE_REG_3, 0x400 | (idx << 2));
bus_space_write_4(memt, memh, NGLE_REG_4,
(*r << 16) | (*g << 8) | *b);
idx++;
r++, g++, b++;
}
bus_space_write_4(memt, memh, NGLE_REG_2, 0x400);
bus_space_write_4(memt, memh, scr->cmap_finish_register, cmap_finish);
ngle_setup_fb(memt, memh, scr->reg10_value);
return 0;
}
void
ngle_setup_hw(bus_space_tag_t memt, bus_space_handle_t memh)
{
uint8_t stat;
do {
stat = bus_space_read_1(memt, memh, NGLE_REG_15b0);
if (stat == 0)
stat = bus_space_read_1(memt, memh, NGLE_REG_15b0);
} while (stat != 0);
}
void
ngle_setup_fb(bus_space_tag_t memt, bus_space_handle_t memh, uint32_t reg10)
{
ngle_setup_hw(memt, memh);
bus_space_write_4(memt, memh, NGLE_REG_10, reg10);
bus_space_write_4(memt, memh, NGLE_REG_14, 0x83000300);
ngle_setup_hw(memt, memh);
bus_space_write_1(memt, memh, NGLE_REG_16b1, 1);
}
#endif /* SMALL_KERNEL */

View File

@ -1,4 +1,4 @@
/* $NetBSD: stivar.h,v 1.9.34.1 2020/05/18 17:52:22 martin Exp $ */
/* $NetBSD: stivar.h,v 1.9.34.2 2020/12/28 20:10:04 martin Exp $ */
/* $OpenBSD: stivar.h,v 1.24 2009/02/06 22:51:04 miod Exp $ */
@ -42,11 +42,15 @@ struct sti_rom {
bus_space_tag_t iot, memt; /* XXX iot unused */
bus_space_handle_t romh;
bus_space_handle_t regh[STI_REGION_MAX];
bus_addr_t *bases;
struct sti_dd rom_dd; /* in word format */
vaddr_t rom_code;
/*
* ROM-provided function pointers
*/
sti_init_t init;
sti_mgmt_t mgmt;
sti_unpmv_t unpmv;
@ -98,10 +102,20 @@ struct sti_screen {
struct wsscreen_descr scr_wsd;
const struct wsscreen_descr *scr_scrlist[1];
struct wsscreen_list scr_screenlist;
/*
* Board-specific function data and pointers
*/
void (*setupfb)(struct sti_screen *);
int (*putcmap)(struct sti_screen *, u_int, u_int);
uint32_t reg10_value;
uint32_t reg12_value;
bus_addr_t cmap_finish_register;
};
/*
* STI Device state
* STI device state
*/
struct sti_softc {
device_t sc_dev;
@ -134,6 +148,7 @@ u_int sti_rom_size(bus_space_tag_t, bus_space_handle_t);
int sti_init(struct sti_screen *, int);
#define STI_TEXTMODE 0x01
#define STI_CLEARSCR 0x02
#define STI_FBMODE 0x04
int sti_ioctl(void *, void *, u_long, void *, int, struct lwp *);
paddr_t sti_mmap(void *, void *, off_t, int);
int sti_alloc_screen(void *, const struct wsscreen_descr *,