Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add 3Dfx Voodoo2 driver. Still needs some cleanu...
details: https://anonhg.NetBSD.org/src/rev/b2cc5ce12aac
branches: trunk
changeset: 780277:b2cc5ce12aac
user: rkujawa <rkujawa%NetBSD.org@localhost>
date: Wed Jul 18 23:30:13 2012 +0000
description:
Add 3Dfx Voodoo2 driver. Still needs some cleanup and prettyfying, but hey
it works.
diffstat:
sys/dev/pci/files.pci | 8 +-
sys/dev/pci/tdvfb.c | 753 +++++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/pci/tdvfbreg.h | 179 +++++++++++
sys/dev/pci/tdvfbvar.h | 84 +++++
4 files changed, 1023 insertions(+), 1 deletions(-)
diffs (truncated from 1047 to 300 lines):
diff -r 9219b2f7bab4 -r b2cc5ce12aac sys/dev/pci/files.pci
--- a/sys/dev/pci/files.pci Wed Jul 18 22:22:26 2012 +0000
+++ b/sys/dev/pci/files.pci Wed Jul 18 23:30:13 2012 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.pci,v 1.357 2012/04/19 17:50:51 bouyer Exp $
+# $NetBSD: files.pci,v 1.358 2012/07/18 23:30:13 rkujawa Exp $
#
# Config file and device description for machine-independent PCI code.
# Included by ports that need it. Requires that the SCSI files be
@@ -1112,3 +1112,9 @@
device lynxfb: wsemuldisplaydev, rasops16
attach lynxfb at pci
file dev/pci/lynxfb.c lynxfb needs-flag
+
+# 3Dfx Voodoo Graphics
+defflag opt_tdvfb.h TDVFB_CONSOLE
+device tdvfb: wsemuldisplaydev, rasops8, vcons, videomode
+attach tdvfb at pci
+file dev/pci/tdvfb.c tdvfb
diff -r 9219b2f7bab4 -r b2cc5ce12aac sys/dev/pci/tdvfb.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/tdvfb.c Wed Jul 18 23:30:13 2012 +0000
@@ -0,0 +1,753 @@
+/* $NetBSD: tdvfb.c,v 1.1 2012/07/18 23:30:14 rkujawa Exp $ */
+
+/*
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Radoslaw Kujawa.
+ *
+ * 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 AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * A console driver for 3Dfx Voodoo2 (CVG).
+ *
+ * 3Dfx Glide 2.x source code, Linux driver by Ghozlane Toumi, and
+ * "Voodoo2 Graphics Engine for 3D Game Acceleration" document were used as
+ * reference. wscons attachment code based mostly on genfb by Michael
+ * Lorenz.
+ *
+ * This driver currently only support boards with ICS GENDAC (which seems to
+ * be most popular, however at least two different DACs were used with CVG).
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tdvfb.c,v 1.1 2012/07/18 23:30:14 rkujawa Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/endian.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pciio.h>
+
+#include <dev/pci/tdvfbreg.h>
+#include <dev/pci/tdvfbvar.h>
+
+#include <dev/videomode/videomode.h>
+
+#include "opt_wsemul.h"
+#include "opt_tdvfb.h"
+
+#define MAXLOOP 4096
+
+static int tdvfb_match(device_t, cfdata_t, void *);
+static void tdvfb_attach(device_t, device_t, void *);
+
+static uint32_t tdvfb_cvg_read(struct tdvfb_softc *sc, uint32_t reg);
+static void tdvfb_cvg_write(struct tdvfb_softc *sc, uint32_t reg,
+ uint32_t val);
+static void tdvfb_cvg_set(struct tdvfb_softc *sc, uint32_t reg,
+ uint32_t bits);
+static void tdvfb_cvg_unset(struct tdvfb_softc *sc, uint32_t reg,
+ uint32_t bits);
+static uint8_t tdvfb_cvg_dac_read(struct tdvfb_softc *sc, uint32_t reg);
+void tdvfb_cvg_dac_write(struct tdvfb_softc *sc, uint32_t reg,
+ uint32_t val);
+static void tdvfb_wait(struct tdvfb_softc *sc);
+
+static bool tdvfb_init(struct tdvfb_softc *sc);
+static void tdvfb_fbiinit_defaults(struct tdvfb_softc *sc);
+static size_t tdvfb_mem_size(struct tdvfb_softc *sc);
+
+static bool tdvfb_videomode_set(struct tdvfb_softc *sc);
+static void tdvfb_videomode_dac(struct tdvfb_softc *sc);
+
+static bool tdvfb_gendac_detect(struct tdvfb_softc *sc);
+static struct tdvfb_dac_timing tdvfb_gendac_calc_pll(int freq);
+static void tdvfb_gendac_set_cvg_timing(struct tdvfb_softc *sc,
+ struct tdvfb_dac_timing *timing);
+static void tdvfb_gendac_set_vid_timing(struct tdvfb_softc *sc,
+ struct tdvfb_dac_timing *timing);
+
+static void tdvfb_init_screen(void *cookie, struct vcons_screen *scr,
+ int existing, long *defattr);
+static void tdvfb_init_palette(struct tdvfb_softc *sc);
+
+CFATTACH_DECL_NEW(tdvfb, sizeof(struct tdvfb_softc),
+ tdvfb_match, tdvfb_attach, NULL, NULL);
+
+static int
+tdvfb_match(device_t parent, cfdata_t match, void *aux)
+{
+ const struct pci_attach_args *pa = (const struct pci_attach_args *)aux;
+
+ if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_3DFX) &&
+ (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3DFX_VOODOO2))
+ return 100;
+
+ return 0;
+}
+
+static void
+tdvfb_attach(device_t parent, device_t self, void *aux)
+{
+ struct tdvfb_softc *sc = device_private(self);
+ struct wsemuldisplaydev_attach_args ws_aa;
+ struct rasops_info *ri;
+ const struct pci_attach_args *pa = aux;
+ pcireg_t screg;
+ bool console;
+ long defattr;
+
+#ifdef TDVFB_CONSOLE
+ console = true;
+#else
+ console = false;
+#endif
+
+ sc->sc_pc = pa->pa_pc;
+ sc->sc_pcitag = pa->pa_tag;
+ sc->sc_dev = self;
+
+ screg = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ PCI_COMMAND_STATUS_REG);
+ screg |= PCI_COMMAND_MEM_ENABLE;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG,
+ screg);
+
+ pci_aprint_devinfo(pa, NULL);
+
+ /* map the BAR */
+ if (pci_mapreg_map(pa, TDV_MM_BAR, PCI_MAPREG_TYPE_MEM, 0,
+ &sc->sc_cvgt, &sc->sc_cvgh, &sc->sc_cvg_pa, 0) != 0 ) {
+ aprint_error_dev(sc->sc_dev, "unable to map CVG BAR");
+ return;
+ }
+
+ /* Map the framebuffer. */
+ if (bus_space_subregion(sc->sc_cvgt, sc->sc_cvgh, TDV_OFF_FB,
+ TDV_FB_SIZE, &sc->sc_fbh)) {
+ aprint_error_dev(sc->sc_dev, "unable to map the framebuffer");
+ }
+
+ aprint_normal_dev(sc->sc_dev, "CVG at 0x%08x, fb at 0x%08x\n",
+ sc->sc_cvg_pa, sc->sc_cvg_pa + TDV_OFF_FB);
+
+ /* Do the low level setup. */
+ if (!tdvfb_init(sc)) {
+ aprint_error_dev(sc->sc_dev, "could not initialize CVG\n");
+ return;
+ }
+
+ /*
+ * The card is alive now, let's check how much framebuffer memory
+ * do we have.
+ */
+ sc->sc_memsize = tdvfb_mem_size(sc);
+
+ /* Select video mode, 800x600x60 by default... */
+ sc->sc_width = 800;
+ sc->sc_height = 600;
+ sc->sc_bpp = 32;
+ sc->sc_linebytes = 1024 * (sc->sc_bpp / 8);
+ sc->sc_videomode = pick_mode_by_ref(sc->sc_width, sc->sc_height, 60);
+
+ tdvfb_videomode_set(sc);
+
+ sc->sc_defaultscreen_descr = (struct wsscreen_descr){
+ "default",
+ 0, 0,
+ NULL,
+ 8, 16,
+ WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
+ NULL
+ };
+ sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
+ sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
+ sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
+
+ vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
+ &sc->sc_accessops);
+ sc->vd.init_screen = tdvfb_init_screen;
+
+ ri = &sc->sc_console_screen.scr_ri;
+
+ tdvfb_init_palette(sc);
+
+ if (console) {
+ vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+ &defattr);
+
+ sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC |
+ VCONS_DONT_READ;
+ vcons_redraw_screen(&sc->sc_console_screen);
+
+ sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
+ sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
+ sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
+ sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
+
+ wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
+ defattr);
+ vcons_replay_msgbuf(&sc->sc_console_screen);
+ } else if (sc->sc_console_screen.scr_ri.ri_rows == 0) {
+ vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+ &defattr);
+ }
+
+ ws_aa.console = console;
+ ws_aa.scrdata = &sc->sc_screenlist;
+ ws_aa.accessops = &sc->sc_accessops;
+ ws_aa.accesscookie = &sc->vd;
+
+ config_found(sc->sc_dev, &ws_aa, wsemuldisplaydevprint);
+}
+
+static void
+tdvfb_init_palette(struct tdvfb_softc *sc)
+{
+ int i, j;
+
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ sc->sc_cmap_red[i] = rasops_cmap[j];
+ sc->sc_cmap_green[i] = rasops_cmap[j + 1];
+ sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
+ j += 3;
+ }
+}
+
+static void
+tdvfb_init_screen(void *cookie, struct vcons_screen *scr, int existing,
+ long *defattr)
+{
+ struct tdvfb_softc *sc = cookie;
+ struct rasops_info *ri = &scr->scr_ri;
+
+ wsfont_init();
+
+ ri->ri_depth = sc->sc_bpp;
+ ri->ri_width = sc->sc_width;
+ ri->ri_height = sc->sc_height;
+ ri->ri_stride = sc->sc_linebytes;
+ ri->ri_flg = RI_CENTER;
+ ri->ri_bits = (char *) bus_space_vaddr(sc->sc_cvgt, sc->sc_fbh);
+
+ scr->scr_flags |= VCONS_DONT_READ;
+
+ rasops_init(ri, 0, 0);
+ ri->ri_caps = WSSCREEN_WSCOLORS;
+ rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
+ sc->sc_width / ri->ri_font->fontwidth);
+
+ ri->ri_hw = scr;
+}
+
+static bool
+tdvfb_videomode_set(struct tdvfb_softc *sc)
+{
+ uint32_t fbiinit1, fbiinit5, fbiinit6, lfbmode;
+ uint16_t vbackporch, vsyncon, vsyncoff;
+ uint16_t hbackporch, hsyncon, hsyncoff;
+ uint16_t yheight, xwidth;
+
Home |
Main Index |
Thread Index |
Old Index