1- /* $NetBSD: gffb.c,v 1.28 2025/10/06 07:51:44 macallan Exp $ */
1+ /* $NetBSD: gffb.c,v 1.29 2025/10/14 05:40:35 macallan Exp $ */
22
33/*
44 * Copyright (c) 2013 Michael Lorenz
3535 */
3636
3737#include <sys/cdefs.h>
38- __KERNEL_RCSID (0 , "$NetBSD: gffb.c,v 1.28 2025/10/06 07:51:44 macallan Exp $" );
38+ __KERNEL_RCSID (0 , "$NetBSD: gffb.c,v 1.29 2025/10/14 05:40:35 macallan Exp $" );
3939
4040#include <sys/param.h>
4141#include <sys/systm.h>
@@ -135,6 +135,7 @@ static void gffb_rop(struct gffb_softc *, int);
135135
136136static void gffb_cursor (void * , int , int , int );
137137static void gffb_putchar (void * , int , int , u_int , long );
138+ static void gffb_putchar_mono (void * , int , int , u_int , long );
138139static void gffb_copycols (void * , int , int , int , int );
139140static void gffb_erasecols (void * , int , int , int , long );
140141static void gffb_copyrows (void * , int , int , int );
@@ -279,8 +280,7 @@ gffb_attach(device_t parent, device_t self, void *aux)
279280 }
280281
281282 /*
282- * on !2MX we need to use the firmware's offset - for some reason
283- * register writes to anything other than the DACs go wrong
283+ * we need this for the unaccelerated case, aka nv40
284284 */
285285 sc -> sc_fboffset = 0 ;
286286 if (prop_dictionary_get_uint32 (dict , "address" , & addr )) {
@@ -654,8 +654,8 @@ gffb_init_screen(void *cookie, struct vcons_screen *scr,
654654 ri -> ri_stride = sc -> sc_stride ;
655655 if (sc -> sc_depth == 8 )
656656 ri -> ri_bits = sc -> sc_fbaddr + sc -> sc_fboffset ;
657- ri -> ri_flg = RI_CENTER ;
658- ri -> ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA ;
657+ ri -> ri_flg = RI_CENTER | RI_FULLCLEAR ;
658+ ri -> ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA ;
659659
660660 rasops_init (ri , 0 , 0 );
661661 ri -> ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_RESIZE ;
@@ -667,13 +667,16 @@ gffb_init_screen(void *cookie, struct vcons_screen *scr,
667667 ri -> ri_hw = scr ;
668668
669669 if (sc -> sc_accel ) {
670- sc -> sc_putchar = ri -> ri_ops .putchar ;
671670 ri -> ri_ops .copyrows = gffb_copyrows ;
672671 ri -> ri_ops .copycols = gffb_copycols ;
673672 ri -> ri_ops .eraserows = gffb_eraserows ;
674673 ri -> ri_ops .erasecols = gffb_erasecols ;
675674 ri -> ri_ops .cursor = gffb_cursor ;
676- ri -> ri_ops .putchar = gffb_putchar ;
675+ if (FONT_IS_ALPHA (ri -> ri_font )) {
676+ sc -> sc_putchar = ri -> ri_ops .putchar ;
677+ ri -> ri_ops .putchar = gffb_putchar ;
678+ } else
679+ ri -> ri_ops .putchar = gffb_putchar_mono ;
677680 } else {
678681 scr -> scr_flags |= VCONS_DONT_READ ;
679682 }
@@ -1040,7 +1043,7 @@ gffb_init(struct gffb_softc *sc)
10401043 GFFB_WRITE_4 (GFFB_PRAMIN + 0x2054 , 0 );
10411044 GFFB_WRITE_4 (GFFB_PRAMIN + 0x2058 , 0 );
10421045 GFFB_WRITE_4 (GFFB_PRAMIN + 0x205c , 0 );
1043- /* XXX 0x0100805f if !WaitVSynvPossible */
1046+ /* XXX 0x0100805f if !WaitVSyncPossible */
10441047 GFFB_WRITE_4 (GFFB_PRAMIN + 0x2060 , 0x0100805f );
10451048 GFFB_WRITE_4 (GFFB_PRAMIN + 0x2064 , 0 );
10461049 GFFB_WRITE_4 (GFFB_PRAMIN + 0x2068 , 0x12001200 );
@@ -1383,6 +1386,86 @@ gffb_putchar(void *cookie, int row, int col, u_int c, long attr)
13831386 }
13841387}
13851388
1389+ static void
1390+ gffb_putchar_mono (void * cookie , int row , int col , u_int c , long attr )
1391+ {
1392+ struct rasops_info * ri = cookie ;
1393+ struct wsdisplay_font * font = PICK_FONT (ri , c );
1394+ struct vcons_screen * scr = ri -> ri_hw ;
1395+ struct gffb_softc * sc = scr -> scr_cookie ;
1396+ void * data ;
1397+ int x , y , wi , he , rv = GC_NOPE , i ;
1398+ uint32_t bg , fg ;
1399+
1400+ if (sc -> sc_mode != WSDISPLAYIO_MODE_EMUL )
1401+ return ;
1402+
1403+ if (!CHAR_IN_FONT (c , font ))
1404+ return ;
1405+
1406+ wi = font -> fontwidth ;
1407+ he = font -> fontheight ;
1408+
1409+ x = ri -> ri_xorigin + col * wi ;
1410+ y = ri -> ri_yorigin + row * he ;
1411+ bg = ri -> ri_devcmap [(attr >> 16 ) & 0xf ];
1412+
1413+ if (c == 0x20 ) {
1414+ gffb_rectfill (sc , x , y , wi , he , bg );
1415+ return ;
1416+ }
1417+ rv = glyphcache_try (& sc -> sc_gc , c , x , y , attr );
1418+ if (rv == GC_OK )
1419+ return ;
1420+
1421+ fg = ri -> ri_devcmap [(attr >> 24 ) & 0xf ];
1422+ data = WSFONT_GLYPH (c , font );
1423+
1424+ mutex_enter (& sc -> sc_lock );
1425+
1426+ gffb_rop (sc , 0xcc );
1427+
1428+ gffb_dmastart (sc , RECT_EXPAND_TWO_COLOR_CLIP , 7 );
1429+ gffb_dmanext (sc , (y << 16 ) | (x & 0xFFFF ));
1430+ gffb_dmanext (sc , ((y + he ) << 16 ) | ((x + wi ) & 0xFFFF ));
1431+ gffb_dmanext (sc , bg );
1432+ gffb_dmanext (sc , fg );
1433+ gffb_dmanext (sc , (he << 16 ) | 32 );
1434+ gffb_dmanext (sc , (he << 16 ) | 32 );
1435+ gffb_dmanext (sc , (y << 16 ) | (x & 0xFFFF ));
1436+
1437+ gffb_dmastart (sc , RECT_EXPAND_TWO_COLOR_DATA (0 ), he );
1438+ switch (font -> stride ) {
1439+ case 1 : {
1440+ uint8_t * data8 = data ;
1441+ uint32_t reg ;
1442+ for (i = 0 ; i < he ; i ++ ) {
1443+ reg = * data8 ;
1444+ gffb_dmanext (sc , reg << 24 );
1445+ data8 ++ ;
1446+ }
1447+ break ;
1448+ }
1449+ case 2 : {
1450+ uint16_t * data16 = data ;
1451+ uint32_t reg ;
1452+ for (i = 0 ; i < he ; i ++ ) {
1453+ reg = * data16 ;
1454+ gffb_dmanext (sc , reg << 16 );
1455+ data16 ++ ;
1456+ }
1457+ break ;
1458+ }
1459+ }
1460+
1461+ gffb_dma_kickoff (sc );
1462+ mutex_exit (& sc -> sc_lock );
1463+
1464+ if (rv == GC_ADD ) {
1465+ glyphcache_add (& sc -> sc_gc , c , x , y );
1466+ }
1467+ }
1468+
13861469static void
13871470gffb_copycols (void * cookie , int row , int srccol , int dstcol , int ncols )
13881471{
@@ -1447,10 +1530,18 @@ gffb_eraserows(void *cookie, int row, int nrows, long fillattr)
14471530 int32_t x , y , width , height , fg , bg , ul ;
14481531
14491532 if ((sc -> sc_locked == 0 ) && (sc -> sc_mode == WSDISPLAYIO_MODE_EMUL )) {
1450- x = ri -> ri_xorigin ;
1451- y = ri -> ri_yorigin + ri -> ri_font -> fontheight * row ;
1452- width = ri -> ri_emuwidth ;
1453- height = ri -> ri_font -> fontheight * nrows ;
1533+ if ((row == 0 ) && (nrows == ri -> ri_emuheight )) {
1534+ /* fullclear */
1535+ x = 0 ;
1536+ y = 0 ;
1537+ width = sc -> sc_width ;
1538+ height = sc -> sc_height ;
1539+ } else {
1540+ x = ri -> ri_xorigin ;
1541+ y = ri -> ri_yorigin + ri -> ri_font -> fontheight * row ;
1542+ width = ri -> ri_emuwidth ;
1543+ height = ri -> ri_font -> fontheight * nrows ;
1544+ }
14541545 rasops_unpack_attr (fillattr , & fg , & bg , & ul );
14551546
14561547 gffb_rectfill (sc , x , y , width , height , ri -> ri_devcmap [bg ]);
0 commit comments