Module Name: src
Committed By: macallan
Date: Thu Feb 11 02:23:44 UTC 2016
Modified Files:
src/sys/dev/sbus: files.sbus mgx.c mgxreg.h
Log Message:
switch to 32bit colour in WSDISPLAYIO_MODE_MAPPED, now X with wsfb will work
Not optimal though - for some reason the framebuffer's endianness in 32bit
colour is wrong and I have no idea (yet) how to change that, so many apps
using xrender will crash.
To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/sys/dev/sbus/files.sbus
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/sbus/mgx.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/sbus/mgxreg.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/sbus/files.sbus
diff -u src/sys/dev/sbus/files.sbus:1.41 src/sys/dev/sbus/files.sbus:1.42
--- src/sys/dev/sbus/files.sbus:1.41 Sun Jan 4 18:18:20 2015
+++ src/sys/dev/sbus/files.sbus Thu Feb 11 02:23:44 2016
@@ -1,4 +1,4 @@
-# $NetBSD: files.sbus,v 1.41 2015/01/04 18:18:20 macallan Exp $
+# $NetBSD: files.sbus,v 1.42 2016/02/11 02:23:44 macallan Exp $
#
# Config file and device description for machine-independent SBUS code.
# Included by ports that need it.
@@ -156,7 +156,8 @@ attach cgtwelve at sbus
file dev/sbus/cgtwelve.c cgtwelve
# SSB MGX
-defflag opt_mgx.h MGX_DEBUG
-device mgx: fb, rasops8, wsemuldisplaydev, vcons, glyphcache
+defflag opt_mgx.h MGX_DEBUG
+defparam opt_mgx.h MGX_DEPTH=8
+device mgx: fb, rasops8, rasops32, wsemuldisplaydev, vcons, glyphcache
attach mgx at sbus
file dev/sbus/mgx.c mgx
Index: src/sys/dev/sbus/mgx.c
diff -u src/sys/dev/sbus/mgx.c:1.4 src/sys/dev/sbus/mgx.c:1.5
--- src/sys/dev/sbus/mgx.c:1.4 Tue Jan 6 17:41:30 2015
+++ src/sys/dev/sbus/mgx.c Thu Feb 11 02:23:44 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: mgx.c,v 1.4 2015/01/06 17:41:30 macallan Exp $ */
+/* $NetBSD: mgx.c,v 1.5 2016/02/11 02:23:44 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.4 2015/01/06 17:41:30 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.5 2016/02/11 02:23:44 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -58,7 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.4
#include <dev/sbus/mgxreg.h>
#include "opt_wsemul.h"
-
+#include "opt_mgx.h"
struct mgx_softc {
device_t sc_dev;
@@ -70,8 +70,10 @@ struct mgx_softc {
int sc_width;
int sc_height;
int sc_stride;
+ int sc_depth;
int sc_fbsize;
int sc_mode;
+ char sc_name[8];
uint32_t sc_dec;
u_char sc_cmap_red[256];
u_char sc_cmap_green[256];
@@ -98,6 +100,7 @@ static void mgx_init_palette(struct mgx_
static int mgx_putcmap(struct mgx_softc *, struct wsdisplay_cmap *);
static int mgx_getcmap(struct mgx_softc *, struct wsdisplay_cmap *);
static int mgx_wait_engine(struct mgx_softc *);
+static int mgx_wait_host(struct mgx_softc *);
static int mgx_wait_fifo(struct mgx_softc *, unsigned int);
static void mgx_bitblt(void *, int, int, int, int, int, int, int);
@@ -124,6 +127,36 @@ struct wsdisplay_accessops mgx_accessops
NULL, /* scroll */
};
+static inline void
+mgx_write_vga(struct mgx_softc *sc, uint32_t reg, uint8_t val)
+{
+ bus_space_write_1(sc->sc_tag, sc->sc_vgah, reg ^ 3, val);
+}
+
+static inline uint8_t
+mgx_read_vga(struct mgx_softc *sc, uint32_t reg)
+{
+ return bus_space_read_1(sc->sc_tag, sc->sc_vgah, reg ^ 3);
+}
+
+static inline void
+mgx_write_1(struct mgx_softc *sc, uint32_t reg, uint8_t val)
+{
+ bus_space_write_1(sc->sc_tag, sc->sc_blith, reg ^ 3, val);
+}
+
+static inline uint8_t
+mgx_read_1(struct mgx_softc *sc, uint32_t reg)
+{
+ return bus_space_read_1(sc->sc_tag, sc->sc_blith, reg ^ 3);
+}
+
+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);
+}
+
static int
mgx_match(device_t parent, cfdata_t cf, void *aux)
{
@@ -159,8 +192,8 @@ mgx_attach(device_t parent, device_t sel
/* read geometry information from the device tree */
sc->sc_width = prom_getpropint(sa->sa_node, "width", 1152);
sc->sc_height = prom_getpropint(sa->sa_node, "height", 900);
- sc->sc_stride = prom_getpropint(sa->sa_node, "linebytes", 900);
- sc->sc_fbsize = sc->sc_height * sc->sc_stride;
+ sc->sc_stride = prom_getpropint(sa->sa_node, "linebytes", 1152);
+ sc->sc_fbsize = prom_getpropint(sa->sa_node, "fb_size", 0x00400000);
sc->sc_fbaddr = NULL;
if (sc->sc_fbaddr == NULL) {
if (sbus_bus_map(sa->sa_bustag,
@@ -169,14 +202,12 @@ mgx_attach(device_t parent, device_t sel
sc->sc_fbsize,
BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
&bh) != 0) {
- aprint_error_dev(self, "cannot map framebuffer\n");
+ aprint_error_dev(self, "couldn't map framebuffer\n");
return;
}
sc->sc_fbaddr = bus_space_vaddr(sa->sa_bustag, bh);
}
- aprint_normal_dev(self, "%d x %d\n", sc->sc_width, sc->sc_height);
-
if (sbus_bus_map(sa->sa_bustag,
sa->sa_slot,
sa->sa_reg[4].oa_base, 0x1000, 0,
@@ -195,7 +226,11 @@ mgx_attach(device_t parent, device_t sel
return;
}
- mgx_setup(sc, 8);
+ mgx_setup(sc, MGX_DEPTH);
+
+ aprint_normal_dev(self, "[%s] %d MB framebuffer, %d x %d\n",
+ sc->sc_name, sc->sc_fbsize >> 20, sc->sc_width, sc->sc_height);
+
sc->sc_defaultscreen_descr = (struct wsscreen_descr) {
"default",
@@ -253,33 +288,21 @@ mgx_attach(device_t parent, device_t sel
aa.accesscookie = &sc->vd;
config_found(self, &aa, wsemuldisplaydevprint);
-}
-
-static inline void
-mgx_write_vga(struct mgx_softc *sc, uint32_t reg, uint8_t val)
-{
- bus_space_write_1(sc->sc_tag, sc->sc_vgah, reg ^ 3, val);
-}
-
-static inline void
-mgx_write_1(struct mgx_softc *sc, uint32_t reg, uint8_t val)
-{
- bus_space_write_1(sc->sc_tag, sc->sc_blith, reg ^ 3, val);
-}
-static inline uint8_t
-mgx_read_1(struct mgx_softc *sc, uint32_t reg)
-{
- return bus_space_read_1(sc->sc_tag, sc->sc_blith, reg ^ 3);
-}
+#if 0
+ uint32_t *fb = sc->sc_fbaddr;
+ int i, j;
+ for (i = 0; i < 256; i += 16) {
+ printf("%04x:", i);
+ for (j = 0; j < 16; j += 4) {
+ printf(" %08x", fb[(i + j) >> 2]);
+ }
+ printf("\n");
+ }
+#endif
-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);
}
-
static void
mgx_write_dac(struct mgx_softc *sc, int idx, int r, int g, int b)
{
@@ -296,13 +319,20 @@ mgx_init_palette(struct mgx_softc *sc)
int i, j = 0;
uint8_t cmap[768];
- rasops_get_cmap(ri, cmap, sizeof(cmap));
- for (i = 0; i < 256; i++) {
- sc->sc_cmap_red[i] = cmap[j];
- sc->sc_cmap_green[i] = cmap[j + 1];
- sc->sc_cmap_blue[i] = cmap[j + 2];
- mgx_write_dac(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]);
- j += 3;
+ if (sc->sc_depth == 8) {
+ rasops_get_cmap(ri, cmap, sizeof(cmap));
+ for (i = 0; i < 256; i++) {
+ sc->sc_cmap_red[i] = cmap[j];
+ sc->sc_cmap_green[i] = cmap[j + 1];
+ sc->sc_cmap_blue[i] = cmap[j + 2];
+ mgx_write_dac(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]);
+ j += 3;
+ }
+ } else {
+ /* linear ramp for true colour modes */
+ for (i = 0; i < 256; i++) {
+ mgx_write_dac(sc, i, i, i, i);
+ }
}
}
@@ -382,6 +412,21 @@ mgx_wait_engine(struct mgx_softc *sc)
return i;
}
+static inline int
+mgx_wait_host(struct mgx_softc *sc)
+{
+ unsigned int i;
+ uint8_t stat;
+
+ for (i = 10000; i != 0; i--) {
+ stat = mgx_read_1(sc, ATR_BLT_STATUS);
+ if ((stat & BLT_HOST_BUSY) == 0)
+ break;
+ }
+
+ return i;
+}
+
static int
mgx_wait_fifo(struct mgx_softc *sc, unsigned int nfifo)
{
@@ -402,31 +447,57 @@ mgx_wait_fifo(struct mgx_softc *sc, unsi
static void
mgx_setup(struct mgx_softc *sc, int depth)
{
+ uint32_t stride;
+ int i;
+ uint8_t reg;
+
/* wait for everything to go idle */
if (mgx_wait_engine(sc) == 0)
return;
if (mgx_wait_fifo(sc, FIFO_AT24) == 0)
return;
- /*
- * Compute the invariant bits of the DEC register.
- */
+
+ /* read name from sequencer */
+ for (i = 0; i < 8; i++) {
+ mgx_write_vga(sc, SEQ_INDEX, i + 0x11);
+ sc->sc_name[i] = mgx_read_vga(sc, SEQ_DATA);
+ }
+ sc->sc_name[7] = 0;
+
+ reg = mgx_read_1(sc, ATR_PIXEL);
+ reg &= ~PIXEL_DEPTH_MASK;
switch (depth) {
case 8:
sc->sc_dec = DEC_DEPTH_8 << DEC_DEPTH_SHIFT;
+ reg |= PIXEL_8;
break;
case 15:
+ sc->sc_dec = DEC_DEPTH_16 << DEC_DEPTH_SHIFT;
+ reg |= PIXEL_15;
+ break;
case 16:
sc->sc_dec = DEC_DEPTH_16 << DEC_DEPTH_SHIFT;
+ reg |= PIXEL_16;
break;
case 32:
sc->sc_dec = DEC_DEPTH_32 << DEC_DEPTH_SHIFT;
+ reg |= PIXEL_32;
break;
default:
return; /* not supported */
}
- switch (sc->sc_stride) {
+ /* the chip wants stride in units of 8 bytes */
+ sc->sc_stride = sc->sc_width * (depth >> 3);
+ stride = sc->sc_stride >> 3;
+#ifdef MGX_DEBUG
+ sc->sc_height = 600;
+#endif
+
+ sc->sc_depth = depth;
+
+ switch (sc->sc_width) {
case 640:
sc->sc_dec |= DEC_WIDTH_640 << DEC_WIDTH_SHIFT;
break;
@@ -450,6 +521,28 @@ mgx_setup(struct mgx_softc *sc, int dept
}
mgx_write_1(sc, ATR_CLIP_CONTROL, 0);
mgx_write_1(sc, ATR_BYTEMASK, 0xff);
+ mgx_write_1(sc, ATR_PIXEL, reg);
+ mgx_write_vga(sc, CRTC_INDEX, 0x13);
+ mgx_write_vga(sc, CRTC_DATA, stride & 0xff);
+ mgx_write_vga(sc, CRTC_INDEX, 0x1c);
+ mgx_write_vga(sc, CRTC_DATA, (stride & 0xf00) >> 4);
+#ifdef MGX_DEBUG
+ int j;
+ mgx_write_vga(sc, SEQ_INDEX, 0x10);
+ mgx_write_vga(sc, SEQ_DATA, 0x12);
+ for (i = 0x10; i < 0x30; i += 16) {
+ printf("%02x:", i);
+ for (j = 0; j < 16; j++) {
+ mgx_write_vga(sc, SEQ_INDEX, i + j);
+ printf(" %02x", mgx_read_vga(sc, SEQ_DATA));
+ }
+ printf("\n");
+ }
+#if 0
+ mgx_write_vga(sc, SEQ_INDEX, 0x1a);
+ mgx_write_vga(sc, SEQ_DATA, 0x0f);
+#endif
+#endif
}
static void
@@ -533,10 +626,11 @@ mgx_putchar(void *cookie, int row, int c
mgx_wait_engine(sc);
sc->sc_putchar(cookie, row, col, c, attr & ~1);
- junk = *(uint32_t *)sc->sc_fbaddr;
- __USE(junk);
- if (rv == GC_ADD)
+ if (rv == GC_ADD) {
+ junk = *(uint32_t *)sc->sc_fbaddr;
+ __USE(junk);
glyphcache_add(&sc->sc_gc, c, x, y);
+ }
}
if (attr & 1)
mgx_rectfill(sc, x, y + he - 2, wi, 1, fg);
@@ -649,7 +743,7 @@ mgx_init_screen(void *cookie, struct vco
struct mgx_softc *sc = cookie;
struct rasops_info *ri = &scr->scr_ri;
- ri->ri_depth = 8;
+ ri->ri_depth = sc->sc_depth;
ri->ri_width = sc->sc_width;
ri->ri_height = sc->sc_height;
ri->ri_stride = sc->sc_stride;
@@ -658,6 +752,17 @@ mgx_init_screen(void *cookie, struct vco
if (ri->ri_depth == 8)
ri->ri_flg |= RI_8BIT_IS_RGB;
+#ifdef MGX_NOACCEL
+ scr->scr_flags |= VCONS_DONT_READ;
+#endif
+
+ ri->ri_rnum = 8;
+ ri->ri_rpos = 0;
+ ri->ri_gnum = 8;
+ ri->ri_gpos = 8;
+ ri->ri_bnum = 8;
+ ri->ri_bpos = 16;
+
ri->ri_bits = sc->sc_fbaddr;
rasops_init(ri, 0, 0);
@@ -669,12 +774,18 @@ mgx_init_screen(void *cookie, struct vco
ri->ri_width / ri->ri_font->fontwidth);
ri->ri_hw = scr;
- ri->ri_ops.putchar = mgx_putchar;
- ri->ri_ops.cursor = mgx_cursor;
- ri->ri_ops.copyrows = mgx_copyrows;
- ri->ri_ops.eraserows = mgx_eraserows;
- ri->ri_ops.copycols = mgx_copycols;
- ri->ri_ops.erasecols = mgx_erasecols;
+
+#ifdef MGX_NOACCEL
+if (0)
+#endif
+ {
+ ri->ri_ops.putchar = mgx_putchar;
+ ri->ri_ops.cursor = mgx_cursor;
+ ri->ri_ops.copyrows = mgx_copyrows;
+ ri->ri_ops.eraserows = mgx_eraserows;
+ ri->ri_ops.copycols = mgx_copycols;
+ ri->ri_ops.erasecols = mgx_erasecols;
+ }
}
static int
@@ -723,12 +834,13 @@ mgx_ioctl(void *v, void *vs, u_long cmd,
sc->sc_mode = new_mode;
if (new_mode == WSDISPLAYIO_MODE_EMUL)
{
- mgx_setup(sc, 8);
+ mgx_setup(sc, MGX_DEPTH);
glyphcache_wipe(&sc->sc_gc);
mgx_init_palette(sc);
vcons_redraw_screen(ms);
} else {
mgx_setup(sc, 32);
+ mgx_init_palette(sc);
}
}
}
@@ -743,11 +855,22 @@ mgx_ioctl(void *v, void *vs, u_long cmd,
case WSDISPLAYIO_GET_FBINFO:
{
struct wsdisplayio_fbinfo *fbi = data;
- int ret;
-
- ret = wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
- fbi->fbi_fbsize = 0x400000;
- return ret;
+
+ fbi->fbi_fbsize = sc->sc_fbsize;
+ fbi->fbi_width = sc->sc_width;
+ fbi->fbi_height = sc->sc_height;
+ fbi->fbi_bitsperpixel = sc->sc_depth;
+ fbi->fbi_stride = sc->sc_stride;
+ fbi->fbi_pixeltype = WSFB_RGB;
+ fbi->fbi_subtype.fbi_rgbmasks.red_offset = 8;
+ fbi->fbi_subtype.fbi_rgbmasks.red_size = 8;
+ fbi->fbi_subtype.fbi_rgbmasks.green_offset = 16;
+ fbi->fbi_subtype.fbi_rgbmasks.green_size = 8;
+ fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 24;
+ fbi->fbi_subtype.fbi_rgbmasks.blue_size = 8;
+ fbi->fbi_subtype.fbi_rgbmasks.alpha_offset = 0;
+ fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 8;
+ return 0;
}
}
return EPASSTHROUGH;
@@ -760,7 +883,7 @@ mgx_mmap(void *v, void *vs, off_t offset
struct mgx_softc *sc = vd->cookie;
/* regular fb mapping at 0 */
- if ((offset >= 0) && (offset < 0x400000)) {
+ if ((offset >= 0) && (offset < sc->sc_fbsize)) {
return bus_space_mmap(sc->sc_tag, sc->sc_paddr,
offset, prot, BUS_SPACE_MAP_LINEAR);
}
Index: src/sys/dev/sbus/mgxreg.h
diff -u src/sys/dev/sbus/mgxreg.h:1.2 src/sys/dev/sbus/mgxreg.h:1.3
--- src/sys/dev/sbus/mgxreg.h:1.2 Sun Jan 4 18:18:20 2015
+++ src/sys/dev/sbus/mgxreg.h Thu Feb 11 02:23:44 2016
@@ -1,40 +1,10 @@
-/* $NetBSD: mgxreg.h,v 1.2 2015/01/04 18:18:20 macallan Exp $ */
-
-/*-
- * Copyright (c) 2014 Michael Lorenz
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MGX_REG_H
-#define MGX_REG_H
-
-#define VGA_BASE 0x3c0
+/* $NetBSD: mgxreg.h,v 1.3 2016/02/11 02:23:44 macallan Exp $ */
/* register definitions based on OpenBSD's atxxreg.h: */
/*
* Copyright (c) 2008 Miodrag Vallat.
+ * Copyright (c) 2014 Michael Lorenz
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -57,6 +27,28 @@
* apm_regs.h for more madness.
*/
+#ifndef MGX_REG_H
+#define MGX_REG_H
+
+#define VGA_BASE 0x3c0
+#define CRTC_INDEX 0x3d4
+#define CRTC_DATA 0x3d5
+#define SEQ_INDEX 0x3c4
+#define SEQ_DATA 0x3c5
+
+/*
+ * some bits from the XFree86 3.x vga256 / apm driver:
+ * - sequencer registers 0x11 - 0x17 contain the chip's ID, 'Pro6424' for AT24
+ */
+
+#define SEQ_APERTURE 0x1c
+ #define AP_SIZE_MASK 0x06
+ #define AP_SIZE_1MB 0x00
+ #define AP_SIZE_2MB 0x02
+ #define AP_SIZE_4MB 0x04
+ #define AP_SIZE_6MB 0x06
+ #define AP_SIMULTANEOUS 0x20 /* sim. access to VRAM? */
+
/*
* Clipping Control
*/