The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pci/igsfb_pci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: igsfb_pci.c,v 1.7 2003/05/10 01:51:56 uwe Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2002, 2003 Valeriy E. Ushakov
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28  */
   29 
   30 /*
   31  * Integraphics Systems IGA 168x and CyberPro series.
   32  */
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: igsfb_pci.c,v 1.7 2003/05/10 01:51:56 uwe Exp $");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/kernel.h>
   39 #include <sys/device.h>
   40 #include <sys/malloc.h>
   41 #include <sys/buf.h>
   42 
   43 #ifdef __sparc__  /* XXX: this doesn't belong here */
   44 #include <machine/autoconf.h>
   45 #endif
   46 #include <machine/bus.h>
   47 #include <machine/intr.h>
   48 
   49 #include <dev/pci/pcivar.h>
   50 #include <dev/pci/pcireg.h>
   51 #include <dev/pci/pcidevs.h>
   52 
   53 #include <dev/wscons/wsdisplayvar.h>
   54 #include <dev/wscons/wsconsio.h>
   55 #include <dev/rasops/rasops.h>
   56 
   57 #include <dev/ic/igsfbreg.h>
   58 #include <dev/ic/igsfbvar.h>
   59 #include <dev/pci/igsfb_pcivar.h>
   60 
   61 
   62 static int      igsfb_pci_match_by_id(pcireg_t);
   63 static int      igsfb_pci_map_regs(struct igsfb_devconfig *,
   64                                    bus_space_tag_t, bus_space_tag_t,
   65                                    pci_chipset_tag_t,
   66                                    pcitag_t, pci_product_id_t);
   67 static int      igsfb_pci_is_console(pci_chipset_tag_t, pcitag_t);
   68 
   69 static int igsfb_pci_console = 0;
   70 static pcitag_t igsfb_pci_constag;
   71 
   72 
   73 
   74 static int      igsfb_pci_match(struct device *, struct cfdata *, void *);
   75 static void     igsfb_pci_attach(struct device *, struct device *, void *);
   76 
   77 CFATTACH_DECL(igsfb_pci, sizeof(struct igsfb_softc),
   78     igsfb_pci_match, igsfb_pci_attach, NULL, NULL);
   79 
   80 
   81 static int
   82 igsfb_pci_match_by_id(id)
   83         pcireg_t id;
   84 {
   85 
   86         if (PCI_VENDOR(id) != PCI_VENDOR_INTEGRAPHICS)
   87                 return (0);
   88 
   89         switch (PCI_PRODUCT(id)) {
   90         case PCI_PRODUCT_INTEGRAPHICS_IGA1682:          /* FALLTHROUGH */
   91         case PCI_PRODUCT_INTEGRAPHICS_CYBERPRO2000:     /* FALLTHROUGH */
   92         case PCI_PRODUCT_INTEGRAPHICS_CYBERPRO2010:
   93                 return (1);
   94         default:
   95                 return (0);
   96         }
   97 }
   98 
   99 
  100 int
  101 igsfb_pci_cnattach(iot, memt, pc, bus, device, function)
  102         bus_space_tag_t iot, memt;
  103         pci_chipset_tag_t pc;
  104         int bus, device, function;
  105 {
  106         struct igsfb_devconfig *dc;
  107         pcitag_t tag;
  108         pcireg_t id;
  109         int ret;
  110 
  111         tag = pci_make_tag(pc, bus, device, function);
  112         id = pci_conf_read(pc, tag, PCI_ID_REG);
  113 
  114         if (igsfb_pci_match_by_id(id) == 0)
  115                 return (1);
  116 
  117         dc = &igsfb_console_dc;
  118         if (igsfb_pci_map_regs(dc, iot, memt, pc, tag, PCI_PRODUCT(id)) != 0)
  119                 return (1);
  120 
  121         ret = igsfb_enable(dc->dc_iot, dc->dc_iobase, dc->dc_ioflags);
  122         if (ret)
  123                 return (ret);
  124 
  125         ret = igsfb_cnattach_subr(dc);
  126         if (ret)
  127                 return (ret);
  128 
  129         igsfb_pci_console = 1;
  130         igsfb_pci_constag = tag;
  131 
  132         return (0);
  133 }
  134 
  135 
  136 static int
  137 igsfb_pci_is_console(pc, tag)
  138         pci_chipset_tag_t pc;
  139         pcitag_t tag;
  140 {
  141 
  142         return (igsfb_pci_is_console && (tag == igsfb_pci_constag));
  143 }
  144 
  145 
  146 static int
  147 igsfb_pci_match(parent, match, aux)
  148         struct device *parent;
  149         struct cfdata *match;
  150         void *aux;
  151 {
  152         struct pci_attach_args *pa = aux;
  153 
  154         return (igsfb_pci_match_by_id(pa->pa_id));
  155 }
  156 
  157 
  158 static void
  159 igsfb_pci_attach(parent, self, aux)
  160         struct device *parent, *self;
  161         void *aux;
  162 {
  163         struct igsfb_softc *sc = (struct igsfb_softc *)self;
  164         struct pci_attach_args *pa = aux;
  165         int isconsole;
  166         char devinfo[256];
  167 
  168         pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
  169         printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
  170 
  171 
  172 #if defined(__sparc__) && !defined(KRUPS_FORCE_SERIAL_CONSOLE)
  173         /* XXX: this doesn't belong here */
  174         if (PCITAG_NODE(pa->pa_tag) == prom_instance_to_package(prom_stdout()))
  175         {
  176                 int b, d, f;
  177 
  178                 pci_decompose_tag(pa->pa_pc, pa->pa_tag, &b, &d, &f);
  179                 igsfb_pci_cnattach(pa->pa_iot, pa->pa_memt, pa->pa_pc, b,d,f);
  180         }
  181 #endif
  182 
  183         isconsole = 0;
  184         if (igsfb_pci_is_console(pa->pa_pc, pa->pa_tag)) {
  185                 sc->sc_dc = &igsfb_console_dc;
  186                 isconsole = 1;
  187         } else {
  188                 sc->sc_dc = malloc(sizeof(struct igsfb_devconfig),
  189                                    M_DEVBUF, M_NOWAIT | M_ZERO);
  190                 if (sc->sc_dc == NULL)
  191                         panic("unable to allocate igsfb_devconfig");
  192                 if (igsfb_pci_map_regs(sc->sc_dc,
  193                             pa->pa_iot, pa->pa_memt, pa->pa_pc,
  194                             pa->pa_tag, PCI_PRODUCT(pa->pa_id)) != 0)
  195                 {
  196                         printf("unable to map device registers\n");
  197                         free(sc->sc_dc, M_DEVBUF);
  198                         sc->sc_dc = NULL;
  199                         return;
  200                 }
  201 
  202                 igsfb_enable(sc->sc_dc->dc_iot, sc->sc_dc->dc_iobase,
  203                              sc->sc_dc->dc_ioflags);
  204         }
  205 
  206         igsfb_attach_subr(sc, isconsole);
  207 }
  208 
  209 
  210 /*
  211  * Init memory and i/o bus space tags.  Map device registers.
  212  * Use memory space mapped i/o space access for i/o registers
  213  * for CyberPro cards.
  214  */
  215 static int
  216 igsfb_pci_map_regs(dc, iot, memt, pc, tag, id)
  217         struct igsfb_devconfig *dc;
  218         bus_space_tag_t iot, memt;
  219         pci_chipset_tag_t pc;
  220         pcitag_t tag;
  221         pci_product_id_t id;
  222 {
  223 
  224         dc->dc_id = id;
  225 
  226         /*
  227          * Configure memory space first since for CyberPro we use
  228          * memory-mapped i/o access.  Note that we are NOT mapping any
  229          * of it yet.  (XXX: search for memory BAR?)
  230          */
  231 #define IGS_MEM_MAPREG (PCI_MAPREG_START + 0)
  232 
  233         dc->dc_memt = memt;
  234         if (pci_mapreg_info(pc, tag,
  235                 IGS_MEM_MAPREG, PCI_MAPREG_TYPE_MEM,
  236                 &dc->dc_memaddr, &dc->dc_memsz, &dc->dc_memflags) != 0)
  237         {
  238                 printf("unable to configure memory space\n");
  239                 return (1);
  240         }
  241 
  242         /*
  243          * Configure I/O space.  On CyberPro use MMIO.  IGS 168x doesn't
  244          * have a BAR for its i/o space, so we have to hardcode it.
  245          */
  246         if (id >= PCI_PRODUCT_INTEGRAPHICS_CYBERPRO2000) {
  247                 dc->dc_iot = dc->dc_memt;
  248                 dc->dc_iobase = dc->dc_memaddr | IGS_MEM_MMIO_SELECT;
  249                 dc->dc_ioflags = dc->dc_memflags;
  250         } else {
  251                 dc->dc_iot = iot;
  252                 dc->dc_iobase = 0;
  253                 dc->dc_ioflags = 0;
  254         }
  255 
  256         /*
  257          * Map I/O registers.  This is done in bus glue, not in common
  258          * code because on e.g. ISA bus we'd need to access registers
  259          * to obtain/program linear memory location.
  260          */
  261         if (bus_space_map(dc->dc_iot,
  262                           dc->dc_iobase + IGS_REG_BASE, IGS_REG_SIZE,
  263                           dc->dc_ioflags,
  264                           &dc->dc_ioh) != 0)
  265         {
  266                 printf("unable to map I/O registers\n");
  267                 return (1);
  268         }
  269 
  270         return (0);
  271 }

Cache object: faa28d77d036b14d8817544f5487abbf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.