Last active
May 4, 2020 03:32
-
-
Save tsutsui/90acb9591ec4f8aaf4490dc00bdb92fd to your computer and use it in GitHub Desktop.
WIP diff for NetBSD/hp300 to add bitmap framebuffer support for HP 9000/425e (updated again; EVRX check by sti_dd, pointed out by miod)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: sys/arch/hp300/dev/sti_sgc.c | |
=================================================================== | |
RCS file: /cvsroot/src/sys/arch/hp300/dev/sti_sgc.c,v | |
retrieving revision 1.2 | |
diff -u -p -d -r1.2 sti_sgc.c | |
--- sys/arch/hp300/dev/sti_sgc.c 20 Apr 2014 04:12:54 -0000 1.2 | |
+++ sys/arch/hp300/dev/sti_sgc.c 4 May 2020 03:17:04 -0000 | |
@@ -35,6 +35,7 @@ __KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v | |
#include <uvm/uvm_extern.h> | |
+#include <dev/wscons/wsconsio.h> | |
#include <dev/wscons/wsdisplayvar.h> | |
#include <dev/ic/stireg.h> | |
@@ -44,6 +45,36 @@ __KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v | |
#include <hp300/dev/sti_sgcvar.h> | |
#include <machine/autoconf.h> | |
+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 | |
+#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) | |
+ | |
+/* 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_MAGIC10_BSY 0x00010000 | |
+#define EVRX_MAGIC18 0x618 | |
+#define EVRX_MAGIC1C 0x61c | |
+ | |
static int sticonslot = -1; | |
static struct sti_rom sticn_rom; | |
static struct sti_screen sticn_scr; | |
@@ -54,9 +85,25 @@ static void sti_sgc_attach(device_t, dev | |
static int sti_sgc_probe(bus_space_tag_t, int); | |
-CFATTACH_DECL_NEW(sti_sgc, sizeof(struct sti_softc), | |
+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); | |
+ | |
+static const struct wsdisplay_accessops sti_evrx_accessops = { | |
+ sti_evrx_ioctl, | |
+ sti_evrx_mmap, | |
+ sti_alloc_screen, | |
+ sti_free_screen, | |
+ sti_show_screen, | |
+ sti_load_font | |
+}; | |
+ | |
static int | |
sti_sgc_match(device_t parent, struct cfdata *cf, void *aux) | |
{ | |
@@ -75,24 +122,31 @@ sti_sgc_match(device_t parent, struct cf | |
static void | |
sti_sgc_attach(device_t parent, device_t self, void *aux) | |
{ | |
- struct sti_softc *sc = device_private(self); | |
+ struct sti_sgc_softc *sc = device_private(self); | |
+ struct sti_softc *ssc = &sc->sc_sti; | |
struct sgc_attach_args *saa = aux; | |
+ struct sti_screen *scr; | |
bus_space_handle_t romh; | |
bus_addr_t base; | |
+ struct wsemuldisplaydev_attach_args waa; | |
u_int romend; | |
+ struct sti_dd *rom_dd; | |
+ uint32_t grid0; | |
int i; | |
- sc->sc_dev = self; | |
+ ssc->sc_dev = self; | |
+ base = (bus_addr_t)sgc_slottopa(saa->saa_slot); | |
if (saa->saa_slot == sticonslot) { | |
- sc->sc_flags |= STI_CONSOLE | STI_ATTACHED; | |
- sc->sc_rom = &sticn_rom; | |
- sc->sc_scr = &sticn_scr; | |
- memcpy(sc->bases, sticn_bases, sizeof(sc->bases)); | |
+ ssc->sc_flags |= STI_CONSOLE | STI_ATTACHED; | |
+ ssc->sc_rom = &sticn_rom; | |
+ ssc->sc_rom->rom_softc = ssc; | |
+ ssc->sc_scr = &sticn_scr; | |
+ ssc->sc_scr->scr_rom = ssc->sc_rom; | |
+ memcpy(ssc->bases, sticn_bases, sizeof(ssc->bases)); | |
- sti_describe(sc); | |
+ sti_describe(ssc); | |
} else { | |
- base = (bus_addr_t)sgc_slottopa(saa->saa_slot); | |
if (bus_space_map(saa->saa_iot, base, PAGE_SIZE, 0, &romh)) { | |
aprint_error(": can't map ROM"); | |
return; | |
@@ -109,22 +163,70 @@ sti_sgc_attach(device_t parent, device_t | |
return; | |
} | |
- sc->bases[0] = romh; | |
+ ssc->bases[0] = romh; | |
for (i = 0; i < STI_REGION_MAX; i++) | |
- sc->bases[i] = base; | |
+ ssc->bases[i] = base; | |
- if (sti_attach_common(sc, saa->saa_iot, saa->saa_iot, romh, | |
+ if (sti_attach_common(ssc, saa->saa_iot, saa->saa_iot, romh, | |
STI_CODEBASE_ALT) != 0) | |
return; | |
} | |
- /* | |
- * Note on 425e sti(4) framebuffer bitmap memory can be accessed at | |
- * (sgc_slottopa(saa->saa_slot) + 0x200000) | |
- * but the mmap function to map bitmap display is not provided yet. | |
- */ | |
+ /* Identify the board model by dd_grid */ | |
+ rom_dd = &ssc->sc_rom->rom_dd; | |
+ grid0 = rom_dd->dd_grid[0]; | |
+ scr = ssc->sc_scr; | |
- sti_end_attach(sc); | |
+ switch (grid0) { | |
+ case STI_DD_EVRX: | |
+ /* | |
+ * 425e on-board EVRX framebuffer. | |
+ * bitmap memory can be accessed at offset +0x200000. | |
+ */ | |
+ 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); | |
+ | |
+ 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.accesscookie = scr; | |
+ | |
+ config_found(ssc->sc_dev, &waa, wsemuldisplaydevprint); | |
+ break; | |
+ | |
+ case STI_DD_CRX: | |
+ /* | |
+ * HP A1659A CRX on some 425t variants. | |
+ * Not investigated yet; needs to check HP-UX libddgcrx.a etc. | |
+ */ | |
+ /* FALLTHROUGH */ | |
+ default: | |
+ /* | |
+ * Unsupported variants. | |
+ * Use default common sti(4) attachment (no bitmap support). | |
+ */ | |
+ sti_end_attach(ssc); | |
+ break; | |
+ } | |
} | |
static int | |
@@ -153,6 +255,214 @@ sti_sgc_probe(bus_space_tag_t iot, int s | |
return 1; | |
} | |
+static int | |
+sti_evrx_setcmap(struct sti_sgc_softc *sc, struct wsdisplay_cmap *p) | |
+{ | |
+ 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); | |
+ | |
+ /* magic setup from HP-UX */ | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC08, 0x00000001); | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC00, 0x00000001); | |
+ for (i = index; i < index + count; i++) { | |
+ /* this is what HP-UX woodDownloadCmap() does */ | |
+ while ((bus_space_read_4(bst, bsh, EVRX_MAGIC10) & | |
+ EVRX_MAGIC10_BSY) != 0) | |
+ continue; | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_ADDR, i); | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_CMAP, scr->scr_rcmap[i]); | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_CMAP, scr->scr_gcmap[i]); | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC10, scr->scr_bcmap[i]); | |
+ } | |
+ return 0; | |
+} | |
+ | |
+static void | |
+sti_evrx_resetramdac(struct sti_sgc_softc *sc) | |
+{ | |
+ bus_space_tag_t bst = sc->sc_bst; | |
+ bus_space_handle_t bsh = sc->sc_ramdach; | |
+#if 0 | |
+ int i; | |
+#endif | |
+ | |
+ /* | |
+ * Initialize the Bt458. When we write to control registers, | |
+ * the address is not incremented automatically. So we specify | |
+ * it ourselves for each control register. | |
+ */ | |
+ | |
+ /* all planes will be read */ | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_ADDR, 0x04); | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_CTRL, 0xff); | |
+ | |
+ /* all planes have non-blink */ | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_ADDR, 0x05); | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_CTRL, 0x00); | |
+ | |
+ /* pallete enabled, ovly plane disabled */ | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_ADDR, 0x06); | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_CTRL, 0x40); | |
+ | |
+ /* no test mode */ | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_ADDR, 0x07); | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_CTRL, 0x00); | |
+ | |
+ /* magic initialization from HP-UX woodInitializeHardware() */ | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC00, 0x00000001); | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC04, 0x00000001); | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC08, 0x00000001); | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC0C, 0x00000001); | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC18, 0xFFFFFFFF); | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC1C, 0x00000000); | |
+ | |
+#if 0 | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_ADDR, 0x00); | |
+ for (i = 0; i < 4; i++) { | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_OMAP, 0x00); | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_OMAP, 0x00); | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_OMAP, 0x00); | |
+ } | |
+#endif | |
+} | |
+ | |
+static void | |
+sti_evrx_resetcmap(struct sti_sgc_softc *sc) | |
+{ | |
+ 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; | |
+ int i; | |
+ | |
+ /* magic setup from HP-UX */ | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC08, 0x00000001); | |
+ bus_space_write_4(bst, bsh, EVRX_MAGIC00, 0x00000001); | |
+ | |
+ /* preserve palette values initialized by STI firmware */ | |
+ for (i = 0; i < STI_NCMAP; i++) { | |
+ /* this is what HP-UX woodUploadCmap() does */ | |
+ while ((bus_space_read_4(bst, bsh, EVRX_MAGIC10) & | |
+ EVRX_MAGIC10_BSY) != 0) | |
+ continue; | |
+ bus_space_write_1(bst, bsh, EVRX_BT458_ADDR, i); | |
+ scr->scr_rcmap[i] = bus_space_read_1(bst, bsh, EVRX_BT458_CMAP); | |
+ scr->scr_gcmap[i] = bus_space_read_1(bst, bsh, EVRX_BT458_CMAP); | |
+ scr->scr_bcmap[i] = bus_space_read_1(bst, bsh, EVRX_BT458_CMAP); | |
+ } | |
+} | |
+ | |
+static int | |
+sti_evrx_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 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); | |
+} | |
+ | |
+static paddr_t | |
+sti_evrx_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; | |
+ struct sti_softc *ssc = rom->rom_softc; | |
+ struct sti_sgc_softc *sc = device_private(ssc->sc_dev); | |
+ paddr_t cookie = -1; | |
+ | |
+ if ((offset & PAGE_MASK) != 0) | |
+ return -1; | |
+ | |
+ switch (scr->scr_wsmode) { | |
+ case WSDISPLAYIO_MODE_MAPPED: | |
+ /* not implemented yet; what should be shown? */ | |
+ break; | |
+ case WSDISPLAYIO_MODE_DUMBFB: | |
+ if (offset >= 0 && offset < (scr->fbwidth * scr->fbheight)) | |
+ cookie = m68k_btop(sc->sc_bitmap + offset); | |
+ break; | |
+ default: | |
+ break; | |
+ } | |
+ | |
+ return cookie; | |
+} | |
+ | |
int | |
sti_sgc_cnprobe(bus_space_tag_t bst, bus_addr_t addr, int slot) | |
{ | |
Index: sys/dev/ic/sti.c | |
=================================================================== | |
RCS file: /cvsroot/src/sys/dev/ic/sti.c,v | |
retrieving revision 1.19 | |
diff -u -p -d -r1.19 sti.c | |
--- sys/dev/ic/sti.c 13 Jun 2017 19:13:55 -0000 1.19 | |
+++ sys/dev/ic/sti.c 4 May 2020 03:17:05 -0000 | |
@@ -103,9 +103,6 @@ enum sti_bmove_funcs { | |
bmf_clear, bmf_copy, bmf_invert, bmf_underline | |
}; | |
-int sti_init(struct sti_screen *, int); | |
-#define STI_TEXTMODE 0x01 | |
-#define STI_CLEARSCR 0x02 | |
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); | |
@@ -861,10 +858,16 @@ sti_init(struct sti_screen *scr, int mod | |
KASSERT(rom != NULL); | |
memset(&a, 0, sizeof(a)); | |
- a.flags.flags = STI_INITF_WAIT | STI_INITF_CMB | STI_INITF_EBET | | |
- (mode & STI_TEXTMODE ? STI_INITF_TEXT | STI_INITF_PBET | | |
- STI_INITF_PBETI | STI_INITF_ICMT : 0) | | |
- (mode & STI_CLEARSCR ? STI_INITF_CLEAR : 0); | |
+ a.flags.flags = STI_INITF_WAIT | STI_INITF_EBET; | |
+ if ((mode & STI_TEXTMODE) != 0) { | |
+ a.flags.flags |= STI_INITF_TEXT | STI_INITF_CMB | | |
+ STI_INITF_PBET | STI_INITF_PBETI | STI_INITF_ICMT; | |
+ } else { | |
+ a.flags.flags |= STI_INITF_NTEXT; | |
+ } | |
+ if ((mode & STI_CLEARSCR) != 0) | |
+ a.flags.flags |= STI_INITF_CLEAR; | |
+ | |
a.in.text_planes = 1; | |
a.in.ext_in = &a.ein; | |
Index: sys/dev/ic/stivar.h | |
=================================================================== | |
RCS file: /cvsroot/src/sys/dev/ic/stivar.h,v | |
retrieving revision 1.9 | |
diff -u -p -d -r1.9 stivar.h | |
--- sys/dev/ic/stivar.h 29 Jun 2014 04:08:43 -0000 1.9 | |
+++ sys/dev/ic/stivar.h 4 May 2020 03:17:05 -0000 | |
@@ -131,6 +131,9 @@ void sti_describe(struct sti_softc *); | |
void sti_end_attach(struct sti_softc *); | |
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 | |
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 *, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment