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