Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/sbus support screen blanking and hw cursor



details:   https://anonhg.NetBSD.org/src/rev/ad5b25341c9d
branches:  trunk
changeset: 343527:ad5b25341c9d
user:      macallan <macallan%NetBSD.org@localhost>
date:      Thu Feb 11 20:53:06 2016 +0000

description:
support screen blanking and hw cursor

diffstat:

 sys/dev/sbus/mgx.c    |  185 ++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/dev/sbus/mgxreg.h |   15 ++-
 2 files changed, 189 insertions(+), 11 deletions(-)

diffs (truncated from 303 to 300 lines):

diff -r 0b596a4b085c -r ad5b25341c9d sys/dev/sbus/mgx.c
--- a/sys/dev/sbus/mgx.c        Thu Feb 11 19:21:04 2016 +0000
+++ b/sys/dev/sbus/mgx.c        Thu Feb 11 20:53:06 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mgx.c,v 1.5 2016/02/11 02:23:44 macallan Exp $ */
+/*     $NetBSD: mgx.c,v 1.6 2016/02/11 20:53:06 macallan Exp $ */
 
 /*-
  * Copyright (c) 2014 Michael Lorenz
@@ -29,7 +29,7 @@
 /* a console driver for the SSB 4096V-MGX graphics card */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.5 2016/02/11 02:23:44 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.6 2016/02/11 20:53:06 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -67,6 +67,7 @@
        bus_space_handle_t sc_vgah;
        bus_addr_t      sc_paddr;
        void            *sc_fbaddr;
+       uint8_t         *sc_cursor;
        int             sc_width;
        int             sc_height;
        int             sc_stride;
@@ -78,6 +79,9 @@
        u_char          sc_cmap_red[256];
        u_char          sc_cmap_green[256];
        u_char          sc_cmap_blue[256];
+       int             sc_cursor_x, sc_cursor_y;
+       int             sc_hotspot_x, sc_hotspot_y;
+       int             sc_video;
        void (*sc_putchar)(void *, int, int, u_int, long);
        struct vcons_screen sc_console_screen;
        struct wsscreen_descr sc_defaultscreen_descr;
@@ -113,6 +117,10 @@
 static void    mgx_copyrows(void *, int, int, int);
 static void    mgx_eraserows(void *, int, int, long);
 
+static int     mgx_do_cursor(struct mgx_softc *, struct wsdisplay_cursor *);
+static void    mgx_set_cursor(struct mgx_softc *);
+static void    mgx_set_video(struct mgx_softc *, int);
+
 CFATTACH_DECL_NEW(mgx, sizeof(struct mgx_softc),
     mgx_match, mgx_attach, NULL, NULL);
 
@@ -152,6 +160,12 @@
 }
 
 static inline void
+mgx_write_2(struct mgx_softc *sc, uint32_t reg, uint16_t val)
+{
+       bus_space_write_2(sc->sc_tag, sc->sc_blith, reg ^ 2, val);
+}
+
+static inline void
 mgx_write_4(struct mgx_softc *sc, uint32_t reg, uint32_t val)
 {
        bus_space_write_4(sc->sc_tag, sc->sc_blith, reg, val);
@@ -240,6 +254,13 @@
                WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
                NULL
        };
+       
+       sc->sc_cursor_x = 0;
+       sc->sc_cursor_y = 0;
+       sc->sc_hotspot_x = 0;
+       sc->sc_hotspot_y = 0;
+       sc->sc_video = WSDISPLAYIO_VIDEO_ON;
+
        sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
        sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
 
@@ -526,6 +547,17 @@
        mgx_write_vga(sc, CRTC_DATA, stride & 0xff);
        mgx_write_vga(sc, CRTC_INDEX, 0x1c);
        mgx_write_vga(sc, CRTC_DATA, (stride & 0xf00) >> 4);
+
+       /* clean up the screen if we're switching to != 8bit */
+       if (depth != MGX_DEPTH) 
+               mgx_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, 0); 
+
+       /* initialize hardware cursor stuff */
+       mgx_write_2(sc, ATR_CURSOR_ADDRESS, (sc->sc_fbsize - 1024) >> 10);
+       mgx_write_1(sc, ATR_CURSOR_ENABLE, 0);
+       sc->sc_cursor = (uint8_t *)sc->sc_fbaddr + sc->sc_fbsize - 1024;
+       memset(sc->sc_cursor, 0xf0, 1024);
+
 #ifdef MGX_DEBUG
        int j;
        mgx_write_vga(sc, SEQ_INDEX, 0x10);
@@ -812,11 +844,12 @@
 
                case FBIOGVIDEO:
                case WSDISPLAYIO_GVIDEO:
-                       *(int *)data = 1;
+                       *(int *)data = sc->sc_video;
                        return 0;
 
                case WSDISPLAYIO_SVIDEO:
                case FBIOSVIDEO:
+                       mgx_set_video(sc, *(int *)data);
                        return 0;
 
                case WSDISPLAYIO_LINEBYTES:
@@ -852,11 +885,45 @@
                case WSDISPLAYIO_PUTCMAP:
                        return mgx_putcmap(sc, (struct wsdisplay_cmap *)data);
 
+               case WSDISPLAYIO_GCURPOS:
+                       {
+                               struct wsdisplay_curpos *cp = (void *)data;
+
+                               cp->x = sc->sc_cursor_x;
+                               cp->y = sc->sc_cursor_y;
+                       }
+                       return 0;
+
+               case WSDISPLAYIO_SCURPOS:
+                       {
+                               struct wsdisplay_curpos *cp = (void *)data;
+
+                               sc->sc_cursor_x = cp->x;
+                               sc->sc_cursor_y = cp->y;
+                               mgx_set_cursor(sc);
+                       }
+                       return 0;
+
+               case WSDISPLAYIO_GCURMAX:
+                       {
+                               struct wsdisplay_curpos *cp = (void *)data;
+
+                               cp->x = 64;
+                               cp->y = 64;
+                       }
+                       return 0;
+
+               case WSDISPLAYIO_SCURSOR:
+                       {
+                               struct wsdisplay_cursor *cursor = (void *)data;
+
+                               return mgx_do_cursor(sc, cursor);
+                       }
                case WSDISPLAYIO_GET_FBINFO:
                        {
                                struct wsdisplayio_fbinfo *fbi = data;
                                
-                               fbi->fbi_fbsize = sc->sc_fbsize;
+                               fbi->fbi_fbsize = sc->sc_fbsize - 1024;
                                fbi->fbi_width = sc->sc_width;
                                fbi->fbi_height = sc->sc_height;
                                fbi->fbi_bitsperpixel = sc->sc_depth;
@@ -890,3 +957,113 @@
 
        return -1;
 }
+
+static int
+mgx_do_cursor(struct mgx_softc *sc, struct wsdisplay_cursor *cur)
+{
+       int i;
+       if (cur->which & WSDISPLAY_CURSOR_DOCUR) {
+
+               if (cur->enable) {
+                       mgx_set_cursor(sc);
+                       mgx_write_1(sc, ATR_CURSOR_ENABLE, 1);
+               } else {
+                       mgx_write_1(sc, ATR_CURSOR_ENABLE, 0);
+               }
+       }
+       if (cur->which & WSDISPLAY_CURSOR_DOHOT) {
+
+               sc->sc_hotspot_x = cur->hot.x;
+               sc->sc_hotspot_y = cur->hot.y;
+               mgx_set_cursor(sc);
+       }
+       if (cur->which & WSDISPLAY_CURSOR_DOPOS) {
+
+               sc->sc_cursor_x = cur->pos.x;
+               sc->sc_cursor_y = cur->pos.y;
+               mgx_set_cursor(sc);
+       }
+       if (cur->which & WSDISPLAY_CURSOR_DOCMAP) {
+               int cnt = min(2, cur->cmap.count);
+               uint8_t c;
+               uint8_t r[2], g[2], b[2];
+
+               copyin(cur->cmap.red, r, cnt);
+               copyin(cur->cmap.green, g, cnt);
+               copyin(cur->cmap.blue, b, cnt);
+       
+               for (i = 0; i < cnt; i++) {
+                       c = r[i] & 0xe0;
+                       c |= (g[i] & 0xe0) >> 3;
+                       c |= (b[i] & 0xc0) >> 6;
+                       mgx_write_1(sc, ATR_CURSOR_FG + i, c);
+               }
+       }
+       if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) {
+               int j;
+               uint8_t *fb = sc->sc_cursor;
+               uint8_t temp;
+               uint8_t im, ma, px;
+
+               for (i = 0; i < 512; i++) {
+                       temp = 0;
+                       copyin(&cur->image[i], &im, 1);
+                       copyin(&cur->mask[i], &ma, 1);
+                       for (j = 0; j < 4; j++) {
+                               temp >>= 2;
+                               px = (ma & 1) ? 0 : 0x80;
+                               if (px == 0)
+                                       px |= (im & 1) ? 0 : 0x40;
+                               temp |= px;
+                               im >>= 1;
+                               ma >>= 1;
+                       }
+                       *fb = temp;
+                       fb++;
+                       temp = 0;
+                       for (j = 0; j < 4; j++) {
+                               temp >>= 2;
+                               px = (ma & 1) ? 0 : 0x80;
+                               if (px == 0)
+                                       px |= (im & 1) ? 0 : 0x40;
+                               temp |= px;
+                               im >>= 1;
+                               ma >>= 1;
+                       }
+                       *fb = temp;
+                       fb++;
+               }
+       }
+       return 0;
+}
+
+static void
+mgx_set_cursor(struct mgx_softc *sc)
+{
+       uint32_t reg;
+       uint16_t hot;
+
+       reg = (sc->sc_cursor_y << 16) | (sc->sc_cursor_x & 0xffff);
+       mgx_write_4(sc, ATR_CURSOR_POSITION, reg);
+       hot = (sc->sc_hotspot_y << 8) | (sc->sc_hotspot_x & 0xff);
+       mgx_write_2(sc, ATR_CURSOR_HOTSPOT, hot);
+}
+
+static void
+mgx_set_video(struct mgx_softc *sc, int v)
+{
+       uint8_t reg;
+
+       if (sc->sc_video == v)
+               return;
+
+       sc->sc_video = v;
+       reg = mgx_read_1(sc, ATR_DPMS);
+
+       if (v == WSDISPLAYIO_VIDEO_ON) {
+               reg &= ~DPMS_SYNC_DISABLE_ALL;
+       } else {
+               reg |= DPMS_SYNC_DISABLE_ALL;
+       }
+       mgx_write_1(sc, ATR_DPMS, reg);
+}
diff -r 0b596a4b085c -r ad5b25341c9d sys/dev/sbus/mgxreg.h
--- a/sys/dev/sbus/mgxreg.h     Thu Feb 11 19:21:04 2016 +0000
+++ b/sys/dev/sbus/mgxreg.h     Thu Feb 11 20:53:06 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mgxreg.h,v 1.3 2016/02/11 02:23:44 macallan Exp $ */
+/*     $NetBSD: mgxreg.h,v 1.4 2016/02/11 20:53:06 macallan Exp $ */
 
 /* register definitions based on OpenBSD's atxxreg.h: */
 
@@ -178,6 +178,7 @@
 #define ATR_DPMS                        0x00d0  /* byte access */
 #define DPMS_HSYNC_DISABLE              0x01
 #define DPMS_VSYNC_DISABLE              0x02
+#define DPMS_SYNC_DISABLE_ALL          0x03
 
 /*
  * RAMDAC
@@ -195,12 +196,12 @@
  * cross the upper-left corner.
  */
 
-#define ATR_CURSOR_ENABLE               0x0140
-#define ATR_CURSOR_FG                   0x0141  /* 3:3:2 */
-#define ATR_CURSOR_BG                   0x0142  /* 3:3:2 */
-#define ATR_CURSOR_ADDRESS              0x0144  /* in KB from vram */
-#define ATR_CURSOR_POSITION             0x0148
-#define ATR_CURSOR_OFFSET               0x014c  /* short access */
+#define ATR_CURSOR_ENABLE              0x0140
+#define ATR_CURSOR_FG                  0x0141  /* 3:3:2 */
+#define ATR_CURSOR_BG                  0x0142  /* 3:3:2 */
+#define ATR_CURSOR_ADDRESS             0x0144  /* in KB from vram */
+#define ATR_CURSOR_POSITION            0x0148
+#define ATR_CURSOR_HOTSPOT             0x014c  /* short access */



Home | Main Index | Thread Index | Old Index