Module Name: src
Committed By: macallan
Date: Wed Jul 24 08:34:03 UTC 2024
Modified Files:
src/sys/arch/hppa/dev: hyperfb.c
Log Message:
hand X a 24bit framebuffer if the hardware supports it
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/hppa/dev/hyperfb.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/hppa/dev/hyperfb.c
diff -u src/sys/arch/hppa/dev/hyperfb.c:1.4 src/sys/arch/hppa/dev/hyperfb.c:1.5
--- src/sys/arch/hppa/dev/hyperfb.c:1.4 Wed Jul 17 08:30:28 2024
+++ src/sys/arch/hppa/dev/hyperfb.c Wed Jul 24 08:34:03 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: hyperfb.c,v 1.4 2024/07/17 08:30:28 macallan Exp $ */
+/* $NetBSD: hyperfb.c,v 1.5 2024/07/24 08:34:03 macallan Exp $ */
/*
* Copyright (c) 2024 Michael Lorenz
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hyperfb.c,v 1.4 2024/07/17 08:30:28 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hyperfb.c,v 1.5 2024/07/24 08:34:03 macallan Exp $");
#include "opt_cputype.h"
#include "opt_hyperfb.h"
@@ -113,7 +113,8 @@ extern struct cfdriver hyperfb_cd;
CFATTACH_DECL_NEW(hyperfb, sizeof(struct hyperfb_softc), hyperfb_match,
hyperfb_attach, NULL, NULL);
-void hyperfb_setup_fb(struct hyperfb_softc *);
+static inline void hyperfb_setup_fb(struct hyperfb_softc *);
+static inline void hyperfb_setup_fb24(struct hyperfb_softc *);
static void hyperfb_init_screen(void *, struct vcons_screen *,
int, long *);
static int hyperfb_ioctl(void *, void *, u_long, void *, int,
@@ -205,13 +206,31 @@ hyperfb_wait_fifo(struct hyperfb_softc *
} while (reg < slots);
}
-void
+static inline void
hyperfb_setup_fb(struct hyperfb_softc *sc)
{
hyperfb_wait(sc);
- hyperfb_write4(sc, NGLE_REG_10, 0x13602000); /* 8bit */
+ if ((sc->sc_mode != WSDISPLAYIO_MODE_EMUL) && sc->sc_24bit) {
+ hyperfb_write4(sc, NGLE_REG_10, 0xBBA0A000); /* 24bit */
+ hyperfb_write4(sc, NGLE_REG_13, 0xffffffff);
+ } else
+ hyperfb_write4(sc, NGLE_REG_10, 0x13602000); /* 8bit */
+ hyperfb_write4(sc, NGLE_REG_14, 0x83000300);
+ hyperfb_wait(sc);
+ hyperfb_write1(sc, NGLE_REG_16b1, 1);
+ sc->sc_hwmode = HW_FB;
+}
+
+static inline void
+hyperfb_setup_fb24(struct hyperfb_softc *sc)
+{
+
+ hyperfb_wait(sc);
+ hyperfb_write4(sc, NGLE_REG_10, 0xBBA0A000); /* 24bit */
+ hyperfb_write4(sc, NGLE_REG_13, 0xffffffff);
hyperfb_write4(sc, NGLE_REG_14, 0x83000300);
+ //IBOvals(RopSrc,0,BitmapExtent08,0,DataDynamic,MaskDynamic,0,0)
hyperfb_wait(sc);
hyperfb_write1(sc, NGLE_REG_16b1, 1);
sc->sc_hwmode = HW_FB;
@@ -367,6 +386,9 @@ hyperfb_attach(device_t parent, device_t
eaio_l2(PCXL2_ACCEL_IO_ADDR2MASK(ca->ca_hpa));
#endif /* HP7300LC_CPU */
+ sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
+ sc->sc_locked = 0;
+
hyperfb_setup(sc);
hyperfb_setup_fb(sc);
@@ -382,8 +404,6 @@ hyperfb_attach(device_t parent, device_t
sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
- sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
- sc->sc_locked = 0;
vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
&hyperfb_accessops);
@@ -458,6 +478,8 @@ hyperfb_attach(device_t parent, device_t
config_found(sc->sc_dev, &aa, wsemuldisplaydevprint, CFARGS_NONE);
+ hyperfb_setup_fb(sc);
+
}
static void
@@ -513,7 +535,7 @@ hyperfb_ioctl(void *v, void *vs, u_long
return ENODEV;
wdf = (void *)data;
wdf->height = ms->scr_ri.ri_height;
- wdf->width = ms->scr_ri.ri_width;
+ wdf->width = sc->sc_24bit ? ms->scr_ri.ri_width << 2 : ms->scr_ri.ri_width;
wdf->depth = ms->scr_ri.ri_depth;
wdf->cmsize = 256;
return 0;
@@ -526,7 +548,7 @@ hyperfb_ioctl(void *v, void *vs, u_long
return hyperfb_putcmap(sc,
(struct wsdisplay_cmap *)data);
case WSDISPLAYIO_LINEBYTES:
- *(u_int *)data = 2048;
+ *(u_int *)data = sc->sc_24bit ? 8192 : 2048;
return 0;
case WSDISPLAYIO_SMODE: {
@@ -544,6 +566,11 @@ hyperfb_ioctl(void *v, void *vs, u_long
(ms->scr_defattr >> 16) & 0xff]);
vcons_redraw_screen(ms);
hyperfb_set_video(sc, 1);
+ } else {
+ hyperfb_setup(sc);
+ hyperfb_rectfill(sc, 0, 0, sc->sc_width,
+ sc->sc_height, 0xff);
+ hyperfb_setup_fb24(sc);
}
}
}
@@ -556,6 +583,19 @@ hyperfb_ioctl(void *v, void *vs, u_long
ret = wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
fbi->fbi_fbsize = sc->sc_height * 2048;
+ if (sc->sc_24bit) {
+ fbi->fbi_stride = 8192;
+ fbi->fbi_bitsperpixel = 32;
+ fbi->fbi_pixeltype = WSFB_RGB;
+ fbi->fbi_subtype.fbi_rgbmasks.red_offset = 16;
+ fbi->fbi_subtype.fbi_rgbmasks.red_size = 8;
+ fbi->fbi_subtype.fbi_rgbmasks.green_offset = 8;
+ fbi->fbi_subtype.fbi_rgbmasks.green_size = 8;
+ fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 0;
+ fbi->fbi_subtype.fbi_rgbmasks.blue_size = 8;
+ fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 0;
+ fbi->fbi_fbsize = sc->sc_height * 8192;
+ }
return ret;
}
@@ -746,15 +786,36 @@ hyperfb_setup(struct hyperfb_softc *sc)
reg = hyperfb_read4(sc, NGLE_REG_32);
DPRINTF("planereg %08x\n", reg);
- hyperfb_write4(sc, NGLE_REG_32, 0xffff0000);
+ hyperfb_write4(sc, NGLE_REG_32, 0xffffffff);
- hyperfb_setup_fb(sc);
+ /* hyperbowl */
+ hyperfb_wait(sc);
+ if(sc->sc_24bit) {
+ /* write must happen twice because hw bug */
+ hyperfb_write4(sc, NGLE_REG_40, HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE);
+ hyperfb_write4(sc, NGLE_REG_40, HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE);
+ hyperfb_write4(sc, NGLE_REG_39, HYPERBOWL_MODE2_8_24);
+ hyperfb_write4(sc, NGLE_REG_42, 0x014c0148); /* Set lut 0 to be the direct color */
+ hyperfb_write4(sc, NGLE_REG_43, 0x404c4048);
+ hyperfb_write4(sc, NGLE_REG_44, 0x034c0348);
+ hyperfb_write4(sc, NGLE_REG_45, 0x444c4448);
+ } else {
+ hyperfb_write4(sc, NGLE_REG_40, HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES);
+ hyperfb_write4(sc, NGLE_REG_40, HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES);
+
+ hyperfb_write4(sc, NGLE_REG_42, 0);
+ hyperfb_write4(sc, NGLE_REG_43, 0);
+ hyperfb_write4(sc, NGLE_REG_44, 0);
+ hyperfb_write4(sc, NGLE_REG_45, 0x444c4048);
+ }
/* attr. planes */
hyperfb_wait(sc);
- hyperfb_write4(sc, NGLE_REG_11, 0x2ea0d000);
- hyperfb_write4(sc, NGLE_REG_14, 0x23000302);
- hyperfb_write4(sc, NGLE_REG_12, NGLE_BUFF1_CMAP0);
+ hyperfb_write4(sc, NGLE_REG_11,
+ BA(IndexedDcd, Otc32, OtsIndirect, AddrLong, 0, BINattr, 0));
+ hyperfb_write4(sc, NGLE_REG_14,
+ IBOvals(RopSrc, 0, BitmapExtent08, 1, DataDynamic, MaskOtc, 1, 0));
+ hyperfb_write4(sc, NGLE_REG_12, 0x04000F00/*NGLE_BUFF0_CMAP0*/);
hyperfb_write4(sc, NGLE_REG_8, 0xffffffff);
hyperfb_wait(sc);
@@ -765,11 +826,62 @@ hyperfb_setup(struct hyperfb_softc *sc)
* blit into offscreen memory to force flush previous - apparently
* some chips have a bug this works around
*/
+ hyperfb_wait(sc);
hyperfb_write4(sc, NGLE_REG_6, 0x05000000);
hyperfb_write4(sc, NGLE_REG_9, 0x00040001);
- hyperfb_wait(sc);
- hyperfb_write4(sc, NGLE_REG_12, 0x00000000);
+ /*
+ * on 24bit-capable hardware we:
+ * - make overlay colour 255 transparent
+ * - blit the 24bit buffer all white
+ * - install a linear ramp in CMAP 0
+ */
+ if(sc->sc_24bit) {
+ /* overlay transparency */
+ hyperfb_wait_fifo(sc, 7);
+ hyperfb_write4(sc, NGLE_REG_11, 0x13a02000);
+ hyperfb_write4(sc, NGLE_REG_14, 0x03000300);
+ hyperfb_write4(sc, NGLE_REG_3, 0x000017f0);
+ hyperfb_write4(sc, NGLE_REG_13, 0xffffffff);
+ hyperfb_write4(sc, NGLE_REG_22, 0xffffffff);
+ hyperfb_write4(sc, NGLE_REG_23, 0x0);
+
+ hyperfb_wait(sc);
+ hyperfb_write4(sc, NGLE_REG_12, 0x00000000);
+
+ /* clear 24bit buffer */
+ hyperfb_wait(sc);
+ /* plane mask */
+ hyperfb_write4(sc, NGLE_REG_13, 0xffffffff);
+ hyperfb_write4(sc, NGLE_REG_8, 0xffffffff); /* transfer data */
+ /* bitmap op */
+ hyperfb_write4(sc, NGLE_REG_14,
+ IBOvals(RopSrc, 0, BitmapExtent32, 0, DataDynamic, MaskOtc, 0, 0));
+ /* dst bitmap access */
+ hyperfb_write4(sc, NGLE_REG_11,
+ BA(IndexedDcd, Otc32, OtsIndirect, AddrLong, 0, BINapp0F8, 0));
+ hyperfb_wait_fifo(sc, 3);
+ hyperfb_write4(sc, NGLE_REG_35, 0x00ffffff); /* fg colour */
+ hyperfb_write4(sc, NGLE_REG_6, 0x00000000); /* dst xy */
+ hyperfb_write4(sc, NGLE_REG_9,
+ (sc->sc_width << 16) | sc->sc_height);
+
+ /* write a linear ramp into CMAP0 */
+ hyperfb_wait(sc);
+ hyperfb_write4(sc, NGLE_REG_10, 0xbbe0f000);
+ hyperfb_write4(sc, NGLE_REG_14, 0x03000300);
+ hyperfb_write4(sc, NGLE_REG_13, 0xffffffff);
+
+ hyperfb_wait(sc);
+ hyperfb_write4(sc, NGLE_REG_3, 0);
+ for (i = 0; i < 256; i++) {
+ hyperfb_wait(sc);
+ hyperfb_write4(sc, NGLE_REG_4, (i << 16) | (i << 8) | i);
+ }
+ hyperfb_write4(sc, NGLE_REG_2, 0x0);
+ hyperfb_write4(sc, NGLE_REG_38, LBC_ENABLE | LBC_TYPE_CMAP | 0x100);
+ hyperfb_wait(sc);
+ }
hyperfb_setup_fb(sc);
@@ -777,27 +889,7 @@ hyperfb_setup(struct hyperfb_softc *sc)
hyperfb_wait(sc);
hyperfb_write4(sc, NGLE_REG_33,
hyperfb_read4(sc, NGLE_REG_33) | 0x0a000000);
-
- /* hyperbowl */
- hyperfb_wait(sc);
- if(sc->sc_24bit) {
- /* write must happen twice because hw bug */
- hyperfb_write4(sc, NGLE_REG_40, HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE);
- hyperfb_write4(sc, NGLE_REG_40, HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE);
- hyperfb_write4(sc, NGLE_REG_39, HYPERBOWL_MODE2_8_24);
- hyperfb_write4(sc, NGLE_REG_42, 0x014c0148); /* Set lut 0 to be the direct color */
- hyperfb_write4(sc, NGLE_REG_43, 0x404c4048);
- hyperfb_write4(sc, NGLE_REG_44, 0x034c0348);
- hyperfb_write4(sc, NGLE_REG_45, 0x444c4448);
- } else {
- hyperfb_write4(sc, NGLE_REG_40, HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES);
- hyperfb_write4(sc, NGLE_REG_40, HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES);
-
- hyperfb_write4(sc, NGLE_REG_42, 0);
- hyperfb_write4(sc, NGLE_REG_43, 0);
- hyperfb_write4(sc, NGLE_REG_44, 0);
- hyperfb_write4(sc, NGLE_REG_45, 0);
- }
+
/* cursor mask */
hyperfb_wait(sc);
hyperfb_write4(sc, NGLE_REG_30, 0);
@@ -814,7 +906,7 @@ hyperfb_setup(struct hyperfb_softc *sc)
hyperfb_write4(sc, NGLE_REG_31, 0xff00ff00);
}
- /* colour map - doesn't work yet*/
+ /* colour map */
hyperfb_wait(sc);
hyperfb_write4(sc, NGLE_REG_10, 0xBBE0F000);
hyperfb_write4(sc, NGLE_REG_14, 0x03000300);
@@ -829,7 +921,7 @@ hyperfb_setup(struct hyperfb_softc *sc)
hyperfb_setup_fb(sc);
hyperfb_move_cursor(sc, 100, 100);
-
+
}
static void