1- /* $NetBSD: hyperfb.c,v 1.27 2025/12/15 12:43:16 macallan Exp $ */
1+ /* $NetBSD: hyperfb.c,v 1.28 2026/01/20 14:33:25 macallan Exp $ */
22
33/*
44 * Copyright (c) 2024 Michael Lorenz
3232 */
3333
3434#include <sys/cdefs.h>
35- __KERNEL_RCSID (0 , "$NetBSD: hyperfb.c,v 1.27 2025/12/15 12:43:16 macallan Exp $" );
35+ __KERNEL_RCSID (0 , "$NetBSD: hyperfb.c,v 1.28 2026/01/20 14:33:25 macallan Exp $" );
3636
3737#include "opt_cputype.h"
3838#include "opt_hyperfb.h"
@@ -69,7 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: hyperfb.c,v 1.27 2025/12/15 12:43:16 macallan Exp $"
6969#define HCRX_FBOFFSET 0x01000000
7070#define HCRX_FBLEN 0x01000000
7171#define HCRX_REGOFFSET 0x00100000
72- #define HCRX_REGLEN 0x00280000
72+ #define HCRX_REGLEN 0x00290000
7373
7474#define HCRX_CONFIG_24BIT 0x100
7575
@@ -95,10 +95,7 @@ struct hyperfb_softc {
9595 u_char sc_cmap_green [256 ];
9696 u_char sc_cmap_blue [256 ];
9797 kmutex_t sc_hwlock ;
98- uint32_t sc_hwmode ;
99- #define HW_FB 0
100- #define HW_FILL 1
101- #define HW_BLIT 2
98+ uint32_t sc_sba , sc_dba ;
10299 /* cursor stuff */
103100 int sc_cursor_x , sc_cursor_y ;
104101 int sc_hot_x , sc_hot_y , sc_enabled ;
@@ -203,6 +200,26 @@ hyperfb_wait_fifo(struct hyperfb_softc *sc, uint32_t slots)
203200 } while (reg < slots );
204201}
205202
203+ static inline void
204+ hyperfb_sba (struct hyperfb_softc * sc , uint32_t mode )
205+ {
206+ if (sc -> sc_sba != mode ) {
207+ hyperfb_wait (sc );
208+ hyperfb_write4 (sc , NGLE_SBA , mode );
209+ sc -> sc_sba = mode ;
210+ }
211+ }
212+
213+ static inline void
214+ hyperfb_dba (struct hyperfb_softc * sc , uint32_t mode )
215+ {
216+ if (sc -> sc_dba != mode ) {
217+ hyperfb_wait_fifo (sc , 2 );
218+ hyperfb_write4 (sc , NGLE_DBA , mode );
219+ sc -> sc_dba = mode ;
220+ }
221+ }
222+
206223static inline void
207224hyperfb_setup_fb (struct hyperfb_softc * sc )
208225{
@@ -213,34 +230,36 @@ hyperfb_setup_fb(struct hyperfb_softc *sc)
213230 */
214231 hyperfb_wait (sc );
215232 if ((sc -> sc_mode != WSDISPLAYIO_MODE_EMUL ) && sc -> sc_24bit ) {
216- hyperfb_write4 (sc , NGLE_BAboth ,
233+ hyperfb_sba (sc ,
234+ BA (FractDcd , Otc01 , Ots08 , AddrLong , 0 , BINapp0F8 , 0 ));
235+ hyperfb_dba (sc ,
217236 BA (FractDcd , Otc01 , Ots08 , AddrLong , 0 , BINapp0F8 , 0 ));
218237 hyperfb_write4 (sc , NGLE_PLANEMASK , 0xffffffff );
219238 } else {
220- hyperfb_write4 (sc , NGLE_BAboth ,
239+ hyperfb_sba (sc ,
240+ BA (IndexedDcd , Otc04 , Ots08 , AddrByte , 0 , BINovly , 0 ));
241+ hyperfb_dba (sc ,
221242 BA (IndexedDcd , Otc04 , Ots08 , AddrByte , 0 , BINovly , 0 ));
222243 hyperfb_write4 (sc , NGLE_PLANEMASK , 0xff );
223244 }
224245 hyperfb_write4 (sc , NGLE_IBO , 0x83000300 );
225246 //IBOvals(RopSrc, 0, BitmapExtent08, 0, DataDynamic, 1, 0, 0);
226247 hyperfb_wait (sc );
227248 hyperfb_write1 (sc , NGLE_CONTROL_FB , 1 );
228- sc -> sc_hwmode = HW_FB ;
229249}
230250
231251static inline void
232252hyperfb_setup_fb24 (struct hyperfb_softc * sc )
233253{
234254
235255 hyperfb_wait (sc );
236- hyperfb_write4 (sc , NGLE_BAboth ,
237- BA (FractDcd , Otc01 , Ots08 , AddrLong , 0 , BINapp0F8 , 0 ));
256+ hyperfb_sba (sc , BA ( FractDcd , Otc01 , Ots08 , AddrLong , 0 , BINapp0F8 , 0 ));
257+ hyperfb_dba ( sc , BA (FractDcd , Otc01 , Ots08 , AddrLong , 0 , BINapp0F8 , 0 ));
238258 hyperfb_write4 (sc , NGLE_PLANEMASK , 0xffffffff );
239259 hyperfb_write4 (sc , NGLE_IBO , 0x83000300 );
240260 //IBOvals(RopSrc,0,BitmapExtent08,0,DataDynamic,1,0,0)
241261 hyperfb_wait (sc );
242262 hyperfb_write1 (sc , NGLE_CONTROL_FB , 1 );
243- sc -> sc_hwmode = HW_FB ;
244263}
245264
246265int
@@ -340,6 +359,7 @@ hyperfb_attach(device_t parent, device_t self, void *aux)
340359 sc -> sc_is_console = (ca -> ca_hpa == consaddr );
341360 sc -> sc_width = 1280 ;
342361 sc -> sc_height = 1024 ;
362+ sc -> sc_sba = sc -> sc_dba = 0 ;
343363
344364 /* we can *not* be interrupted when doing colour map accesses */
345365 mutex_init (& sc -> sc_hwlock , MUTEX_DEFAULT , IPL_HIGH );
@@ -451,6 +471,12 @@ hyperfb_attach(device_t parent, device_t self, void *aux)
451471 config_found (sc -> sc_dev , & aa , wsemuldisplaydevprint , CFARGS_NONE );
452472
453473 hyperfb_setup_fb (sc );
474+ {
475+ int i ;
476+ for (i = 0 ; i < 128 ; i += 4 ) {
477+ printf ("%08x: %08x\n" , i + 0x38000 , hyperfb_read4 (sc , i + 0x38000 ));
478+ }
479+ }
454480}
455481
456482static void
@@ -722,11 +748,9 @@ static int
722748hyperfb_putpalreg (struct hyperfb_softc * sc , uint8_t idx , uint8_t r , uint8_t g ,
723749 uint8_t b )
724750{
725-
726751 mutex_enter (& sc -> sc_hwlock );
727- hyperfb_wait (sc );
728- hyperfb_write4 (sc , NGLE_BAboth ,
729- BA (FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
752+ hyperfb_sba (sc , BA (FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
753+ hyperfb_dba (sc , BA (FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
730754 hyperfb_write4 (sc , NGLE_IBO ,
731755 IBOvals (RopSrc , 0 , BitmapExtent08 , 0 , DataDynamic , MaskOtc , 0 , 0 )); // 0x03000300
732756 hyperfb_write4 (sc , NGLE_PLANEMASK , 0xffffffff );
@@ -737,6 +761,7 @@ hyperfb_putpalreg(struct hyperfb_softc *sc, uint8_t idx, uint8_t r, uint8_t g,
737761
738762 hyperfb_write4 (sc , NGLE_BINC_SRC , 0x400 );
739763 hyperfb_write4 (sc , NGLE_HCRX_LUTBLT , 0x82000100 );
764+ // LBC_ENABLE | (0x200 << OFFSET_SHIFT) | LBC_TYPE_CMAP | 0x100
740765 hyperfb_setup_fb (sc );
741766 mutex_exit (& sc -> sc_hwlock );
742767 return 0 ;
@@ -747,7 +772,6 @@ hyperfb_setup(struct hyperfb_softc *sc)
747772{
748773 int i ;
749774
750- sc -> sc_hwmode = HW_FB ;
751775 sc -> sc_hot_x = 0 ;
752776 sc -> sc_hot_y = 0 ;
753777 sc -> sc_enabled = 0 ;
@@ -796,15 +820,13 @@ hyperfb_setup(struct hyperfb_softc *sc)
796820 * Then there are HYPER_CMAP* defines with yet another set of
797821 * different values that aren't used anywhere.
798822 */
799- hyperfb_wait (sc );
800- hyperfb_write4 (sc , NGLE_DBA ,
823+ hyperfb_dba (sc ,
801824 BA (IndexedDcd , Otc32 , OtsIndirect , AddrLong , 0 , BINattr , 0 ));
825+ hyperfb_wait_fifo (sc , 5 );
802826 hyperfb_write4 (sc , NGLE_IBO ,
803827 IBOvals (RopSrc , 0 , BitmapExtent08 , 1 , DataDynamic , MaskOtc , 1 , 0 ));
804828 hyperfb_write4 (sc , NGLE_CPR , 0x04000F00 );
805829 hyperfb_write4 (sc , NGLE_TRANSFER_DATA , 0xffffffff );
806-
807- hyperfb_wait (sc );
808830 hyperfb_write4 (sc , NGLE_DST_XY , 0x00000000 );
809831 hyperfb_write4 (sc , NGLE_RECT_SIZE_START ,
810832 (sc -> sc_width << 16 ) | sc -> sc_height );
@@ -825,7 +847,7 @@ hyperfb_setup(struct hyperfb_softc *sc)
825847 if (sc -> sc_24bit ) {
826848 /* overlay transparency */
827849 hyperfb_wait_fifo (sc , 7 );
828- hyperfb_write4 (sc , NGLE_DBA ,
850+ hyperfb_dba (sc ,
829851 BA (IndexedDcd , Otc04 , Ots08 , AddrLong , 0 , BINovly , 0 ));
830852 hyperfb_write4 (sc , NGLE_IBO ,
831853 IBOvals (RopSrc , 0 , BitmapExtent08 , 0 , DataDynamic , MaskOtc ,
@@ -852,7 +874,7 @@ hyperfb_setup(struct hyperfb_softc *sc)
852874 IBOvals (RopSrc , 0 , BitmapExtent32 , 0 , DataDynamic , MaskOtc ,
853875 0 , 0 ));
854876 /* dst bitmap access */
855- hyperfb_write4 (sc , NGLE_DBA ,
877+ hyperfb_dba (sc ,
856878 BA (FractDcd , Otc32 , OtsIndirect , AddrLong , 0 , BINapp0F8 ,
857879 0 ));
858880 hyperfb_wait_fifo (sc , 3 );
@@ -862,9 +884,11 @@ hyperfb_setup(struct hyperfb_softc *sc)
862884 (sc -> sc_width << 16 ) | sc -> sc_height );
863885
864886 /* write a linear ramp into CMAP0 */
865- hyperfb_wait (sc );
866- hyperfb_write4 (sc , NGLE_BAboth ,
867- BA (FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
887+ hyperfb_sba (sc ,
888+ BA (FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
889+ hyperfb_dba (sc ,
890+ BA (FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
891+ hyperfb_wait_fifo (sc , 2 );
868892 hyperfb_write4 (sc , NGLE_IBO ,
869893 IBOvals (RopSrc , 0 , BitmapExtent08 , 0 , DataDynamic , MaskOtc , 0 , 0 )); // 0x03000300
870894 hyperfb_write4 (sc , NGLE_PLANEMASK , 0xffffffff );
@@ -906,9 +930,9 @@ hyperfb_setup(struct hyperfb_softc *sc)
906930 }
907931
908932 /* colour map */
909- hyperfb_wait (sc );
910- hyperfb_write4 (sc , NGLE_BAboth ,
911- BA ( FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
933+ hyperfb_sba (sc , BA ( FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
934+ hyperfb_dba (sc , BA ( FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
935+ hyperfb_wait_fifo ( sc , 2 );
912936 hyperfb_write4 (sc , NGLE_IBO ,
913937 IBOvals (RopSrc , 0 , BitmapExtent08 , 0 , DataDynamic , MaskOtc , 0 , 0 )); // 0x03000300
914938 hyperfb_write4 (sc , NGLE_PLANEMASK , 0xffffffff );
@@ -947,20 +971,12 @@ hyperfb_set_video(struct hyperfb_softc *sc, int on)
947971static inline void
948972hyperfb_fillmode (struct hyperfb_softc * sc )
949973{
950- if (sc -> sc_hwmode != HW_FILL ) {
951- hyperfb_wait_fifo (sc , 3 );
952- /* plane mask */
953- hyperfb_write4 (sc , NGLE_PLANEMASK , 0xff );
954- /* bitmap op */
955- hyperfb_write4 (sc , NGLE_IBO ,
956- IBOvals (RopSrc , 0 , BitmapExtent08 , 1 , DataDynamic , 0 ,
957- 0 , 0 ));
958- /* dst bitmap access */
959- hyperfb_write4 (sc , NGLE_DBA ,
960- BA (IndexedDcd , Otc32 , OtsIndirect , AddrLong , 0 , BINovly ,
961- 0 ));
962- sc -> sc_hwmode = HW_FILL ;
963- }
974+ hyperfb_dba (sc ,
975+ BA (IndexedDcd , Otc32 , OtsIndirect , AddrLong , 0 , BINovly , 0 ));
976+ hyperfb_wait_fifo (sc , 3 );
977+ hyperfb_write4 (sc , NGLE_PLANEMASK , 0xff );
978+ hyperfb_write4 (sc , NGLE_IBO ,
979+ IBOvals (RopSrc , 0 , BitmapExtent08 , 1 , DataDynamic , 0 , 0 , 0 ));
964980}
965981
966982static void
@@ -979,9 +995,7 @@ hyperfb_rectfill(struct hyperfb_softc *sc, int x, int y, int wi, int he,
979995 hyperfb_write4 (sc , NGLE_TRANSFER_DATA , 0xffffffff );
980996
981997 hyperfb_write4 (sc , NGLE_FG , bg );
982- /* dst XY */
983998 hyperfb_write4 (sc , NGLE_DST_XY , (x << 16 ) | y );
984- /* len XY start */
985999 hyperfb_write4 (sc , NGLE_RECT_SIZE_START , (wi << 16 ) | he );
9861000}
9871001
@@ -991,14 +1005,10 @@ hyperfb_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi,
9911005{
9921006 struct hyperfb_softc * sc = cookie ;
9931007
994- if (sc -> sc_hwmode != HW_BLIT ) {
995- hyperfb_wait (sc );
996- hyperfb_write4 (sc , NGLE_BAboth ,
997- BA (IndexedDcd , Otc04 , Ots08 , AddrLong , 0 , BINovly , 0 ));
998- hyperfb_write4 (sc , NGLE_PLANEMASK , 0xff );
999- sc -> sc_hwmode = HW_BLIT ;
1000- }
1001- hyperfb_wait_fifo (sc , 4 );
1008+ hyperfb_sba (sc , BA (IndexedDcd , Otc04 , Ots08 , AddrLong , 0 , BINovly , 0 ));
1009+ hyperfb_dba (sc , BA (IndexedDcd , Otc04 , Ots08 , AddrLong , 0 , BINovly , 0 ));
1010+ hyperfb_wait_fifo (sc , 5 );
1011+ hyperfb_write4 (sc , NGLE_PLANEMASK , 0xff );
10021012 hyperfb_write4 (sc , NGLE_IBO , ((rop << 8 ) & 0xf00 ) | 0x23000000 );
10031013 /* IBOvals(rop, 0, BitmapExtent08, 1, DataDynamic, MaskOtc, 0, 0) */
10041014 hyperfb_write4 (sc , NGLE_SRC_XY , (xs << 16 ) | ys );
@@ -1278,9 +1288,11 @@ hyperfb_do_cursor(struct hyperfb_softc *sc, struct wsdisplay_cursor *cur)
12781288 copyin (cur -> cmap .green , g , 2 );
12791289 copyin (cur -> cmap .red , r , 2 );
12801290 mutex_enter (& sc -> sc_hwlock );
1281- hyperfb_wait (sc );
1282- hyperfb_write4 (sc , NGLE_BAboth ,
1291+ hyperfb_sba (sc ,
12831292 BA (FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
1293+ hyperfb_dba (sc ,
1294+ BA (FractDcd , Otc01 , Ots08 , Addr24 , 0 , BINcmap , 0 )); // 0xbbe0f000
1295+ hyperfb_wait_fifo (sc , 2 );
12841296 hyperfb_write4 (sc , NGLE_IBO ,
12851297 IBOvals (RopSrc , 0 , BitmapExtent08 , 0 , DataDynamic , MaskOtc , 0 , 0 )); // 0x03000300
12861298 hyperfb_write4 (sc , NGLE_PLANEMASK , 0xffffffff );
@@ -1296,7 +1308,6 @@ hyperfb_do_cursor(struct hyperfb_softc *sc, struct wsdisplay_cursor *cur)
12961308
12971309 hyperfb_setup_fb (sc );
12981310 mutex_exit (& sc -> sc_hwlock );
1299-
13001311 }
13011312 if (cur -> which & WSDISPLAY_CURSOR_DOSHAPE ) {
13021313 uint32_t buffer [128 ], latch , tmp ;
0 commit comments