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/sbus/tcx.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: tcx.c,v 1.15.4.1 2004/07/15 19:17:28 he Exp $ */
    2 
    3 /*
    4  *  Copyright (c) 1996,1998 The NetBSD Foundation, Inc.
    5  *  All rights reserved.
    6  *
    7  *  This code is derived from software contributed to The NetBSD Foundation
    8  *  by Paul Kranenburg.
    9  *
   10  *  Redistribution and use in source and binary forms, with or without
   11  *  modification, are permitted provided that the following conditions
   12  *  are met:
   13  *  1. Redistributions of source code must retain the above copyright
   14  *     notice, this list of conditions and the following disclaimer.
   15  *  2. Redistributions in binary form must reproduce the above copyright
   16  *     notice, this list of conditions and the following disclaimer in the
   17  *     documentation and/or other materials provided with the distribution.
   18  *  3. All advertising materials mentioning features or use of this software
   19  *     must display the following acknowledgement:
   20  *         This product includes software developed by the NetBSD
   21  *         Foundation, Inc. and its contributors.
   22  *  4. Neither the name of The NetBSD Foundation nor the names of its
   23  *     contributors may be used to endorse or promote products derived
   24  *     from this software without specific prior written permission.
   25  *
   26  *  THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  *  POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * color display (TCX) driver.
   41  *
   42  * Does not handle interrupts, even though they can occur.
   43  *
   44  * XXX should defer colormap updates to vertical retrace interrupts
   45  */
   46 
   47 #include <sys/cdefs.h>
   48 __KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.15.4.1 2004/07/15 19:17:28 he Exp $");
   49 
   50 /*
   51  * define for cg8 emulation on S24 (24-bit version of tcx) for the SS5;
   52  * it is bypassed on the 8-bit version (onboard framebuffer for SS4)
   53  */
   54 #undef TCX_CG8
   55 
   56 #include <sys/param.h>
   57 #include <sys/systm.h>
   58 #include <sys/buf.h>
   59 #include <sys/device.h>
   60 #include <sys/ioctl.h>
   61 #include <sys/malloc.h>
   62 #include <sys/mman.h>
   63 #include <sys/tty.h>
   64 #include <sys/conf.h>
   65 
   66 #ifdef DEBUG
   67 #include <sys/proc.h>
   68 #include <sys/syslog.h>
   69 #endif
   70 
   71 #include <machine/bus.h>
   72 #include <machine/autoconf.h>
   73 
   74 #include <dev/sun/fbio.h>
   75 #include <dev/sun/fbvar.h>
   76 #include <dev/sun/btreg.h>
   77 #include <dev/sun/btvar.h>
   78 
   79 #include <dev/sbus/sbusvar.h>
   80 #include <dev/sbus/tcxreg.h>
   81 
   82 /* per-display variables */
   83 struct tcx_softc {
   84         struct device   sc_dev;         /* base device */
   85         struct sbusdev  sc_sd;          /* sbus device */
   86         struct fbdevice sc_fb;          /* frame buffer device */
   87         bus_space_tag_t sc_bustag;
   88         struct openprom_addr sc_physadr[TCX_NREG];/* phys addr of h/w */
   89 
   90         volatile struct bt_regs *sc_bt; /* Brooktree registers */
   91         volatile struct tcx_thc *sc_thc;/* THC registers */
   92 #ifdef TCX_CG8
   93         volatile ulong *sc_cplane;      /* framebuffer with control planes */
   94 #endif
   95         short   sc_8bit;                /* true if 8-bit hardware */
   96         short   sc_blanked;             /* true if blanked */
   97         union   bt_cmap sc_cmap;        /* Brooktree color map */
   98 };
   99 
  100 /*
  101  * The S24 provides the framebuffer RAM mapped in three ways:
  102  * 26 bits per pixel, in 32-bit words; the low-order 24 bits are
  103  * blue, green, and red values, and the other two bits select the
  104  * display modes, per pixel);
  105  * 24 bits per pixel, in 32-bit words; the high-order byte reads as
  106  * zero, and is ignored on writes (so the mode bits cannot be altered);
  107  * 8 bits per pixel, unpadded; writes to this space do not modify the
  108  * other 18 bits.
  109  */
  110 #define TCX_CTL_8_MAPPED        0x00000000      /* 8 bits, uses color map */
  111 #define TCX_CTL_24_MAPPED       0x01000000      /* 24 bits, uses color map */
  112 #define TCX_CTL_24_LEVEL        0x03000000      /* 24 bits, ignores color map */
  113 #define TCX_CTL_PIXELMASK       0x00FFFFFF      /* mask for index/level */
  114 
  115 /* autoconfiguration driver */
  116 static void     tcxattach __P((struct device *, struct device *, void *));
  117 static int      tcxmatch __P((struct device *, struct cfdata *, void *));
  118 static void     tcx_unblank __P((struct device *));
  119 
  120 CFATTACH_DECL(tcx, sizeof(struct tcx_softc),
  121     tcxmatch, tcxattach, NULL, NULL);
  122 
  123 extern struct cfdriver tcx_cd;
  124 
  125 dev_type_open(tcxopen);
  126 dev_type_close(tcxclose);
  127 dev_type_ioctl(tcxioctl);
  128 dev_type_mmap(tcxmmap);
  129 
  130 const struct cdevsw tcx_cdevsw = {
  131         tcxopen, tcxclose, noread, nowrite, tcxioctl,
  132         nostop, notty, nopoll, tcxmmap, nokqfilter,
  133 };
  134 
  135 /* frame buffer generic driver */
  136 static struct fbdriver tcx_fbdriver = {
  137         tcx_unblank, tcxopen, tcxclose, tcxioctl, nopoll, tcxmmap,
  138         nokqfilter
  139 };
  140 
  141 static void tcx_reset __P((struct tcx_softc *));
  142 static void tcx_loadcmap __P((struct tcx_softc *, int, int));
  143 
  144 #define OBPNAME "SUNW,tcx"
  145 
  146 #ifdef TCX_CG8
  147 /*
  148  * For CG8 emulation, we map the 32-bit-deep framebuffer at an offset of
  149  * 256K; the cg8 space begins with a mono overlay plane and an overlay
  150  * enable plane (128K bytes each, 1 bit per pixel), immediately followed
  151  * by the color planes, 32 bits per pixel.  We also map just the 32-bit
  152  * framebuffer at 0x04000000 (TCX_USER_RAM_COMPAT), for compatibility
  153  * with the cg8 driver.
  154  */
  155 #define TCX_CG8OVERLAY  (256 * 1024)
  156 #define TCX_SIZE_DFB32  (1152 * 900 * 4) /* max size of the framebuffer */
  157 #endif
  158 
  159 /*
  160  * Match a tcx.
  161  */
  162 int
  163 tcxmatch(parent, cf, aux)
  164         struct device *parent;
  165         struct cfdata *cf;
  166         void *aux;
  167 {
  168         struct sbus_attach_args *sa = aux;
  169 
  170         return (strcmp(sa->sa_name, OBPNAME) == 0);
  171 }
  172 
  173 /*
  174  * Attach a display.
  175  */
  176 void
  177 tcxattach(parent, self, args)
  178         struct device *parent, *self;
  179         void *args;
  180 {
  181         struct tcx_softc *sc = (struct tcx_softc *)self;
  182         struct sbus_attach_args *sa = args;
  183         int node, ramsize;
  184         volatile struct bt_regs *bt;
  185         struct fbdevice *fb = &sc->sc_fb;
  186         bus_space_handle_t bh;
  187         int isconsole;
  188 
  189         sc->sc_bustag = sa->sa_bustag;
  190         node = sa->sa_node;
  191 
  192         fb->fb_driver = &tcx_fbdriver;
  193         fb->fb_device = &sc->sc_dev;
  194         /* Mask out invalid flags from the user. */
  195         fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags & FB_USERMASK;
  196         /*
  197          * The onboard framebuffer on the SS4 supports only 8-bit mode;
  198          * it can be distinguished from the S24 card for the SS5 by the
  199          * presence of the "tcx-8-bit" attribute on the SS4 version.
  200          */
  201         sc->sc_8bit = node_has_property(node, "tcx-8-bit");
  202 #ifdef TCX_CG8
  203         if (sc->sc_8bit) {
  204 #endif
  205                 /*
  206                  * cg8 emulation is either not compiled in or not supported
  207                  * on this hardware.  Report values for the 8-bit framebuffer
  208                  * so cg3 emulation works.  (If this hardware supports
  209                  * 24-bit mode, the 24-bit framebuffer will also be available)
  210                  */
  211                 fb->fb_type.fb_depth = 8;
  212                 fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node);
  213 
  214                 ramsize = fb->fb_type.fb_height * fb->fb_linebytes;
  215 #ifdef TCX_CG8
  216         } else {
  217                 /*
  218                  * for cg8 emulation, unconditionally report the depth as
  219                  * 32 bits, but use the height and width reported by the
  220                  * boot prom.  cg8 users want to see the full size of
  221                  * overlay planes plus color planes included in the
  222                  * reported framebuffer size.
  223                  */
  224                 fb->fb_type.fb_depth = 32;
  225                 fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node);
  226                 fb->fb_linebytes =
  227                         (fb->fb_type.fb_width * fb->fb_type.fb_depth) / 8;
  228                 ramsize = TCX_CG8OVERLAY +
  229                         (fb->fb_type.fb_height * fb->fb_linebytes);
  230         }
  231 #endif
  232         fb->fb_type.fb_cmsize = 256;
  233         fb->fb_type.fb_size = ramsize;
  234         printf(": %s, %d x %d", OBPNAME,
  235                 fb->fb_type.fb_width,
  236                 fb->fb_type.fb_height);
  237 #ifdef TCX_CG8
  238         /*
  239          * if cg8 emulation is enabled, say so; but if hardware can't
  240          * emulate cg8, explain that instead
  241          */
  242         printf( (sc->sc_8bit)?
  243                 " (8-bit only)" :
  244                 " (emulating cg8)");
  245 #endif
  246 
  247         /*
  248          * XXX - should be set to FBTYPE_TCX.
  249          * XXX For CG3 emulation to work in current (96/6) X11 servers,
  250          * XXX `fbtype' must point to an "unregocnised" entry.
  251          */
  252 #ifdef TCX_CG8
  253         if (sc->sc_8bit) {
  254                 fb->fb_type.fb_type = FBTYPE_RESERVED3;
  255         } else {
  256                 fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
  257         }
  258 #else
  259         fb->fb_type.fb_type = FBTYPE_RESERVED3;
  260 #endif
  261 
  262 
  263         if (sa->sa_nreg != TCX_NREG) {
  264                 printf("%s: only %d register sets\n",
  265                         self->dv_xname, sa->sa_nreg);
  266                 return;
  267         }
  268         bcopy(sa->sa_reg, sc->sc_physadr,
  269               sa->sa_nreg * sizeof(struct openprom_addr));
  270 
  271         /* XXX - fix THC and TEC offsets */
  272         sc->sc_physadr[TCX_REG_TEC].oa_base += 0x1000;
  273         sc->sc_physadr[TCX_REG_THC].oa_base += 0x1000;
  274 
  275         /* Map the register banks we care about */
  276         if (sbus_bus_map(sa->sa_bustag,
  277                          sc->sc_physadr[TCX_REG_THC].oa_space,
  278                          sc->sc_physadr[TCX_REG_THC].oa_base,
  279                          sizeof (struct tcx_thc),
  280                          BUS_SPACE_MAP_LINEAR, &bh) != 0) {
  281                 printf("tcxattach: cannot map thc registers\n");
  282                 return;
  283         }
  284         sc->sc_thc = (volatile struct tcx_thc *)
  285                 bus_space_vaddr(sa->sa_bustag, bh);
  286 
  287         if (sbus_bus_map(sa->sa_bustag,
  288                          sc->sc_physadr[TCX_REG_CMAP].oa_space,
  289                          sc->sc_physadr[TCX_REG_CMAP].oa_base,
  290                          sizeof (struct bt_regs),
  291                          BUS_SPACE_MAP_LINEAR, &bh) != 0) {
  292                 printf("tcxattach: cannot map bt registers\n");
  293                 return;
  294         }
  295         sc->sc_bt = bt = (volatile struct bt_regs *)
  296                 bus_space_vaddr(sa->sa_bustag, bh);
  297 
  298 #ifdef TCX_CG8
  299         if (!sc->sc_8bit) {
  300                 if (sbus_bus_map(sa->sa_bustag,
  301                          sc->sc_physadr[TCX_REG_RDFB32].oa_space,
  302                          sc->sc_physadr[TCX_REG_RDFB32].oa_base,
  303                          TCX_SIZE_DFB32,
  304                          BUS_SPACE_MAP_LINEAR,
  305                          &bh) != 0) {
  306                         printf("tcxattach: cannot map control planes\n");
  307                         return;
  308                 }
  309                 sc->sc_cplane = (volatile ulong *)bh;
  310         }
  311 #endif
  312 
  313         isconsole = fb_is_console(node);
  314 
  315         printf(", id %d, rev %d, sense %d",
  316                 (sc->sc_thc->thc_config & THC_CFG_FBID) >> THC_CFG_FBID_SHIFT,
  317                 (sc->sc_thc->thc_config & THC_CFG_REV) >> THC_CFG_REV_SHIFT,
  318                 (sc->sc_thc->thc_config & THC_CFG_SENSE) >> THC_CFG_SENSE_SHIFT
  319         );
  320 
  321         /* reset cursor & frame buffer controls */
  322         tcx_reset(sc);
  323 
  324         /* Initialize the default color map. */
  325         bt_initcmap(&sc->sc_cmap, 256);
  326         tcx_loadcmap(sc, 0, 256);
  327 
  328         /* enable video */
  329         sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
  330 
  331         if (isconsole) {
  332                 printf(" (console)\n");
  333         } else
  334                 printf("\n");
  335 
  336         sbus_establish(&sc->sc_sd, &sc->sc_dev);
  337         fb_attach(&sc->sc_fb, isconsole);
  338 }
  339 
  340 #ifdef TCX_CG8
  341 /*
  342  * keep track of the number of opens, so we can switch to 24-bit mode
  343  * when the device is first opened, and return to 8-bit mode on the
  344  * last close.  (stolen from cgfourteen driver...)  There can only be
  345  * one TCX per system, so we only need one flag.
  346  */
  347 static int tcx_opens = 0;
  348 #endif
  349 
  350 int
  351 tcxopen(dev, flags, mode, p)
  352         dev_t dev;
  353         int flags, mode;
  354         struct proc *p;
  355 {
  356         int unit = minor(dev);
  357 #ifdef TCX_CG8
  358         struct tcx_softc *sc;
  359         int i, s, oldopens;
  360         volatile ulong *cptr;
  361         struct fbdevice *fb;
  362 #endif
  363 
  364         if (unit >= tcx_cd.cd_ndevs || tcx_cd.cd_devs[unit] == NULL)
  365                 return (ENXIO);
  366 #ifdef TCX_CG8
  367         sc = tcx_cd.cd_devs[unit];
  368         if (!sc->sc_8bit) {
  369                 s = splhigh();
  370                 oldopens = tcx_opens++;
  371                 splx(s);
  372                 if (oldopens == 0) {
  373                         /*
  374                          * rewrite the control planes to select 24-bit mode
  375                          * and clear the screen
  376                          */
  377                         fb = &sc->sc_fb;
  378                         i = fb->fb_type.fb_height * fb->fb_type.fb_width;
  379                         cptr = sc->sc_cplane;
  380                         while (--i >= 0)
  381                                 *cptr++ = TCX_CTL_24_LEVEL;
  382                 }
  383         }
  384 #endif
  385         return (0);
  386 }
  387 
  388 int
  389 tcxclose(dev, flags, mode, p)
  390         dev_t dev;
  391         int flags, mode;
  392         struct proc *p;
  393 {
  394         struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
  395 #ifdef TCX_CG8
  396         int i, s, opens;
  397         volatile ulong *cptr;
  398         struct fbdevice *fb;
  399 #endif
  400 
  401         tcx_reset(sc);
  402 #ifdef TCX_CG8
  403         if (!sc->sc_8bit) {
  404                 s = splhigh();
  405                 opens = --tcx_opens;
  406                 if (tcx_opens <= 0)
  407                         opens = tcx_opens = 0;
  408                 splx(s);
  409                 if (opens == 0) {
  410                         /*
  411                          * rewrite the control planes to select 8-bit mode,
  412                          * preserving the contents of the screen.
  413                          * (or we could just bzero the whole thing...)
  414                          */
  415                         fb = &sc->sc_fb;
  416                         i = fb->fb_type.fb_height * fb->fb_type.fb_width;
  417                         cptr = sc->sc_cplane;
  418                         while (--i >= 0)
  419                                 *cptr++ &= TCX_CTL_PIXELMASK;
  420                 }
  421         }
  422 #endif
  423         return (0);
  424 }
  425 
  426 int
  427 tcxioctl(dev, cmd, data, flags, p)
  428         dev_t dev;
  429         u_long cmd;
  430         caddr_t data;
  431         int flags;
  432         struct proc *p;
  433 {
  434         struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
  435         int error;
  436 
  437         switch (cmd) {
  438 
  439         case FBIOGTYPE:
  440                 *(struct fbtype *)data = sc->sc_fb.fb_type;
  441                 break;
  442 
  443         case FBIOGATTR:
  444 #define fba ((struct fbgattr *)data)
  445                 fba->real_type = sc->sc_fb.fb_type.fb_type;
  446                 fba->owner = 0;         /* XXX ??? */
  447                 fba->fbtype = sc->sc_fb.fb_type;
  448                 fba->sattr.flags = 0;
  449                 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
  450                 fba->sattr.dev_specific[0] = -1;
  451                 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
  452                 fba->emu_types[1] = FBTYPE_SUN3COLOR;
  453                 fba->emu_types[2] = -1;
  454 #undef fba
  455                 break;
  456 
  457         case FBIOGETCMAP:
  458 #define p ((struct fbcmap *)data)
  459                 return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
  460 
  461         case FBIOPUTCMAP:
  462                 /* copy to software map */
  463 #ifdef TCX_CG8
  464                 if (!sc->sc_8bit) {
  465                         /*
  466                          * cg8 has extra bits in high-order byte of the index
  467                          * that bt_putcmap doesn't recognize
  468                          */
  469                         p->index &= 0xffffff;
  470                 }
  471 #endif
  472                 error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
  473                 if (error)
  474                         return (error);
  475                 /* now blast them into the chip */
  476                 /* XXX should use retrace interrupt */
  477                 tcx_loadcmap(sc, p->index, p->count);
  478 #undef p
  479                 break;
  480 
  481         case FBIOGVIDEO:
  482                 *(int *)data = sc->sc_blanked;
  483                 break;
  484 
  485         case FBIOSVIDEO:
  486                 if (*(int *)data)
  487                         tcx_unblank(&sc->sc_dev);
  488                 else if (!sc->sc_blanked) {
  489                         sc->sc_blanked = 1;
  490                         sc->sc_thc->thc_hcmisc &= ~THC_MISC_VIDEN;
  491                         /* Put monitor in `power-saving mode' */
  492                         sc->sc_thc->thc_hcmisc |= THC_MISC_VSYNC_DISABLE;
  493                         sc->sc_thc->thc_hcmisc |= THC_MISC_HSYNC_DISABLE;
  494                 }
  495                 break;
  496 
  497         default:
  498 #ifdef DEBUG
  499                 log(LOG_NOTICE, "tcxioctl(0x%lx) (%s[%d])\n", cmd,
  500                     p->p_comm, p->p_pid);
  501 #endif
  502                 return (ENOTTY);
  503         }
  504         return (0);
  505 }
  506 
  507 /*
  508  * Clean up hardware state (e.g., after bootup or after X crashes).
  509  */
  510 static void
  511 tcx_reset(sc)
  512         struct tcx_softc *sc;
  513 {
  514         volatile struct bt_regs *bt;
  515 
  516         /* Enable cursor in Brooktree DAC. */
  517         bt = sc->sc_bt;
  518         bt->bt_addr = 0x06 << 24;
  519         bt->bt_ctrl |= 0x03 << 24;
  520 }
  521 
  522 /*
  523  * Load a subset of the current (new) colormap into the color DAC.
  524  */
  525 static void
  526 tcx_loadcmap(sc, start, ncolors)
  527         struct tcx_softc *sc;
  528         int start, ncolors;
  529 {
  530         volatile struct bt_regs *bt;
  531         u_int *ip, i;
  532         int count;
  533 
  534         ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)];      /* start/4 * 3 */
  535         count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
  536         bt = sc->sc_bt;
  537         bt->bt_addr = BT_D4M4(start) << 24;
  538         while (--count >= 0) {
  539                 i = *ip++;
  540                 /* hardware that makes one want to pound boards with hammers */
  541                 bt->bt_cmap = i;
  542                 bt->bt_cmap = i << 8;
  543                 bt->bt_cmap = i << 16;
  544                 bt->bt_cmap = i << 24;
  545         }
  546 }
  547 
  548 static void
  549 tcx_unblank(dev)
  550         struct device *dev;
  551 {
  552         struct tcx_softc *sc = (struct tcx_softc *)dev;
  553 
  554         if (sc->sc_blanked) {
  555                 sc->sc_blanked = 0;
  556                 sc->sc_thc->thc_hcmisc &= ~THC_MISC_VSYNC_DISABLE;
  557                 sc->sc_thc->thc_hcmisc &= ~THC_MISC_HSYNC_DISABLE;
  558                 sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
  559         }
  560 }
  561 
  562 /*
  563  * Base addresses at which users can mmap() the various pieces of a tcx.
  564  */
  565 #define TCX_USER_RAM    0x00000000
  566 #define TCX_USER_RAM24  0x01000000
  567 #define TCX_USER_RAM_COMPAT     0x04000000      /* cg3 emulation */
  568 #define TCX_USER_STIP   0x10000000
  569 #define TCX_USER_BLIT   0x20000000
  570 #define TCX_USER_RDFB32 0x28000000
  571 #define TCX_USER_RSTIP  0x30000000
  572 #define TCX_USER_RBLIT  0x38000000
  573 #define TCX_USER_TEC    0x70001000
  574 #define TCX_USER_BTREGS 0x70002000
  575 #define TCX_USER_THC    0x70004000
  576 #define TCX_USER_DHC    0x70008000
  577 #define TCX_USER_ALT    0x7000a000
  578 #define TCX_USER_UART   0x7000c000
  579 #define TCX_USER_VRT    0x7000e000
  580 #define TCX_USER_ROM    0x70010000
  581 
  582 struct mmo {
  583         u_int   mo_uaddr;       /* user (virtual) address */
  584         u_int   mo_size;        /* size, or 0 for video ram size */
  585         u_int   mo_bank;        /* register bank number */
  586 };
  587 
  588 /*
  589  * Return the address that would map the given device at the given
  590  * offset, allowing for the given protection, or return -1 for error.
  591  *
  592  * XXX  needs testing against `demanding' applications (e.g., aviator)
  593  */
  594 paddr_t
  595 tcxmmap(dev, off, prot)
  596         dev_t dev;
  597         off_t off;
  598         int prot;
  599 {
  600         struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
  601         struct openprom_addr *rr = sc->sc_physadr;
  602         struct mmo *mo, *mo_end;
  603         u_int u, sz;
  604         static struct mmo mmo[] = {
  605                 { TCX_USER_RAM, 0, TCX_REG_DFB8 },
  606                 { TCX_USER_RAM24, 0, TCX_REG_DFB24 },
  607                 { TCX_USER_RAM_COMPAT, 0, TCX_REG_DFB8 },
  608 
  609                 { TCX_USER_STIP, 1, TCX_REG_STIP },
  610                 { TCX_USER_BLIT, 1, TCX_REG_BLIT },
  611                 { TCX_USER_RDFB32, 0, TCX_REG_RDFB32 },
  612                 { TCX_USER_RSTIP, 1, TCX_REG_RSTIP },
  613                 { TCX_USER_RBLIT, 1, TCX_REG_RBLIT },
  614                 { TCX_USER_TEC, 1, TCX_REG_TEC },
  615                 { TCX_USER_BTREGS, 8192 /* XXX */, TCX_REG_CMAP },
  616                 { TCX_USER_THC, sizeof(struct tcx_thc), TCX_REG_THC },
  617                 { TCX_USER_DHC, 1, TCX_REG_DHC },
  618                 { TCX_USER_ALT, 1, TCX_REG_ALT },
  619                 { TCX_USER_ROM, 65536, TCX_REG_ROM },
  620         };
  621 #define NMMO (sizeof mmo / sizeof *mmo)
  622 #ifdef TCX_CG8
  623         /*
  624          * alternate mapping for CG8 emulation:
  625          * map part of the 8-bit-deep framebuffer into the cg8 overlay
  626          * space, just so there's something there, and map the 32-bit-deep
  627          * framebuffer where cg8 users expect to find it.
  628          */
  629         static struct mmo mmo_cg8[] = {
  630                 { TCX_USER_RAM, TCX_CG8OVERLAY, TCX_REG_DFB8 },
  631                 { TCX_CG8OVERLAY, TCX_SIZE_DFB32, TCX_REG_DFB24 },
  632                 { TCX_USER_RAM_COMPAT, TCX_SIZE_DFB32, TCX_REG_DFB24 }
  633         };
  634 #define NMMO_CG8 (sizeof mmo_cg8 / sizeof *mmo_cg8)
  635 #endif
  636 
  637         if (off & PGOFSET)
  638                 panic("tcxmmap");
  639 
  640         /*
  641          * Entries with size 0 map video RAM (i.e., the size in fb data).
  642          * Entries that map 32-bit deep regions are adjusted for their
  643          * depth (fb_size gives the size of the 8-bit-deep region).
  644          *
  645          * Since we work in pages, the fact that the map offset table's
  646          * sizes are sometimes bizarre (e.g., 1) is effectively ignored:
  647          * one byte is as good as one page.
  648          */
  649 #ifdef TCX_CG8
  650         if (sc->sc_8bit) {
  651                 mo = mmo;
  652                 mo_end = &mmo[NMMO];
  653         } else {
  654                 mo = mmo_cg8;
  655                 mo_end = &mmo_cg8[NMMO_CG8];
  656         }
  657 #else
  658         mo = mmo;
  659         mo_end = &mmo[NMMO];
  660 #endif
  661         for (; mo < mo_end; mo++) {
  662                 if ((u_int)off < mo->mo_uaddr)
  663                         continue;
  664                 u = off - mo->mo_uaddr;
  665                 sz = mo->mo_size;
  666                 if (sz == 0) {
  667                         sz = sc->sc_fb.fb_type.fb_size;
  668                         /*
  669                          * check for the 32-bit-deep regions and adjust
  670                          * accordingly
  671                          */
  672                         if (mo->mo_uaddr == TCX_USER_RAM24 ||
  673                             mo->mo_uaddr == TCX_USER_RDFB32) {
  674                                 if (sc->sc_8bit) {
  675                                         /*
  676                                          * not present on 8-bit hardware
  677                                          */
  678                                         continue;
  679                                 }
  680                                 sz *= 4;
  681                         }
  682                 }
  683                 if (u < sz) {
  684                         return (bus_space_mmap(sc->sc_bustag,
  685                                 BUS_ADDR(rr[mo->mo_bank].oa_space,
  686                                          rr[mo->mo_bank].oa_base),
  687                                 u,
  688                                 prot,
  689                                 BUS_SPACE_MAP_LINEAR));
  690                 }
  691         }
  692         return (-1);
  693 }

Cache object: b4f46d737a046ba5dd696ef43fc7620f


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