diff options
Diffstat (limited to 'sys/arch/mac68k/dev/grf_mv.c')
-rw-r--r-- | sys/arch/mac68k/dev/grf_mv.c | 367 |
1 files changed, 321 insertions, 46 deletions
diff --git a/sys/arch/mac68k/dev/grf_mv.c b/sys/arch/mac68k/dev/grf_mv.c index 939c3a8a29d..3660ee02950 100644 --- a/sys/arch/mac68k/dev/grf_mv.c +++ b/sys/arch/mac68k/dev/grf_mv.c @@ -1,5 +1,5 @@ -/* $OpenBSD: grf_mv.c,v 1.21 2005/04/26 21:09:35 martin Exp $ */ -/* $NetBSD: grf_mv.c,v 1.24 1997/05/03 02:29:54 briggs Exp $ */ +/* $OpenBSD: grf_mv.c,v 1.22 2005/05/01 17:04:52 martin Exp $ */ +/* $NetBSD: grf_nubus.c,v 1.62 2001/01/22 20:27:02 briggs Exp $ */ /* * Copyright (c) 1995 Allen Briggs. All rights reserved. @@ -12,10 +12,7 @@ * 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 Allen Briggs. - * 4. The name of the author may not be used to endorse or promote products + * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR @@ -48,16 +45,28 @@ #include <machine/grfioctl.h> #include <machine/viareg.h> -#include "nubus.h" -#include "grfvar.h" +#include <mac68k/dev/nubus.h> +#include <mac68k/dev/grfvar.h> static void load_image_data(caddr_t data, struct image_data *image); -static int grfmv_intr_generic(void *vsc); -static int grfmv_intr_radius(void *vsc); -static int grfmv_intr_cti(void *vsc); +static int grfmv_intr_generic_write1(void *vsc); +static int grfmv_intr_generic_write4(void *vsc); +static int grfmv_intr_generic_or4(void *vsc); + static int grfmv_intr_cb264(void *vsc); static int grfmv_intr_cb364(void *vsc); +static int grfmv_intr_cmax(void *vsc); +static int grfmv_intr_cti(void *vsc); +static int grfmv_intr_radius(void *vsc); +static int grfmv_intr_radius24(void *vsc); +static int grfmv_intr_supermacgfx(void *vsc); +static int grfmv_intr_lapis(void *vsc); +static int grfmv_intr_formac(void *vsc); +static int grfmv_intr_vimage(void *vsc); +static int grfmv_intr_gvimage(void *vsc); +static int grfmv_intr_radius_gsc(void *vsc); +static int grfmv_intr_radius_gx(void *vsc); static int grfmv_mode(struct grf_softc *gp, int cmd, void *arg); static caddr_t grfmv_phys(struct grf_softc *gp, vm_offset_t addr); @@ -137,11 +146,11 @@ grfmv_attach(parent, self, aux) nubus_dir dir, mode_dir; int mode; + bcopy(na->fmt, &sc->sc_slot, sizeof(nubus_slot)); + sc->sc_tag = na->na_tag; sc->card_id = na->drhw; - bcopy(na->fmt, &sc->sc_slot, sizeof(nubus_slot)); - if (bus_space_map(sc->sc_tag, NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &sc->sc_regh)) { printf(": grfmv_attach: failed to map slot %d\n", na->slot); @@ -193,17 +202,16 @@ bad: gm = &sc->curr_mode; gm->mode_id = mode; - gm->fbbase = (caddr_t)(sc->sc_regh + - m68k_trunc_page(image.offset)); /* XXX evil! */ - gm->fboff = image.offset & PGOFSET; - gm->rowbytes = image.rowbytes; + gm->ptype = image.pixelType; + gm->psize = image.pixelSize; gm->width = image.right - image.left; gm->height = image.bottom - image.top; - gm->fbsize = sc->curr_mode.height * sc->curr_mode.rowbytes; + gm->rowbytes = image.rowbytes; gm->hres = image.hRes; gm->vres = image.vRes; - gm->ptype = image.pixelType; - gm->psize = image.pixelSize; + gm->fbsize = gm->height * gm->rowbytes; + gm->fbbase = (caddr_t)sc->sc_regh; /* XXX evil hack */ + gm->fboff = image.offset; strncpy(cardname, nubus_get_card_name(sc->sc_tag, sc->sc_regh, &sc->sc_slot), CARD_NAME_LEN); @@ -225,51 +233,142 @@ bad: } switch (sc->card_id) { - case NUBUS_DRHW_M2HRVC: case NUBUS_DRHW_TFB: + case NUBUS_DRHW_M2HRVC: + case NUBUS_DRHW_PVC: sc->cli_offset = 0xa0000; sc->cli_value = 0; - add_nubus_intr(na->slot, grfmv_intr_generic, sc, + add_nubus_intr(na->slot, grfmv_intr_generic_write1, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_WVC: sc->cli_offset = 0xa00000; sc->cli_value = 0; - add_nubus_intr(na->slot, grfmv_intr_generic, sc, + add_nubus_intr(na->slot, grfmv_intr_generic_write1, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_COLORMAX: + add_nubus_intr(na->slot, grfmv_intr_cmax, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_SE30: + /* Do nothing--SE/30 interrupts are disabled */ + break; + case NUBUS_DRHW_MDC: + sc->cli_offset = 0x200148; + sc->cli_value = 1; + add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc, + sc->sc_dev.dv_xname); + + /* Enable interrupts; to disable, write 0x7 to this location */ + bus_space_write_4(sc->sc_tag, sc->sc_regh, 0x20013C, 5); + break; + case NUBUS_DRHW_CB264: + add_nubus_intr(na->slot, grfmv_intr_cb264, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_CB364: + add_nubus_intr(na->slot, grfmv_intr_cb364, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_RPC8: + sc->cli_offset = 0xfdff8f; + sc->cli_value = 0xff; + add_nubus_intr(na->slot, grfmv_intr_generic_write1, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_RPC8XJ: + sc->cli_value = 0x66; + add_nubus_intr(na->slot, grfmv_intr_radius, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_RPC24X: + case NUBUS_DRHW_BOOGIE: + sc->cli_value = 0x64; add_nubus_intr(na->slot, grfmv_intr_radius, sc, sc->sc_dev.dv_xname); break; + case NUBUS_DRHW_RPC24XP: + add_nubus_intr(na->slot, grfmv_intr_radius24, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_RADGSC: + add_nubus_intr(na->slot, grfmv_intr_radius_gsc, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_RDCGX: + case NUBUS_DRHW_MPGX: + add_nubus_intr(na->slot, grfmv_intr_radius_gx, sc, + sc->sc_dev.dv_xname); + break; case NUBUS_DRHW_FIILX: case NUBUS_DRHW_FIISXDSP: + case NUBUS_DRHW_FUTURASX: sc->cli_offset = 0xf05000; sc->cli_value = 0x80; - add_nubus_intr(na->slot, grfmv_intr_generic, sc, + add_nubus_intr(na->slot, grfmv_intr_generic_write1, sc, sc->sc_dev.dv_xname); break; case NUBUS_DRHW_SAM768: add_nubus_intr(na->slot, grfmv_intr_cti, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_SUPRGFX: + add_nubus_intr(na->slot, grfmv_intr_supermacgfx, sc, sc->sc_dev.dv_xname); break; - case NUBUS_DRHW_CB264: - add_nubus_intr(na->slot, grfmv_intr_cb264, sc, + case NUBUS_DRHW_SPECTRM8: + sc->cli_offset = 0x0de178; + sc->cli_value = 0x80; + add_nubus_intr(na->slot, grfmv_intr_generic_or4, sc, sc->sc_dev.dv_xname); break; - case NUBUS_DRHW_CB364: - add_nubus_intr(na->slot, grfmv_intr_cb364, sc, + case NUBUS_DRHW_LAPIS: + add_nubus_intr(na->slot, grfmv_intr_lapis, sc, sc->sc_dev.dv_xname); break; - case NUBUS_DRHW_SE30: - /* Do nothing--SE/30 interrupts are disabled */ + case NUBUS_DRHW_FORMAC: + add_nubus_intr(na->slot, grfmv_intr_formac, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_ROPS24LXI: + case NUBUS_DRHW_ROPS24XLTV: + case NUBUS_DRHW_ROPS24MXTV: + sc->cli_offset = 0xfb0010; + sc->cli_value = 0x00; + add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_ROPSPPGT: + sc->cli_offset = 0xf50010; + sc->cli_value = 0x02; + add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_VIMAGE: + add_nubus_intr(na->slot, grfmv_intr_vimage, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_GVIMAGE: + add_nubus_intr(na->slot, grfmv_intr_gvimage, sc, + sc->sc_dev.dv_xname); + break; + case NUBUS_DRHW_MC2124NB: + sc->cli_offset = 0xfd1000; + sc->cli_value = 0x00; + add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc, + sc->sc_dev.dv_xname); break; case NUBUS_DRHW_MICRON: - /* What do we know about this one? */ + sc->cli_offset = 0xa00014; + sc->cli_value = 0; + add_nubus_intr(na->slot, grfmv_intr_generic_write4, sc, + sc->sc_dev.dv_xname); + break; default: - printf("%s: Unknown video card 0x%x--", + printf("%s: Unknown video card ID 0x%x --", sc->sc_dev.dv_xname, sc->card_id); - printf("Not installing interrupt routine.\n"); + printf(" Not installing interrupt routine.\n"); break; } @@ -309,22 +408,58 @@ grfmv_phys(gp, addr) /* Interrupt handlers... */ /* * Generic routine to clear interrupts for cards where it simply takes - * a CLR.B to clear the interrupt. The offset of this byte varies between - * cards. + * a MOV.B to clear the interrupt. The offset and value of this byte + * varies between cards. */ /*ARGSUSED*/ static int -grfmv_intr_generic(vsc) +grfmv_intr_generic_write1(vsc) void *vsc; { struct grfbus_softc *sc = (struct grfbus_softc *)vsc; bus_space_write_1(sc->sc_tag, sc->sc_regh, + sc->cli_offset, (u_int8_t)sc->cli_value); + return (1); +} + +/* + * Generic routine to clear interrupts for cards where it simply takes + * a MOV.L to clear the interrupt. The offset and value of this byte + * varies between cards. + */ +/*ARGSUSED*/ +static int +grfmv_intr_generic_write4(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + + bus_space_write_4(sc->sc_tag, sc->sc_regh, sc->cli_offset, sc->cli_value); return (1); } /* + * Generic routine to clear interrupts for cards where it simply takes + * an OR.L to clear the interrupt. The offset and value of this byte + * varies between cards. + */ +/*ARGSUSED*/ +static int +grfmv_intr_generic_or4(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + unsigned long scratch; + + scratch = bus_space_read_4(sc->sc_tag, sc->sc_regh, sc->cli_offset); + scratch |= 0x80; + bus_space_write_4(sc->sc_tag, sc->sc_regh, sc->cli_offset, scratch); + return (1); +} + +/* * Routine to clear interrupts for the Radius PrecisionColor 8xj card. */ /*ARGSUSED*/ @@ -335,12 +470,7 @@ grfmv_intr_radius(vsc) struct grfbus_softc *sc = (struct grfbus_softc *)vsc; u_int8_t c; - /* - * The value 0x66 was the observed value on one card. It is read - * from the driver's information block, so this may not be sufficient. - * Then again, we're not setting up any other interrupts... - */ - c = 0x66; + c = sc->cli_value; c |= 0x80; bus_space_write_1(sc->sc_tag, sc->sc_regh, 0xd00403, c); @@ -350,6 +480,25 @@ grfmv_intr_radius(vsc) } /* + * Routine to clear interrupts for the Radius PrecisionColor 24Xp card. + * Is this what the 8xj routine is doing, too? + */ +/*ARGSUSED*/ +static int +grfmv_intr_radius24(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + u_int8_t c; + + c = 0x80 | bus_space_read_1(sc->sc_tag, sc->sc_regh, 0xfffd8); + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0xd00403, c); + c &= 0x7f; + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0xd00403, c); + return (1); +} + +/* * Routine to clear interrupts on Samsung 768x1006 video controller. * This controller was manufactured by Cornerstone Technology, Inc., * now known as Cornerstone Imaging. @@ -376,13 +525,14 @@ grfmv_intr_cti(vsc) /*ARGSUSED*/ static int -grfmv_intr_cb264(void *vsc) +grfmv_intr_cb264(vsc) + void *vsc; { struct grfbus_softc *sc; volatile char *slotbase; sc = (struct grfbus_softc *)vsc; - slotbase = (volatile char *)sc->sc_regh; /* XXX evil hack */ + slotbase = (volatile char *)sc->sc_regh; /* XXX evil hack */ asm volatile(" movl %0,a0 movl a0@(0xff6028),d0 andl #0x2,d0 @@ -430,13 +580,14 @@ grfmv_intr_cb264(void *vsc) */ /*ARGSUSED*/ static int -grfmv_intr_cb364(void *vsc) +grfmv_intr_cb364(vsc) + void *vsc; { struct grfbus_softc *sc; volatile char *slotbase; sc = (struct grfbus_softc *)vsc; - slotbase = (volatile char *)sc->sc_regh; /* XXX evil hack */ + slotbase = (volatile char *)sc->sc_regh; /* XXX evil hack */ asm volatile(" movl %0,a0 movl a0@(0xfe6028),d0 andl #0x2,d0 @@ -512,3 +663,127 @@ grfmv_intr_cb364(void *vsc) " : : "g" (slotbase) : "a0","d0","d1","d2"); return (1); } + +/* + * Interrupt clearing routine for SuperMac GFX card. + */ +/*ARGSUSED*/ +static int +grfmv_intr_supermacgfx(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + u_int8_t dummy; + + dummy = bus_space_read_1(sc->sc_tag, sc->sc_regh, 0xE70D3); + return (1); +} + +/* + * Routine to clear interrupts for the Sigma Designs ColorMax card. + */ +/*ARGSUSED*/ +static int +grfmv_intr_cmax(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + u_int32_t dummy; + + dummy = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0xf501c); + dummy = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0xf5018); + return (1); +} + +/* + * Routine to clear interrupts for the Lapis ProColorServer 8 PDS card + * (for the SE/30). + */ +/*ARGSUSED*/ +static int +grfmv_intr_lapis(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0xff7000, 0x08); + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0xff7000, 0x0C); + return (1); +} + +/* + * Routine to clear interrupts for the Formac Color Card II + */ +/*ARGSUSED*/ +static int +grfmv_intr_formac(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + u_int8_t dummy; + + dummy = bus_space_read_1(sc->sc_tag, sc->sc_regh, 0xde80db); + dummy = bus_space_read_1(sc->sc_tag, sc->sc_regh, 0xde80d3); + return (1); +} + +/* + * Routine to clear interrupts for the Vimage by Interware Co., Ltd. + */ +/*ARGSUSED*/ +static int +grfmv_intr_vimage(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x800000, 0x67); + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x800000, 0xE7); + return (1); +} + +/* + * Routine to clear interrupts for the Grand Vimage by Interware Co., Ltd. + */ +/*ARGSUSED*/ +static int +grfmv_intr_gvimage(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + u_int8_t dummy; + + dummy = bus_space_read_1(sc->sc_tag, sc->sc_regh, 0xf00000); + return (1); +} + +/* + * Routine to clear interrupts for the Radius GS/C + */ +/*ARGSUSED*/ +static int +grfmv_intr_radius_gsc(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + u_int8_t dummy; + + dummy = bus_space_read_1(sc->sc_tag, sc->sc_regh, 0xfb802); + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0xfb802, 0xff); + return (1); +} + +/* + * Routine to clear interrupts for the Radius GS/C + */ +/*ARGSUSED*/ +static int +grfmv_intr_radius_gx(vsc) + void *vsc; +{ + struct grfbus_softc *sc = (struct grfbus_softc *)vsc; + + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x600000, 0x00); + bus_space_write_1(sc->sc_tag, sc->sc_regh, 0x600000, 0x20); + return (1); +} |