Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci a preliminary driver for nvidia geforce graphics...



details:   https://anonhg.NetBSD.org/src/rev/f3b3ba25b066
branches:  trunk
changeset: 790092:f3b3ba25b066
user:      macallan <macallan%NetBSD.org@localhost>
date:      Wed Sep 18 14:30:45 2013 +0000

description:
a preliminary driver for nvidia geforce graphics chips
so far it only supports the GeForce 2MX, tested on macppc only
no acceleration yet, just some DAC setup
the main advantage over genfb is that this driver knows how to setup the
palette registers for the 2nd output

diffstat:

 sys/dev/pci/files.pci |    8 +-
 sys/dev/pci/gffb.c    |  622 ++++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/pci/gffbreg.h |   62 ++++
 3 files changed, 691 insertions(+), 1 deletions(-)

diffs (truncated from 712 to 300 lines):

diff -r 3872727e3ce8 -r f3b3ba25b066 sys/dev/pci/files.pci
--- a/sys/dev/pci/files.pci     Wed Sep 18 13:31:39 2013 +0000
+++ b/sys/dev/pci/files.pci     Wed Sep 18 14:30:45 2013 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.pci,v 1.366 2013/08/21 18:08:29 jakllsch Exp $
+#      $NetBSD: files.pci,v 1.367 2013/09/18 14:30:45 macallan Exp $
 #
 # Config file and device description for machine-independent PCI code.
 # Included by ports that need it.  Requires that the SCSI files be
@@ -1133,3 +1133,9 @@
 device tdvfb: wsemuldisplaydev, rasops16, rasops32, vcons, videomode
 attach tdvfb at pci
 file   dev/pci/tdvfb.c         tdvfb   
+
+# nvidia geforce framebuffer console driver
+device gffb: wsemuldisplaydev, rasops8, vcons, videomode, i2cbus, i2c_bitbang, glyphcache
+attach gffb at pci
+file   dev/pci/gffb.c          gffb
+defflag        opt_gffb.h      GFFB_DEBUG
diff -r 3872727e3ce8 -r f3b3ba25b066 sys/dev/pci/gffb.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/gffb.c        Wed Sep 18 14:30:45 2013 +0000
@@ -0,0 +1,622 @@
+/*     $NetBSD: gffb.c,v 1.1 2013/09/18 14:30:45 macallan Exp $        */
+
+/*
+ * Copyright (c) 2007, 2012 Michael Lorenz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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 nvidia geforce graphics controllers
+ * tested on macppc only so far
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: gffb.c,v 1.1 2013/09/18 14:30:45 macallan Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/lwp.h>
+#include <sys/kauth.h>
+
+#include <dev/videomode/videomode.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pciio.h>
+#include <dev/pci/gffbreg.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wsfont/wsfont.h>
+#include <dev/rasops/rasops.h>
+#include <dev/wscons/wsdisplay_vconsvar.h>
+#include <dev/pci/wsdisplay_pci.h>
+#include <dev/wscons/wsdisplay_glyphcachevar.h>
+
+#include <dev/i2c/i2cvar.h>
+
+#include "opt_gffb.h"
+#include "opt_vcons.h"
+
+#ifdef GFFB_DEBUG
+#define DPRINTF printf
+#else
+#define DPRINTF while(0) printf
+#endif
+
+struct gffb_softc {
+       device_t sc_dev;
+
+       pci_chipset_tag_t sc_pc;
+       pcitag_t sc_pcitag;
+
+       bus_space_tag_t sc_memt;
+       bus_space_tag_t sc_iot;
+
+       bus_space_handle_t sc_regh, sc_fbh;
+       bus_addr_t sc_fb, sc_reg;
+       bus_size_t sc_fbsize, sc_regsize;
+       uint8_t *sc_fbaddr;
+
+       int sc_width, sc_height, sc_depth, sc_stride;
+       int sc_locked;
+       struct vcons_screen sc_console_screen;
+       struct wsscreen_descr sc_defaultscreen_descr;
+       const struct wsscreen_descr *sc_screens[1];
+       struct wsscreen_list sc_screenlist;
+       struct vcons_data vd;
+       int sc_mode;
+       u_char sc_cmap_red[256];
+       u_char sc_cmap_green[256];
+       u_char sc_cmap_blue[256];
+       glyphcache sc_gc;
+};
+
+static int     gffb_match(device_t, cfdata_t, void *);
+static void    gffb_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(gffb, sizeof(struct gffb_softc),
+    gffb_match, gffb_attach, NULL, NULL);
+
+static int     gffb_ioctl(void *, void *, u_long, void *, int,
+                            struct lwp *);
+static paddr_t gffb_mmap(void *, void *, off_t, int);
+static void    gffb_init_screen(void *, struct vcons_screen *, int, long *);
+
+static int     gffb_putcmap(struct gffb_softc *, struct wsdisplay_cmap *);
+static int     gffb_getcmap(struct gffb_softc *, struct wsdisplay_cmap *);
+static void    gffb_restore_palette(struct gffb_softc *);
+static int     gffb_putpalreg(struct gffb_softc *, uint8_t, uint8_t,
+                           uint8_t, uint8_t);
+
+static void    gffb_init(struct gffb_softc *);
+
+#if notyet
+static void    gffb_flush_engine(struct gffb_softc *);
+static void    gffb_rectfill(struct gffb_softc *, int, int, int, int,
+                           uint32_t);
+static void    gffb_bitblt(void *, int, int, int, int, int,
+                           int, int);
+
+static void    gffb_cursor(void *, int, int, int);
+static void    gffb_putchar(void *, int, int, u_int, long);
+static void    gffb_putchar_aa(void *, int, int, u_int, long);
+static void    gffb_copycols(void *, int, int, int, int);
+static void    gffb_erasecols(void *, int, int, int, long);
+static void    gffb_copyrows(void *, int, int, int);
+static void    gffb_eraserows(void *, int, int, long);
+#endif /* notyet */
+
+struct wsdisplay_accessops gffb_accessops = {
+       gffb_ioctl,
+       gffb_mmap,
+       NULL,   /* alloc_screen */
+       NULL,   /* free_screen */
+       NULL,   /* show_screen */
+       NULL,   /* load_font */
+       NULL,   /* pollc */
+       NULL    /* scroll */
+};
+
+static int
+gffb_match(device_t parent, cfdata_t match, void *aux)
+{
+       struct pci_attach_args *pa = (struct pci_attach_args *)aux;
+
+       if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
+               return 0;
+       if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA)
+               return 0;
+
+       /* only card tested on so far - likely need a list */
+       if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NVIDIA_GEFORCE2MX)
+               return 100;
+       return (0);
+}
+
+static void
+gffb_attach(device_t parent, device_t self, void *aux)
+{
+       struct gffb_softc       *sc = device_private(self);
+       struct pci_attach_args  *pa = aux;
+       struct rasops_info      *ri;
+       bus_space_tag_t         tag;
+       struct wsemuldisplaydev_attach_args aa;
+       prop_dictionary_t       dict;
+       unsigned long           defattr;
+       bool                    is_console;
+       int                     i, j;
+       uint8_t                 cmap[768];
+
+       sc->sc_pc = pa->pa_pc;
+       sc->sc_pcitag = pa->pa_tag;
+       sc->sc_memt = pa->pa_memt;
+       sc->sc_iot = pa->pa_iot;
+       sc->sc_dev = self;
+
+       pci_aprint_devinfo(pa, NULL);
+
+       /* fill in parameters from properties */
+       dict = device_properties(self);
+       if (!prop_dictionary_get_uint32(dict, "width", &sc->sc_width)) {
+               aprint_error("%s: no width property\n", device_xname(self));
+               return;
+       }
+       if (!prop_dictionary_get_uint32(dict, "height", &sc->sc_height)) {
+               aprint_error("%s: no height property\n", device_xname(self));
+               return;
+       }
+
+#ifdef GLYPHCACHE_DEBUG
+       /* leave some visible VRAM unused so we can see the glyph cache */
+       sc->sc_height -= 200;
+#endif
+
+       if (!prop_dictionary_get_uint32(dict, "depth", &sc->sc_depth)) {
+               aprint_error("%s: no depth property\n", device_xname(self));
+               return;
+       }
+       if (!prop_dictionary_get_uint32(dict, "linebytes", &sc->sc_stride)) {
+               aprint_error("%s: no linebytes property\n",
+                   device_xname(self));
+               return;
+       }
+
+       prop_dictionary_get_bool(dict, "is_console", &is_console);
+
+       if (pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_MEM,
+           BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR,
+           &tag, &sc->sc_fbh, &sc->sc_fb, &sc->sc_fbsize)) {
+               aprint_error("%s: failed to map the framebuffer.\n",
+                   device_xname(sc->sc_dev));
+       }
+       sc->sc_fbaddr = bus_space_vaddr(tag, sc->sc_fbh);
+
+       if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, 0,
+           &tag, &sc->sc_regh, &sc->sc_reg, &sc->sc_regsize)) {
+               aprint_error("%s: failed to map registers.\n",
+                   device_xname(sc->sc_dev));
+       }
+
+       aprint_normal("%s: %d MB aperture at 0x%08x\n", device_xname(self),
+           (int)(sc->sc_fbsize >> 20), (uint32_t)sc->sc_fb);
+
+       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;
+       sc->sc_locked = 0;
+
+       vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
+           &gffb_accessops);
+       sc->vd.init_screen = gffb_init_screen;
+
+       /* init engine here */
+       gffb_init(sc);
+
+       ri = &sc->sc_console_screen.scr_ri;
+
+#if notyet
+       sc->sc_gc.gc_bitblt = gffb_bitblt;
+       sc->sc_gc.gc_blitcookie = sc;
+       sc->sc_gc.gc_rop = R128_ROP3_S;
+#endif
+
+       if (is_console) {
+               vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+                   &defattr);
+               sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+
+#if notyet
+               gffb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height,
+                   ri->ri_devcmap[(defattr >> 16) & 0xff]);
+#else
+               memset(sc->sc_fbaddr,
+                   ri->ri_devcmap[(defattr >> 16) & 0xff],
+                   sc->sc_height * sc->sc_stride);
+#endif
+               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;
+#if notyet
+               glyphcache_init(&sc->sc_gc, sc->sc_height + 5,
+                               (0x800000 / sc->sc_stride) - sc->sc_height - 5,
+                               sc->sc_width,
+                               ri->ri_font->fontwidth,



Home | Main Index | Thread Index | Old Index