summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormatthieu <matthieu@openbsd.org>2002-04-01 11:26:32 +0000
committermatthieu <matthieu@openbsd.org>2002-04-01 11:26:32 +0000
commite00d3f43a0a0d44f25d7d19c35affde653e3966d (patch)
tree93b23bc9f6545f2f276285dff43463e4f19a52c2
parentOnly call dc_ramdac_intr if initialized(). Fixes a panic when (diff)
downloadwireguard-openbsd-e00d3f43a0a0d44f25d7d19c35affde653e3966d.tar.xz
wireguard-openbsd-e00d3f43a0a0d44f25d7d19c35affde653e3966d.zip
Add support for PowerStorm 4D20 TGA boqrds with IBM 561 ramdac (aka
32bit TGA) From NetBSD, ok deraadt@.
-rw-r--r--sys/dev/ic/bt463.c3
-rw-r--r--sys/dev/ic/bt485.c3
-rw-r--r--sys/dev/ic/ibm561.c524
-rw-r--r--sys/dev/ic/ibm561reg.h81
-rw-r--r--sys/dev/ic/ibm561var.h48
-rw-r--r--sys/dev/ic/ramdac.h6
-rw-r--r--sys/dev/pci/files.pci3
-rw-r--r--sys/dev/pci/tga.c102
-rw-r--r--sys/dev/pci/tga_conf.c27
-rw-r--r--sys/dev/pci/tgavar.h5
10 files changed, 762 insertions, 40 deletions
diff --git a/sys/dev/ic/bt463.c b/sys/dev/ic/bt463.c
index 1937d1e8703..b1e55c03064 100644
--- a/sys/dev/ic/bt463.c
+++ b/sys/dev/ic/bt463.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bt463.c,v 1.7 2002/03/14 03:16:04 millert Exp $ */
+/* $OpenBSD: bt463.c,v 1.8 2002/04/01 11:26:32 matthieu Exp $ */
/* $NetBSD: bt463.c,v 1.2 2000/06/13 17:21:06 nathanw Exp $ */
/*-
@@ -132,6 +132,7 @@ struct ramdac_funcs bt463_funcsstruct = {
bt463_check_curcmap,
bt463_set_curcmap,
bt463_get_curcmap,
+ NULL,
};
/*
diff --git a/sys/dev/ic/bt485.c b/sys/dev/ic/bt485.c
index 39d0b24a88d..58d22e6e0c0 100644
--- a/sys/dev/ic/bt485.c
+++ b/sys/dev/ic/bt485.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bt485.c,v 1.9 2002/03/14 03:16:04 millert Exp $ */
+/* $OpenBSD: bt485.c,v 1.10 2002/04/01 11:26:32 matthieu Exp $ */
/* $NetBSD: bt485.c,v 1.2 2000/04/02 18:55:01 nathanw Exp $ */
/*
@@ -84,6 +84,7 @@ struct ramdac_funcs bt485_funcsstruct = {
NULL, /* check_curcmap; not needed */
NULL, /* set_curcmap; not needed */
NULL, /* get_curcmap; not needed */
+ NULL, /* no dot clock to set */
};
/*
diff --git a/sys/dev/ic/ibm561.c b/sys/dev/ic/ibm561.c
new file mode 100644
index 00000000000..78ef0882298
--- /dev/null
+++ b/sys/dev/ic/ibm561.c
@@ -0,0 +1,524 @@
+/* $NetBSD: ibm561.c,v 1.1 2001/12/12 07:46:48 elric Exp $ */
+/* $OpenBSD: ibm561.c,v 1.1 2002/04/01 11:26:32 matthieu Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Roland C. Dowdeswell of Ponte, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/ic/ibm561reg.h>
+#include <dev/ic/ibm561var.h>
+#include <dev/ic/ramdac.h>
+
+#include <dev/wscons/wsconsio.h>
+
+/*
+ * Functions exported via the RAMDAC configuration table.
+ */
+void ibm561_init(struct ramdac_cookie *);
+int ibm561_set_cmap(struct ramdac_cookie *,
+ struct wsdisplay_cmap *);
+int ibm561_get_cmap(struct ramdac_cookie *,
+ struct wsdisplay_cmap *);
+int ibm561_set_cursor(struct ramdac_cookie *,
+ struct wsdisplay_cursor *);
+int ibm561_get_cursor(struct ramdac_cookie *,
+ struct wsdisplay_cursor *);
+int ibm561_set_curpos(struct ramdac_cookie *,
+ struct wsdisplay_curpos *);
+int ibm561_get_curpos(struct ramdac_cookie *,
+ struct wsdisplay_curpos *);
+int ibm561_get_curmax(struct ramdac_cookie *,
+ struct wsdisplay_curpos *);
+int ibm561_set_dotclock(struct ramdac_cookie *,
+ unsigned);
+
+/* XXX const */
+struct ramdac_funcs ibm561_funcsstruct = {
+ "IBM561",
+ ibm561_register,
+ ibm561_init,
+ ibm561_set_cmap,
+ ibm561_get_cmap,
+ ibm561_set_cursor,
+ ibm561_get_cursor,
+ ibm561_set_curpos,
+ ibm561_get_curpos,
+ ibm561_get_curmax,
+ NULL, /* check_curcmap; not needed */
+ NULL, /* set_curcmap; not needed */
+ NULL, /* get_curcmap; not needed */
+ ibm561_set_dotclock,
+};
+
+/*
+ * Private data.
+ */
+struct ibm561data {
+ void *cookie;
+
+ int (*ramdac_sched_update)(void *, void (*)(void *));
+ void (*ramdac_wr)(void *, u_int, u_int8_t);
+ u_int8_t (*ramdac_rd)(void *, u_int);
+
+#define CHANGED_CURCMAP 0x0001 /* cursor cmap */
+#define CHANGED_CMAP 0x0002 /* color map */
+#define CHANGED_WTYPE 0x0004 /* window types */
+#define CHANGED_DOTCLOCK 0x0008 /* dot clock */
+#define CHANGED_ALL 0x000f /* or of all above */
+ u_int8_t changed;
+
+ /* dotclock parameters */
+ u_int8_t vco_div;
+ u_int8_t pll_ref;
+ u_int8_t div_dotclock;
+
+ /* colormaps et al. */
+ u_int8_t curcmap_r[2];
+ u_int8_t curcmap_g[2];
+ u_int8_t curcmap_b[2];
+
+ u_int8_t cmap_r[IBM561_NCMAP_ENTRIES];
+ u_int8_t cmap_g[IBM561_NCMAP_ENTRIES];
+ u_int8_t cmap_b[IBM561_NCMAP_ENTRIES];
+
+ u_int16_t gamma_r[IBM561_NGAMMA_ENTRIES];
+ u_int16_t gamma_g[IBM561_NGAMMA_ENTRIES];
+ u_int16_t gamma_b[IBM561_NGAMMA_ENTRIES];
+
+ u_int16_t wtype[IBM561_NWTYPES];
+};
+
+/*
+ * private functions
+ */
+void ibm561_update(void *);
+static void ibm561_load_cmap(struct ibm561data *);
+static void ibm561_load_dotclock(struct ibm561data *);
+static void ibm561_regbegin(struct ibm561data *, u_int16_t);
+static void ibm561_regcont(struct ibm561data *, u_int16_t, u_int8_t);
+static void ibm561_regcont10bit(struct ibm561data *, u_int16_t, u_int16_t);
+static void ibm561_regwr(struct ibm561data *, u_int16_t, u_int8_t);
+
+struct ramdac_funcs *
+ibm561_funcs(void)
+{
+ return &ibm561_funcsstruct;
+}
+
+struct ramdac_cookie *
+ibm561_register(v, sched_update, wr, rd)
+ void *v;
+ int (*sched_update)(void *, void (*)(void *));
+ void (*wr)(void *, u_int, u_int8_t);
+ u_int8_t (*rd)(void *, u_int);
+{
+ struct ibm561data *data;
+
+ data = malloc(sizeof *data, M_DEVBUF, M_WAITOK); // XXX |M_ZERO);
+ data->cookie = v;
+ data->ramdac_sched_update = sched_update;
+ data->ramdac_wr = wr;
+ data->ramdac_rd = rd;
+ return (struct ramdac_cookie *)data;
+}
+
+/*
+ * This function exists solely to provide a means to init
+ * the RAMDAC without first registering. It is useful for
+ * initializing the console early on.
+ */
+
+struct ibm561data *saved_console_data;
+
+void
+ibm561_cninit(v, sched_update, wr, rd, dotclock)
+ void *v;
+ int (*sched_update)(void *, void (*)(void *));
+ void (*wr)(void *, u_int, u_int8_t);
+ u_int8_t (*rd)(void *, u_int);
+ u_int dotclock;
+{
+ struct ibm561data tmp, *data = &tmp;
+ memset(data, 0x0, sizeof *data);
+ data->cookie = v;
+ data->ramdac_sched_update = sched_update;
+ data->ramdac_wr = wr;
+ data->ramdac_rd = rd;
+ ibm561_set_dotclock((struct ramdac_cookie *)data, dotclock);
+ saved_console_data = data;
+ ibm561_init((struct ramdac_cookie *)data);
+ saved_console_data = NULL;
+}
+
+void
+ibm561_init(rc)
+ struct ramdac_cookie *rc;
+{
+ struct ibm561data *data = (struct ibm561data *)rc;
+ int i;
+
+ /* XXX this is _essential_ */
+
+ ibm561_load_dotclock(data);
+
+ /* XXXrcd: bunch of magic of which I have no current clue */
+ ibm561_regwr(data, IBM561_CONFIG_REG1, 0x2a);
+ ibm561_regwr(data, IBM561_CONFIG_REG3, 0x41);
+ ibm561_regwr(data, IBM561_CONFIG_REG4, 0x20);
+
+ /* initialize the card a bit */
+ ibm561_regwr(data, IBM561_SYNC_CNTL, 0x1);
+ ibm561_regwr(data, IBM561_CONFIG_REG2, 0x19);
+
+ ibm561_regwr(data, IBM561_CONFIG_REG1, 0x2a);
+ ibm561_regwr(data, IBM561_CONFIG_REG4, 0x20);
+
+ ibm561_regbegin(data, IBM561_WAT_SEG_REG);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regbegin(data, IBM561_CHROMAKEY0);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+
+ ibm561_regwr(data, IBM561_CURS_CNTL_REG, 0x00); /* XXX off? */
+
+ /* cursor `hot spot' registers */
+ ibm561_regbegin(data, IBM561_HOTSPOT_REG);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+ ibm561_regcont(data, IBM561_CMD, 0x00);
+
+ /* VRAM Mask Registers (diagnostics) */
+ ibm561_regbegin(data, IBM561_VRAM_MASK_REG);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+ ibm561_regcont(data, IBM561_CMD, 0xff);
+
+ /* let's set up some decent default colour maps and gammas */
+ for (i=0; i < IBM561_NCMAP_ENTRIES; i++)
+ data->cmap_r[i] = data->cmap_g[i] = data->cmap_b[i] = 0xff;
+ data->cmap_r[0] = data->cmap_g[0] = data->cmap_b[0] = 0x00;
+ data->cmap_r[256] = data->cmap_g[256] = data->cmap_b[256] = 0x00;
+ data->cmap_r[512] = data->cmap_g[512] = data->cmap_b[512] = 0x00;
+ data->cmap_r[768] = data->cmap_g[768] = data->cmap_b[768] = 0x00;
+
+ data->gamma_r[0] = data->gamma_g[0] = data->gamma_b[0] = 0x00;
+ for (i=0; i < IBM561_NGAMMA_ENTRIES; i++)
+ data->gamma_r[i] = data->gamma_g[i] = data->gamma_b[i] = 0xff;
+
+ for (i=0; i < IBM561_NWTYPES; i++)
+ data->wtype[i] = 0x0036;
+ data->wtype[1] = 0x0028;
+
+ /* the last step: */
+ data->changed = CHANGED_ALL;
+ data->ramdac_sched_update(data->cookie, ibm561_update);
+}
+
+int
+ibm561_set_cmap(rc, cmapp)
+ struct ramdac_cookie *rc;
+ struct wsdisplay_cmap *cmapp;
+{
+ struct ibm561data *data = (struct ibm561data *)rc;
+ int count;
+ int index;
+ int s;
+
+ if ((u_int)cmapp->index >= IBM561_NCMAP_ENTRIES ||
+ ((u_int)cmapp->index + (u_int)cmapp->count) > IBM561_NCMAP_ENTRIES)
+ return (EINVAL);
+ if (!uvm_useracc(cmapp->red, cmapp->count, B_READ) ||
+ !uvm_useracc(cmapp->green, cmapp->count, B_READ) ||
+ !uvm_useracc(cmapp->blue, cmapp->count, B_READ))
+ return (EFAULT);
+
+ s = spltty();
+ index = cmapp->index;
+ count = cmapp->count;
+ copyin(cmapp->red, &data->cmap_r[index], count);
+ copyin(cmapp->green, &data->cmap_g[index], count);
+ copyin(cmapp->blue, &data->cmap_b[index], count);
+ data->changed |= CHANGED_CMAP;
+ data->ramdac_sched_update(data->cookie, ibm561_update);
+ splx(s);
+ return (0);
+}
+
+int
+ibm561_get_cmap(rc, cmapp)
+ struct ramdac_cookie *rc;
+ struct wsdisplay_cmap *cmapp;
+{
+ struct ibm561data *data = (struct ibm561data *)rc;
+ int error;
+ int count;
+ int index;
+
+ if ((u_int)cmapp->index >= IBM561_NCMAP_ENTRIES ||
+ ((u_int)cmapp->index + (u_int)cmapp->count) > IBM561_NCMAP_ENTRIES)
+ return (EINVAL);
+ count = cmapp->count;
+ index = cmapp->index;
+ error = copyout(&data->cmap_r[index], cmapp->red, count);
+ if (error)
+ return (error);
+ error = copyout(&data->cmap_g[index], cmapp->green, count);
+ if (error)
+ return (error);
+ error = copyout(&data->cmap_b[index], cmapp->blue, count);
+ return (error);
+}
+
+/*
+ * XXX:
+ * I am leaving these functions returning EINVAL, as they are
+ * not strictly necessary for the correct functioning of the
+ * card and in fact are not used on the other TGA variants, except
+ * they are exported via ioctl(2) to userland, which does not in
+ * fact use them.
+ */
+
+int
+ibm561_set_cursor(rc, cursorp)
+ struct ramdac_cookie *rc;
+ struct wsdisplay_cursor *cursorp;
+{
+ return EINVAL;
+}
+
+int
+ibm561_get_cursor(rc, cursorp)
+ struct ramdac_cookie *rc;
+ struct wsdisplay_cursor *cursorp;
+{
+ return EINVAL;
+}
+
+int
+ibm561_set_curpos(rc, curposp)
+ struct ramdac_cookie *rc;
+ struct wsdisplay_curpos *curposp;
+{
+ return EINVAL;
+}
+
+int
+ibm561_get_curpos(rc, curposp)
+ struct ramdac_cookie *rc;
+ struct wsdisplay_curpos *curposp;
+{
+ return EINVAL;
+}
+
+int
+ibm561_get_curmax(rc, curposp)
+ struct ramdac_cookie *rc;
+ struct wsdisplay_curpos *curposp;
+{
+ return EINVAL;
+}
+
+int
+ibm561_set_dotclock(rc, dotclock)
+ struct ramdac_cookie *rc;
+ unsigned dotclock;
+{
+ struct ibm561data *data = (struct ibm561data *)rc;
+
+ /* XXXrcd: a couple of these are a little hazy, vis a vis
+ * check 175MHz and 202MHz, which are wrong...
+ */
+ switch (dotclock) {
+ case 25175000: data->vco_div = 0x3e; data->pll_ref = 0x09; break;
+ case 31500000: data->vco_div = 0x17; data->pll_ref = 0x05; break;
+ case 40000000: data->vco_div = 0x42; data->pll_ref = 0x06; break;
+ case 50000000: data->vco_div = 0x45; data->pll_ref = 0x05; break;
+ case 65000000: data->vco_div = 0xac; data->pll_ref = 0x0c; break;
+ case 69000000: data->vco_div = 0xa9; data->pll_ref = 0x0b; break;
+ case 74000000: data->vco_div = 0x9c; data->pll_ref = 0x09; break;
+ case 75000000: data->vco_div = 0x93; data->pll_ref = 0x08; break;
+ case 103994000: data->vco_div = 0x96; data->pll_ref = 0x06; break;
+ case 108180000: data->vco_div = 0xb8; data->pll_ref = 0x08; break;
+ case 110000000: data->vco_div = 0xba; data->pll_ref = 0x08; break;
+ case 119840000: data->vco_div = 0x82; data->pll_ref = 0x04; break;
+ case 130808000: data->vco_div = 0xc8; data->pll_ref = 0x08; break;
+ case 135000000: data->vco_div = 0xc1; data->pll_ref = 0x07; break;
+ case 175000000: data->vco_div = 0xe2; data->pll_ref = 0x07; break;
+ case 202500000: data->vco_div = 0xe2; data->pll_ref = 0x07; break;
+ default:
+ return EINVAL;
+ }
+
+ data->div_dotclock = 0xb0;
+ data->changed |= CHANGED_DOTCLOCK;
+ return 0;
+}
+
+/*
+ * Internal Functions
+ */
+
+void
+ibm561_update(vp)
+ void *vp;
+{
+ struct ibm561data *data = (struct ibm561data *)vp;
+ int i;
+
+ /* XXX see comment above ibm561_cninit() */
+ if (!data)
+ data = saved_console_data;
+
+ if (data->changed & CHANGED_WTYPE) {
+ ibm561_regbegin(data, IBM561_FB_WINTYPE);
+ for (i=0; i < IBM561_NWTYPES; i++)
+ ibm561_regcont10bit(data, IBM561_CMD_FB_WAT, data->wtype[i]);
+
+ /* XXXrcd: quick hack here for AUX FB table */
+ ibm561_regbegin(data, IBM561_AUXFB_WINTYPE);
+ for (i=0; i < IBM561_NWTYPES; i++)
+ ibm561_regcont(data, IBM561_CMD, 0x04);
+
+ /* XXXrcd: quick hack here for OL WAT table */
+ ibm561_regbegin(data, IBM561_OL_WINTYPE);
+ for (i=0; i < IBM561_NWTYPES; i++)
+ ibm561_regcont10bit(data, IBM561_CMD_FB_WAT, 0x0231);
+
+ /* XXXrcd: quick hack here for AUX OL WAT table */
+ ibm561_regbegin(data, IBM561_AUXOL_WINTYPE);
+ for (i=0; i < IBM561_NWTYPES; i++)
+ ibm561_regcont(data, IBM561_CMD, 0x0c);
+ }
+
+ if (data->changed & CHANGED_CMAP)
+ ibm561_load_cmap(data);
+
+ /* XXX: I am not sure in what situations it is safe to
+ * change the dotclock---hope this is good.
+ */
+ if (data->changed & CHANGED_DOTCLOCK)
+ ibm561_load_dotclock(data);
+}
+
+static void
+ibm561_load_cmap(struct ibm561data *data)
+{
+ int i;
+
+ ibm561_regbegin(data, IBM561_CMAP_TABLE);
+ for (i=0; i < IBM561_NCMAP_ENTRIES; i++) {
+ ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_r[i]);
+ ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_g[i]);
+ ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_b[i]);
+ }
+
+ ibm561_regbegin(data, IBM561_RED_GAMMA_TABLE);
+ for (i=0; i < 256; i++)
+ ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_r[i]);
+
+ ibm561_regbegin(data, IBM561_GREEN_GAMMA_TABLE);
+ for (i=1; i < 256; i++)
+ ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_g[i]);
+
+ ibm561_regbegin(data, IBM561_BLUE_GAMMA_TABLE);
+ for (i=1; i < 256; i++)
+ ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_b[i]);
+
+}
+
+static void
+ibm561_load_dotclock(struct ibm561data *data)
+{
+ /* XXX
+ * we should probably be more pro-active here, but it shouldn't
+ * actually happen...
+ */
+ if (!data->vco_div || !data->pll_ref || ! data->div_dotclock) {
+ panic("ibm561_load_dotclock: called uninitialized");
+ }
+
+ ibm561_regwr(data, IBM561_PLL_VCO_DIV, data->vco_div);
+ ibm561_regwr(data, IBM561_PLL_REF_REG, data->pll_ref);
+ ibm561_regwr(data, IBM561_DIV_DOTCLCK, data->div_dotclock);
+}
+
+static void
+ibm561_regcont10bit(struct ibm561data *data, u_int16_t reg, u_int16_t val)
+{
+ data->ramdac_wr(data->cookie, IBM561_CMD_GAMMA, (val >> 2) & 0xff);
+ data->ramdac_wr(data->cookie, IBM561_CMD_GAMMA, (val & 0x3) << 6);
+}
+
+static void
+ibm561_regbegin(struct ibm561data *data, u_int16_t reg)
+{
+ data->ramdac_wr(data->cookie, IBM561_ADDR_LOW, reg & 0xff);
+ data->ramdac_wr(data->cookie, IBM561_ADDR_HIGH, (reg >> 8) & 0xff);
+}
+
+static void
+ibm561_regcont(struct ibm561data *data, u_int16_t reg, u_int8_t val)
+{
+ data->ramdac_wr(data->cookie, reg, val);
+}
+
+static void
+ibm561_regwr(struct ibm561data *data, u_int16_t reg, u_int8_t val)
+{
+ ibm561_regbegin(data, reg);
+ ibm561_regcont(data, IBM561_CMD, val);
+}
diff --git a/sys/dev/ic/ibm561reg.h b/sys/dev/ic/ibm561reg.h
new file mode 100644
index 00000000000..ee9d7f651df
--- /dev/null
+++ b/sys/dev/ic/ibm561reg.h
@@ -0,0 +1,81 @@
+/* $NetBSD: ibm561reg.h,v 1.1 2001/12/12 07:46:48 elric Exp $ */
+/* $OpenBSD: ibm561reg.h,v 1.1 2002/04/01 11:26:32 matthieu Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Roland C. Dowdeswell of Ponte, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#define IBM561_ADDR_LOW 0x00
+#define IBM561_ADDR_HIGH 0x01
+#define IBM561_CMD 0x02
+#define IBM561_CMD_FB_WAT 0x03
+#define IBM561_CMD_CMAP 0x03
+#define IBM561_CMD_GAMMA 0x03
+
+#define IBM561_CONFIG_REG1 0x0001
+#define IBM561_CONFIG_REG2 0x0002
+#define IBM561_CONFIG_REG3 0x0003
+#define IBM561_CONFIG_REG4 0x0004
+
+#define IBM561_SYNC_CNTL 0x0020
+#define IBM561_PLL_VCO_DIV 0x0021
+#define IBM561_PLL_REF_REG 0x0022
+#define IBM561_CURS_CNTL_REG 0x0030
+#define IBM561_HOTSPOT_REG 0x0034
+#define IBM561_VRAM_MASK_REG 0x0050
+#define IBM561_DIV_DOTCLCK 0x0082
+#define IBM561_FB_WINTYPE 0x1000
+#define IBM561_AUXFB_WINTYPE 0x0e00
+#define IBM561_OL_WINTYPE 0x1400
+#define IBM561_AUXOL_WINTYPE 0x0f00
+#define IBM561_CMAP_TABLE 0x4000
+#define IBM561_RED_GAMMA_TABLE 0x3000
+#define IBM561_GREEN_GAMMA_TABLE 0x3400
+#define IBM561_BLUE_GAMMA_TABLE 0x3800
+
+#define IBM561_CHROMAKEY0 0x0010
+#define IBM561_CHROMAKEY1 0x0011
+#define IBM561_CHROMAKEYMASK0 0x0012
+#define IBM561_CHROMAKEYMASK1 0x0013
+
+#define IBM561_WAT_SEG_REG 0x0006
+
+#define IBM561_NCMAP_ENTRIES 1024
+#define IBM561_NGAMMA_ENTRIES 256
+
+/* we actually have 1024 of them, but I am just
+ * going define a few, so this is good.
+ */
+#define IBM561_NWTYPES 16
diff --git a/sys/dev/ic/ibm561var.h b/sys/dev/ic/ibm561var.h
new file mode 100644
index 00000000000..f9e62326c86
--- /dev/null
+++ b/sys/dev/ic/ibm561var.h
@@ -0,0 +1,48 @@
+/* $NetBSD: ibm561var.h,v 1.1 2001/12/12 07:46:48 elric Exp $ */
+/* $OpenBSD: ibm561var.h,v 1.1 2002/04/01 11:26:32 matthieu Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Roland C. Dowdeswell of Ponte, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+struct ramdac_funcs *ibm561_funcs(void);
+struct ramdac_cookie *ibm561_register (void *,
+ int (*)(void *, void (*)(void *)),
+ void (*)(void *, u_int, u_int8_t),
+ u_int8_t (*)(void *, u_int));
+void ibm561_cninit (void *,
+ int (*)(void *, void (*)(void *)),
+ void (*)(void *, u_int, u_int8_t),
+ u_int8_t (*)(void *, u_int), u_int);
diff --git a/sys/dev/ic/ramdac.h b/sys/dev/ic/ramdac.h
index af17750c9c7..be539c70230 100644
--- a/sys/dev/ic/ramdac.h
+++ b/sys/dev/ic/ramdac.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ramdac.h,v 1.4 2002/03/14 03:16:05 millert Exp $ */
+/* $OpenBSD: ramdac.h,v 1.5 2002/04/01 11:26:32 matthieu Exp $ */
/* $NetBSD: ramdac.h,v 1.1 2000/03/04 10:23:39 elric Exp $ */
/*-
@@ -76,6 +76,10 @@ struct ramdac_funcs {
struct wsdisplay_cursor *);
int (*ramdac_get_curcmap)(struct ramdac_cookie *,
struct wsdisplay_cursor *);
+
+ /* XXXrcd: new test code for setting the DOTCLOCK */
+ int (*ramdac_set_dotclock)(struct ramdac_cookie *,
+ unsigned);
};
#endif
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index 01fc09e530c..91a84a85fc1 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.127 2002/02/18 01:55:30 krw Exp $
+# $OpenBSD: files.pci,v 1.128 2002/04/01 11:26:32 matthieu Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -22,6 +22,7 @@ file dev/pci/tga.c tga needs-flag
file dev/pci/tga_conf.c tga
file dev/ic/bt463.c tga
file dev/ic/bt485.c tga
+file dev/ic/ibm561.c tga
# Cypress 82c693 hyperCache(tm) Stand-Alone PCI Peripheral Controller
# with USB. This is a combo chip:
diff --git a/sys/dev/pci/tga.c b/sys/dev/pci/tga.c
index eb8590890dc..d507836cd81 100644
--- a/sys/dev/pci/tga.c
+++ b/sys/dev/pci/tga.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tga.c,v 1.13 2002/04/01 11:17:47 matthieu Exp $ */
-/* $NetBSD: tga.c,v 1.31 2001/02/11 19:34:58 nathanw Exp $ */
+/* $OpenBSD: tga.c,v 1.14 2002/04/01 11:26:32 matthieu Exp $ */
+/* $NetBSD: tga.c,v 1.40 2002/03/13 15:05:18 ad Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -49,6 +49,7 @@
#include <dev/ic/bt485var.h>
#include <dev/ic/bt463reg.h>
#include <dev/ic/bt463var.h>
+#include <dev/ic/ibm561var.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wscons_raster.h>
@@ -80,6 +81,7 @@ int tga_identify(struct tga_devconfig *);
const struct tga_conf *tga_getconf(int);
void tga_getdevconfig(bus_space_tag_t memt, pci_chipset_tag_t pc,
pcitag_t tag, struct tga_devconfig *dc);
+unsigned tga_getdotclock(struct tga_devconfig *dc);
struct tga_devconfig tga_console_dc;
@@ -100,7 +102,7 @@ static void tga_putchar(void *c, int row, int col,
u_int uc, long attr);
static void tga_eraserows(void *, int, int, long);
static void tga_erasecols(void *, int, int, int, long);
-void tga2_init(struct tga_devconfig *, int);
+void tga2_init(struct tga_devconfig *);
void tga_config_interrupts(struct device *);
@@ -272,11 +274,7 @@ tga_getdevconfig(memt, pc, tag, dc)
}
if (dc->dc_tga2) {
- int monitor;
-
- monitor = (~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f;
- DPRINTF("tga_getdevconfig: tga2_init\n");
- tga2_init(dc, monitor);
+ tga2_init(dc);
}
i = TGARREG(dc, TGA_REG_VHCR) & 0x1ff;
@@ -381,7 +379,10 @@ tga_getdevconfig(memt, pc, tag, dc)
return;
}
dc->dc_rinfo.ri_wsfcookie = cookie;
- rasops_init(rip, 34, 80);
+ /* fill screen size */
+ rasops_init(rip, dc->dc_ht / rip->ri_font->fontheight,
+ dc->dc_wid / rip->ri_font->fontwidth);
+ /* rasops_init(rip, 34, 80); */
/* add our accelerated functions */
/* XXX shouldn't have to do this; rasops should leave non-NULL
@@ -501,8 +502,13 @@ tgaattach(parent, self, aux)
sc->sc_dc->dc_ramdac_cookie =
sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
tga_sched_update, tga2_ramdac_wr, tga2_ramdac_rd);
- }
+ /* XXX this is a bit of a hack, setting the dotclock here */
+ if (sc->sc_dc->dc_tgaconf->ramdac_funcs != bt485_funcs)
+ (*sc->sc_dc->dc_ramdac_funcs->ramdac_set_dotclock)
+ (sc->sc_dc->dc_ramdac_cookie,
+ tga_getdotclock(sc->sc_dc));
+ }
DPRINTF("tgaattach: sc->sc_dc->dc_ramdac_cookie = 0x%016llx\n",
sc->sc_dc->dc_ramdac_cookie);
/*
@@ -571,7 +577,7 @@ tga_ioctl(v, cmd, data, flag, p)
wsd_fbip->height = sc->sc_dc->dc_ht;
wsd_fbip->width = sc->sc_dc->dc_wid;
wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth;
- wsd_fbip->cmsize = 256; /* XXX ??? */
+ wsd_fbip->cmsize = 1024; /* XXX ??? */
#undef wsd_fbip
return (0);
@@ -778,10 +784,14 @@ tga_cnattach(iot, memt, pc, bus, device, function)
* Initialization includes disabling cursor, setting a sane
* colormap, etc. It will be reinitialized in tgaattach().
*/
- if (dcp->dc_tga2)
- bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
- tga2_ramdac_rd);
- else {
+ if (dcp->dc_tga2) {
+ if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
+ bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
+ tga2_ramdac_rd);
+ else
+ ibm561_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
+ tga2_ramdac_rd, tga_getdotclock(dcp));
+ } else {
if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr,
tga_ramdac_rd);
@@ -1533,31 +1543,47 @@ void tga2_ics9110_wr(
int dotclock
);
+struct monitor *tga_getmonitor(struct tga_devconfig *dc);
+
void
-tga2_init(dc, m)
+tga2_init(dc)
struct tga_devconfig *dc;
- int m;
{
+ struct monitor *m = tga_getmonitor(dc);
+
- tga2_ics9110_wr(dc, decmonitors[m].dotclock);
+ /* Deal with the dot clocks.
+ */
+ if (dc->dc_tga_type == TGA_TYPE_POWERSTORM_4D20) {
+ /* Set this up as a reference clock for the
+ * ibm561's PLL.
+ */
+ tga2_ics9110_wr(dc, 14300000);
+ /* XXX Can't set up the dotclock properly, until such time
+ * as the RAMDAC is configured.
+ */
+ } else {
+ /* otherwise the ics9110 is our clock. */
+ tga2_ics9110_wr(dc, m->dotclock);
+ }
#if 0
TGAWREG(dc, TGA_REG_VHCR,
- ((decmonitors[m].hbp / 4) << 21) |
- ((decmonitors[m].hsync / 4) << 14) |
- (((decmonitors[m].hfp - 4) / 4) << 9) |
- ((decmonitors[m].cols + 4) / 4));
+ ((m->hbp / 4) << 21) |
+ ((m->hsync / 4) << 14) |
+ (((m->hfp - 4) / 4) << 9) |
+ ((m->cols + 4) / 4));
#else
TGAWREG(dc, TGA_REG_VHCR,
- ((decmonitors[m].hbp / 4) << 21) |
- ((decmonitors[m].hsync / 4) << 14) |
- (((decmonitors[m].hfp) / 4) << 9) |
- ((decmonitors[m].cols) / 4));
+ ((m->hbp / 4) << 21) |
+ ((m->hsync / 4) << 14) |
+ (((m->hfp) / 4) << 9) |
+ ((m->cols) / 4));
#endif
TGAWREG(dc, TGA_REG_VVCR,
- (decmonitors[m].vbp << 22) |
- (decmonitors[m].vsync << 16) |
- (decmonitors[m].vfp << 11) |
- (decmonitors[m].rows));
+ (m->vbp << 22) |
+ (m->vsync << 16) |
+ (m->vfp << 11) |
+ (m->rows));
TGAWREG(dc, TGA_REG_VVBR, 1);
TGAREGRWB(dc, TGA_REG_VHCR, 3);
TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 1);
@@ -1609,6 +1635,8 @@ tga2_ics9110_wr(dc, dotclock)
N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
case 202500000:
N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
+ case 14300000: /* this one is just a ref clock */
+ N = 0x03; M = 0x03; V = 0x1; X = 0x1; R = 0x3; break;
default:
panic("unrecognized clock rate %d\n", dotclock);
}
@@ -1637,3 +1665,17 @@ tga2_ics9110_wr(dc, dotclock)
bus_space_write_4(dc->dc_memt, clock, 0, 0x0);
bus_space_barrier(dc->dc_memt, clock, 0, 0, BUS_SPACE_BARRIER_WRITE);
}
+
+struct monitor *
+tga_getmonitor(dc)
+ struct tga_devconfig *dc;
+{
+ return &decmonitors[(~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f];
+}
+
+unsigned
+tga_getdotclock(dc)
+ struct tga_devconfig *dc;
+{
+ return tga_getmonitor(dc)->dotclock;
+}
diff --git a/sys/dev/pci/tga_conf.c b/sys/dev/pci/tga_conf.c
index 7834a9f05fa..2dbc0377295 100644
--- a/sys/dev/pci/tga_conf.c
+++ b/sys/dev/pci/tga_conf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tga_conf.c,v 1.4 2001/03/18 04:37:21 nate Exp $ */
-/* $NetBSD: tga_conf.c,v 1.3 2000/03/12 05:32:29 nathanw Exp $ */
+/* $OpenBSD: tga_conf.c,v 1.5 2002/04/01 11:26:32 matthieu Exp $ */
+/* $NetBSD: tga_conf.c,v 1.5 2001/11/13 07:48:49 lukem Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -37,6 +37,7 @@
#include <dev/ic/bt485var.h>
#include <dev/ic/bt463var.h>
+#include <dev/ic/ibm561var.h>
#undef KB
#define KB * 1024
@@ -114,6 +115,17 @@ static const struct tga_conf tga_configs[TGA_TYPE_UNKNOWN] = {
1, { 16 MB, 0 }, { 8 MB, 0 },
1, { 24 MB, 0 }, { 8 MB, 0 },
},
+ /* TGA_TYPE_POWERSTORM_4D20 */
+ /* XXX: These numbers may be incorrect */
+ {
+ "PS4d20",
+ ibm561_funcs,
+ 32,
+ 32 MB,
+ 16 KB,
+ 1, { 16 MB, 0 }, { 8 MB, 0 },
+ 1, { 24 MB, 0 }, { 8 MB, 0 },
+ },
};
#undef KB
@@ -125,13 +137,17 @@ tga_identify(dc)
{
int type;
int gder;
+ int grev;
int deep, addrmask, wide;
+ int tga2;
gder = TGARREG(dc, TGA_REG_GDER);
+ grev = TGARREG(dc, TGA_REG_GREV);
deep = (gder & 0x1) != 0; /* XXX */
addrmask = (gder >> 2) & 0x7; /* XXX */
wide = (gder & 0x200) == 0; /* XXX */
+ tga2 = (grev & 0x20) != 0;
type = TGA_TYPE_UNKNOWN;
@@ -159,6 +175,10 @@ tga_identify(dc)
}
} else {
/* 32bpp frame buffer */
+ if (addrmask == 0x00 && tga2 && wide) {
+ /* My PowerStorm 4d20 shows up this way? */
+ type = TGA_TYPE_POWERSTORM_4D20;
+ }
if (addrmask == 0x3) {
/* 16MB core map; T32-04 or T32-08 */
@@ -170,7 +190,7 @@ tga_identify(dc)
} else if (addrmask == 0x7) {
/* 32MB core map; T32-88 */
- if (wide) /* sanity */
+ if (wide && !tga2) /* sanity */
type = TGA_TYPE_T32_88;
}
}
@@ -188,4 +208,3 @@ tga_getconf(type)
return (NULL);
}
-
diff --git a/sys/dev/pci/tgavar.h b/sys/dev/pci/tgavar.h
index f29f81616f3..3f3bfb75076 100644
--- a/sys/dev/pci/tgavar.h
+++ b/sys/dev/pci/tgavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tgavar.h,v 1.5 2002/03/14 01:27:00 millert Exp $ */
+/* $OpenBSD: tgavar.h,v 1.6 2002/04/01 11:26:32 matthieu Exp $ */
/* $NetBSD: tgavar.h,v 1.8 2000/04/02 19:01:11 nathanw Exp $ */
/*
@@ -111,7 +111,8 @@ struct tga_softc {
#define TGA_TYPE_T32_04 4 /* 32bpp, 4MB */
#define TGA_TYPE_T32_08 5 /* 32bpp, 8MB */
#define TGA_TYPE_T32_88 6 /* 32bpp, 16MB */
-#define TGA_TYPE_UNKNOWN 7 /* unknown */
+#define TGA_TYPE_POWERSTORM_4D20 7 /* unknown */
+#define TGA_TYPE_UNKNOWN 8 /* unknown */
#define DEVICE_IS_TGA(class, id) \
(((PCI_VENDOR(id) == PCI_VENDOR_DEC && \