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