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/sun/cgsix.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: cgsix.c,v 1.17 2004/02/13 11:36:22 wiz Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 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  * Copyright (c) 1993
   41  *      The Regents of the University of California.  All rights reserved.
   42  *
   43  * This software was developed by the Computer Systems Engineering group
   44  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
   45  * contributed to Berkeley.
   46  *
   47  * All advertising materials mentioning features or use of this software
   48  * must display the following acknowledgement:
   49  *      This product includes software developed by the University of
   50  *      California, Lawrence Berkeley Laboratory.
   51  *
   52  * Redistribution and use in source and binary forms, with or without
   53  * modification, are permitted provided that the following conditions
   54  * are met:
   55  * 1. Redistributions of source code must retain the above copyright
   56  *    notice, this list of conditions and the following disclaimer.
   57  * 2. Redistributions in binary form must reproduce the above copyright
   58  *    notice, this list of conditions and the following disclaimer in the
   59  *    documentation and/or other materials provided with the distribution.
   60  * 3. Neither the name of the University nor the names of its contributors
   61  *    may be used to endorse or promote products derived from this software
   62  *    without specific prior written permission.
   63  *
   64  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   65  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   66  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   67  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   68  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   69  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   70  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   71  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   72  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   73  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   74  * SUCH DAMAGE.
   75  *
   76  *      @(#)cgsix.c     8.4 (Berkeley) 1/21/94
   77  */
   78 
   79 /*
   80  * color display (cgsix) driver.
   81  *
   82  * Does not handle interrupts, even though they can occur.
   83  *
   84  * XXX should defer colormap updates to vertical retrace interrupts
   85  */
   86 
   87 #include <sys/cdefs.h>
   88 __KERNEL_RCSID(0, "$NetBSD: cgsix.c,v 1.17 2004/02/13 11:36:22 wiz Exp $");
   89 
   90 #include <sys/param.h>
   91 #include <sys/systm.h>
   92 #include <sys/buf.h>
   93 #include <sys/device.h>
   94 #include <sys/ioctl.h>
   95 #include <sys/malloc.h>
   96 #include <sys/mman.h>
   97 #include <sys/tty.h>
   98 #include <sys/conf.h>
   99 
  100 #ifdef DEBUG
  101 #include <sys/proc.h>
  102 #include <sys/syslog.h>
  103 #endif
  104 
  105 #include <uvm/uvm_extern.h>
  106 
  107 #include <machine/bus.h>
  108 
  109 #include <dev/sun/fbio.h>
  110 #include <dev/sun/fbvar.h>
  111 
  112 #include <dev/sun/btreg.h>
  113 #include <dev/sun/btvar.h>
  114 #include <dev/sun/cgsixreg.h>
  115 #include <dev/sun/cgsixvar.h>
  116 #include <dev/sun/pfourreg.h>
  117 
  118 #ifdef RASTERCONSOLE
  119 #include <dev/rasops/rasops.h>
  120 #include <dev/wscons/wsconsio.h>
  121 #endif
  122 
  123 static void     cg6_unblank(struct device *);
  124 
  125 extern struct cfdriver cgsix_cd;
  126 
  127 dev_type_open(cgsixopen);
  128 dev_type_close(cgsixclose);
  129 dev_type_ioctl(cgsixioctl);
  130 dev_type_mmap(cgsixmmap);
  131 
  132 const struct cdevsw cgsix_cdevsw = {
  133         cgsixopen, cgsixclose, noread, nowrite, cgsixioctl,
  134         nostop, notty, nopoll, cgsixmmap, nokqfilter,
  135 };
  136 
  137 /* frame buffer generic driver */
  138 static struct fbdriver cg6_fbdriver = {
  139         cg6_unblank, cgsixopen, cgsixclose, cgsixioctl, nopoll, cgsixmmap,
  140         nokqfilter
  141 };
  142 
  143 static void cg6_reset (struct cgsix_softc *);
  144 static void cg6_loadcmap (struct cgsix_softc *, int, int);
  145 static void cg6_loadomap (struct cgsix_softc *);
  146 static void cg6_setcursor (struct cgsix_softc *);/* set position */
  147 static void cg6_loadcursor (struct cgsix_softc *);/* set shape */
  148 
  149 #ifdef RASTERCONSOLE
  150 int cgsix_use_rasterconsole = 1;
  151 
  152 /*
  153  * cg6 accelerated console routines.
  154  *
  155  * Note that buried in this code in several places is the assumption
  156  * that pixels are exactly one byte wide.  Since this is cg6-specific
  157  * code, this seems safe.  This assumption resides in things like the
  158  * use of ri_emuwidth without messing around with ri_pelbytes, or the
  159  * assumption that ri_font->fontwidth is the right thing to multiply
  160  * character-cell counts by to get byte counts.
  161  */
  162 
  163 /*
  164  * Magic values for blitter
  165  */
  166 
  167 /* Values for the mode register */
  168 #define CG6_MODE        (                                               \
  169           0x00200000 /* GX_BLIT_SRC */                                  \
  170         | 0x00020000 /* GX_MODE_COLOR8 */                               \
  171         | 0x00008000 /* GX_DRAW_RENDER */                               \
  172         | 0x00002000 /* GX_BWRITE0_ENABLE */                            \
  173         | 0x00001000 /* GX_BWRITE1_DISABLE */                           \
  174         | 0x00000200 /* GX_BREAD_0 */                                   \
  175         | 0x00000080 /* GX_BDISP_0 */                                   \
  176 )
  177 #define CG6_MODE_MASK   (                                               \
  178           0x00300000 /* GX_BLIT_ALL */                                  \
  179         | 0x00060000 /* GX_MODE_ALL */                                  \
  180         | 0x00018000 /* GX_DRAW_ALL */                                  \
  181         | 0x00006000 /* GX_BWRITE0_ALL */                               \
  182         | 0x00001800 /* GX_BWRITE1_ALL */                               \
  183         | 0x00000600 /* GX_BREAD_ALL */                                 \
  184         | 0x00000180 /* GX_BDISP_ALL */                                 \
  185 )
  186 
  187 /* Value for the alu register for screen-to-screen copies */
  188 #define CG6_ALU_COPY    (                                               \
  189           0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
  190         | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
  191         | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
  192         | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
  193         | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
  194         | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
  195         | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
  196         | 0x0000cccc /* ALU = src */                                    \
  197 )
  198 
  199 /* Value for the alu register for region fills */
  200 #define CG6_ALU_FILL    (                                               \
  201           0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
  202         | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
  203         | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
  204         | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
  205         | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
  206         | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
  207         | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
  208         | 0x0000ff00 /* ALU = fg color */                               \
  209 )
  210 
  211 /* Value for the alu register for toggling an area */
  212 #define CG6_ALU_FLIP    (                                               \
  213           0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
  214         | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
  215         | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
  216         | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
  217         | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
  218         | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
  219         | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
  220         | 0x00005555 /* ALU = ~dst */                                   \
  221 )
  222 
  223 /*
  224  * Wait for a blit to finish.
  225  * 0x8000000 bit: function unknown; 0x20000000 bit: GX_BLT_INPROGRESS
  226  */
  227 #define CG6_BLIT_WAIT(fbc) do {                                         \
  228         while (((fbc)->fbc_blit & 0xa0000000) == 0xa0000000)            \
  229                 /*EMPTY*/;                                              \
  230 } while (0)
  231 
  232 /*
  233  * Wait for a drawing operation to finish, or at least get queued.
  234  * 0x8000000 bit: function unknown; 0x20000000 bit: GX_FULL
  235  */
  236 #define CG6_DRAW_WAIT(fbc) do {                                         \
  237         while (((fbc)->fbc_draw & 0xa0000000) == 0xa0000000)            \
  238                 /*EMPTY*/;                                              \
  239 } while (0)
  240 
  241 /*
  242  * Wait for the whole engine to go idle.  This may not matter in our case;
  243  * I'm not sure whether blits are actually queued or not.  It more likely
  244  * is intended for lines and such that do get queued.
  245  * 0x10000000 bit: GX_INPROGRESS
  246  */
  247 #define CG6_DRAIN(fbc) do {                                             \
  248         while ((fbc)->fbc_s & 0x10000000)                               \
  249                 /*EMPTY*/;                                              \
  250 } while (0)
  251 
  252 static void cg6_ras_init(struct cgsix_softc *);
  253 static void cg6_ras_copyrows(void *, int, int, int);
  254 static void cg6_ras_copycols(void *, int, int, int, int);
  255 static void cg6_ras_erasecols(void *, int, int, int, long int);
  256 static void cg6_ras_eraserows(void *, int, int, long int);
  257 static void cg6_ras_do_cursor(struct rasops_info *);
  258 
  259 static void
  260 cg6_ras_init(struct cgsix_softc *sc)
  261 {
  262         volatile struct cg6_fbc *fbc = sc->sc_fbc;
  263 
  264         CG6_DRAIN(fbc);
  265         fbc->fbc_mode &= ~CG6_MODE_MASK;
  266         fbc->fbc_mode |= CG6_MODE;
  267 }
  268 
  269 static void
  270 cg6_ras_copyrows(void *cookie, int src, int dst, int n)
  271 {
  272         struct rasops_info *ri;
  273         volatile struct cg6_fbc *fbc;
  274 
  275         ri = cookie;
  276         if (dst == src)
  277                 return;
  278         if (src < 0) {
  279                 n += src;
  280                 src = 0;
  281         }
  282         if (src+n > ri->ri_rows)
  283                 n = ri->ri_rows - src;
  284         if (dst < 0) {
  285                 n += dst;
  286                 dst = 0;
  287         }
  288         if (dst+n > ri->ri_rows)
  289                 n = ri->ri_rows - dst;
  290         if (n <= 0)
  291                 return;
  292         n *= ri->ri_font->fontheight;
  293         src *= ri->ri_font->fontheight;
  294         dst *= ri->ri_font->fontheight;
  295         fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
  296         fbc->fbc_clip = 0;
  297         fbc->fbc_s = 0;
  298         fbc->fbc_offx = 0;
  299         fbc->fbc_offy = 0;
  300         fbc->fbc_clipminx = 0;
  301         fbc->fbc_clipminy = 0;
  302         fbc->fbc_clipmaxx = ri->ri_width - 1;
  303         fbc->fbc_clipmaxy = ri->ri_height - 1;
  304         fbc->fbc_alu = CG6_ALU_COPY;
  305         fbc->fbc_x0 = ri->ri_xorigin;
  306         fbc->fbc_y0 = ri->ri_yorigin + src;
  307         fbc->fbc_x1 = ri->ri_xorigin + ri->ri_emuwidth - 1;
  308         fbc->fbc_y1 = ri->ri_yorigin + src + n - 1;
  309         fbc->fbc_x2 = ri->ri_xorigin;
  310         fbc->fbc_y2 = ri->ri_yorigin + dst;
  311         fbc->fbc_x3 = ri->ri_xorigin + ri->ri_emuwidth - 1;
  312         fbc->fbc_y3 = ri->ri_yorigin + dst + n - 1;
  313         CG6_BLIT_WAIT(fbc);
  314         CG6_DRAIN(fbc);
  315 }
  316 
  317 static void
  318 cg6_ras_copycols(void *cookie, int row, int src, int dst, int n)
  319 {
  320         struct rasops_info *ri;
  321         volatile struct cg6_fbc *fbc;
  322 
  323         ri = cookie;
  324         if (dst == src)
  325                 return;
  326         if ((row < 0) || (row >= ri->ri_rows))
  327                 return;
  328         if (src < 0) {
  329                 n += src;
  330                 src = 0;
  331         }
  332         if (src+n > ri->ri_cols)
  333                 n = ri->ri_cols - src;
  334         if (dst < 0) {
  335                 n += dst;
  336                 dst = 0;
  337         }
  338         if (dst+n > ri->ri_cols)
  339                 n = ri->ri_cols - dst;
  340         if (n <= 0)
  341                 return;
  342         n *= ri->ri_font->fontwidth;
  343         src *= ri->ri_font->fontwidth;
  344         dst *= ri->ri_font->fontwidth;
  345         row *= ri->ri_font->fontheight;
  346         fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
  347         fbc->fbc_clip = 0;
  348         fbc->fbc_s = 0;
  349         fbc->fbc_offx = 0;
  350         fbc->fbc_offy = 0;
  351         fbc->fbc_clipminx = 0;
  352         fbc->fbc_clipminy = 0;
  353         fbc->fbc_clipmaxx = ri->ri_width - 1;
  354         fbc->fbc_clipmaxy = ri->ri_height - 1;
  355         fbc->fbc_alu = CG6_ALU_COPY;
  356         fbc->fbc_x0 = ri->ri_xorigin + src;
  357         fbc->fbc_y0 = ri->ri_yorigin + row;
  358         fbc->fbc_x1 = ri->ri_xorigin + src + n - 1;
  359         fbc->fbc_y1 = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
  360         fbc->fbc_x2 = ri->ri_xorigin + dst;
  361         fbc->fbc_y2 = ri->ri_yorigin + row;
  362         fbc->fbc_x3 = ri->ri_xorigin + dst + n - 1;
  363         fbc->fbc_y3 = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
  364         CG6_BLIT_WAIT(fbc);
  365         CG6_DRAIN(fbc);
  366 }
  367 
  368 static void
  369 cg6_ras_erasecols(void *cookie, int row, int col, int n, long int attr)
  370 {
  371         struct rasops_info *ri;
  372         volatile struct cg6_fbc *fbc;
  373 
  374         ri = cookie;
  375         if ((row < 0) || (row >= ri->ri_rows))
  376                 return;
  377         if (col < 0) {
  378                 n += col;
  379                 col = 0;
  380         }
  381         if (col+n > ri->ri_cols)
  382                 n = ri->ri_cols - col;
  383         if (n <= 0)
  384                 return;
  385         n *= ri->ri_font->fontwidth;
  386         col *= ri->ri_font->fontwidth;
  387         row *= ri->ri_font->fontheight;
  388         fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
  389         fbc->fbc_clip = 0;
  390         fbc->fbc_s = 0;
  391         fbc->fbc_offx = 0;
  392         fbc->fbc_offy = 0;
  393         fbc->fbc_clipminx = 0;
  394         fbc->fbc_clipminy = 0;
  395         fbc->fbc_clipmaxx = ri->ri_width - 1;
  396         fbc->fbc_clipmaxy = ri->ri_height - 1;
  397         fbc->fbc_alu = CG6_ALU_FILL;
  398         fbc->fbc_fg = ri->ri_devcmap[(attr >> 16) & 0xf];
  399         fbc->fbc_arecty = ri->ri_yorigin + row;
  400         fbc->fbc_arectx = ri->ri_xorigin + col;
  401         fbc->fbc_arecty = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
  402         fbc->fbc_arectx = ri->ri_xorigin + col + n - 1;
  403         CG6_DRAW_WAIT(fbc);
  404         CG6_DRAIN(fbc);
  405 }
  406 
  407 static void
  408 cg6_ras_eraserows(void *cookie, int row, int n, long int attr)
  409 {
  410         struct rasops_info *ri;
  411         volatile struct cg6_fbc *fbc;
  412 
  413         ri = cookie;
  414         if (row < 0) {
  415                 n += row;
  416                 row = 0;
  417         }
  418         if (row+n > ri->ri_rows)
  419                 n = ri->ri_rows - row;
  420         if (n <= 0)
  421                 return;
  422         fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
  423         fbc->fbc_clip = 0;
  424         fbc->fbc_s = 0;
  425         fbc->fbc_offx = 0;
  426         fbc->fbc_offy = 0;
  427         fbc->fbc_clipminx = 0;
  428         fbc->fbc_clipminy = 0;
  429         fbc->fbc_clipmaxx = ri->ri_width - 1;
  430         fbc->fbc_clipmaxy = ri->ri_height - 1;
  431         fbc->fbc_alu = CG6_ALU_FILL;
  432         fbc->fbc_fg = ri->ri_devcmap[(attr >> 16) & 0xf];
  433         if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
  434                 fbc->fbc_arecty = 0;
  435                 fbc->fbc_arectx = 0;
  436                 fbc->fbc_arecty = ri->ri_height - 1;
  437                 fbc->fbc_arectx = ri->ri_width - 1;
  438         } else {
  439                 row *= ri->ri_font->fontheight;
  440                 fbc->fbc_arecty = ri->ri_yorigin + row;
  441                 fbc->fbc_arectx = ri->ri_xorigin;
  442                 fbc->fbc_arecty = ri->ri_yorigin + row + (n * ri->ri_font->fontheight) - 1;
  443                 fbc->fbc_arectx = ri->ri_xorigin + ri->ri_emuwidth - 1;
  444         }
  445         CG6_DRAW_WAIT(fbc);
  446         CG6_DRAIN(fbc);
  447 }
  448 
  449 /*
  450  * Really want something more like fg^bg here, but that would be more
  451  * or less impossible to migrate to colors.  So we hope there's
  452  * something not too inappropriate in the colormap...besides, it's what
  453  * the non-accelerated code did. :-)
  454  */
  455 static void
  456 cg6_ras_do_cursor(struct rasops_info *ri)
  457 {
  458         volatile struct cg6_fbc *fbc;
  459         int row;
  460         int col;
  461 
  462         row = ri->ri_crow * ri->ri_font->fontheight;
  463         col = ri->ri_ccol * ri->ri_font->fontwidth;
  464         fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
  465         fbc->fbc_clip = 0;
  466         fbc->fbc_s = 0;
  467         fbc->fbc_offx = 0;
  468         fbc->fbc_offy = 0;
  469         fbc->fbc_clipminx = 0;
  470         fbc->fbc_clipminy = 0;
  471         fbc->fbc_clipmaxx = ri->ri_width - 1;
  472         fbc->fbc_clipmaxy = ri->ri_height - 1;
  473         fbc->fbc_alu = CG6_ALU_FLIP;
  474         fbc->fbc_arecty = ri->ri_yorigin + row;
  475         fbc->fbc_arectx = ri->ri_xorigin + col;
  476         fbc->fbc_arecty = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
  477         fbc->fbc_arectx = ri->ri_xorigin + col + ri->ri_font->fontwidth - 1;
  478         CG6_DRAW_WAIT(fbc);
  479         CG6_DRAIN(fbc);
  480 }
  481 #endif /* RASTERCONSOLE */
  482 
  483 void
  484 cg6attach(sc, name, isconsole)
  485         struct cgsix_softc *sc;
  486         char *name;
  487         int isconsole;
  488 {
  489         struct fbdevice *fb = &sc->sc_fb;
  490 
  491         fb->fb_driver = &cg6_fbdriver;
  492 
  493         /* Don't have to map the pfour register on the cgsix. */
  494         fb->fb_pfour = NULL;
  495 
  496         fb->fb_type.fb_cmsize = 256;
  497         fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
  498         printf(": %s, %d x %d", name,
  499                fb->fb_type.fb_width, fb->fb_type.fb_height);
  500 
  501         sc->sc_fhcrev = (*sc->sc_fhc >> FHC_REV_SHIFT) &
  502                         (FHC_REV_MASK >> FHC_REV_SHIFT);
  503 
  504         printf(", rev %d", sc->sc_fhcrev);
  505 
  506         /* reset cursor & frame buffer controls */
  507         cg6_reset(sc);
  508 
  509         /* enable video */
  510         sc->sc_thc->thc_misc |= THC_MISC_VIDEN;
  511 
  512         if (isconsole) {
  513                 printf(" (console)");
  514 #ifdef RASTERCONSOLE
  515                 if (cgsix_use_rasterconsole) {
  516                         fbrcons_init(&sc->sc_fb);
  517                         sc->sc_fb.fb_rinfo.ri_hw = sc;
  518                         sc->sc_fb.fb_rinfo.ri_ops.copyrows = cg6_ras_copyrows;
  519                         sc->sc_fb.fb_rinfo.ri_ops.copycols = cg6_ras_copycols;
  520                         sc->sc_fb.fb_rinfo.ri_ops.erasecols = cg6_ras_erasecols;
  521                         sc->sc_fb.fb_rinfo.ri_ops.eraserows = cg6_ras_eraserows;
  522                         sc->sc_fb.fb_rinfo.ri_do_cursor = cg6_ras_do_cursor;
  523                         cg6_ras_init(sc);
  524                 }
  525 #endif
  526         }
  527 
  528         printf("\n");
  529         fb_attach(&sc->sc_fb, isconsole);
  530 }
  531 
  532 
  533 int
  534 cgsixopen(dev, flags, mode, p)
  535         dev_t dev;
  536         int flags, mode;
  537         struct proc *p;
  538 {
  539         int unit = minor(dev);
  540 
  541         if (unit >= cgsix_cd.cd_ndevs || cgsix_cd.cd_devs[unit] == NULL)
  542                 return (ENXIO);
  543         return (0);
  544 }
  545 
  546 int
  547 cgsixclose(dev, flags, mode, p)
  548         dev_t dev;
  549         int flags, mode;
  550         struct proc *p;
  551 {
  552         struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
  553 
  554         cg6_reset(sc);
  555 
  556         /* (re-)initialize the default color map */
  557         bt_initcmap(&sc->sc_cmap, 256);
  558         cg6_loadcmap(sc, 0, 256);
  559 
  560         return (0);
  561 }
  562 
  563 int
  564 cgsixioctl(dev, cmd, data, flags, p)
  565         dev_t dev;
  566         u_long cmd;
  567         caddr_t data;
  568         int flags;
  569         struct proc *p;
  570 {
  571         struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
  572         union cursor_cmap tcm;
  573         uint32_t image[32], mask[32];
  574         u_int count;
  575         int v, error;
  576 
  577         switch (cmd) {
  578 
  579         case FBIOGTYPE:
  580                 *(struct fbtype *)data = sc->sc_fb.fb_type;
  581                 break;
  582 
  583         case FBIOGATTR:
  584 #define fba ((struct fbgattr *)data)
  585                 fba->real_type = sc->sc_fb.fb_type.fb_type;
  586                 fba->owner = 0;         /* XXX ??? */
  587                 fba->fbtype = sc->sc_fb.fb_type;
  588                 fba->sattr.flags = 0;
  589                 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
  590                 fba->sattr.dev_specific[0] = -1;
  591                 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
  592                 fba->emu_types[1] = -1;
  593 #undef fba
  594                 break;
  595 
  596         case FBIOGETCMAP:
  597 #define p ((struct fbcmap *)data)
  598                 return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
  599 
  600         case FBIOPUTCMAP:
  601                 /* copy to software map */
  602                 error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
  603                 if (error)
  604                         return (error);
  605                 /* now blast them into the chip */
  606                 /* XXX should use retrace interrupt */
  607                 cg6_loadcmap(sc, p->index, p->count);
  608 #undef p
  609                 break;
  610 
  611         case FBIOGVIDEO:
  612                 *(int *)data = sc->sc_blanked;
  613                 break;
  614 
  615         case FBIOSVIDEO:
  616                 if (*(int *)data)
  617                         cg6_unblank(&sc->sc_dev);
  618                 else if (!sc->sc_blanked) {
  619                         sc->sc_blanked = 1;
  620                         sc->sc_thc->thc_misc &= ~THC_MISC_VIDEN;
  621                 }
  622                 break;
  623 
  624 /* these are for both FBIOSCURSOR and FBIOGCURSOR */
  625 #define p ((struct fbcursor *)data)
  626 #define cc (&sc->sc_cursor)
  627 
  628         case FBIOGCURSOR:
  629                 /* do not quite want everything here... */
  630                 p->set = FB_CUR_SETALL; /* close enough, anyway */
  631                 p->enable = cc->cc_enable;
  632                 p->pos = cc->cc_pos;
  633                 p->hot = cc->cc_hot;
  634                 p->size = cc->cc_size;
  635 
  636                 /* begin ugh ... can we lose some of this crap?? */
  637                 if (p->image != NULL) {
  638                         count = cc->cc_size.y * 32 / NBBY;
  639                         error = copyout(cc->cc_bits[1], p->image, count);
  640                         if (error)
  641                                 return (error);
  642                         error = copyout(cc->cc_bits[0], p->mask, count);
  643                         if (error)
  644                                 return (error);
  645                 }
  646                 if (p->cmap.red != NULL) {
  647                         error = bt_getcmap(&p->cmap,
  648                             (union bt_cmap *)&cc->cc_color, 2, 1);
  649                         if (error)
  650                                 return (error);
  651                 } else {
  652                         p->cmap.index = 0;
  653                         p->cmap.count = 2;
  654                 }
  655                 /* end ugh */
  656                 break;
  657 
  658         case FBIOSCURSOR:
  659                 /*
  660                  * For setcmap and setshape, verify parameters, so that
  661                  * we do not get halfway through an update and then crap
  662                  * out with the software state screwed up.
  663                  */
  664                 v = p->set;
  665                 if (v & FB_CUR_SETCMAP) {
  666                         /*
  667                          * This use of a temporary copy of the cursor
  668                          * colormap is not terribly efficient, but these
  669                          * copies are small (8 bytes)...
  670                          */
  671                         tcm = cc->cc_color;
  672                         error = bt_putcmap(&p->cmap, (union bt_cmap *)&tcm, 2, 1);
  673                         if (error)
  674                                 return (error);
  675                 }
  676                 if (v & FB_CUR_SETSHAPE) {
  677                         if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)
  678                                 return (EINVAL);
  679                         count = p->size.y * 32 / NBBY;
  680                         error = copyin(p->image, image, count);
  681                         if (error)
  682                                 return error;
  683                         error = copyin(p->mask, mask, count);
  684                         if (error)
  685                                 return error;
  686                 }
  687 
  688                 /* parameters are OK; do it */
  689                 if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
  690                         if (v & FB_CUR_SETCUR)
  691                                 cc->cc_enable = p->enable;
  692                         if (v & FB_CUR_SETPOS)
  693                                 cc->cc_pos = p->pos;
  694                         if (v & FB_CUR_SETHOT)
  695                                 cc->cc_hot = p->hot;
  696                         cg6_setcursor(sc);
  697                 }
  698                 if (v & FB_CUR_SETCMAP) {
  699                         cc->cc_color = tcm;
  700                         cg6_loadomap(sc); /* XXX defer to vertical retrace */
  701                 }
  702                 if (v & FB_CUR_SETSHAPE) {
  703                         cc->cc_size = p->size;
  704                         count = p->size.y * 32 / NBBY;
  705                         memset(cc->cc_bits, 0, sizeof cc->cc_bits);
  706                         memcpy(cc->cc_bits[1], image, count);
  707                         memcpy(cc->cc_bits[0], mask, count);
  708                         cg6_loadcursor(sc);
  709                 }
  710                 break;
  711 
  712 #undef p
  713 #undef cc
  714 
  715         case FBIOGCURPOS:
  716                 *(struct fbcurpos *)data = sc->sc_cursor.cc_pos;
  717                 break;
  718 
  719         case FBIOSCURPOS:
  720                 sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;
  721                 cg6_setcursor(sc);
  722                 break;
  723 
  724         case FBIOGCURMAX:
  725                 /* max cursor size is 32x32 */
  726                 ((struct fbcurpos *)data)->x = 32;
  727                 ((struct fbcurpos *)data)->y = 32;
  728                 break;
  729 
  730         default:
  731 #ifdef DEBUG
  732                 log(LOG_NOTICE, "cgsixioctl(0x%lx) (%s[%d])\n", cmd,
  733                     p->p_comm, p->p_pid);
  734 #endif
  735                 return (ENOTTY);
  736         }
  737         return (0);
  738 }
  739 
  740 /*
  741  * Clean up hardware state (e.g., after bootup or after X crashes).
  742  */
  743 static void
  744 cg6_reset(sc)
  745         struct cgsix_softc *sc;
  746 {
  747         volatile struct cg6_tec_xxx *tec;
  748         int fhc;
  749         volatile struct bt_regs *bt;
  750 
  751         /* hide the cursor, just in case */
  752         sc->sc_thc->thc_cursxy = (THC_CURSOFF << 16) | THC_CURSOFF;
  753 
  754         /* turn off frobs in transform engine (makes X11 work) */
  755         tec = sc->sc_tec;
  756         tec->tec_mv = 0;
  757         tec->tec_clip = 0;
  758         tec->tec_vdc = 0;
  759 
  760         /* take care of hardware bugs in old revisions */
  761         if (sc->sc_fhcrev < 5) {
  762                 /*
  763                  * Keep current resolution; set CPU to 68020, set test
  764                  * window (size 1Kx1K), and for rev 1, disable dest cache.
  765                  */
  766                 fhc = (*sc->sc_fhc & FHC_RES_MASK) | FHC_CPU_68020 |
  767                     FHC_TEST |
  768                     (11 << FHC_TESTX_SHIFT) | (11 << FHC_TESTY_SHIFT);
  769                 if (sc->sc_fhcrev < 2)
  770                         fhc |= FHC_DST_DISABLE;
  771                 *sc->sc_fhc = fhc;
  772         }
  773 
  774         /* Enable cursor in Brooktree DAC. */
  775         bt = sc->sc_bt;
  776         bt->bt_addr = 0x06 << 24;
  777         bt->bt_ctrl |= 0x03 << 24;
  778 }
  779 
  780 static void
  781 cg6_setcursor(sc)
  782         struct cgsix_softc *sc;
  783 {
  784 
  785         /* we need to subtract the hot-spot value here */
  786 #define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
  787         sc->sc_thc->thc_cursxy = sc->sc_cursor.cc_enable ?
  788             ((COORD(x) << 16) | (COORD(y) & 0xffff)) :
  789             (THC_CURSOFF << 16) | THC_CURSOFF;
  790 #undef COORD
  791 }
  792 
  793 static void
  794 cg6_loadcursor(sc)
  795         struct cgsix_softc *sc;
  796 {
  797         volatile struct cg6_thc *thc;
  798         u_int edgemask, m;
  799         int i;
  800 
  801         /*
  802          * Keep the top size.x bits.  Here we *throw out* the top
  803          * size.x bits from an all-one-bits word, introducing zeros in
  804          * the top size.x bits, then invert all the bits to get what
  805          * we really wanted as our mask.  But this fails if size.x is
  806          * 32---a sparc uses only the low 5 bits of the shift count---
  807          * so we have to special case that.
  808          */
  809         edgemask = ~0;
  810         if (sc->sc_cursor.cc_size.x < 32)
  811                 edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);
  812         thc = sc->sc_thc;
  813         for (i = 0; i < 32; i++) {
  814                 m = sc->sc_cursor.cc_bits[0][i] & edgemask;
  815                 thc->thc_cursmask[i] = m;
  816                 thc->thc_cursbits[i] = m & sc->sc_cursor.cc_bits[1][i];
  817         }
  818 }
  819 
  820 /*
  821  * Load a subset of the current (new) colormap into the color DAC.
  822  */
  823 static void
  824 cg6_loadcmap(sc, start, ncolors)
  825         struct cgsix_softc *sc;
  826         int start, ncolors;
  827 {
  828         volatile struct bt_regs *bt;
  829         u_int *ip, i;
  830         int count;
  831 
  832         ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)];      /* start/4 * 3 */
  833         count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
  834         bt = sc->sc_bt;
  835         bt->bt_addr = BT_D4M4(start) << 24;
  836         while (--count >= 0) {
  837                 i = *ip++;
  838                 /* hardware that makes one want to pound boards with hammers */
  839                 bt->bt_cmap = i;
  840                 bt->bt_cmap = i << 8;
  841                 bt->bt_cmap = i << 16;
  842                 bt->bt_cmap = i << 24;
  843         }
  844 }
  845 
  846 /*
  847  * Load the cursor (overlay `foreground' and `background') colors.
  848  */
  849 static void
  850 cg6_loadomap(sc)
  851         struct cgsix_softc *sc;
  852 {
  853         volatile struct bt_regs *bt;
  854         u_int i;
  855 
  856         bt = sc->sc_bt;
  857         bt->bt_addr = 0x01 << 24;       /* set background color */
  858         i = sc->sc_cursor.cc_color.cm_chip[0];
  859         bt->bt_omap = i;                /* R */
  860         bt->bt_omap = i << 8;           /* G */
  861         bt->bt_omap = i << 16;          /* B */
  862 
  863         bt->bt_addr = 0x03 << 24;       /* set foreground color */
  864         bt->bt_omap = i << 24;          /* R */
  865         i = sc->sc_cursor.cc_color.cm_chip[1];
  866         bt->bt_omap = i;                /* G */
  867         bt->bt_omap = i << 8;           /* B */
  868 }
  869 
  870 static void
  871 cg6_unblank(dev)
  872         struct device *dev;
  873 {
  874         struct cgsix_softc *sc = (struct cgsix_softc *)dev;
  875 
  876         if (sc->sc_blanked) {
  877                 sc->sc_blanked = 0;
  878                 sc->sc_thc->thc_misc |= THC_MISC_VIDEN;
  879         }
  880 }
  881 
  882 /* XXX the following should be moved to a "user interface" header */
  883 /*
  884  * Base addresses at which users can mmap() the various pieces of a cg6.
  885  * Note that although the Brooktree color registers do not occupy 8K,
  886  * the X server dies if we do not allow it to map 8K there (it just maps
  887  * from 0x70000000 forwards, as a contiguous chunk).
  888  */
  889 #define CG6_USER_FBC    0x70000000
  890 #define CG6_USER_TEC    0x70001000
  891 #define CG6_USER_BTREGS 0x70002000
  892 #define CG6_USER_FHC    0x70004000
  893 #define CG6_USER_THC    0x70005000
  894 #define CG6_USER_ROM    0x70006000
  895 #define CG6_USER_RAM    0x70016000
  896 #define CG6_USER_DHC    0x80000000
  897 
  898 struct mmo {
  899         u_long  mo_uaddr;       /* user (virtual) address */
  900         u_long  mo_size;        /* size, or 0 for video ram size */
  901         u_long  mo_physoff;     /* offset from sc_physadr */
  902 };
  903 
  904 /*
  905  * Return the address that would map the given device at the given
  906  * offset, allowing for the given protection, or return -1 for error.
  907  *
  908  * XXX  needs testing against `demanding' applications (e.g., aviator)
  909  */
  910 paddr_t
  911 cgsixmmap(dev, off, prot)
  912         dev_t dev;
  913         off_t off;
  914         int prot;
  915 {
  916         struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
  917         struct mmo *mo;
  918         u_int u, sz;
  919         static struct mmo mmo[] = {
  920                 { CG6_USER_RAM, 0, CGSIX_RAM_OFFSET },
  921 
  922                 /* do not actually know how big most of these are! */
  923                 { CG6_USER_FBC, 1, CGSIX_FBC_OFFSET },
  924                 { CG6_USER_TEC, 1, CGSIX_TEC_OFFSET },
  925                 { CG6_USER_BTREGS, 8192 /* XXX */, CGSIX_BT_OFFSET },
  926                 { CG6_USER_FHC, 1, CGSIX_FHC_OFFSET },
  927                 { CG6_USER_THC, sizeof(struct cg6_thc), CGSIX_THC_OFFSET },
  928                 { CG6_USER_ROM, 65536, CGSIX_ROM_OFFSET },
  929                 { CG6_USER_DHC, 1, CGSIX_DHC_OFFSET },
  930         };
  931 #define NMMO (sizeof mmo / sizeof *mmo)
  932 
  933         if (off & PGOFSET)
  934                 panic("cgsixmmap");
  935 
  936         /*
  937          * Entries with size 0 map video RAM (i.e., the size in fb data).
  938          *
  939          * Since we work in pages, the fact that the map offset table's
  940          * sizes are sometimes bizarre (e.g., 1) is effectively ignored:
  941          * one byte is as good as one page.
  942          */
  943         for (mo = mmo; mo < &mmo[NMMO]; mo++) {
  944                 if ((u_long)off < mo->mo_uaddr)
  945                         continue;
  946                 u = off - mo->mo_uaddr;
  947                 sz = mo->mo_size ? mo->mo_size : sc->sc_fb.fb_type.fb_size;
  948                 if (u < sz) {
  949                         return (bus_space_mmap(sc->sc_bustag,
  950                                 sc->sc_paddr, u+mo->mo_physoff,
  951                                 prot, BUS_SPACE_MAP_LINEAR));
  952                 }
  953         }
  954 
  955 #ifdef DEBUG
  956         {
  957           struct proc *p = curlwp->l_proc;      /* XXX */
  958           log(LOG_NOTICE, "cgsixmmap(0x%llx) (%s[%d])\n",
  959                 (long long)off, p->p_comm, p->p_pid);
  960         }
  961 #endif
  962         return (-1);    /* not a user-map offset */
  963 }

Cache object: 0b780043e9d44332568bec32aaa1c500


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