Port-hppa archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
HP9000/425t A1659A CRX framebuffer bitmap support
Hi,
Recently I received SGC CRX framebuffers (A1659) with the SGC
connector and flexible cable for HP9000/425t from Miod Vallat.
After a few days work I've managed to get working bitmap support
for it, i.e. now Xorg server (and other applications like mlterm-wscons)
work as the 8bpp bitmap framebuffers.
Diffs against -current is on github gist (and also attached):
https://gist.github.com/tsutsui/8560841f666ebe7866ab9e810a465a29
Changes summary:
- Pull OpenBSD's latest sti(4) sources
- Essencial part is "ngle" support in the following commit:
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/dev/ic/sti.c#rev1.76
- Also pull misc cosmetic changes to reduce diffs
- Add hp300 specific CRX bitmap attach functions
- Modify existing 425e EVRX attachment to utilize updated MI sti(4)
- 1 plane A1924 (GRX?) is not tested yet (how should we handle grayscale?)
- No hppa specific attachments, but no error on hppa GENERIC build
- The following models could be supported?
> CRX (720/735/750), Timber (710, old 715), Artist (712, 715), EG (B-series)
- "options SMALL_KERNEL" is not enabled (to disable bitmap ops)
I'll commit changes soon if there is no particular objections.
Note Miod-san also sent a DIO-II "Hyperion" framebuffer and
I've also confirmed hyper(4) mono driver just works with
wscons backend, i.e. 1bpp Xorg and mlterm-wscons also work fine.
Thanks again, Miod-san!
Index: arch/hp300/dev/sti_sgc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/sti_sgc.c,v
retrieving revision 1.3
diff -u -p -d -r1.3 sti_sgc.c
--- arch/hp300/dev/sti_sgc.c 4 May 2020 06:52:53 -0000 1.3
+++ arch/hp300/dev/sti_sgc.c 19 Dec 2020 01:39:22 -0000
@@ -75,7 +75,13 @@ struct sti_sgc_softc {
#define EVRX_MAGIC18 0x618
#define EVRX_MAGIC1C 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 +94,26 @@ static int sti_sgc_probe(bus_space_tag_t
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 *);
+/* 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_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);
+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,
+ sti_ioctl,
+ sti_m68k_mmap,
+ sti_alloc_screen,
+ sti_free_screen,
+ sti_show_screen,
+ sti_load_font
+};
+
+/* A1659A CRX specific access functions */
+static const struct wsdisplay_accessops sti_crx_accessops = {
+ sti_ioctl,
+ sti_m68k_mmap,
sti_alloc_screen,
sti_free_screen,
sti_show_screen,
@@ -135,6 +151,7 @@ sti_sgc_attach(device_t parent, device_t
int i;
ssc->sc_dev = self;
+ sc->sc_bst = saa->saa_iot;
base = (bus_addr_t)sgc_slottopa(saa->saa_slot);
if (saa->saa_slot == sticonslot) {
@@ -147,18 +164,18 @@ sti_sgc_attach(device_t parent, device_t
sti_describe(ssc);
} else {
- if (bus_space_map(saa->saa_iot, base, PAGE_SIZE, 0, &romh)) {
+ if (bus_space_map(sc->sc_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(sc->sc_bst, romh);
- bus_space_unmap(saa->saa_iot, romh, PAGE_SIZE);
+ bus_space_unmap(sc->sc_bst, romh, PAGE_SIZE);
- if (bus_space_map(saa->saa_iot, base, romend, 0, &romh)) {
+ if (bus_space_map(sc->sc_bst, base, romend, 0, &romh)) {
aprint_error(": can't map frame buffer");
return;
}
@@ -167,7 +184,7 @@ sti_sgc_attach(device_t parent, device_t
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, sc->sc_bst, sc->sc_bst, romh,
STI_CODEBASE_ALT) != 0)
return;
}
@@ -189,7 +206,6 @@ sti_sgc_attach(device_t parent, device_t
* 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");
@@ -204,6 +220,9 @@ sti_sgc_attach(device_t parent, device_t
sti_evrx_resetramdac(sc);
sti_evrx_resetcmap(sc);
+ 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;
@@ -216,9 +235,20 @@ sti_sgc_attach(device_t parent, device_t
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_crx_accessops;
+ waa.accesscookie = scr;
+
+ config_found(ssc->sc_dev, &waa, wsemuldisplaydevprint);
+ break;
default:
/*
* Unsupported variants.
@@ -256,34 +286,14 @@ sti_sgc_probe(bus_space_tag_t iot, int s
}
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;
+ struct sti_rom *rom = scr->scr_rom;
+ struct sti_softc *ssc = rom->rom_softc;
+ struct sti_sgc_softc *sc = device_private(ssc->sc_dev);
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);
+ int i;
/* magic setup from HP-UX */
bus_space_write_4(bst, bsh, EVRX_MAGIC08, 0x00000001);
@@ -376,68 +386,19 @@ sti_evrx_resetcmap(struct sti_sgc_softc
}
}
-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(sc);
}
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 +452,13 @@ sti_sgc_cnattach(bus_space_tag_t bst, bu
{
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;
Index: dev/ic/sti.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/sti.c,v
retrieving revision 1.22
diff -u -p -d -r1.22 sti.c
--- dev/ic/sti.c 5 Sep 2020 16:30:11 -0000 1.22
+++ dev/ic/sti.c 19 Dec 2020 01:39:23 -0000
@@ -31,7 +31,7 @@
* TODO:
* call sti procs asynchronously;
* implement console scroll-back;
- * X11 support.
+ * X11 support on more models.
*/
#include <sys/cdefs.h>
@@ -80,32 +80,32 @@ void sti_eraserows(void *, int, int, lon
int sti_alloc_attr(void *, int, int, int, long *);
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 +118,15 @@ int sti_rom_setup(struct sti_rom *, bus_
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 { \
@@ -210,51 +219,52 @@ sti_rom_setup(struct sti_rom *rom, bus_s
/*
* 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);
@@ -288,7 +298,7 @@ sti_rom_setup(struct sti_rom *rom, bus_s
* 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];
@@ -300,13 +310,12 @@ sti_rom_setup(struct sti_rom *rom, bus_s
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.
@@ -322,8 +331,7 @@ sti_rom_setup(struct sti_rom *rom, bus_s
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,
@@ -349,26 +357,27 @@ sti_rom_setup(struct sti_rom *rom, bus_s
(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;
}
@@ -388,7 +397,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;
@@ -449,14 +457,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;
@@ -616,6 +624,73 @@ sti_screen_setup(struct sti_screen *scr,
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:
@@ -656,6 +731,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)
{
@@ -827,6 +907,7 @@ rescan:
/*
* Wrappers around STI code pointers
*/
+
int
sti_init(struct sti_screen *scr, int mode)
{
@@ -955,11 +1036,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) {
@@ -969,13 +1049,31 @@ sti_ioctl(void *v, void *vs, u_long cmd,
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:
@@ -987,19 +1085,22 @@ sti_ioctl(void *v, void *vs, u_long cmd,
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;
@@ -1014,8 +1115,8 @@ sti_ioctl(void *v, void *vs, u_long cmd,
break;
case WSDISPLAYIO_PUTCMAP:
- 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;
@@ -1027,19 +1128,7 @@ sti_ioctl(void *v, void *vs, u_long cmd,
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:
@@ -1059,11 +1148,26 @@ sti_ioctl(void *v, void *vs, u_long cmd,
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
@@ -1080,7 +1184,6 @@ sti_alloc_screen(void *v, const struct w
*cyp = 0;
sti_alloc_attr(scr, 0, 0, 0, defattr);
scr->scr_nscreens++;
-
return 0;
}
@@ -1122,8 +1225,10 @@ sti_cursor(void *v, int on, int row, int
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);
}
/*
@@ -1247,8 +1352,10 @@ sti_copycols(void *v, int row, int srcco
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
@@ -1257,9 +1364,10 @@ sti_erasecols(void *v, int row, int star
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
@@ -1333,3 +1441,185 @@ sti_cnattach(struct sti_rom *rom, struct
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 */
Index: dev/ic/stivar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/stivar.h,v
retrieving revision 1.10
diff -u -p -d -r1.10 stivar.h
--- dev/ic/stivar.h 4 May 2020 06:52:53 -0000 1.10
+++ dev/ic/stivar.h 19 Dec 2020 01:39:23 -0000
@@ -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_
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 *,
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index