diff options
author | 2002-04-01 11:26:32 +0000 | |
---|---|---|
committer | 2002-04-01 11:26:32 +0000 | |
commit | e00d3f43a0a0d44f25d7d19c35affde653e3966d (patch) | |
tree | 93b23bc9f6545f2f276285dff43463e4f19a52c2 | |
parent | Only call dc_ramdac_intr if initialized(). Fixes a panic when (diff) | |
download | wireguard-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.c | 3 | ||||
-rw-r--r-- | sys/dev/ic/bt485.c | 3 | ||||
-rw-r--r-- | sys/dev/ic/ibm561.c | 524 | ||||
-rw-r--r-- | sys/dev/ic/ibm561reg.h | 81 | ||||
-rw-r--r-- | sys/dev/ic/ibm561var.h | 48 | ||||
-rw-r--r-- | sys/dev/ic/ramdac.h | 6 | ||||
-rw-r--r-- | sys/dev/pci/files.pci | 3 | ||||
-rw-r--r-- | sys/dev/pci/tga.c | 102 | ||||
-rw-r--r-- | sys/dev/pci/tga_conf.c | 27 | ||||
-rw-r--r-- | sys/dev/pci/tgavar.h | 5 |
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 && \ |