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