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/sparc64/creator/creator_upa.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 /*-
    2  * Copyright (c) 2003 Jake Burkholder.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: releng/6.3/sys/sparc64/creator/creator_upa.c 147880 2005-07-10 11:16:34Z marius $");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/bus.h>
   33 #include <sys/conf.h>
   34 #include <sys/consio.h>
   35 #include <sys/eventhandler.h>
   36 #include <sys/fbio.h>
   37 #include <sys/kernel.h>
   38 #include <sys/module.h>
   39 
   40 #include <machine/bus.h>
   41 #include <machine/resource.h>
   42 
   43 #include <sys/rman.h>
   44 
   45 #include <dev/ofw/openfirm.h>
   46 
   47 #include <dev/fb/fbreg.h>
   48 #include <dev/syscons/syscons.h>
   49 
   50 #include <machine/nexusvar.h>
   51 #include <machine/ofw_upa.h>
   52 
   53 #include <sparc64/creator/creator.h>
   54 
   55 static int creator_upa_attach(device_t dev);
   56 static int creator_upa_probe(device_t dev);
   57 
   58 static d_open_t creator_open;
   59 static d_close_t creator_close;
   60 static d_ioctl_t creator_ioctl;
   61 static d_mmap_t creator_mmap;
   62 
   63 static void creator_shutdown(void *v);
   64 
   65 static device_method_t creator_upa_methods[] = {
   66         DEVMETHOD(device_probe,         creator_upa_probe),
   67         DEVMETHOD(device_attach,        creator_upa_attach),
   68 
   69         { 0, 0 }
   70 };
   71 
   72 static driver_t creator_upa_driver = {
   73         CREATOR_DRIVER_NAME,
   74         creator_upa_methods,
   75         sizeof(struct creator_softc),
   76 };
   77 
   78 static devclass_t creator_upa_devclass;
   79 
   80 static struct cdevsw creator_devsw = {
   81         .d_version =    D_VERSION,
   82         .d_flags =      D_NEEDGIANT,
   83         .d_open =       creator_open,
   84         .d_close =      creator_close,
   85         .d_ioctl =      creator_ioctl,
   86         .d_mmap =       creator_mmap,
   87         .d_name =       "fb",
   88 };
   89 
   90 struct ffb_map {
   91         uint64_t fm_virt;
   92         uint64_t fm_phys;
   93         uint64_t fm_size;
   94 };
   95 
   96 static const struct ffb_map ffb_map[] = {
   97         { FFB_VIRT_SFB8R,       FFB_PHYS_SFB8R,         0x00400000 },
   98         { FFB_VIRT_SFB8G,       FFB_PHYS_SFB8G,         0x00400000 },
   99         { FFB_VIRT_SFB8B,       FFB_PHYS_SFB8B,         0x00400000 },
  100         { FFB_VIRT_SFB8X,       FFB_PHYS_SFB8X,         0x00400000 },
  101         { FFB_VIRT_SFB32,       FFB_PHYS_SFB32,         0x01000000 },
  102         { FFB_VIRT_SFB64,       FFB_PHYS_SFB64,         0x02000000 },
  103         { FFB_VIRT_FBC,         FFB_PHYS_FBC,           0x00002000 },
  104         { FFB_VIRT_FBC_BM,      FFB_PHYS_FBC_BM,        0x00002000 },
  105         { FFB_VIRT_DFB8R,       FFB_PHYS_DFB8R,         0x00400000 },
  106         { FFB_VIRT_DFB8G,       FFB_PHYS_DFB8G,         0x00400000 },
  107         { FFB_VIRT_DFB8B,       FFB_PHYS_DFB8B,         0x00400000 },
  108         { FFB_VIRT_DFB8X,       FFB_PHYS_DFB8X,         0x00400000 },
  109         { FFB_VIRT_DFB24,       FFB_PHYS_DFB24,         0x01000000 },
  110         { FFB_VIRT_DFB32,       FFB_PHYS_DFB32,         0x01000000 },
  111         { FFB_VIRT_DFB422A,     FFB_PHYS_DFB422A,       0x00800000 },
  112         { FFB_VIRT_DFB422AD,    FFB_PHYS_DFB422AD,      0x00800000 },
  113         { FFB_VIRT_DFB24B,      FFB_PHYS_DFB24B,        0x01000000 },
  114         { FFB_VIRT_DFB422B,     FFB_PHYS_DFB422B,       0x00800000 },
  115         { FFB_VIRT_DFB422BD,    FFB_PHYS_DFB422BD,      0x00800000 },
  116         { FFB_VIRT_SFB16Z,      FFB_PHYS_SFB16Z,        0x00800000 },
  117         { FFB_VIRT_SFB8Z,       FFB_PHYS_SFB8Z,         0x00800000 },
  118         { FFB_VIRT_SFB422,      FFB_PHYS_SFB422,        0x00800000 },
  119         { FFB_VIRT_SFB422D,     FFB_PHYS_SFB422D,       0x00800000 },
  120         { FFB_VIRT_FBC_KREG,    FFB_PHYS_FBC_KREG,      0x00002000 },
  121         { FFB_VIRT_DAC,         FFB_PHYS_DAC,           0x00002000 },
  122         { FFB_VIRT_PROM,        FFB_PHYS_PROM,          0x00010000 },
  123         { FFB_VIRT_EXP,         FFB_PHYS_EXP,           0x00002000 },
  124         { 0x0,                  0x0,                    0x00000000 }
  125 };
  126 
  127 DRIVER_MODULE(creator, nexus, creator_upa_driver, creator_upa_devclass, 0, 0);
  128 
  129 static int
  130 creator_upa_probe(device_t dev)
  131 {
  132         const char *name;
  133         phandle_t node;
  134         int type;
  135 
  136         name = nexus_get_name(dev);
  137         node = nexus_get_node(dev);
  138         if (strcmp(name, "SUNW,ffb") == 0) {
  139                 if (OF_getprop(node, "board_type", &type, sizeof(type)) == -1)
  140                         return (ENXIO);
  141                 switch (type & 7) {
  142                 case 0x0:
  143                         device_set_desc(dev, "Creator");
  144                         break;
  145                 case 0x3:
  146                         device_set_desc(dev, "Creator3D");
  147                         break;
  148                 default:
  149                         return (ENXIO);
  150                 }
  151         } else if (strcmp(name, "SUNW,afb") == 0)
  152                 device_set_desc(dev, "Elite3D");
  153         else
  154                 return (ENXIO);
  155         return (BUS_PROBE_DEFAULT);
  156 }
  157 
  158 static int
  159 creator_upa_attach(device_t dev)
  160 {
  161         struct creator_softc *sc;
  162         struct upa_regs *reg;
  163         video_switch_t *sw;
  164         phandle_t node;
  165         bus_addr_t phys;
  166         bus_size_t size;
  167         int error;
  168         int nreg;
  169         int unit;
  170         int i;
  171 
  172         node = nexus_get_node(dev);
  173         if ((sc = (struct creator_softc *)vid_get_adapter(vid_find_adapter(
  174             CREATOR_DRIVER_NAME, 0))) != NULL && sc->sc_node == node) {
  175                 device_printf(dev, "console\n");
  176                 device_set_softc(dev, sc);
  177         } else {
  178                 sc = device_get_softc(dev);
  179                 bzero(sc, sizeof(struct creator_softc));
  180                 sc->sc_node = node;
  181                 nreg = nexus_get_nreg(dev);
  182                 reg = nexus_get_reg(dev);
  183                 for (i = 0; i < nreg; i++) {
  184                         phys = UPA_REG_PHYS(reg + i);
  185                         size = UPA_REG_SIZE(reg + i);
  186                         sc->sc_rid[i] = 0;
  187                         sc->sc_reg[i] = bus_alloc_resource(dev, SYS_RES_MEMORY,
  188                             &sc->sc_rid[i], phys, phys + size - 1, size,
  189                             RF_ACTIVE);
  190                         if (sc->sc_reg[i] == NULL) {
  191                                 device_printf(dev,
  192                                     "cannot allocate resources\n");
  193                                 error = ENXIO;
  194                                 goto fail;
  195                         }
  196                         sc->sc_bt[i] = rman_get_bustag(sc->sc_reg[i]);
  197                         sc->sc_bh[i] = rman_get_bushandle(sc->sc_reg[i]);
  198                 }
  199                 if (strcmp(nexus_get_name(dev), "SUNW,afb") == 0)
  200                         sc->sc_flags |= CREATOR_AFB;
  201                 if ((sw = vid_get_switch(CREATOR_DRIVER_NAME)) == NULL) {
  202                         device_printf(dev, "cannot get video switch\n");
  203                         error = ENODEV;
  204                         goto fail;
  205                 }
  206                 /*
  207                  * During device configuration we don't necessarily probe
  208                  * the adapter which is the console first so we can't use
  209                  * the device unit number for the video adapter unit. The
  210                  * worst case would be that we use the video adapter unit
  211                  * 0 twice. As it doesn't really matter which unit number
  212                  * the corresponding video adapter has just use the next
  213                  * unused one.
  214                  */
  215                 for (i = 0; i < devclass_get_maxunit(creator_upa_devclass); i++)
  216                         if (vid_find_adapter(CREATOR_DRIVER_NAME, i) < 0)
  217                                 break;
  218                 if ((error = sw->init(i, &sc->sc_va, 0)) != 0) {
  219                         device_printf(dev, "cannot initialize adapter\n");
  220                         goto fail;
  221                 }
  222         }
  223 
  224         if (bootverbose) {
  225                 if (sc->sc_flags & CREATOR_PAC1)
  226                         device_printf(dev,
  227                             "BT9068/PAC1 RAMDAC (%s cursor control)\n",
  228                             sc->sc_flags & CREATOR_CURINV ? "inverted" :
  229                             "normal");
  230                 else
  231                         device_printf(dev, "BT498/PAC2 RAMDAC\n");
  232         }
  233         device_printf(dev, "resolution %dx%d\n", sc->sc_width, sc->sc_height);
  234 
  235         unit = device_get_unit(dev);
  236         sc->sc_si = make_dev(&creator_devsw, unit, UID_ROOT, GID_WHEEL,
  237             0600, "fb%d", unit);
  238         sc->sc_si->si_drv1 = sc;
  239 
  240         EVENTHANDLER_REGISTER(shutdown_final, creator_shutdown, sc,
  241             SHUTDOWN_PRI_DEFAULT);
  242 
  243         return (0);
  244 
  245  fail:
  246         for (i = 0; i < FFB_NREG; i++)
  247                 if (sc->sc_reg[i] != NULL)
  248                         bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid[i],
  249                             sc->sc_reg[i]);
  250         return (error);
  251 }
  252 
  253 static int
  254 creator_open(struct cdev *dev, int flags, int mode, struct thread *td)
  255 {
  256 
  257         return (0);
  258 }
  259 
  260 static int
  261 creator_close(struct cdev *dev, int flags, int mode, struct thread *td)
  262 {
  263 
  264         return (0);
  265 }
  266 
  267 static int
  268 creator_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags,
  269     struct thread *td)
  270 {
  271         struct creator_softc *sc;
  272 
  273         sc = dev->si_drv1;
  274         return ((*vidsw[sc->sc_va.va_index]->ioctl)(&sc->sc_va, cmd, data));
  275 }
  276 
  277 static int
  278 creator_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int prot)
  279 {
  280         struct creator_softc *sc;
  281         const struct ffb_map *fm;
  282 
  283         sc = dev->si_drv1;
  284         for (fm = ffb_map; fm->fm_size != 0; fm++) {
  285                 if (offset >= fm->fm_virt &&
  286                     offset < fm->fm_virt + fm->fm_size) {
  287                         *paddr = sc->sc_bh[0] + fm->fm_phys +
  288                             (offset - fm->fm_virt);
  289                         return (0);
  290                 }
  291         }
  292         return (EINVAL);
  293 }
  294 
  295 static void
  296 creator_shutdown(void *v)
  297 {
  298         struct creator_softc *sc = v;
  299 
  300         FFB_WRITE(sc, FFB_DAC, FFB_DAC_TYPE2, FFB_DAC_CUR_CTRL);
  301         FFB_WRITE(sc, FFB_DAC, FFB_DAC_VALUE2,
  302             sc->sc_flags & CREATOR_CURINV ? 0 :
  303             FFB_DAC_CUR_CTRL_P0 | FFB_DAC_CUR_CTRL_P1);
  304         /*
  305          * In case this is the console set the cursor of the stdout
  306          * instance to the start of the last line so OFW output ends
  307          * up beneath what FreeBSD left on the screen.
  308          */
  309         if (sc->sc_flags & CREATOR_CONSOLE) {
  310                 OF_interpret("stdout @ is my-self 0 to column#", 0);
  311                 OF_interpret("stdout @ is my-self #lines 1 - to line#", 0);
  312         }
  313 }

Cache object: d4a3ca66851b232ad303e48541ceab62


[ 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.