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/tfb.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: tfb.c,v 1.44 2003/12/20 07:10:01 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: tfb.c,v 1.44 2003/12/20 07:10:01 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/bt463reg.h>
   55 #include <dev/ic/bt431reg.h>    
   56 
   57 #include <uvm/uvm_extern.h>
   58 
   59 #if defined(pmax)
   60 #define machine_btop(x) mips_btop(MIPS_KSEG1_TO_PHYS(x))
   61 #endif
   62 
   63 #if defined(alpha)
   64 #define machine_btop(x) alpha_btop(ALPHA_K0SEG_TO_PHYS(x))
   65 #endif
   66 
   67 /*
   68  * struct bt463reg {
   69  *      u_int8_t        bt_lo;
   70  *      unsigned : 24;
   71  *      u_int8_t        bt_hi;
   72  *      unsigned : 24;
   73  *      u_int8_t        bt_reg;
   74  *      unsigned : 24;
   75  *      u_int8_t        bt_cmap;
   76  * };
   77  *
   78  * N.B. a pair of Bt431s are located adjascently.
   79  *      struct bt431twin {
   80  *              struct {
   81  *                      u_int8_t u0;    for sprite mask
   82  *                      u_int8_t u1;    for sprite image
   83  *                      unsigned :16;
   84  *              } bt_lo;
   85  *              ...
   86  *
   87  * struct bt431reg {
   88  *      u_int16_t       bt_lo;
   89  *      unsigned : 16;
   90  *      u_int16_t       bt_hi;
   91  *      unsigned : 16;
   92  *      u_int16_t       bt_ram;
   93  *      unsigned : 16;
   94  *      u_int16_t       bt_ctl;
   95  * };
   96  */
   97 
   98 /* Bt463 hardware registers, memory-mapped in 32bit stride */
   99 #define bt_lo   0x0
  100 #define bt_hi   0x4
  101 #define bt_reg  0x8
  102 #define bt_cmap 0xc
  103 
  104 /* Bt431 hardware registers, memory-mapped in 32bit stride */
  105 #define bt_ram  0x8
  106 #define bt_ctl  0xc
  107 
  108 #define REGWRITE32(p,i,v) do {                                  \
  109         *(volatile u_int32_t *)((p) + (i)) = (v); tc_wmb();     \
  110     } while (0)
  111 
  112 #define SELECT463(p,r) do {                                     \
  113         REGWRITE32((p), bt_lo, 0xff & (r));                     \
  114         REGWRITE32((p), bt_hi, 0xff & ((r)>>8));                \
  115    } while (0)
  116 
  117 #define TWIN(x)    ((x) | ((x) << 8))
  118 #define TWIN_LO(x) (twin = (x) & 0x00ff, (twin << 8) | twin)
  119 #define TWIN_HI(x) (twin = (x) & 0xff00, twin | (twin >> 8))
  120 
  121 #define SELECT431(p,r) do {                                     \
  122         REGWRITE32((p), bt_lo, TWIN(r));                        \
  123         REGWRITE32((p), bt_hi, 0);                              \
  124    } while (0)
  125 
  126 struct hwcmap256 {
  127 #define CMAP_SIZE       256     /* R/G/B entries */
  128         u_int8_t r[CMAP_SIZE];
  129         u_int8_t g[CMAP_SIZE];
  130         u_int8_t b[CMAP_SIZE];
  131 };
  132 
  133 struct hwcursor64 {
  134         struct wsdisplay_curpos cc_pos;
  135         struct wsdisplay_curpos cc_hot;
  136         struct wsdisplay_curpos cc_size;
  137         struct wsdisplay_curpos cc_magic;
  138 #define CURSOR_MAX_SIZE 64
  139         u_int8_t cc_color[6];
  140         u_int64_t cc_image[CURSOR_MAX_SIZE];
  141         u_int64_t cc_mask[CURSOR_MAX_SIZE];
  142 };
  143 
  144 struct tfb_softc {
  145         struct device sc_dev;
  146         vaddr_t sc_vaddr;
  147         size_t sc_size; 
  148         struct rasops_info *sc_ri;
  149         struct hwcmap256 sc_cmap;       /* software copy of colormap */
  150         struct hwcursor64 sc_cursor;    /* software copy of cursor */
  151         int sc_blanked;                 /* video visibility disabled */
  152         int sc_curenb;                  /* cursor sprite enabled */
  153         int sc_changed;                 /* need update of hardware */
  154 #define WSDISPLAY_CMAP_DOLUT    0x20
  155         int nscreens;
  156 };
  157 
  158 #define TX_MAGIC_X      360
  159 #define TX_MAGIC_Y      36
  160 
  161 #define TX_BT463_OFFSET 0x040000
  162 #define TX_BT431_OFFSET 0x040010
  163 #define TX_CONTROL      0x040030
  164 #define TX_MAP_REGISTER 0x040030
  165 #define TX_PIP_OFFSET   0x0800c0
  166 #define TX_SELECTION    0x100000
  167 #define TX_8BPP_OFFSET  0x200000
  168 #define TX_8BPP_SIZE    0x200000
  169 #define TX_24BPP_OFFSET 0x400000
  170 #define TX_24BPP_SIZE   0x600000
  171 #define TX_VIDEO_ENABLE 0xa00000
  172 
  173 #define TX_CTL_VIDEO_ON 0x80
  174 #define TX_CTL_INT_ENA  0x40
  175 #define TX_CTL_INT_PEND 0x20
  176 #define TX_CTL_SEG_ENA  0x10
  177 #define TX_CTL_SEG      0x0f
  178 
  179 static int  tfbmatch(struct device *, struct cfdata *, void *);
  180 static void tfbattach(struct device *, struct device *, void *);
  181 
  182 CFATTACH_DECL(tfb, sizeof(struct tfb_softc),
  183     tfbmatch, tfbattach, NULL, NULL);
  184 
  185 static void tfb_common_init(struct rasops_info *);
  186 static void tfb_cmap_init(struct tfb_softc *);
  187 static struct rasops_info tfb_console_ri;
  188 static tc_addr_t tfb_consaddr;
  189 
  190 static struct wsscreen_descr tfb_stdscreen = {
  191         "std", 0, 0,
  192         0, /* textops */
  193         0, 0,
  194         WSSCREEN_REVERSE
  195 };
  196 
  197 static const struct wsscreen_descr *_tfb_scrlist[] = {
  198         &tfb_stdscreen,
  199 };
  200 
  201 static const struct wsscreen_list tfb_screenlist = {
  202         sizeof(_tfb_scrlist) / sizeof(struct wsscreen_descr *), _tfb_scrlist
  203 };
  204 
  205 static int      tfbioctl(void *, u_long, caddr_t, int, struct proc *);
  206 static paddr_t  tfbmmap(void *, off_t, int);
  207 
  208 static int      tfb_alloc_screen(void *, const struct wsscreen_descr *,
  209                                       void **, int *, int *, long *);
  210 static void     tfb_free_screen(void *, void *);
  211 static int      tfb_show_screen(void *, void *, int,
  212                                      void (*) (void *, int, int), void *);
  213 
  214 static const struct wsdisplay_accessops tfb_accessops = {
  215         tfbioctl,
  216         tfbmmap,
  217         tfb_alloc_screen,
  218         tfb_free_screen,
  219         tfb_show_screen,
  220         0 /* load_font */
  221 };
  222 
  223 int  tfb_cnattach(tc_addr_t);
  224 static int  tfbintr(void *);
  225 static void tfbhwinit(caddr_t);
  226 
  227 static int  get_cmap(struct tfb_softc *, struct wsdisplay_cmap *);
  228 static int  set_cmap(struct tfb_softc *, struct wsdisplay_cmap *);
  229 static int  set_cursor(struct tfb_softc *, struct wsdisplay_cursor *);
  230 static int  get_cursor(struct tfb_softc *, struct wsdisplay_cursor *);
  231 static void set_curpos(struct tfb_softc *, struct wsdisplay_curpos *);
  232 
  233 /* bit order reverse */
  234 static const u_int8_t flip[256] = {
  235         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  236         0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  237         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  238         0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  239         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  240         0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  241         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  242         0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  243         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  244         0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  245         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  246         0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  247         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  248         0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  249         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  250         0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  251         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  252         0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  253         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  254         0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  255         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  256         0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  257         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  258         0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  259         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  260         0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  261         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  262         0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  263         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  264         0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  265         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  266         0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
  267 };
  268 
  269 static int
  270 tfbmatch(parent, match, aux)
  271         struct device *parent;
  272         struct cfdata *match;
  273         void *aux;
  274 {
  275         struct tc_attach_args *ta = aux;
  276 
  277         if (strncmp("PMAG-RO ", ta->ta_modname, TC_ROM_LLEN) != 0
  278             && strncmp("PMAG-JA ", ta->ta_modname, TC_ROM_LLEN) != 0)
  279                 return (0);
  280 
  281         return (1);
  282 }
  283 
  284 
  285 static void
  286 tfbattach(parent, self, aux)
  287         struct device *parent, *self;
  288         void *aux;
  289 {
  290         struct tfb_softc *sc = (struct tfb_softc *)self;
  291         struct tc_attach_args *ta = aux;
  292         struct rasops_info *ri;
  293         struct wsemuldisplaydev_attach_args waa;
  294         int console;
  295 
  296         console = (ta->ta_addr == tfb_consaddr);
  297         if (console) {
  298                 sc->sc_ri = ri = &tfb_console_ri;
  299                 sc->nscreens = 1;
  300         }
  301         else {
  302                 MALLOC(ri, struct rasops_info *, sizeof(struct rasops_info),
  303                         M_DEVBUF, M_NOWAIT);
  304                 if (ri == NULL) {
  305                         printf(": can't alloc memory\n");
  306                         return;
  307                 }
  308                 memset(ri, 0, sizeof(struct rasops_info));
  309 
  310                 ri->ri_hw = (void *)ta->ta_addr;
  311                 tfb_common_init(ri);
  312                 sc->sc_ri = ri;
  313         }
  314         printf(": %dx%d, 8,24bpp\n", ri->ri_width, ri->ri_height);
  315 
  316         tfb_cmap_init(sc);
  317 
  318         sc->sc_vaddr = ta->ta_addr;
  319         sc->sc_cursor.cc_magic.x = TX_MAGIC_X;
  320         sc->sc_cursor.cc_magic.y = TX_MAGIC_Y;
  321         sc->sc_blanked = sc->sc_curenb = 0;
  322 
  323         tc_intr_establish(parent, ta->ta_cookie, IPL_TTY, tfbintr, sc);
  324 
  325         *(u_int8_t *)((caddr_t)ri->ri_hw + TX_CONTROL) &= ~0x40;
  326         *(u_int8_t *)((caddr_t)ri->ri_hw + TX_CONTROL) |= 0x40;
  327 
  328         waa.console = console;
  329         waa.scrdata = &tfb_screenlist;
  330         waa.accessops = &tfb_accessops;
  331         waa.accesscookie = sc;
  332 
  333         config_found(self, &waa, wsemuldisplaydevprint);
  334 }
  335 
  336 static void
  337 tfb_common_init(ri)
  338         struct rasops_info *ri;
  339 {
  340         caddr_t base;
  341         int cookie;
  342 
  343         base = (caddr_t)ri->ri_hw;
  344 
  345         /* initialize colormap and cursor hardware */
  346         tfbhwinit(base);
  347 
  348         ri->ri_flg = RI_CENTER;
  349         ri->ri_depth = 8;
  350         ri->ri_width = 1280;
  351         ri->ri_height = 1024;
  352         ri->ri_stride = 1280;
  353         ri->ri_bits = base + TX_8BPP_OFFSET;
  354 
  355         /* clear the screen */
  356         memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
  357 
  358         wsfont_init();
  359         /* prefer 12 pixel wide font */
  360         cookie = wsfont_find(NULL, 12, 0, 0, WSDISPLAY_FONTORDER_L2R,
  361             WSDISPLAY_FONTORDER_L2R);
  362         if (cookie <= 0)
  363                 cookie = wsfont_find(NULL, 0, 0, 0, WSDISPLAY_FONTORDER_L2R,
  364                     WSDISPLAY_FONTORDER_L2R);
  365         if (cookie <= 0) {
  366                 printf("tfb: font table is empty\n");
  367                 return;
  368         }
  369 
  370         if (wsfont_lock(cookie, &ri->ri_font)) {
  371                 printf("tfb: couldn't lock font\n");
  372                 return;
  373         }
  374         ri->ri_wsfcookie = cookie;
  375 
  376         rasops_init(ri, 34, 80);
  377 
  378         /* XXX shouldn't be global */
  379         tfb_stdscreen.nrows = ri->ri_rows;
  380         tfb_stdscreen.ncols = ri->ri_cols;
  381         tfb_stdscreen.textops = &ri->ri_ops;
  382         tfb_stdscreen.capabilities = ri->ri_caps;
  383 }
  384 
  385 static void
  386 tfb_cmap_init(sc)
  387         struct tfb_softc *sc;
  388 {
  389         struct hwcmap256 *cm;
  390         const u_int8_t *p;
  391         int index;
  392 
  393         cm = &sc->sc_cmap;
  394         p = rasops_cmap;
  395         for (index = 0; index < CMAP_SIZE; index++, p += 3) {
  396                 cm->r[index] = p[0];
  397                 cm->g[index] = p[1];
  398                 cm->b[index] = p[2];
  399         }
  400 }
  401 
  402 static int
  403 tfbioctl(v, cmd, data, flag, p)
  404         void *v;
  405         u_long cmd;
  406         caddr_t data;
  407         int flag;
  408         struct proc *p;
  409 {
  410         struct tfb_softc *sc = v;
  411         struct rasops_info *ri = sc->sc_ri;
  412         int turnoff, s;
  413 
  414         switch (cmd) {
  415         case WSDISPLAYIO_GTYPE:
  416                 *(u_int *)data = WSDISPLAY_TYPE_TX;
  417                 return (0);
  418 
  419         case WSDISPLAYIO_GINFO:
  420 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
  421                 wsd_fbip->height = ri->ri_height;
  422                 wsd_fbip->width = ri->ri_width;
  423                 wsd_fbip->depth = ri->ri_depth;
  424                 wsd_fbip->cmsize = CMAP_SIZE;
  425 #undef fbt
  426                 return (0);
  427 
  428         case WSDISPLAYIO_GETCMAP:
  429                 return get_cmap(sc, (struct wsdisplay_cmap *)data);
  430 
  431         case WSDISPLAYIO_PUTCMAP:
  432                 return set_cmap(sc, (struct wsdisplay_cmap *)data);
  433 
  434         case WSDISPLAYIO_SVIDEO:
  435                 turnoff = *(int *)data == WSDISPLAYIO_VIDEO_OFF;
  436                 if ((sc->sc_blanked == 0) ^ turnoff) {
  437                         sc->sc_blanked = turnoff;
  438 #if 0   /* XXX later XXX */             
  439         To turn off;
  440         - clear the MSB of TX control register; &= ~0x80,
  441         - assign Bt431 register #0 with value 0x4 to hide sprite cursor.
  442 #endif  /* XXX XXX XXX */
  443                 }
  444                 return (0);
  445 
  446         case WSDISPLAYIO_GVIDEO:
  447                 *(u_int *)data = sc->sc_blanked ?
  448                     WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
  449                 return (0);
  450 
  451         case WSDISPLAYIO_GCURPOS:
  452                 *(struct wsdisplay_curpos *)data = sc->sc_cursor.cc_pos;
  453                 return (0);
  454 
  455         case WSDISPLAYIO_SCURPOS:
  456                 s = spltty();
  457                 set_curpos(sc, (struct wsdisplay_curpos *)data);
  458                 sc->sc_changed |= WSDISPLAY_CURSOR_DOPOS;
  459                 splx(s);
  460                 return (0);
  461 
  462         case WSDISPLAYIO_GCURMAX:
  463                 ((struct wsdisplay_curpos *)data)->x =
  464                 ((struct wsdisplay_curpos *)data)->y = CURSOR_MAX_SIZE;
  465                 return (0);
  466 
  467         case WSDISPLAYIO_GCURSOR:
  468                 return get_cursor(sc, (struct wsdisplay_cursor *)data);
  469 
  470         case WSDISPLAYIO_SCURSOR:
  471                 return set_cursor(sc, (struct wsdisplay_cursor *)data);
  472 
  473         case WSDISPLAYIO_SMODE:
  474                 if (*(int *)data == WSDISPLAYIO_MODE_EMUL) {
  475                         s = spltty();
  476                         tfb_cmap_init(sc);
  477                         sc->sc_curenb = 0;
  478                         sc->sc_blanked = 0;
  479                         sc->sc_changed |= (WSDISPLAY_CURSOR_DOCUR |
  480                             WSDISPLAY_CMAP_DOLUT);
  481                         splx(s);
  482                 }
  483                 return (0);
  484         }
  485         return (EPASSTHROUGH);
  486 }
  487 
  488 static paddr_t
  489 tfbmmap(v, offset, prot)
  490         void *v;
  491         off_t offset;
  492         int prot;
  493 {
  494         struct tfb_softc *sc = v;
  495 
  496         if (offset >= TX_8BPP_SIZE || offset < 0) /* XXX 24bpp XXX */
  497                 return (-1);
  498         return machine_btop(sc->sc_vaddr + TX_8BPP_OFFSET + offset);
  499 }
  500 
  501 static int
  502 tfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
  503         void *v;
  504         const struct wsscreen_descr *type;
  505         void **cookiep;
  506         int *curxp, *curyp;
  507         long *attrp;
  508 {
  509         struct tfb_softc *sc = v;
  510         struct rasops_info *ri = sc->sc_ri;
  511         long defattr;
  512 
  513         if (sc->nscreens > 0)
  514                 return (ENOMEM);
  515 
  516         *cookiep = ri; /* one and only for now */
  517         *curxp = 0;
  518         *curyp = 0;
  519         (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
  520         *attrp = defattr;
  521         sc->nscreens++;
  522         return (0);
  523 }
  524 
  525 static void
  526 tfb_free_screen(v, cookie)
  527         void *v;
  528         void *cookie;
  529 {
  530         struct tfb_softc *sc = v;
  531 
  532         if (sc->sc_ri == &tfb_console_ri)
  533                 panic("tfb_free_screen: console");
  534 
  535         sc->nscreens--;
  536 }
  537 
  538 static int
  539 tfb_show_screen(v, cookie, waitok, cb, cbarg)
  540         void *v;
  541         void *cookie;
  542         int waitok;
  543         void (*cb)(void *, int, int);
  544         void *cbarg;
  545 {
  546 
  547         return (0);
  548 }
  549 
  550 /* EXPORT */ int
  551 tfb_cnattach(addr)
  552         tc_addr_t addr;
  553 {
  554         struct rasops_info *ri;
  555         long defattr;
  556 
  557         ri = &tfb_console_ri;
  558         ri->ri_hw = (void *)addr;
  559         tfb_common_init(ri);
  560         (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
  561         wsdisplay_cnattach(&tfb_stdscreen, ri, 0, 0, defattr);
  562         tfb_consaddr = addr;
  563         return (0);
  564 }
  565 
  566 static int
  567 tfbintr(arg)
  568         void *arg;
  569 {
  570         struct tfb_softc *sc = arg;
  571         caddr_t base, vdac, curs;
  572         int v;
  573         
  574         base = (caddr_t)sc->sc_ri->ri_hw;
  575         *(u_int8_t *)(base + TX_CONTROL) &= ~0x40;
  576         if (sc->sc_changed == 0)
  577                 goto done;
  578 
  579         vdac = base + TX_BT463_OFFSET;
  580         curs = base + TX_BT431_OFFSET;
  581         v = sc->sc_changed;
  582         if (v & WSDISPLAY_CURSOR_DOCUR) {
  583                 int onoff;
  584 
  585                 onoff = (sc->sc_curenb) ? 0x4444 : 0x0404;
  586                 SELECT431(curs, BT431_REG_COMMAND);
  587                 REGWRITE32(curs, bt_ctl, onoff);
  588         }
  589         if (v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
  590                 int x, y;
  591                 u_int32_t twin;
  592 
  593                 x = sc->sc_cursor.cc_pos.x - sc->sc_cursor.cc_hot.x;
  594                 y = sc->sc_cursor.cc_pos.y - sc->sc_cursor.cc_hot.y;
  595 
  596                 x += sc->sc_cursor.cc_magic.x;
  597                 y += sc->sc_cursor.cc_magic.y;
  598 
  599                 SELECT431(curs, BT431_REG_CURSOR_X_LOW);
  600                 REGWRITE32(curs, bt_ctl, TWIN_LO(x));
  601                 REGWRITE32(curs, bt_ctl, TWIN_HI(x));
  602                 REGWRITE32(curs, bt_ctl, TWIN_LO(y));
  603                 REGWRITE32(curs, bt_ctl, TWIN_HI(y));
  604         }
  605         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  606                 u_int8_t *cp = sc->sc_cursor.cc_color;
  607 
  608                 SELECT463(vdac, BT463_IREG_CURSOR_COLOR_0);
  609                 REGWRITE32(vdac, bt_reg, cp[1]);
  610                 REGWRITE32(vdac, bt_reg, cp[3]);
  611                 REGWRITE32(vdac, bt_reg, cp[5]);
  612 
  613                 REGWRITE32(vdac, bt_reg, cp[0]);
  614                 REGWRITE32(vdac, bt_reg, cp[2]);
  615                 REGWRITE32(vdac, bt_reg, cp[4]);
  616 
  617                 REGWRITE32(vdac, bt_reg, cp[1]);
  618                 REGWRITE32(vdac, bt_reg, cp[3]);
  619                 REGWRITE32(vdac, bt_reg, cp[5]);
  620 
  621                 REGWRITE32(vdac, bt_reg, cp[1]);
  622                 REGWRITE32(vdac, bt_reg, cp[3]);
  623                 REGWRITE32(vdac, bt_reg, cp[5]);
  624         }
  625         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  626                 u_int8_t *ip, *mp, img, msk;
  627                 int bcnt;
  628 
  629                 ip = (u_int8_t *)sc->sc_cursor.cc_image;
  630                 mp = (u_int8_t *)sc->sc_cursor.cc_mask;
  631                 bcnt = 0;
  632                 SELECT431(curs, BT431_REG_CRAM_BASE);
  633 
  634                 /* 64 pixel scan line is consisted with 16 byte cursor ram */
  635                 while (bcnt < sc->sc_cursor.cc_size.y * 16) {
  636                         /* pad right half 32 pixel when smaller than 33 */
  637                         if ((bcnt & 0x8) && sc->sc_cursor.cc_size.x < 33) {
  638                                 REGWRITE32(curs, bt_ram, 0);
  639                         }
  640                         else {
  641                                 int half;
  642                                 img = *ip++;
  643                                 msk = *mp++;
  644                                 img &= msk;     /* cookie off image */
  645                                 half = (flip[img] << 8) | flip[msk]; 
  646                                 REGWRITE32(curs, bt_ram, half);
  647                         }
  648                         bcnt += 2;
  649                 }
  650                 /* pad unoccupied scan lines */
  651                 while (bcnt < CURSOR_MAX_SIZE * 16) {
  652                         REGWRITE32(curs, bt_ram, 0);
  653                         bcnt += 2;
  654                 }
  655         }
  656         if (v & WSDISPLAY_CMAP_DOLUT) {
  657                 struct hwcmap256 *cm = &sc->sc_cmap;
  658                 int index;
  659 
  660                 SELECT463(vdac, BT463_IREG_CPALETTE_RAM);
  661                 for (index = 0; index < CMAP_SIZE; index++) {
  662                         REGWRITE32(vdac, bt_cmap, cm->r[index]);
  663                         REGWRITE32(vdac, bt_cmap, cm->g[index]);
  664                         REGWRITE32(vdac, bt_cmap, cm->b[index]);
  665                 }
  666         }
  667         sc->sc_changed = 0;
  668 done:
  669         *(u_int8_t *)(base + TX_CONTROL) &= ~0x40;      /* !? Eeeh !? */
  670         *(u_int8_t *)(base + TX_CONTROL) |= 0x40;
  671         return (1);
  672 }
  673 
  674 static void
  675 tfbhwinit(tfbbase)
  676         caddr_t tfbbase;
  677 {
  678         caddr_t vdac, curs;
  679         const u_int8_t *p;
  680         int i;
  681 
  682         vdac = tfbbase + TX_BT463_OFFSET;
  683         curs = tfbbase + TX_BT431_OFFSET;
  684         SELECT463(vdac, BT463_IREG_COMMAND_0);
  685         REGWRITE32(vdac, bt_reg, 0x40); /* CMD 0 */
  686         REGWRITE32(vdac, bt_reg, 0x46); /* CMD 1 */
  687         REGWRITE32(vdac, bt_reg, 0xc0); /* CMD 2 */
  688         REGWRITE32(vdac, bt_reg, 0);    /* !? 204 !? */
  689         REGWRITE32(vdac, bt_reg, 0xff); /* plane  0:7  */
  690         REGWRITE32(vdac, bt_reg, 0xff); /* plane  8:15 */
  691         REGWRITE32(vdac, bt_reg, 0xff); /* plane 16:23 */
  692         REGWRITE32(vdac, bt_reg, 0xff); /* plane 24:27 */
  693         REGWRITE32(vdac, bt_reg, 0x00); /* blink  0:7  */
  694         REGWRITE32(vdac, bt_reg, 0x00); /* blink  8:15 */
  695         REGWRITE32(vdac, bt_reg, 0x00); /* blink 16:23 */
  696         REGWRITE32(vdac, bt_reg, 0x00); /* blink 24:27 */
  697         REGWRITE32(vdac, bt_reg, 0x00);
  698 
  699 #if 0 /* XXX ULTRIX does initialize 16 entry window type here XXX */
  700   {
  701         static u_int32_t windowtype[BT463_IREG_WINDOW_TYPE_TABLE] = {
  702                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  703         };
  704 
  705         SELECT463(vdac, BT463_IREG_WINDOW_TYPE_TABLE);
  706         for (i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
  707                 BYTE(vdac, bt_reg) = windowtype[i];       /*   0:7  */
  708                 BYTE(vdac, bt_reg) = windowtype[i] >> 8;  /*   8:15 */
  709                 BYTE(vdac, bt_reg) = windowtype[i] >> 16; /*  16:23 */
  710         }
  711   }
  712 #endif
  713 
  714         SELECT463(vdac, BT463_IREG_CPALETTE_RAM);
  715         p = rasops_cmap;
  716         for (i = 0; i < 256; i++, p += 3) {
  717                 REGWRITE32(vdac, bt_cmap, p[0]);
  718                 REGWRITE32(vdac, bt_cmap, p[1]);
  719                 REGWRITE32(vdac, bt_cmap, p[2]);
  720         }
  721 
  722         /* !? Eeeh !? */
  723         SELECT463(vdac, 0x0100 /* BT463_IREG_CURSOR_COLOR_0 */);
  724         for (i = 0; i < 256; i++) {
  725                 REGWRITE32(vdac, bt_cmap, i);
  726                 REGWRITE32(vdac, bt_cmap, i);
  727                 REGWRITE32(vdac, bt_cmap, i);
  728         }
  729 
  730         SELECT431(curs, BT431_REG_COMMAND);
  731         REGWRITE32(curs, bt_ctl, 0x0404);       
  732         REGWRITE32(curs, bt_ctl, 0); /* XLO */
  733         REGWRITE32(curs, bt_ctl, 0); /* XHI */
  734         REGWRITE32(curs, bt_ctl, 0); /* YLO */
  735         REGWRITE32(curs, bt_ctl, 0); /* YHI */
  736         REGWRITE32(curs, bt_ctl, 0); /* XWLO */
  737         REGWRITE32(curs, bt_ctl, 0); /* XWHI */
  738         REGWRITE32(curs, bt_ctl, 0); /* WYLO */
  739         REGWRITE32(curs, bt_ctl, 0); /* WYLO */
  740         REGWRITE32(curs, bt_ctl, 0); /* WWLO */
  741         REGWRITE32(curs, bt_ctl, 0); /* WWHI */
  742         REGWRITE32(curs, bt_ctl, 0); /* WHLO */
  743         REGWRITE32(curs, bt_ctl, 0); /* WHHI */
  744 
  745         SELECT431(curs, BT431_REG_CRAM_BASE);
  746         for (i = 0; i < 512; i++) {
  747                 REGWRITE32(curs, bt_ram, 0);
  748         }
  749 }
  750 
  751 static int
  752 get_cmap(sc, p)
  753         struct tfb_softc *sc;
  754         struct wsdisplay_cmap *p;
  755 {
  756         u_int index = p->index, count = p->count;
  757         int error;
  758 
  759         if (index >= CMAP_SIZE || count > CMAP_SIZE - index)
  760                 return (EINVAL);
  761 
  762         error = copyout(&sc->sc_cmap.r[index], p->red, count);
  763         if (error)
  764                 return error;
  765         error = copyout(&sc->sc_cmap.g[index], p->green, count);
  766         if (error)
  767                 return error;
  768         error = copyout(&sc->sc_cmap.b[index], p->blue, count);
  769         return error;
  770 }
  771 
  772 static int
  773 set_cmap(sc, p)
  774         struct tfb_softc *sc;
  775         struct wsdisplay_cmap *p;
  776 {
  777         struct hwcmap256 cmap;
  778         u_int index = p->index, count = p->count;
  779         int error, s;
  780 
  781         if (index >= CMAP_SIZE || count > CMAP_SIZE - index)
  782                 return (EINVAL);
  783 
  784         error = copyin(p->red, &cmap.r[index], count);
  785         if (error)
  786                 return error;
  787         error = copyin(p->green, &cmap.g[index], count);
  788         if (error)
  789                 return error;
  790         error = copyin(p->blue, &cmap.b[index], count);
  791         if (error)
  792                 return error;
  793         s = spltty();
  794         memcpy(&sc->sc_cmap.r[index], &cmap.r[index], count);
  795         memcpy(&sc->sc_cmap.g[index], &cmap.g[index], count);
  796         memcpy(&sc->sc_cmap.b[index], &cmap.b[index], count);
  797         sc->sc_changed |= WSDISPLAY_CMAP_DOLUT;
  798         splx(s);
  799         return (0);
  800 }
  801 
  802 static int
  803 set_cursor(sc, p)
  804         struct tfb_softc *sc;
  805         struct wsdisplay_cursor *p;
  806 {
  807 #define cc (&sc->sc_cursor)
  808         u_int v, index = 0, count = 0, icount = 0;
  809         uint8_t r[2], g[2], b[2], image[512], mask[512];
  810         int error, s;
  811 
  812         v = p->which;
  813         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  814                 index = p->cmap.index;
  815                 count = p->cmap.count;
  816                 if (index >= 2 || (index + count) > 2)
  817                         return (EINVAL);
  818                 error = copyin(p->cmap.red, &r[index], count);
  819                 if (error)
  820                         return error;
  821                 error = copyin(p->cmap.green, &g[index], count);
  822                 if (error)
  823                         return error;
  824                 error = copyin(p->cmap.blue, &b[index], count);
  825                 if (error)
  826                         return error;
  827         }
  828         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  829                 if (p->size.x > CURSOR_MAX_SIZE || p->size.y > CURSOR_MAX_SIZE)
  830                         return (EINVAL);
  831                 icount = ((p->size.x < 33) ? 4 : 8) * p->size.y;
  832                 error = copyin(p->image, image, icount);
  833                 if (error)
  834                         return error;
  835                 error = copyin(p->mask, mask, icount);
  836                 if (error)
  837                         return error;
  838         }
  839 
  840         s = spltty();
  841         if (v & WSDISPLAY_CURSOR_DOCUR)
  842                 sc->sc_curenb = p->enable;
  843         if (v & WSDISPLAY_CURSOR_DOPOS)
  844                 set_curpos(sc, &p->pos);
  845         if (v & WSDISPLAY_CURSOR_DOHOT)
  846                 cc->cc_hot = p->hot;
  847         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  848                 memcpy(&cc->cc_color[index], &r[index], count);
  849                 memcpy(&cc->cc_color[index + 2], &g[index], count);
  850                 memcpy(&cc->cc_color[index + 4], &b[index], count);
  851         }
  852         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  853                 cc->cc_size = p->size;
  854                 memset(cc->cc_image, 0, sizeof cc->cc_image);
  855                 memcpy(cc->cc_image, image, icount);
  856                 memset(cc->cc_mask, 0, sizeof cc->cc_mask);
  857                 memcpy(cc->cc_mask, mask, icount);
  858         }
  859         sc->sc_changed |= v;
  860         splx(s);
  861 
  862         return (0);
  863 #undef cc
  864 }
  865 
  866 static int
  867 get_cursor(sc, p)
  868         struct tfb_softc *sc;
  869         struct wsdisplay_cursor *p;
  870 {
  871         return (EPASSTHROUGH); /* XXX */
  872 }
  873 
  874 static void
  875 set_curpos(sc, curpos)
  876         struct tfb_softc *sc;
  877         struct wsdisplay_curpos *curpos;
  878 {
  879         struct rasops_info *ri = sc->sc_ri;
  880         int x = curpos->x, y = curpos->y;
  881 
  882         if (y < 0)
  883                 y = 0;
  884         else if (y > ri->ri_height)
  885                 y = ri->ri_height;
  886         if (x < 0)
  887                 x = 0;
  888         else if (x > ri->ri_width)
  889                 x = ri->ri_width;
  890         sc->sc_cursor.cc_pos.x = x;
  891         sc->sc_cursor.cc_pos.y = y;
  892 }

Cache object: 6a5bffea5710a6c8ab8cf5ad16f809f3


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