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/tc/mfb.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: mfb.c,v 1.41 2003/12/20 07:10:00 nisimura Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1998, 1999 Tohru Nishimura.  All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Tohru Nishimura
   17  *      for the NetBSD Project.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: mfb.c,v 1.41 2003/12/20 07:10:00 nisimura 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 #include <sys/ioctl.h>
   43 
   44 #include <machine/bus.h>
   45 #include <machine/intr.h>
   46 
   47 #include <dev/wscons/wsconsio.h>
   48 #include <dev/wscons/wsdisplayvar.h>
   49 
   50 #include <dev/rasops/rasops.h>
   51 #include <dev/wsfont/wsfont.h>
   52 
   53 #include <dev/tc/tcvar.h>
   54 #include <dev/ic/bt431reg.h>    
   55 
   56 #include <uvm/uvm_extern.h>
   57 
   58 #if defined(pmax)
   59 #define machine_btop(x) mips_btop(MIPS_KSEG1_TO_PHYS(x))
   60 #endif
   61 
   62 #if defined(alpha)
   63 #define machine_btop(x) alpha_btop(ALPHA_K0SEG_TO_PHYS(x))
   64 #endif
   65 
   66 /* Bt455 hardware registers, memory-mapped in 32bit stride */
   67 #define bt_reg  0x0
   68 #define bt_cmap 0x4
   69 #define bt_clr  0x8
   70 #define bt_ovly 0xc
   71 
   72 /* Bt431 hardware registers, memory-mapped in 32bit stride */
   73 #define bt_lo   0x0
   74 #define bt_hi   0x4
   75 #define bt_ram  0x8
   76 #define bt_ctl  0xc
   77 
   78 #define REGWRITE32(p,i,v) do {                                  \
   79         *(volatile u_int32_t *)((p) + (i)) = (v); tc_wmb();     \
   80     } while (0)
   81 
   82 #define SELECT455(p,r) do {                                     \
   83         REGWRITE32((p), bt_reg, (r));                           \
   84         REGWRITE32((p), bt_clr, 0);                             \
   85    } while (0)
   86 
   87 #define TWIN(x)    ((x)|((x) << 8))
   88 #define TWIN_LO(x) (twin = (x) & 0x00ff, twin << 8 | twin)
   89 #define TWIN_HI(x) (twin = (x) & 0xff00, twin | twin >> 8)
   90 
   91 #define SELECT431(p,r) do {                                     \
   92         REGWRITE32((p), bt_lo, TWIN(r));                        \
   93         REGWRITE32((p), bt_hi, 0);                              \
   94    } while (0)
   95 
   96 struct hwcursor64 {
   97         struct wsdisplay_curpos cc_pos;
   98         struct wsdisplay_curpos cc_hot;
   99         struct wsdisplay_curpos cc_size;
  100         struct wsdisplay_curpos cc_magic;
  101 #define CURSOR_MAX_SIZE 64
  102         u_int8_t cc_color[6];
  103         u_int64_t cc_image[CURSOR_MAX_SIZE];
  104         u_int64_t cc_mask[CURSOR_MAX_SIZE];
  105 };
  106 
  107 struct mfb_softc {
  108         struct device sc_dev;
  109         vaddr_t sc_vaddr;
  110         size_t sc_size;
  111         struct rasops_info *sc_ri;
  112         struct hwcursor64 sc_cursor;    /* software copy of cursor */
  113         int sc_blanked;
  114         int sc_curenb;                  /* cursor sprite enabled */
  115         int sc_changed;                 /* need update of hardware */
  116         int nscreens;
  117 };
  118 
  119 #define MX_MAGIC_X      360
  120 #define MX_MAGIC_Y      36
  121 
  122 #define MX_FB_OFFSET    0x200000
  123 #define MX_FB_SIZE      0x200000
  124 #define MX_BT455_OFFSET 0x100000
  125 #define MX_BT431_OFFSET 0x180000
  126 #define MX_IREQ_OFFSET  0x080000        /* Interrupt req. control */
  127 
  128 static int  mfbmatch(struct device *, struct cfdata *, void *);
  129 static void mfbattach(struct device *, struct device *, void *);
  130 
  131 CFATTACH_DECL(mfb, sizeof(struct mfb_softc),
  132     mfbmatch, mfbattach, NULL, NULL);
  133 
  134 static void mfb_common_init(struct rasops_info *);
  135 static struct rasops_info mfb_console_ri;
  136 static tc_addr_t mfb_consaddr;
  137 
  138 static struct wsscreen_descr mfb_stdscreen = {
  139         "std", 0, 0,
  140         0, /* textops */
  141         0, 0,
  142         WSSCREEN_REVERSE
  143 };
  144 
  145 static const struct wsscreen_descr *_mfb_scrlist[] = {
  146         &mfb_stdscreen,
  147 };
  148 
  149 static const struct wsscreen_list mfb_screenlist = {
  150         sizeof(_mfb_scrlist) / sizeof(struct wsscreen_descr *), _mfb_scrlist
  151 };
  152 
  153 static int      mfbioctl(void *, u_long, caddr_t, int, struct proc *);
  154 static paddr_t  mfbmmap(void *, off_t, int);
  155 
  156 static int      mfb_alloc_screen(void *, const struct wsscreen_descr *,
  157                                       void **, int *, int *, long *);
  158 static void     mfb_free_screen(void *, void *);
  159 static int      mfb_show_screen(void *, void *, int,
  160                                      void (*) (void *, int, int), void *);
  161 
  162 static const struct wsdisplay_accessops mfb_accessops = {
  163         mfbioctl,
  164         mfbmmap,
  165         mfb_alloc_screen,
  166         mfb_free_screen,
  167         mfb_show_screen,
  168         0 /* load_font */
  169 };
  170 
  171 int  mfb_cnattach(tc_addr_t);
  172 static int  mfbintr(void *);
  173 static void mfbhwinit(caddr_t);
  174 
  175 static int  set_cursor(struct mfb_softc *, struct wsdisplay_cursor *);
  176 static int  get_cursor(struct mfb_softc *, struct wsdisplay_cursor *);
  177 static void set_curpos(struct mfb_softc *, struct wsdisplay_curpos *);
  178 
  179 /* bit order reverse */
  180 static const u_int8_t flip[256] = {
  181         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  182         0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  183         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  184         0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  185         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  186         0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  187         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  188         0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  189         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  190         0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  191         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  192         0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  193         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  194         0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  195         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  196         0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  197         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  198         0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  199         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  200         0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  201         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  202         0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  203         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  204         0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  205         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  206         0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  207         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  208         0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  209         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  210         0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  211         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  212         0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
  213 };
  214 
  215 static int
  216 mfbmatch(parent, match, aux)
  217         struct device *parent;
  218         struct cfdata *match;
  219         void *aux;
  220 {
  221         struct tc_attach_args *ta = aux;
  222 
  223         if (strncmp("PMAG-AA ", ta->ta_modname, TC_ROM_LLEN) != 0)
  224                 return (0);
  225 
  226         return (1);
  227 }
  228 
  229 static void
  230 mfbattach(parent, self, aux)
  231         struct device *parent, *self;
  232         void *aux;
  233 {
  234         struct mfb_softc *sc = (struct mfb_softc *)self;
  235         struct tc_attach_args *ta = aux;
  236         struct rasops_info *ri;
  237         struct wsemuldisplaydev_attach_args waa;
  238         int console;
  239         volatile register int junk;
  240 
  241         console = (ta->ta_addr == mfb_consaddr);
  242         if (console) {
  243                 sc->sc_ri = ri = &mfb_console_ri;
  244                 sc->nscreens = 1;
  245         }
  246         else {
  247                 MALLOC(ri, struct rasops_info *, sizeof(struct rasops_info),
  248                         M_DEVBUF, M_NOWAIT);
  249                 if (ri == NULL) {
  250                         printf(": can't alloc memory\n");
  251                         return;
  252                 }
  253                 memset(ri, 0, sizeof(struct rasops_info));
  254 
  255                 ri->ri_hw = (void *)ta->ta_addr;
  256                 mfb_common_init(ri);
  257                 sc->sc_ri = ri;
  258         }
  259         printf(": %dx%d, 1bpp\n", ri->ri_width, ri->ri_height);
  260 
  261         sc->sc_vaddr = ta->ta_addr;
  262         sc->sc_cursor.cc_magic.x = MX_MAGIC_X;
  263         sc->sc_cursor.cc_magic.y = MX_MAGIC_Y;
  264         sc->sc_blanked = sc->sc_curenb = 0;
  265 
  266         tc_intr_establish(parent, ta->ta_cookie, IPL_TTY, mfbintr, sc);
  267 
  268         /* clear any pending interrupts */
  269         *(u_int8_t *)((caddr_t)ri->ri_hw + MX_IREQ_OFFSET) = 0;
  270         junk = *(u_int8_t *)((caddr_t)ri->ri_hw + MX_IREQ_OFFSET);
  271         *(u_int8_t *)((caddr_t)ri->ri_hw + MX_IREQ_OFFSET) = 1;
  272 
  273         waa.console = console;
  274         waa.scrdata = &mfb_screenlist;
  275         waa.accessops = &mfb_accessops;
  276         waa.accesscookie = sc;
  277 
  278         config_found(self, &waa, wsemuldisplaydevprint);
  279 }
  280 
  281 static void
  282 mfb_common_init(ri)
  283         struct rasops_info *ri;
  284 {
  285         caddr_t base;
  286         int cookie;
  287 
  288         base = (caddr_t)ri->ri_hw;
  289 
  290         /* initialize colormap and cursor hardware */
  291         mfbhwinit(base);
  292 
  293         ri->ri_flg = RI_CENTER | RI_FORCEMONO;
  294         ri->ri_depth = 8;       /* !! watch out !! */
  295         ri->ri_width = 1280;
  296         ri->ri_height = 1024;
  297         ri->ri_stride = 2048;
  298         ri->ri_bits = base + MX_FB_OFFSET;
  299 
  300         /* clear the screen */
  301         memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
  302 
  303         wsfont_init();
  304         /* prefer 12 pixel wide font */
  305         cookie = wsfont_find(NULL, 12, 0, 0, WSDISPLAY_FONTORDER_L2R,
  306             WSDISPLAY_FONTORDER_L2R);
  307         if (cookie <= 0)
  308                 cookie = wsfont_find(NULL, 0, 0, 0, WSDISPLAY_FONTORDER_L2R,
  309                     WSDISPLAY_FONTORDER_L2R);
  310         if (cookie <= 0) {
  311                 printf("mfb: font table is empty\n");
  312                 return;
  313         }
  314 
  315         if (wsfont_lock(cookie, &ri->ri_font)) {
  316                 printf("mfb: couldn't lock font\n");
  317                 return;
  318         }
  319         ri->ri_wsfcookie = cookie;
  320 
  321         rasops_init(ri, 34, 80);
  322 
  323         /* XXX shouldn't be global */
  324         mfb_stdscreen.nrows = ri->ri_rows;
  325         mfb_stdscreen.ncols = ri->ri_cols;
  326         mfb_stdscreen.textops = &ri->ri_ops;
  327         mfb_stdscreen.capabilities = ri->ri_caps;
  328 }
  329 
  330 static int
  331 mfbioctl(v, cmd, data, flag, p)
  332         void *v;
  333         u_long cmd;
  334         caddr_t data;
  335         int flag;
  336         struct proc *p;
  337 {
  338         struct mfb_softc *sc = v;
  339         struct rasops_info *ri = sc->sc_ri;
  340         int turnoff, s;
  341 
  342         switch (cmd) {
  343         case WSDISPLAYIO_GTYPE:
  344                 *(u_int *)data = WSDISPLAY_TYPE_MFB;
  345                 return (0);
  346 
  347         case WSDISPLAYIO_GINFO:
  348 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
  349                 wsd_fbip->height = ri->ri_height;
  350                 wsd_fbip->width = ri->ri_width;
  351                 wsd_fbip->depth = ri->ri_depth;
  352                 wsd_fbip->cmsize = 0;
  353 #undef fbt
  354                 return (0);
  355 
  356         case WSDISPLAYIO_GETCMAP:
  357         case WSDISPLAYIO_PUTCMAP:
  358                 return (EPASSTHROUGH);
  359 
  360         case WSDISPLAYIO_SVIDEO:
  361                 turnoff = *(int *)data == WSDISPLAYIO_VIDEO_OFF;
  362                 if ((sc->sc_blanked == 0) ^ turnoff) {
  363                         sc->sc_blanked = turnoff;
  364 #if 0   /* XXX later XXX */
  365         To turn off,
  366         - assign Bt455 cmap[1].green with value 0 (black),
  367         - assign Bt431 register #0 with value 0x04 to hide sprite cursor.
  368 #endif  /* XXX XXX XXX */
  369                 }
  370                 return (0);
  371 
  372         case WSDISPLAYIO_GVIDEO:
  373                 *(u_int *)data = sc->sc_blanked ?
  374                     WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
  375                 return (0);
  376 
  377         case WSDISPLAYIO_GCURPOS:
  378                 *(struct wsdisplay_curpos *)data = sc->sc_cursor.cc_pos;
  379                 return (0);
  380 
  381         case WSDISPLAYIO_SCURPOS:
  382                 s = spltty();
  383                 set_curpos(sc, (struct wsdisplay_curpos *)data);
  384                 sc->sc_changed |= WSDISPLAY_CURSOR_DOPOS;
  385                 splx(s);
  386                 return (0);
  387 
  388         case WSDISPLAYIO_GCURMAX:
  389                 ((struct wsdisplay_curpos *)data)->x =
  390                 ((struct wsdisplay_curpos *)data)->y = CURSOR_MAX_SIZE;
  391                 return (0);
  392 
  393         case WSDISPLAYIO_GCURSOR:
  394                 return get_cursor(sc, (struct wsdisplay_cursor *)data);
  395 
  396         case WSDISPLAYIO_SCURSOR:
  397                 return set_cursor(sc, (struct wsdisplay_cursor *)data);
  398 
  399         case WSDISPLAYIO_SMODE:
  400                 if (*(int *)data == WSDISPLAYIO_MODE_EMUL) {
  401                         s = spltty();
  402                         sc->sc_curenb = 0;
  403                         sc->sc_blanked = 0;
  404                         sc->sc_changed |= WSDISPLAY_CURSOR_DOCUR;
  405                         splx(s);
  406                 }
  407                 return (0);
  408         }
  409         return (EPASSTHROUGH);
  410 }
  411 
  412 static paddr_t
  413 mfbmmap(v, offset, prot)
  414         void *v;
  415         off_t offset;
  416         int prot;
  417 {
  418         struct mfb_softc *sc = v;
  419 
  420         if (offset >= MX_FB_SIZE || offset < 0)
  421                 return (-1);
  422         return machine_btop(sc->sc_vaddr + MX_FB_OFFSET + offset);
  423 }
  424 
  425 static int
  426 mfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
  427         void *v;
  428         const struct wsscreen_descr *type;
  429         void **cookiep;
  430         int *curxp, *curyp;
  431         long *attrp;
  432 {
  433         struct mfb_softc *sc = v;
  434         struct rasops_info *ri = sc->sc_ri;
  435         long defattr;
  436 
  437         if (sc->nscreens > 0)
  438                 return (ENOMEM);
  439 
  440         *cookiep = ri;           /* one and only for now */
  441         *curxp = 0;
  442         *curyp = 0;
  443         (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
  444         *attrp = defattr;
  445         sc->nscreens++;
  446         return (0);
  447 }
  448 
  449 static void
  450 mfb_free_screen(v, cookie)
  451         void *v;
  452         void *cookie;
  453 {
  454         struct mfb_softc *sc = v;
  455 
  456         if (sc->sc_ri == &mfb_console_ri)
  457                 panic("mfb_free_screen: console");
  458 
  459         sc->nscreens--;
  460 }
  461 
  462 static int
  463 mfb_show_screen(v, cookie, waitok, cb, cbarg)
  464         void *v;
  465         void *cookie;
  466         int waitok;
  467         void (*cb)(void *, int, int);
  468         void *cbarg;
  469 {
  470 
  471         return (0);
  472 }
  473 
  474 /* EXPORT */ int
  475 mfb_cnattach(addr)
  476         tc_addr_t addr;
  477 {
  478         struct rasops_info *ri;
  479         long defattr;
  480 
  481         ri = &mfb_console_ri;
  482         ri->ri_hw = (void *)addr;
  483         mfb_common_init(ri);
  484         (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
  485         wsdisplay_cnattach(&mfb_stdscreen, ri, 0, 0, defattr);
  486         mfb_consaddr = addr;
  487         return (0);
  488 }
  489 
  490 static int
  491 mfbintr(arg)
  492         void *arg;
  493 {
  494         struct mfb_softc *sc = arg;
  495         caddr_t base, vdac, curs;
  496         int v;
  497         volatile register int junk;
  498         
  499         base = (caddr_t)sc->sc_ri->ri_hw;
  500         junk = *(u_int8_t *)(base + MX_IREQ_OFFSET);
  501 #if 0
  502         *(u_int8_t *)(base + MX_IREQ_OFFSET) = 0;
  503 #endif
  504         if (sc->sc_changed == 0)
  505                 return (1);
  506 
  507         vdac = base + MX_BT455_OFFSET;
  508         curs = base + MX_BT431_OFFSET;
  509         v = sc->sc_changed;
  510         if (v & WSDISPLAY_CURSOR_DOCUR) {
  511                 int  onoff;
  512 
  513                 onoff = (sc->sc_curenb) ? 0x4444 : 0x0404;
  514                 SELECT431(curs, BT431_REG_COMMAND);
  515                 REGWRITE32(curs, bt_ctl, onoff);
  516         }
  517         if (v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
  518                 int x, y;
  519                 u_int32_t twin;
  520 
  521                 x = sc->sc_cursor.cc_pos.x - sc->sc_cursor.cc_hot.x;
  522                 y = sc->sc_cursor.cc_pos.y - sc->sc_cursor.cc_hot.y;
  523 
  524                 x += sc->sc_cursor.cc_magic.x;
  525                 y += sc->sc_cursor.cc_magic.y;
  526 
  527                 SELECT431(curs, BT431_REG_CURSOR_X_LOW);
  528                 REGWRITE32(curs, bt_ctl, TWIN_LO(x));
  529                 REGWRITE32(curs, bt_ctl, TWIN_HI(x));
  530                 REGWRITE32(curs, bt_ctl, TWIN_LO(y));
  531                 REGWRITE32(curs, bt_ctl, TWIN_HI(y));
  532         }
  533         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  534                 u_int8_t *cp = sc->sc_cursor.cc_color;
  535 
  536                 SELECT455(vdac, 8);
  537                 REGWRITE32(vdac, bt_cmap, 0);
  538                 REGWRITE32(vdac, bt_cmap, cp[1]);
  539                 REGWRITE32(vdac, bt_cmap, 0);
  540 
  541                 REGWRITE32(vdac, bt_cmap, 0);
  542                 REGWRITE32(vdac, bt_cmap, cp[1]);
  543                 REGWRITE32(vdac, bt_cmap, 0);
  544 
  545                 REGWRITE32(vdac, bt_ovly, 0);
  546                 REGWRITE32(vdac, bt_ovly, cp[0]);
  547                 REGWRITE32(vdac, bt_ovly, 0);
  548         }
  549         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  550                 u_int8_t *ip, *mp, img, msk;
  551                 int bcnt;
  552 
  553                 ip = (u_int8_t *)sc->sc_cursor.cc_image;
  554                 mp = (u_int8_t *)sc->sc_cursor.cc_mask;
  555                 bcnt = 0;
  556                 SELECT431(curs, BT431_REG_CRAM_BASE);
  557 
  558                 /* 64 pixel scan line is consisted with 16 byte cursor ram */
  559                 while (bcnt < sc->sc_cursor.cc_size.y * 16) {
  560                         /* pad right half 32 pixel when smaller than 33 */
  561                         if ((bcnt & 0x8) && sc->sc_cursor.cc_size.x < 33) {
  562                                 REGWRITE32(curs, bt_ram, 0);
  563                         }
  564                         else {
  565                                 int half;
  566 
  567                                 img = *ip++;
  568                                 msk = *mp++;
  569                                 img &= msk;     /* cookie off image */
  570                                 half = (flip[msk] << 8) | flip[img];
  571                                 REGWRITE32(curs, bt_ram, half);
  572                         }
  573                         bcnt += 2;
  574                 }
  575                 /* pad unoccupied scan lines */
  576                 while (bcnt < CURSOR_MAX_SIZE * 16) {
  577                         REGWRITE32(curs, bt_ram, 0);
  578                         bcnt += 2;
  579                 }
  580         }
  581         sc->sc_changed = 0;     
  582         return (1);
  583 }
  584 
  585 static void
  586 mfbhwinit(mfbbase)
  587         caddr_t mfbbase;
  588 {
  589         caddr_t vdac, curs;
  590         int i;
  591 
  592         vdac = mfbbase + MX_BT455_OFFSET;
  593         curs = mfbbase + MX_BT431_OFFSET;
  594         SELECT431(curs, BT431_REG_COMMAND);
  595         REGWRITE32(curs, bt_ctl, 0x0404);       
  596         REGWRITE32(curs, bt_ctl, 0); /* XLO */
  597         REGWRITE32(curs, bt_ctl, 0); /* XHI */
  598         REGWRITE32(curs, bt_ctl, 0); /* YLO */
  599         REGWRITE32(curs, bt_ctl, 0); /* YHI */
  600         REGWRITE32(curs, bt_ctl, 0); /* XWLO */
  601         REGWRITE32(curs, bt_ctl, 0); /* XWHI */
  602         REGWRITE32(curs, bt_ctl, 0); /* WYLO */
  603         REGWRITE32(curs, bt_ctl, 0); /* WYLO */
  604         REGWRITE32(curs, bt_ctl, 0); /* WWLO */
  605         REGWRITE32(curs, bt_ctl, 0); /* WWHI */
  606         REGWRITE32(curs, bt_ctl, 0); /* WHLO */
  607         REGWRITE32(curs, bt_ctl, 0); /* WHHI */
  608 
  609         /* 0: black, 1: white, 8,9: cursor mask, ovly: cursor image */
  610         SELECT455(vdac, 0);
  611         REGWRITE32(vdac, bt_cmap, 0);   
  612         REGWRITE32(vdac, bt_cmap, 0);   
  613         REGWRITE32(vdac, bt_cmap, 0);   
  614         REGWRITE32(vdac, bt_cmap, 0);   
  615         REGWRITE32(vdac, bt_cmap, 0xff);        
  616         REGWRITE32(vdac, bt_cmap, 0);   
  617         for (i = 2; i < 16; i++) {
  618                 REGWRITE32(vdac, bt_cmap, 0);
  619                 REGWRITE32(vdac, bt_cmap, 0);
  620                 REGWRITE32(vdac, bt_cmap, 0);
  621         }
  622         REGWRITE32(vdac, bt_ovly, 0);
  623         REGWRITE32(vdac, bt_ovly, 0xff);
  624         REGWRITE32(vdac, bt_ovly, 0);
  625 
  626         SELECT431(curs, BT431_REG_CRAM_BASE);
  627         for (i = 0; i < 512; i++) {
  628                 REGWRITE32(curs, bt_ram, 0);
  629         }
  630 }
  631 
  632 static int
  633 set_cursor(sc, p)
  634         struct mfb_softc *sc;
  635         struct wsdisplay_cursor *p;
  636 {
  637 #define cc (&sc->sc_cursor)
  638         u_int v, count = 0, icount = 0, index = 0;
  639         uint64_t image[CURSOR_MAX_SIZE];
  640         uint64_t mask[CURSOR_MAX_SIZE];
  641         uint8_t color[6];
  642         int error, s;
  643 
  644         v = p->which;
  645         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  646                 index = p->cmap.index;
  647                 count = p->cmap.count;
  648                 if (index >= 2 || (index + count) > 2)
  649                         return (EINVAL);
  650                 error = copyin(p->cmap.red, &color[index], count);
  651                 if (error)
  652                         return error;
  653         }
  654         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  655                 if (p->size.x > CURSOR_MAX_SIZE || p->size.y > CURSOR_MAX_SIZE)
  656                         return (EINVAL);
  657                 icount = ((p->size.x < 33) ? 4 : 8) * p->size.y;
  658                 error = copyin(p->image, image, icount);
  659                 if (error)
  660                         return error;
  661                 error = copyin(p->mask, mask, icount);
  662                 if (error)
  663                         return error;
  664         }
  665 
  666         s = spltty();
  667         if (v & WSDISPLAY_CURSOR_DOCUR)
  668                 sc->sc_curenb = p->enable;
  669         if (v & WSDISPLAY_CURSOR_DOPOS)
  670                 set_curpos(sc, &p->pos);
  671         if (v & WSDISPLAY_CURSOR_DOHOT)
  672                 cc->cc_hot = p->hot;
  673         if (v & WSDISPLAY_CURSOR_DOCMAP)
  674                 memcpy(&cc->cc_color[index], &color[index], count);
  675         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  676                 cc->cc_size = p->size;
  677                 memset(cc->cc_image, 0, sizeof cc->cc_image);
  678                 memcpy(cc->cc_image, image, icount);
  679                 memset(cc->cc_mask, 0, sizeof cc->cc_mask);
  680                 memcpy(cc->cc_mask, mask, icount);
  681         }
  682         sc->sc_changed |= v;
  683         splx(s);
  684 
  685         return (0);
  686 #undef cc
  687 }
  688 
  689 static int
  690 get_cursor(sc, p)
  691         struct mfb_softc *sc;
  692         struct wsdisplay_cursor *p;
  693 {
  694         return (EPASSTHROUGH); /* XXX */
  695 }
  696 
  697 static void
  698 set_curpos(sc, curpos)
  699         struct mfb_softc *sc;
  700         struct wsdisplay_curpos *curpos;
  701 {
  702         struct rasops_info *ri = sc->sc_ri;
  703         int x = curpos->x, y = curpos->y;
  704 
  705         if (y < 0)
  706                 y = 0;
  707         else if (y > ri->ri_height)
  708                 y = ri->ri_height;
  709         if (x < 0)
  710                 x = 0;
  711         else if (x > ri->ri_width)
  712                 x = ri->ri_width;
  713         sc->sc_cursor.cc_pos.x = x;
  714         sc->sc_cursor.cc_pos.y = y;
  715 }

Cache object: 06b8be00ee8685bd17bc06cb29cc76d7


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