root/dev/sbus/zx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zx_match
  2. zx_attach
  3. zx_ioctl
  4. zx_alloc_screen
  5. zx_free_screen
  6. zx_show_screen
  7. zx_mmap
  8. zx_setcolor
  9. zx_reset
  10. zx_cross_wait
  11. zx_cross_loadwid
  12. zx_putcmap
  13. zx_burner
  14. zx_fillrect
  15. zx_copyrect
  16. zx_do_cursor
  17. zx_erasecols
  18. zx_eraserows
  19. zx_copyrows
  20. zx_copycols
  21. zx_putchar

    1 /*      $OpenBSD: zx.c,v 1.13 2007/03/13 19:40:49 miod Exp $    */
    2 /*      $NetBSD: zx.c,v 1.5 2002/10/02 16:52:46 thorpej Exp $   */
    3 
    4 /*
    5  * Copyright (c) 2003, Miodrag Vallat.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   20  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   21  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   27  * POSSIBILITY OF SUCH DAMAGE.
   28  *
   29  * Derived from NetBSD syssrc/sys/dev/sbus/zx.c under the following licence
   30  * terms:
   31  *
   32  *  Copyright (c) 2002 The NetBSD Foundation, Inc.
   33  *  All rights reserved.
   34  *
   35  *  This code is derived from software contributed to The NetBSD Foundation
   36  *  by Andrew Doran.
   37  *
   38  *  Redistribution and use in source and binary forms, with or without
   39  *  modification, are permitted provided that the following conditions
   40  *  are met:
   41  *  1. Redistributions of source code must retain the above copyright
   42  *     notice, this list of conditions and the following disclaimer.
   43  *  2. Redistributions in binary form must reproduce the above copyright
   44  *     notice, this list of conditions and the following disclaimer in the
   45  *     documentation and/or other materials provided with the distribution.
   46  *  3. All advertising materials mentioning features or use of this software
   47  *     must display the following acknowledgement:
   48  *         This product includes software developed by the NetBSD
   49  *         Foundation, Inc. and its contributors.
   50  *  4. Neither the name of The NetBSD Foundation nor the names of its
   51  *     contributors may be used to endorse or promote products derived
   52  *     from this software without specific prior written permission.
   53  *
   54  *  THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   55  *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   56  *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   57  *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   58  *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   59  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   60  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   61  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   62  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   63  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   64  *  POSSIBILITY OF SUCH DAMAGE.
   65  */
   66 
   67 /*
   68  * Driver for the Sun ZX display adapter.  This would be called 'leo', but
   69  * NetBSD/amiga already has a driver by that name.  The XFree86 and Linux
   70  * drivers were used as "living documentation" when writing this; thanks
   71  * to the authors.
   72  */
   73 
   74 #include <sys/param.h>
   75 #include <sys/systm.h>
   76 #include <sys/device.h>
   77 #include <sys/ioctl.h>
   78 #include <sys/malloc.h>
   79 #include <sys/mman.h>
   80 #include <sys/tty.h>
   81 #include <sys/conf.h>
   82 
   83 #include <uvm/uvm_extern.h>
   84 
   85 #include <machine/autoconf.h>
   86 #include <machine/bus.h>
   87 #include <machine/cpu.h>
   88 #include <machine/conf.h>
   89 
   90 #include <dev/wscons/wsconsio.h>
   91 #include <dev/wscons/wsdisplayvar.h>
   92 #include <dev/rasops/rasops.h>
   93 #include <machine/fbvar.h>
   94 
   95 #include <dev/sbus/zxreg.h>
   96 #include <dev/sbus/sbusvar.h>
   97 
   98 #define ZX_WID_SHARED_8         0
   99 #define ZX_WID_SHARED_24        1
  100 #define ZX_WID_DBL_8            2
  101 #define ZX_WID_DBL_24           3
  102 
  103 /*
  104  * Per-instance data.
  105  */
  106 
  107 struct zx_cmap {
  108         u_int8_t        cm_red[256];
  109         u_int8_t        cm_green[256];
  110         u_int8_t        cm_blue[256];
  111 };
  112 
  113 struct zx_softc {
  114         struct  sunfb   sc_sunfb;
  115 
  116         bus_space_tag_t sc_bustag;
  117         bus_addr_t      sc_paddr;
  118 
  119         struct  zx_cmap sc_cmap;        /* shadow color map for overlay plane */
  120 
  121         volatile struct zx_command *sc_zc;
  122         volatile struct zx_cross *sc_zx;
  123         volatile struct zx_draw *sc_zd_ss0;
  124         volatile struct zx_draw_ss1 *sc_zd_ss1;
  125         volatile struct zx_cursor *sc_zcu;
  126 
  127         int     sc_nscreens;
  128 };
  129 
  130 int zx_ioctl(void *, u_long, caddr_t, int, struct proc *);
  131 int zx_alloc_screen(void *, const struct wsscreen_descr *, void **,
  132     int *, int *, long *);
  133 void zx_free_screen(void *, void *);
  134 int zx_show_screen(void *, void *, int, void (*)(void *, int, int), void *);
  135 paddr_t zx_mmap(void *, off_t, int);
  136 void zx_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
  137 void zx_reset(struct zx_softc *, u_int);
  138 void zx_burner(void *, u_int, u_int);
  139 
  140 struct wsdisplay_accessops zx_accessops = {
  141         zx_ioctl,
  142         zx_mmap,
  143         zx_alloc_screen,
  144         zx_free_screen,
  145         zx_show_screen,
  146         NULL,   /* load_font */
  147         NULL,   /* scrollback */
  148         NULL,   /* getchar */
  149         zx_burner
  150 };
  151 
  152 /* Force 32-bit writes. */
  153 #define SETREG(r, v)    (*((volatile u_int32_t *)&r) = (v))
  154 
  155 #define ZX_STD_ROP      (ZX_ROP_NEW | ZX_ATTR_WE_ENABLE | \
  156     ZX_ATTR_OE_ENABLE | ZX_ATTR_FORCE_WID)
  157 
  158 #define ZX_BWIDTH       13
  159 #define ZX_WWIDTH       11      /* word width */
  160 
  161 #define ZX_COORDS(x, y) ((x) | ((y) << ZX_WWIDTH))
  162 
  163 void    zx_attach(struct device *, struct device *, void *);
  164 int     zx_match(struct device *, void *, void *);
  165 
  166 int     zx_putcmap(struct zx_softc *);
  167 void    zx_copyrect(struct rasops_info *, int, int, int, int, int, int);
  168 int     zx_cross_loadwid(struct zx_softc *, u_int, u_int, u_int);
  169 int     zx_cross_wait(struct zx_softc *);
  170 void    zx_fillrect(struct rasops_info *, int, int, int, int, long, int);
  171 int     zx_intr(void *);
  172 void    zx_prom(void *);
  173 
  174 void    zx_putchar(void *, int, int, u_int, long);
  175 void    zx_copycols(void *, int, int, int, int);
  176 void    zx_erasecols(void *, int, int, int, long);
  177 void    zx_copyrows(void *, int, int, int);
  178 void    zx_eraserows(void *, int, int, long);
  179 void    zx_do_cursor(struct rasops_info *);
  180 
  181 struct cfattach zx_ca = {
  182         sizeof(struct zx_softc), zx_match, zx_attach
  183 };
  184 
  185 struct cfdriver zx_cd = {
  186         NULL, "zx", DV_DULL
  187 };
  188 
  189 int
  190 zx_match(struct device *parent, void *vcf, void *aux)
  191 {
  192         struct sbus_attach_args *sa = aux;
  193         
  194         if (strcmp(sa->sa_name, "SUNW,leo") == 0)
  195                 return (1);
  196 
  197         return (0);
  198 }
  199 
  200 void
  201 zx_attach(struct device *parent, struct device *self, void *args)
  202 {
  203         struct zx_softc *sc = (struct zx_softc *)self;
  204         struct sbus_attach_args *sa = args;
  205         struct rasops_info *ri;
  206         bus_space_tag_t bt;
  207         bus_space_handle_t bh;
  208         int node, isconsole = 0;
  209         const char *nam;
  210 
  211         bt = sa->sa_bustag;
  212         ri = &sc->sc_sunfb.sf_ro;
  213         node = sa->sa_node;
  214 
  215         /*
  216          * Map the various parts of the card.
  217          */
  218         sc->sc_bustag = bt;
  219         sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset);
  220 
  221         if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR,
  222             sizeof(struct zx_command), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
  223                 printf(": couldn't map command registers\n");
  224                 return;
  225         }
  226         sc->sc_zc = (struct zx_command *)bus_space_vaddr(bt, bh);
  227 
  228         if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0,
  229             sizeof(struct zx_draw), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
  230                 printf(": couldn't map ss0 drawing registers\n");
  231                 return;
  232         }
  233         sc->sc_zd_ss0 = (struct zx_draw *)bus_space_vaddr(bt, bh);
  234 
  235         if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1,
  236             sizeof(struct zx_draw_ss1), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
  237                 printf(": couldn't map ss1 drawing registers\n");
  238                 return;
  239         }
  240         sc->sc_zd_ss1 = (struct zx_draw_ss1 *)bus_space_vaddr(bt, bh);
  241 
  242         if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS,
  243             sizeof(struct zx_cross), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
  244                 printf(": couldn't map cross registers\n");
  245                 return;
  246         }
  247         sc->sc_zx = (struct zx_cross *)bus_space_vaddr(bt, bh);
  248 
  249         if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR,
  250             sizeof(struct zx_cursor), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
  251                 printf(": couldn't map cursor registers\n");
  252                 return;
  253         }
  254         sc->sc_zcu = (struct zx_cursor *)bus_space_vaddr(bt, bh);
  255 
  256         nam = getpropstring(node, "model");
  257         if (*nam == '\0')
  258                 nam = sa->sa_name;
  259         printf(": %s", nam);
  260 
  261         isconsole = node == fbnode;
  262 
  263         /*
  264          * The console is using the 8-bit overlay plane, while the prom
  265          * will correctly report 32 bit depth.
  266          * The following is an equivalent for
  267          *    fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
  268          * forcing the depth value not to be overwritten.
  269          * Furthermore, the linebytes value is in fact 8192 bytes.
  270          */
  271         sc->sc_sunfb.sf_depth = 8;
  272         sc->sc_sunfb.sf_width = getpropint(node, "width", 1152);
  273         sc->sc_sunfb.sf_height = getpropint(node, "height", 900);
  274         sc->sc_sunfb.sf_linebytes = 1 << ZX_BWIDTH;
  275         sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height << ZX_BWIDTH;
  276 
  277         printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
  278 
  279         if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0,
  280             round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR,
  281             0, &bh) != 0) {
  282                 printf("%s: couldn't map video memory\n", self->dv_xname);
  283                 return;
  284         }
  285         ri->ri_bits = bus_space_vaddr(bt, bh);
  286         ri->ri_hw = sc;
  287 
  288         fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
  289 
  290         /*
  291          * Watch out! rasops_init() invoked via fbwscons_init() did not
  292          * compute ri_bits correctly when centering the display, because
  293          * it has been tricked with the low depth value.
  294          * Recompute now.
  295          */
  296         ri->ri_emustride = ri->ri_emuwidth * 4;
  297         ri->ri_delta = ri->ri_stride - ri->ri_emustride;
  298         ri->ri_pelbytes = 4;
  299         ri->ri_xscale = ri->ri_font->fontwidth * 4;
  300         ri->ri_bits = ri->ri_origbits;
  301         ri->ri_bits += (((ri->ri_width * 4) - ri->ri_emustride) >> 1) & ~3;
  302         ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
  303             ri->ri_stride;
  304         ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
  305             / ri->ri_stride;
  306         ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
  307             % ri->ri_stride) / 4);
  308 
  309         ri->ri_ops.copyrows = zx_copyrows;
  310         ri->ri_ops.copycols = zx_copycols;
  311         ri->ri_ops.eraserows = zx_eraserows;
  312         ri->ri_ops.erasecols = zx_erasecols;
  313         ri->ri_ops.putchar = zx_putchar;
  314         ri->ri_do_cursor = zx_do_cursor;
  315 
  316         if (isconsole) {
  317                 /* zx_reset() below will clear screen, so restart at 1st row */
  318                 fbwscons_console_init(&sc->sc_sunfb, 0);
  319         }
  320 
  321         /* reset cursor & frame buffer controls */
  322         zx_reset(sc, WSDISPLAYIO_MODE_EMUL);
  323 
  324         /* enable video */
  325         zx_burner(sc, 1, 0);
  326 
  327         fbwscons_attach(&sc->sc_sunfb, &zx_accessops, isconsole);
  328 }
  329 
  330 int
  331 zx_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
  332 {
  333         struct zx_softc *sc = dev;
  334         struct wsdisplay_fbinfo *wdf;
  335 
  336         /*
  337          * Note that, although the emulation (text) mode is running in
  338          * a 8-bit plane, we advertize the frame buffer as the full-blown
  339          * 32-bit beast it is.
  340          */
  341         switch (cmd) {
  342         case WSDISPLAYIO_GTYPE:
  343                 *(u_int *)data = WSDISPLAY_TYPE_SUN24;
  344                 break;
  345         case WSDISPLAYIO_GINFO:
  346                 wdf = (struct wsdisplay_fbinfo *)data;
  347                 wdf->height = sc->sc_sunfb.sf_height;
  348                 wdf->width = sc->sc_sunfb.sf_width;
  349                 wdf->depth = 32;
  350                 wdf->cmsize = 0;
  351                 break;
  352         case WSDISPLAYIO_GETSUPPORTEDDEPTH:
  353                 *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
  354                 break;
  355         case WSDISPLAYIO_LINEBYTES:
  356                 *(u_int *)data = sc->sc_sunfb.sf_linebytes;
  357                 break;
  358 
  359         case WSDISPLAYIO_GETCMAP:
  360         case WSDISPLAYIO_PUTCMAP:
  361                 break;
  362 
  363         case WSDISPLAYIO_SMODE:
  364                 zx_reset(sc, *(u_int *)data);
  365                 break;
  366 
  367         case WSDISPLAYIO_SVIDEO:
  368         case WSDISPLAYIO_GVIDEO:
  369                 break;
  370 
  371         default:
  372                 return (-1);
  373         }
  374 
  375         return (0);
  376 }
  377 
  378 int
  379 zx_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
  380     int *curxp, int *curyp, long *attrp)
  381 {
  382         struct zx_softc *sc = v;
  383 
  384         if (sc->sc_nscreens > 0)
  385                 return (ENOMEM);
  386 
  387         *cookiep = &sc->sc_sunfb.sf_ro;
  388         *curyp = 0;
  389         *curxp = 0;
  390         sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
  391             WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
  392         sc->sc_nscreens++;
  393         return (0);
  394 }
  395 
  396 void
  397 zx_free_screen(void *v, void *cookie)
  398 {
  399         struct zx_softc *sc = v;
  400 
  401         sc->sc_nscreens--;
  402 }
  403 
  404 int
  405 zx_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int),
  406     void *cbarg)
  407 {
  408         return (0);
  409 }
  410 
  411 /*
  412  * Return the address that would map the given device at the given
  413  * offset, allowing for the given protection, or return -1 for error.
  414  */
  415 paddr_t
  416 zx_mmap(void *v, off_t offset, int prot)
  417 {
  418         struct zx_softc *sc = v;
  419 
  420         if (offset & PGOFSET)
  421                 return (-1);
  422 
  423         /* Allow mapping as a dumb framebuffer from offset 0 */
  424         if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
  425                 return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
  426                     ZX_OFF_SS0 + offset, prot, BUS_SPACE_MAP_LINEAR));
  427         }
  428 
  429         return (-1);
  430 }
  431 
  432 void
  433 zx_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
  434 {
  435         struct zx_softc *sc = v;
  436 
  437         sc->sc_cmap.cm_red[index] = r;
  438         sc->sc_cmap.cm_green[index] = g;
  439         sc->sc_cmap.cm_blue[index] = b;
  440 }
  441 
  442 void
  443 zx_reset(struct zx_softc *sc, u_int mode)
  444 {
  445         volatile struct zx_draw *zd;
  446         volatile struct zx_command *zc;
  447         u_int32_t i;
  448         const u_char *color;
  449         u_int8_t *r, *g, *b;
  450 
  451         zd = sc->sc_zd_ss0;
  452         zc = sc->sc_zc;
  453 
  454         if (mode == WSDISPLAYIO_MODE_EMUL) {
  455                 /* Back from X11 to emulation mode, or first reset */
  456                 zx_cross_loadwid(sc, ZX_WID_DBL_8, 0, 0x2c0);
  457                 zx_cross_loadwid(sc, ZX_WID_DBL_8, 1, 0x30);
  458                 zx_cross_loadwid(sc, ZX_WID_DBL_8, 2, 0x20);
  459                 zx_cross_loadwid(sc, ZX_WID_DBL_24, 1, 0x30);
  460 
  461                 i = sc->sc_zd_ss1->zd_misc;
  462                 i |= ZX_SS1_MISC_ENABLE;
  463                 SETREG(sc->sc_zd_ss1->zd_misc, i);
  464 
  465                 /*
  466                  * XXX
  467                  * If zc_fill is not set to that value, there will be black
  468                  * bars left in the margins. But then with this value, the
  469                  * screen gets cleared. Go figure.
  470                  */
  471                 SETREG(zd->zd_wid, 0xffffffff);
  472                 SETREG(zd->zd_wmask, 0xffff);
  473                 SETREG(zd->zd_vclipmin, 0);
  474                 SETREG(zd->zd_vclipmax, (sc->sc_sunfb.sf_width - 1) |
  475                     ((sc->sc_sunfb.sf_height - 1) << 16));
  476                 SETREG(zd->zd_fg, 0);
  477                 SETREG(zd->zd_planemask, 0xff000000);
  478                 SETREG(zd->zd_rop, ZX_STD_ROP);
  479                 SETREG(zd->zd_widclip, 0);
  480 
  481                 SETREG(zc->zc_extent, ZX_COORDS(sc->sc_sunfb.sf_width - 1,
  482                     sc->sc_sunfb.sf_height - 1));
  483                 SETREG(zc->zc_addrspace, ZX_ADDRSPC_FONT_OBGR);
  484                 SETREG(zc->zc_fill, ZX_COORDS(0, 0) | ZX_EXTENT_DIR_BACKWARDS);
  485                 SETREG(zc->zc_fontt, 0);
  486 
  487                 while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
  488                         ;
  489 
  490                 /*
  491                  * Initialize the 8-bit colormap
  492                  */
  493                 r = sc->sc_cmap.cm_red;
  494                 g = sc->sc_cmap.cm_green;
  495                 b = sc->sc_cmap.cm_blue;
  496                 color = rasops_cmap;
  497                 for (i = 0; i < 256; i++) {
  498                         *r++ = *color++;
  499                         *g++ = *color++;
  500                         *b++ = *color++;
  501                 }
  502                 fbwscons_setcolormap(&sc->sc_sunfb, zx_setcolor);
  503                 zx_putcmap(sc);
  504         } else {
  505                 /* Starting X11 - switch to 24bit WID */
  506                 SETREG(zd->zd_wid, 1);
  507                 SETREG(zd->zd_widclip, 0);
  508                 SETREG(zd->zd_wmask, 0xffff);
  509                 SETREG(zd->zd_planemask, 0x00ffffff);
  510                 SETREG(zc->zc_extent, ZX_COORDS(sc->sc_sunfb.sf_width - 1,
  511                     sc->sc_sunfb.sf_height - 1));
  512                 SETREG(zc->zc_fill, 0);
  513                 while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
  514                         ;
  515 
  516                 SETREG(zc->zc_addrspace, ZX_ADDRSPC_OBGR);
  517                 SETREG(zd->zd_rop, ZX_ATTR_RGBE_ENABLE |
  518                     ZX_ROP_NEW /* | ZX_ATTR_FORCE_WID */);
  519         }
  520 }
  521 
  522 int
  523 zx_cross_wait(struct zx_softc *sc)
  524 {
  525         volatile struct zx_cross *zx;
  526         int i;
  527 
  528         zx = sc->sc_zx;
  529 
  530         for (i = 300000; i != 0; i--) {
  531                 if ((zx->zx_csr & ZX_CROSS_CSR_PROGRESS) == 0)
  532                         break;
  533                 DELAY(1);
  534         }
  535 
  536         if (i == 0)
  537                 printf("%s: zx_cross_wait: timed out\n",
  538                     sc->sc_sunfb.sf_dev.dv_xname);
  539 
  540         return (i);
  541 }
  542 
  543 int
  544 zx_cross_loadwid(struct zx_softc *sc, u_int type, u_int index, u_int value)
  545 {
  546         volatile struct zx_cross *zx;
  547         u_int tmp;
  548 
  549         zx = sc->sc_zx;
  550         SETREG(zx->zx_type, ZX_CROSS_TYPE_WID);
  551 
  552         if (!zx_cross_wait(sc))
  553                 return (1);
  554 
  555         if (type == ZX_WID_DBL_8)
  556                 tmp = (index & 0x0f) + 0x40;
  557         else if (type == ZX_WID_DBL_24)
  558                 tmp = index & 0x3f;
  559 
  560         SETREG(zx->zx_type, 0x5800 + tmp);
  561         SETREG(zx->zx_value, value);
  562         SETREG(zx->zx_type, ZX_CROSS_TYPE_WID);
  563         SETREG(zx->zx_csr, ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2);
  564 
  565         return (0);
  566 }
  567 
  568 int
  569 zx_putcmap(struct zx_softc *sc)
  570 {
  571         volatile struct zx_cross *zx;
  572         u_int32_t i;
  573         u_int8_t *r, *g, *b;
  574 
  575         zx = sc->sc_zx;
  576 
  577         SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUT0);
  578         if (!zx_cross_wait(sc))
  579                 return (1);
  580 
  581         SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUTDATA);
  582 
  583         r = sc->sc_cmap.cm_red;
  584         g = sc->sc_cmap.cm_green;
  585         b = sc->sc_cmap.cm_blue;
  586         for (i = 0; i < 256; i++) {
  587                 SETREG(zx->zx_value, *r++ | (*g++ << 8) | (*b++ << 16));
  588         }
  589 
  590         SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUT0);
  591         i = zx->zx_csr;
  592         i = i | ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2;
  593         SETREG(zx->zx_csr, i);
  594         return (0);
  595 }
  596 
  597 void
  598 zx_burner(void *v, u_int on, u_int flags)
  599 {
  600         struct zx_softc *sc = v;
  601         volatile struct zx_cross *zx;
  602         u_int32_t i;
  603 
  604         zx = sc->sc_zx;
  605 
  606         SETREG(zx->zx_type, ZX_CROSS_TYPE_VIDEO);
  607         i = zx->zx_csr;
  608         if (on) {
  609                 i |= ZX_CROSS_CSR_ENABLE;
  610         } else {
  611                 i &= ~ZX_CROSS_CSR_ENABLE;
  612         }
  613         SETREG(zx->zx_csr, i);
  614 }
  615 
  616 void
  617 zx_fillrect(struct rasops_info *ri, int x, int y, int w, int h, long attr,
  618             int rop)
  619 {
  620         struct zx_softc *sc;
  621         volatile struct zx_command *zc;
  622         volatile struct zx_draw *zd;
  623         int fg, bg;
  624 
  625         sc = ri->ri_hw;
  626         zc = sc->sc_zc;
  627         zd = sc->sc_zd_ss0;
  628 
  629         ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, NULL);
  630         x = x * ri->ri_font->fontwidth + ri->ri_xorigin;
  631         y = y * ri->ri_font->fontheight + ri->ri_yorigin;
  632         w = ri->ri_font->fontwidth * w - 1;
  633         h = ri->ri_font->fontheight * h - 1;
  634 
  635         while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
  636                 ;
  637 
  638         SETREG(zd->zd_rop, rop);
  639         SETREG(zd->zd_fg, ri->ri_devcmap[bg] << 24);
  640         SETREG(zc->zc_extent, ZX_COORDS(w, h));
  641         SETREG(zc->zc_fill, ZX_COORDS(x, y) | ZX_EXTENT_DIR_BACKWARDS);
  642 }
  643 
  644 void
  645 zx_copyrect(struct rasops_info *ri, int sx, int sy, int dx, int dy, int w,
  646             int h)
  647 {
  648         struct zx_softc *sc;
  649         volatile struct zx_command *zc;
  650         volatile struct zx_draw *zd;
  651         int dir;
  652 
  653         sc = ri->ri_hw;
  654         zc = sc->sc_zc;
  655         zd = sc->sc_zd_ss0;
  656 
  657         sx = sx * ri->ri_font->fontwidth + ri->ri_xorigin;
  658         sy = sy * ri->ri_font->fontheight + ri->ri_yorigin;
  659         dx = dx * ri->ri_font->fontwidth + ri->ri_xorigin;
  660         dy = dy * ri->ri_font->fontheight + ri->ri_yorigin;
  661         w = w * ri->ri_font->fontwidth - 1;
  662         h = h * ri->ri_font->fontheight - 1;
  663 
  664         if (sy < dy || sx < dx) {
  665                 dir = ZX_EXTENT_DIR_BACKWARDS;
  666                 sx += w;
  667                 sy += h;
  668                 dx += w;
  669                 dy += h;
  670         } else
  671                 dir = ZX_EXTENT_DIR_FORWARDS;
  672 
  673         while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
  674                 ;
  675 
  676         SETREG(zd->zd_rop, ZX_STD_ROP);
  677         SETREG(zc->zc_extent, ZX_COORDS(w, h) | dir);
  678         SETREG(zc->zc_src, ZX_COORDS(sx, sy));
  679         SETREG(zc->zc_copy, ZX_COORDS(dx, dy));
  680 }
  681 
  682 void
  683 zx_do_cursor(struct rasops_info *ri)
  684 {
  685 
  686         zx_fillrect(ri, ri->ri_ccol, ri->ri_crow, 1, 1, WSCOL_BLACK << 16,
  687             ZX_ROP_NEW_XOR_OLD | ZX_ATTR_WE_ENABLE | ZX_ATTR_OE_ENABLE |
  688             ZX_ATTR_FORCE_WID);
  689 }
  690 
  691 void
  692 zx_erasecols(void *cookie, int row, int col, int num, long attr)
  693 {
  694         struct rasops_info *ri;
  695 
  696         ri = (struct rasops_info *)cookie;
  697 
  698         zx_fillrect(ri, col, row, num, 1, attr, ZX_STD_ROP);
  699 }
  700 
  701 void
  702 zx_eraserows(void *cookie, int row, int num, long attr)
  703 {
  704         struct rasops_info *ri;
  705         struct zx_softc *sc;
  706         volatile struct zx_command *zc;
  707         volatile struct zx_draw *zd;
  708         int fg, bg;
  709 
  710         ri = (struct rasops_info *)cookie;
  711 
  712         if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) {
  713                 sc = ri->ri_hw;
  714                 zc = sc->sc_zc;
  715                 zd = sc->sc_zd_ss0;
  716 
  717                 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
  718 
  719                 while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
  720                         ;
  721 
  722                 SETREG(zd->zd_rop, ZX_STD_ROP);
  723                 SETREG(zd->zd_fg, ri->ri_devcmap[bg] << 24);
  724                 SETREG(zc->zc_extent,
  725                     ZX_COORDS(ri->ri_width - 1, ri->ri_height - 1));
  726                 SETREG(zc->zc_fill, ZX_COORDS(0, 0) | ZX_EXTENT_DIR_BACKWARDS);
  727         } else
  728                 zx_fillrect(ri, 0, row, ri->ri_cols, num, attr, ZX_STD_ROP);
  729 }
  730 
  731 void
  732 zx_copyrows(void *cookie, int src, int dst, int num)
  733 {
  734         struct rasops_info *ri;
  735 
  736         ri = (struct rasops_info *)cookie;
  737 
  738         zx_copyrect(ri, 0, src, 0, dst, ri->ri_cols, num);
  739 }
  740 
  741 void
  742 zx_copycols(void *cookie, int row, int src, int dst, int num)
  743 {
  744         struct rasops_info *ri;
  745 
  746         ri = (struct rasops_info *)cookie;
  747 
  748         zx_copyrect(ri, src, row, dst, row, num, 1);
  749 }
  750 
  751 void
  752 zx_putchar(void *cookie, int row, int col, u_int uc, long attr)
  753 {
  754         struct rasops_info *ri;
  755         struct zx_softc *sc;
  756         struct wsdisplay_font *font;
  757         volatile struct zx_command *zc;
  758         volatile struct zx_draw *zd;
  759         volatile u_int32_t *dp;
  760         u_int8_t *fb;
  761         int fs, i, fg, bg, ul;
  762 
  763         ri = (struct rasops_info *)cookie;
  764         font = ri->ri_font;
  765         ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, &ul);
  766         fg = ri->ri_devcmap[fg];
  767         bg = ri->ri_devcmap[bg];
  768 
  769         dp = (volatile u_int32_t *)ri->ri_bits +
  770             ZX_COORDS(col * font->fontwidth, row * font->fontheight);
  771 
  772         if (uc == ' ') {
  773                 zx_fillrect(ri, col, row, 1, 1, attr, ZX_STD_ROP);
  774                 if (ul == 0)
  775                         return;
  776 
  777                 dp += font->fontheight << ZX_WWIDTH;
  778 
  779                 while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
  780                         ;
  781 
  782                 SETREG(zd->zd_rop, ZX_STD_ROP);
  783                 SETREG(zd->zd_fg, fg << 24);
  784                 SETREG(zd->zd_bg, bg << 24);
  785                 SETREG(zc->zc_fontmsk, 0xffffffff << (32 - font->fontwidth));
  786         } else {
  787                 sc = ri->ri_hw;
  788                 zc = sc->sc_zc;
  789                 zd = sc->sc_zd_ss0;
  790 
  791                 fb = (u_int8_t *)font->data + (uc - font->firstchar) *
  792                     ri->ri_fontscale;
  793                 fs = font->stride;
  794 
  795                 while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
  796                         ;
  797 
  798                 SETREG(zd->zd_rop, ZX_STD_ROP);
  799                 SETREG(zd->zd_fg, fg << 24);
  800                 SETREG(zd->zd_bg, bg << 24);
  801                 SETREG(zc->zc_fontmsk, 0xffffffff << (32 - font->fontwidth));
  802 
  803                 if (font->fontwidth <= 8) {
  804                         for (i = font->fontheight; i != 0;
  805                             i--, dp += 1 << ZX_WWIDTH) {
  806                                 *dp = *fb << 24;
  807                                 fb += fs;
  808                         }
  809                 } else {
  810                         for (i = font->fontheight; i != 0;
  811                             i--, dp += 1 << ZX_WWIDTH) {
  812                                 *dp = *((u_int16_t *)fb) << 16;
  813                                 fb += fs;
  814                         }
  815                 }
  816         }
  817 
  818         /* underline */
  819         if (ul) {
  820                 dp -= 2 << ZX_WWIDTH;
  821                 *dp = 0xffffffff;
  822         }
  823 }

/* [<][>][^][v][top][bottom][index][help] */