root/dev/pci/tga.c

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

DEFINITIONS

This source file includes following definitions.
  1. tgamatch
  2. tga_getdevconfig
  3. tgaattach
  4. tga_config_interrupts
  5. tga_ioctl
  6. tga_sched_update
  7. tga_intr
  8. tga_mmap
  9. tga_alloc_screen
  10. tga_free_screen
  11. tga_show_screen
  12. tga_cnattach
  13. tga_burner
  14. tga_blank
  15. tga_unblank
  16. tga_builtin_set_cursor
  17. tga_builtin_get_cursor
  18. tga_builtin_set_curpos
  19. tga_builtin_get_curpos
  20. tga_builtin_get_curmax
  21. tga_copycols
  22. tga_copyrows
  23. tga_rop
  24. tga_rop_vtov
  25. tga_putchar
  26. tga_eraserows
  27. tga_erasecols
  28. tga_ramdac_wr
  29. tga2_ramdac_wr
  30. tga_bt463_rd
  31. tga_bt463_wr
  32. tga_ramdac_rd
  33. tga2_ramdac_rd
  34. tga2_init
  35. tga2_ics9110_wr
  36. tga_getmonitor
  37. tga_getdotclock

    1 /* $OpenBSD: tga.c,v 1.29 2006/12/17 22:18:16 miod Exp $ */
    2 /* $NetBSD: tga.c,v 1.40 2002/03/13 15:05:18 ad Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
    6  * All rights reserved.
    7  *
    8  * Author: Chris G. Demetriou
    9  * 
   10  * Permission to use, copy, modify and distribute this software and
   11  * its documentation is hereby granted, provided that both the copyright
   12  * notice and this permission notice appear in all copies of the
   13  * software, derivative works or modified versions, and any portions
   14  * thereof, and that both notices appear in supporting documentation.
   15  * 
   16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
   17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
   18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   19  * 
   20  * Carnegie Mellon requests users of this software to return to
   21  *
   22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   23  *  School of Computer Science
   24  *  Carnegie Mellon University
   25  *  Pittsburgh PA 15213-3890
   26  *
   27  * any improvements or extensions that they make and grant Carnegie the
   28  * rights to redistribute these changes.
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/kernel.h>
   34 #include <sys/device.h>
   35 #include <sys/conf.h>
   36 #include <sys/malloc.h>
   37 #include <sys/buf.h>
   38 #include <sys/ioctl.h>
   39 
   40 #include <machine/bus.h>
   41 #include <machine/intr.h>
   42 
   43 #include <dev/pci/pcireg.h>
   44 #include <dev/pci/pcivar.h>
   45 #include <dev/pci/pcidevs.h>
   46 #include <dev/pci/tgareg.h>
   47 #include <dev/pci/tgavar.h>
   48 #include <dev/ic/bt485reg.h>
   49 #include <dev/ic/bt485var.h>
   50 #include <dev/ic/bt463reg.h>
   51 #include <dev/ic/bt463var.h>
   52 #include <dev/ic/ibm561var.h>
   53 
   54 #include <dev/wscons/wsconsio.h>
   55 #include <dev/rasops/rasops.h>
   56 #include <dev/wsfont/wsfont.h>
   57 
   58 #if defined(__alpha__) || defined(__mips__)
   59 #include <uvm/uvm_extern.h>
   60 #endif
   61 
   62 #ifdef __alpha__
   63 #include <machine/pte.h>
   64 #endif
   65 #ifdef __mips__
   66 #include <mips/pte.h>
   67 #endif
   68 
   69 int     tgamatch(struct device *, struct cfdata *, void *);
   70 void    tgaattach(struct device *, struct device *, void *);
   71 int     tgaprint(void *, const char *);
   72 
   73 struct cfdriver tga_cd = {
   74         NULL, "tga", DV_DULL
   75 };
   76 
   77 struct cfattach tga_ca = {
   78         sizeof(struct tga_softc), (cfmatch_t)tgamatch, tgaattach,
   79 };
   80 
   81 int     tga_identify(struct tga_devconfig *);
   82 const struct tga_conf *tga_getconf(int);
   83 void    tga_getdevconfig(bus_space_tag_t memt, pci_chipset_tag_t pc,
   84             pcitag_t tag, struct tga_devconfig *dc);
   85 unsigned tga_getdotclock(struct tga_devconfig *dc);
   86 
   87 struct tga_devconfig tga_console_dc;
   88 
   89 int     tga_ioctl(void *, u_long, caddr_t, int, struct proc *);
   90 paddr_t tga_mmap(void *, off_t, int);
   91 void    tga_copyrows(void *, int, int, int);
   92 void    tga_copycols(void *, int, int, int, int);
   93 int     tga_alloc_screen(void *, const struct wsscreen_descr *,
   94             void **, int *, int *, long *);
   95 void    tga_free_screen(void *, void *);
   96 int     tga_show_screen(void *, void *, int,
   97                            void (*) (void *, int, int), void *);
   98 void    tga_burner(void *, u_int, u_int);
   99 int     tga_rop(struct rasops_info *, int, int, int, int,
  100         struct rasops_info *, int, int);
  101 int     tga_rop_vtov(struct rasops_info *, int, int, int,
  102         int, struct rasops_info *, int, int );
  103 void    tga_putchar(void *c, int row, int col, u_int uc, long attr);
  104 void    tga_eraserows(void *, int, int, long);
  105 void    tga_erasecols(void *, int, int, int, long);
  106 void    tga2_init(struct tga_devconfig *);
  107 
  108 void    tga_config_interrupts(struct device *);
  109 
  110 /* RAMDAC interface functions */
  111 int      tga_sched_update(void *, void (*)(void *));
  112 void     tga_ramdac_wr(void *, u_int, u_int8_t);
  113 u_int8_t tga_ramdac_rd(void *, u_int);
  114 void     tga_bt463_wr(void *, u_int, u_int8_t);
  115 u_int8_t tga_bt463_rd(void *, u_int);
  116 void     tga2_ramdac_wr(void *, u_int, u_int8_t);
  117 u_int8_t tga2_ramdac_rd(void *, u_int);
  118 
  119 /* Interrupt handler */
  120 int     tga_intr(void *);
  121 
  122 /* The NULL entries will get filled in by rasops_init().
  123  * XXX and the non-NULL ones will be overwritten; reset after calling it.
  124  */
  125 struct wsdisplay_emulops tga_emulops = {
  126         NULL,
  127         NULL,
  128         tga_putchar,
  129         tga_copycols,
  130         tga_erasecols,
  131         tga_copyrows,
  132         tga_eraserows,
  133         NULL,
  134         NULL
  135 };
  136 
  137 struct wsscreen_descr tga_stdscreen = {
  138         "std",
  139         0, 0,   /* will be filled in -- XXX shouldn't, it's global */
  140         &tga_emulops,
  141         0, 0,
  142         WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
  143             WSSCREEN_WSCOLORS | WSSCREEN_REVERSE
  144 };
  145 
  146 const struct wsscreen_descr *_tga_scrlist[] = {
  147         &tga_stdscreen,
  148         /* XXX other formats, graphics screen? */
  149 };
  150 
  151 struct wsscreen_list tga_screenlist = {
  152         sizeof(_tga_scrlist) / sizeof(struct wsscreen_descr *), _tga_scrlist
  153 };
  154 
  155 struct wsdisplay_accessops tga_accessops = {
  156         tga_ioctl,
  157         tga_mmap,
  158         tga_alloc_screen,
  159         tga_free_screen,
  160         tga_show_screen,
  161         NULL,                   /* load_font */
  162         NULL,                   /* scrollback */
  163         NULL,                   /* getchar */
  164         tga_burner,
  165 };
  166 
  167 void    tga_blank(struct tga_devconfig *);
  168 void    tga_unblank(struct tga_devconfig *);
  169 
  170 #ifdef TGA_DEBUG
  171 #define DPRINTF(...)      printf (__VA_ARGS__)
  172 #define DPRINTFN(n, ...)   if (tgadebug > (n)) printf (__VA_ARGS__)
  173 int tgadebug = 0;
  174 #else
  175 #define DPRINTF(...)
  176 #define DPRINTFN(n,...)
  177 #endif
  178 
  179 const struct pci_matchid tga_devices[] = {
  180         { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21030 },
  181         { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PBXGB },
  182 };
  183 
  184 int
  185 tgamatch(parent, match, aux)
  186         struct device *parent;
  187         struct cfdata *match;
  188         void *aux;
  189 {
  190         if (pci_matchbyid((struct pci_attach_args *)aux, tga_devices,
  191             sizeof(tga_devices) / sizeof(tga_devices[0])))
  192                 return (10);    /* need to return more than vga_pci here! */
  193 
  194         return (0);
  195 }
  196 
  197 void
  198 tga_getdevconfig(memt, pc, tag, dc)
  199         bus_space_tag_t memt;
  200         pci_chipset_tag_t pc;
  201         pcitag_t tag;
  202         struct tga_devconfig *dc;
  203 {
  204         const struct tga_conf *tgac;
  205         struct rasops_info *rip;
  206         int cookie;
  207         bus_size_t pcisize;
  208         int i;
  209 
  210         dc->dc_memt = memt;
  211 
  212         dc->dc_pcitag = tag;
  213 
  214         DPRINTF("tga_getdevconfig: Getting map info\n");
  215         /* XXX magic number */
  216         if (pci_mapreg_info(pc, tag, 0x10,
  217             PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
  218             &dc->dc_pcipaddr, &pcisize, NULL))
  219                 return;
  220 
  221         DPRINTF("tga_getdevconfig: preparing to map\n");
  222 #ifdef __OpenBSD__
  223         if (bus_space_map(memt, dc->dc_pcipaddr, pcisize, 1, &dc->dc_memh))
  224                 return;
  225         dc->dc_vaddr = dc->dc_memh;
  226 #else
  227         if (bus_space_map(memt, dc->dc_pcipaddr, pcisize,
  228             BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &dc->dc_memh))
  229                 return;
  230         dc->dc_vaddr = (vaddr_t) bus_space_vaddr(memt, dc->dc_memh);
  231 #endif
  232         DPRINTF("tga_getdevconfig: mapped\n");
  233 
  234 #ifdef __alpha__
  235         dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr);       /* XXX */
  236 #endif
  237 #ifdef arc
  238         bus_space_paddr(memt, dc->dc_memh, &dc->dc_paddr);
  239 #endif
  240         DPRINTF("tga_getdevconfig: allocating subregion\n");
  241         bus_space_subregion(dc->dc_memt, dc->dc_memh, 
  242                             TGA_MEM_CREGS, TGA_CREGS_SIZE,
  243                             &dc->dc_regs);
  244 
  245         DPRINTF("tga_getdevconfig: going to identify\n");
  246         dc->dc_tga_type = tga_identify(dc);
  247 
  248         DPRINTF("tga_getdevconfig: preparing to get config\n");
  249         tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type);
  250         if (tgac == NULL)
  251                 return;
  252 
  253 #if 0
  254         /* XXX on the Alpha, pcisize = 4 * cspace_size. */
  255         if (tgac->tgac_cspace_size != pcisize)                  /* sanity */
  256                 panic("tga_getdevconfig: memory size mismatch?");
  257 #endif
  258 
  259         DPRINTF("tga_getdevconfig: get revno\n");
  260         switch (TGARREG(dc, TGA_REG_GREV) & 0xff) {
  261         case 0x01:
  262         case 0x02:
  263         case 0x03:
  264         case 0x04:
  265                 dc->dc_tga2 = 0;
  266                 break;
  267         case 0x20:
  268         case 0x21:
  269         case 0x22:
  270                 dc->dc_tga2 = 1;
  271                 break;
  272         default:
  273                 panic("tga_getdevconfig: TGA Revision not recognized");
  274         }
  275 
  276         if (dc->dc_tga2) {
  277                 tga2_init(dc);
  278         }
  279         
  280         i = TGARREG(dc, TGA_REG_VHCR) & 0x1ff;
  281         DPRINTF("tga_getdevconfig: TGA_REG_VHCR & 0x1ff = %d\n", i);
  282         switch (i) {            /* XXX */
  283         case 0:
  284                 dc->dc_wid = 8192;
  285                 break;
  286 
  287         case 1:
  288                 dc->dc_wid = 8196;
  289                 break;
  290 
  291         default:
  292                 dc->dc_wid = (TGARREG(dc, TGA_REG_VHCR) & 0x1ff) * 4; /* XXX */
  293                 break;
  294         }
  295 
  296         DPRINTF("tga_getdevconfig: dc->dc_wid = %d\n", dc->dc_wid);
  297         /*
  298          * XXX XXX Turning off "odd" shouldn't be necessary,
  299          * XXX XXX but I can't make X work with the weird size.
  300          */
  301         DPRINTF("tga_getdevconfig: beginning magic incantation\n");
  302         if ((TGARREG(dc, TGA_REG_VHCR) & 0x00000001) != 0 &&    /* XXX */
  303             (TGARREG(dc, TGA_REG_VHCR) & 0x80000000) != 0) {    /* XXX */
  304                 TGAWREG(dc, TGA_REG_VHCR,
  305                     (TGARREG(dc, TGA_REG_VHCR) & ~0x80000001));
  306                 dc->dc_wid -= 4;
  307         }
  308 
  309         dc->dc_rowbytes = dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8);
  310         dc->dc_ht = (TGARREG(dc, TGA_REG_VVCR) & 0x7ff);        /* XXX */
  311         DPRINTF("tga_getdevconfig: rowbytes = %d, tgac_phys_depth = %d\n"
  312                 "                  dc_wid = %d, dc_ht = %d\n",
  313                 dc->dc_rowbytes, dc->dc_tgaconf->tgac_phys_depth,
  314                 dc->dc_wid, dc->dc_ht);
  315 
  316         /* XXX this seems to be what DEC does */
  317         DPRINTF("tga_getdevconfig: more magic\n");
  318         TGAWREG(dc, TGA_REG_CCBR, 0);
  319         TGAWREG(dc, TGA_REG_VVBR, 1);
  320         dc->dc_videobase = dc->dc_vaddr + tgac->tgac_dbuf[0] +
  321             1 * tgac->tgac_vvbr_units;
  322         dc->dc_blanked = 1;
  323         tga_unblank(dc);
  324         
  325         DPRINTF("tga_getdevconfig: dc_videobase = 0x%016llx\n"
  326                 "                  dc_vaddr = 0x%016llx\n"
  327                 "                  tgac_dbuf[0] = %d\n"
  328                 "                  tgac_vvbr_units = %d\n",
  329                 dc->dc_videobase, dc->dc_vaddr, tgac->tgac_dbuf[0],
  330                 tgac->tgac_vvbr_units);
  331                
  332         /*
  333          * Set all bits in the pixel mask, to enable writes to all pixels.
  334          * It seems that the console firmware clears some of them
  335          * under some circumstances, which causes cute vertical stripes.
  336          */
  337         DPRINTF("tga_getdevconfig: set pixel mask\n");
  338         TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff);
  339 
  340         /* clear the screen */
  341         DPRINTF("tga_getdevconfig: clear screen\n");
  342         for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
  343                 *(u_int32_t *)(dc->dc_videobase + i) = 0;
  344 
  345         DPRINTF("tga_getdevconfig: raster ops\n");
  346         /* Initialize rasops descriptor */
  347         rip = &dc->dc_rinfo;
  348         rip->ri_flg = RI_CENTER;
  349         rip->ri_depth = tgac->tgac_phys_depth;
  350         rip->ri_bits = (void *)dc->dc_videobase;
  351         rip->ri_width = dc->dc_wid;
  352         rip->ri_height = dc->dc_ht;
  353         rip->ri_stride = dc->dc_rowbytes;
  354         rip->ri_hw = dc;
  355 
  356         if (tgac->tgac_phys_depth == 32) {
  357                 rip->ri_rnum = 8;
  358                 rip->ri_gnum = 8;
  359                 rip->ri_bnum = 8;
  360                 rip->ri_rpos = 16;
  361                 rip->ri_gpos = 8;
  362                 rip->ri_bpos = 0;
  363         }
  364 
  365         DPRINTF("tga_getdevconfig: wsfont_init\n");
  366         wsfont_init();
  367         if (rip->ri_width > 80*12) 
  368                 /* High res screen, choose a big font */
  369                 cookie = wsfont_find(NULL, 12, 0, 0);
  370         else 
  371                 /*  lower res, choose a 8 pixel wide font */
  372                 cookie = wsfont_find(NULL, 8, 0, 0);
  373         if (cookie <= 0)
  374                 cookie = wsfont_find(NULL, 0, 0, 0);
  375         if (cookie <= 0) {
  376                 printf("tga: no appropriate fonts.\n");
  377                 return;
  378         }
  379 
  380         /* the accelerated tga_putchar() needs LSbit left */
  381         if (wsfont_lock(cookie, &rip->ri_font,
  382             WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0) {
  383                 printf("tga: couldn't lock font\n");
  384                 return;
  385         }
  386         rip->ri_wsfcookie = cookie;
  387         /* fill screen size */
  388         rasops_init(rip, rip->ri_height / rip->ri_font->fontheight,
  389             rip->ri_width / rip->ri_font->fontwidth); 
  390         
  391         /* add our accelerated functions */
  392         /* XXX shouldn't have to do this; rasops should leave non-NULL 
  393          * XXX entries alone.
  394          */
  395         rip->ri_ops.copyrows = tga_copyrows;
  396         rip->ri_ops.eraserows = tga_eraserows;
  397         rip->ri_ops.erasecols = tga_erasecols;
  398         rip->ri_ops.copycols = tga_copycols;
  399         rip->ri_ops.putchar = tga_putchar;      
  400 
  401         tga_stdscreen.nrows = rip->ri_rows;
  402         tga_stdscreen.ncols = rip->ri_cols;
  403         tga_stdscreen.textops = &rip->ri_ops;
  404         tga_stdscreen.capabilities = rip->ri_caps;
  405 
  406         dc->dc_intrenabled = 0;
  407 }
  408 
  409 void
  410 tgaattach(parent, self, aux)
  411         struct device *parent, *self;
  412         void *aux;
  413 {
  414         struct pci_attach_args *pa = aux;
  415         struct tga_softc *sc = (struct tga_softc *)self;
  416         struct wsemuldisplaydev_attach_args aa;
  417         pci_intr_handle_t intrh;
  418         const char *intrstr;
  419         u_int8_t rev;
  420         int console;
  421 
  422 #if defined(__alpha__) || defined(arc)
  423         console = (pa->pa_tag == tga_console_dc.dc_pcitag);
  424 #else
  425         console = 0;
  426 #endif
  427         if (console) {
  428                 sc->sc_dc = &tga_console_dc;
  429                 sc->nscreens = 1;
  430         } else {
  431                 sc->sc_dc = (struct tga_devconfig *)
  432                     malloc(sizeof(struct tga_devconfig), M_DEVBUF, M_NOWAIT);
  433                 if (sc->sc_dc == NULL)
  434                         return;
  435                 bzero(sc->sc_dc, sizeof(struct tga_devconfig));
  436                 tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag,
  437                     sc->sc_dc);
  438         }
  439         if (sc->sc_dc->dc_vaddr == NULL) {
  440                 printf(": couldn't map memory space; punt!\n");
  441                 return;
  442         }
  443 
  444         /* XXX say what's going on. */
  445         intrstr = NULL;
  446         if (pci_intr_map(pa, &intrh)) {
  447                 printf(": couldn't map interrupt");
  448                 return;
  449         }
  450         intrstr = pci_intr_string(pa->pa_pc, intrh);
  451         sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, tga_intr,
  452             sc->sc_dc, sc->sc_dev.dv_xname);
  453         if (sc->sc_intr == NULL) {
  454                 printf(": couldn't establish interrupt");
  455                 if (intrstr != NULL)
  456                         printf("at %s", intrstr);
  457                 printf("\n");
  458                 return;
  459         }
  460 
  461         rev = PCI_REVISION(pa->pa_class);
  462         switch (rev) {
  463         case 0x1:
  464         case 0x2:
  465         case 0x3:
  466                 printf(": DC21030 step %c", 'A' + rev - 1);
  467                 break;
  468         case 0x20:
  469                 printf(": TGA2 abstract software model");
  470                 break;
  471         case 0x21:
  472         case 0x22:
  473                 printf(": TGA2 pass %d", rev - 0x20);
  474                 break;
  475 
  476         default:
  477                 printf("unknown stepping (0x%x)", rev);
  478                 break;
  479         }
  480         printf(", ");
  481 
  482         /*
  483          * Get RAMDAC function vectors and call the RAMDAC functions
  484          * to allocate its private storage and pass that back to us.
  485          */
  486 
  487         DPRINTF("tgaattach: Get RAMDAC functions\n");
  488         sc->sc_dc->dc_ramdac_funcs = sc->sc_dc->dc_tgaconf->ramdac_funcs();
  489         if (!sc->sc_dc->dc_tga2) {
  490             DPRINTF("tgaattach: !sc->sc_dc->dc_tga2\n");
  491             DPRINTF("tgaattach: sc->sc_dc->dc_tgaconf->ramdac_funcs %s "
  492                     "bt485_funcs\n",
  493                     (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs)
  494                     ? "==" : "!=");
  495             if (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs) 
  496                   sc->sc_dc->dc_ramdac_cookie = 
  497                         sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
  498                     tga_sched_update, tga_ramdac_wr, tga_ramdac_rd);
  499                 else
  500                   sc->sc_dc->dc_ramdac_cookie = 
  501                         sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
  502                     tga_sched_update, tga_bt463_wr, tga_bt463_rd);
  503         } else {
  504                 DPRINTF("tgaattach: sc->sc_dc->dc_tga2\n");
  505                 sc->sc_dc->dc_ramdac_cookie = 
  506                         sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc, 
  507                         tga_sched_update, tga2_ramdac_wr, tga2_ramdac_rd);
  508 
  509                 /* XXX this is a bit of a hack, setting the dotclock here */
  510                 if (sc->sc_dc->dc_tgaconf->ramdac_funcs != bt485_funcs)
  511                         (*sc->sc_dc->dc_ramdac_funcs->ramdac_set_dotclock)
  512                                 (sc->sc_dc->dc_ramdac_cookie,
  513                                  tga_getdotclock(sc->sc_dc));
  514         }
  515         DPRINTF("tgaattach: sc->sc_dc->dc_ramdac_cookie = 0x%016llx\n",
  516                 sc->sc_dc->dc_ramdac_cookie);
  517         /*
  518          * Initialize the RAMDAC.  Initialization includes disabling
  519          * cursor, setting a sane colormap, etc.
  520          */
  521         DPRINTF("tgaattach: Initializing RAMDAC.\n");
  522         (*sc->sc_dc->dc_ramdac_funcs->ramdac_init)(sc->sc_dc->dc_ramdac_cookie);
  523         TGAWREG(sc->sc_dc, TGA_REG_SISR, 0x00000001); /* XXX */
  524 
  525         if (sc->sc_dc->dc_tgaconf == NULL) {
  526                 printf("unknown board configuration\n");
  527                 return;
  528         }
  529         printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name);
  530         printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname,
  531             sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
  532             sc->sc_dc->dc_tgaconf->tgac_phys_depth,
  533             sc->sc_dc->dc_ramdac_funcs->ramdac_name);
  534 
  535         if (intrstr != NULL)
  536                 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname,
  537                     intrstr);
  538 
  539         aa.console = console;
  540         aa.scrdata = &tga_screenlist;
  541         aa.accessops = &tga_accessops;
  542         aa.accesscookie = sc;
  543         aa.defaultscreens = 0;
  544 
  545         config_found(self, &aa, wsemuldisplaydevprint);
  546 
  547 #ifdef __NetBSD__
  548         config_interrupts(self, tga_config_interrupts);
  549 #else
  550         tga_config_interrupts(self);
  551 #endif
  552 }
  553 
  554 void 
  555 tga_config_interrupts (d)
  556         struct device *d;
  557 {
  558         struct tga_softc *sc = (struct tga_softc *)d;
  559         sc->sc_dc->dc_intrenabled = 1;
  560 }
  561         
  562 
  563 int
  564 tga_ioctl(v, cmd, data, flag, p)
  565         void *v;
  566         u_long cmd;
  567         caddr_t data;
  568         int flag;
  569         struct proc *p;
  570 {
  571         struct tga_softc *sc = v;
  572         struct tga_devconfig *dc = sc->sc_dc;
  573         struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
  574         struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
  575 
  576         switch (cmd) {
  577         case WSDISPLAYIO_GTYPE:
  578                 *(u_int *)data = WSDISPLAY_TYPE_TGA;
  579                 break;
  580 
  581         case WSDISPLAYIO_SMODE:
  582                 sc->sc_mode = *(u_int *)data;
  583                 switch (sc->sc_mode) {
  584                 case WSDISPLAYIO_MODE_DUMBFB:
  585                         /* in dump fb mode start the framebuffer at 0 */
  586                         TGAWREG(dc, TGA_REG_VVBR, 0);
  587                         break;
  588                 default:
  589                         /* XXX it this useful, except for not breaking Xtga? */
  590                         TGAWREG(dc, TGA_REG_VVBR, 1);
  591                         break;                  
  592                 }
  593                 break;
  594 
  595         case WSDISPLAYIO_GINFO:
  596 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
  597                 wsd_fbip->height = sc->sc_dc->dc_ht;
  598                 wsd_fbip->width = sc->sc_dc->dc_wid;
  599                 wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth;
  600                 wsd_fbip->cmsize = 1024;                /* XXX ??? */
  601 #undef wsd_fbip
  602                 break;
  603 
  604         case WSDISPLAYIO_LINEBYTES:
  605                 *(u_int *)data = sc->sc_dc->dc_rowbytes;
  606                 break;
  607 
  608         case WSDISPLAYIO_GETCMAP:
  609                 return (*dcrf->ramdac_get_cmap)(dcrc,
  610                     (struct wsdisplay_cmap *)data);
  611         case WSDISPLAYIO_PUTCMAP:
  612                 return (*dcrf->ramdac_set_cmap)(dcrc,
  613                     (struct wsdisplay_cmap *)data);
  614 
  615         case WSDISPLAYIO_SVIDEO:
  616         case WSDISPLAYIO_GVIDEO:
  617                 break;
  618 
  619         case WSDISPLAYIO_GCURPOS:
  620                 return (*dcrf->ramdac_get_curpos)(dcrc,
  621                     (struct wsdisplay_curpos *)data);
  622 
  623         case WSDISPLAYIO_SCURPOS:
  624                 return (*dcrf->ramdac_set_curpos)(dcrc,
  625                     (struct wsdisplay_curpos *)data);
  626 
  627         case WSDISPLAYIO_GCURMAX:
  628                 return (*dcrf->ramdac_get_curmax)(dcrc,
  629                     (struct wsdisplay_curpos *)data);
  630 
  631         case WSDISPLAYIO_GCURSOR:
  632                 return (*dcrf->ramdac_get_cursor)(dcrc,
  633                     (struct wsdisplay_cursor *)data);
  634 
  635         case WSDISPLAYIO_SCURSOR:
  636                 return (*dcrf->ramdac_set_cursor)(dcrc,
  637                     (struct wsdisplay_cursor *)data);
  638 
  639         default:
  640                 return (-1);
  641         }
  642 
  643         return (0);
  644 }
  645 
  646 int
  647 tga_sched_update(v, f)
  648         void    *v;
  649         void    (*f)(void *);
  650 {
  651         struct tga_devconfig *dc = v;
  652 
  653         if (dc->dc_intrenabled) {
  654                 /* Arrange for f to be called at the next end-of-frame interrupt */
  655                 dc->dc_ramdac_intr = f;
  656                 TGAWREG(dc, TGA_REG_SISR, 0x00010000);
  657         } else {
  658                 /* Spin until the end-of-frame, then call f */
  659                 TGAWREG(dc, TGA_REG_SISR, 0x00010001);
  660                 TGAREGWB(dc, TGA_REG_SISR, 1);
  661                 while ((TGARREG(dc, TGA_REG_SISR) & 0x00000001) == 0)
  662                         ;
  663                 f(dc->dc_ramdac_cookie);
  664                 TGAWREG(dc, TGA_REG_SISR, 0x00000001);
  665                 TGAREGWB(dc, TGA_REG_SISR, 1);
  666         }
  667                 
  668         return 0;
  669 }
  670 
  671 int
  672 tga_intr(v)
  673         void *v;
  674 {
  675         struct tga_devconfig *dc = v;
  676         struct ramdac_cookie *dcrc= dc->dc_ramdac_cookie;
  677 
  678         u_int32_t reg;
  679 
  680         reg = TGARREG(dc, TGA_REG_SISR);
  681         if (( reg & 0x00010001) != 0x00010001) {
  682                 /* Odd. We never set any of the other interrupt enables. */
  683                 if ((reg & 0x1f) != 0) {
  684                         /* Clear the mysterious pending interrupts. */
  685                         TGAWREG(dc, TGA_REG_SISR, (reg & 0x1f));
  686                         TGAREGWB(dc, TGA_REG_SISR, 1);
  687                         /* This was our interrupt, even if we're puzzled as to why
  688                          * we got it.  Don't make the interrupt handler think it
  689                          * was a stray.  
  690                          */
  691                         return -1;
  692                 } else {
  693                         return 0;
  694                 }
  695         }
  696         /* if we have something to do, do it */
  697         if (dc->dc_ramdac_intr) {
  698                 dc->dc_ramdac_intr(dcrc);
  699                 dc->dc_ramdac_intr = NULL;
  700         }
  701         TGAWREG(dc, TGA_REG_SISR, 0x00000001);
  702         TGAREGWB(dc, TGA_REG_SISR, 1);
  703         return (1);
  704 }
  705 
  706 paddr_t
  707 tga_mmap(v, offset, prot)
  708         void *v;
  709         off_t offset;
  710         int prot;
  711 {
  712         struct tga_softc *sc = v;
  713         struct tga_devconfig *dc = sc->sc_dc;
  714 
  715         if (offset >= dc->dc_tgaconf->tgac_cspace_size || offset < 0)
  716                 return -1;
  717 
  718         if (sc->sc_mode == WSDISPLAYIO_MODE_DUMBFB) {
  719                 /* 
  720                  * The framebuffer starts at the upper half of tga mem
  721                  */
  722                 offset += dc->dc_tgaconf->tgac_cspace_size / 2;
  723         }
  724 #if defined(__alpha__) || defined(__mips__)
  725         return atop(sc->sc_dc->dc_paddr + offset);
  726 #else
  727         return (-1);
  728 #endif
  729 }
  730 
  731 int
  732 tga_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
  733         void *v;
  734         const struct wsscreen_descr *type;
  735         void **cookiep;
  736         int *curxp, *curyp;
  737         long *attrp;
  738 {
  739         struct tga_softc *sc = v;
  740         long defattr;
  741 
  742         if (sc->nscreens > 0)
  743                 return (ENOMEM);
  744 
  745         *cookiep = &sc->sc_dc->dc_rinfo; /* one and only for now */
  746         *curxp = 0;
  747         *curyp = 0;
  748         sc->sc_dc->dc_rinfo.ri_ops.alloc_attr(&sc->sc_dc->dc_rinfo, 
  749                 0, 0, 0, &defattr);
  750         *attrp = defattr;
  751         sc->nscreens++;
  752         return (0);
  753 }
  754 
  755 void
  756 tga_free_screen(v, cookie)
  757         void *v;
  758         void *cookie;
  759 {
  760         struct tga_softc *sc = v;
  761 
  762         if (sc->sc_dc == &tga_console_dc)
  763                 panic("tga_free_screen: console");
  764 
  765         sc->nscreens--;
  766 }
  767 
  768 int
  769 tga_show_screen(v, cookie, waitok, cb, cbarg)
  770         void *v;
  771         void *cookie;
  772         int waitok;
  773         void (*cb)(void *, int, int);
  774         void *cbarg;
  775 {
  776 
  777         return (0);
  778 }
  779 
  780 int
  781 tga_cnattach(iot, memt, pc, bus, device, function)
  782         bus_space_tag_t iot, memt;
  783         pci_chipset_tag_t pc;
  784         int bus, device, function;
  785 {
  786         struct tga_devconfig *dcp = &tga_console_dc;
  787         long defattr;
  788 
  789         tga_getdevconfig(memt, pc,
  790             pci_make_tag(pc, bus, device, function), dcp);
  791 
  792         /* sanity checks */
  793         if (dcp->dc_vaddr == NULL)
  794                 panic("tga_console(%d, %d): couldn't map memory space",
  795                     device, function);
  796         if (dcp->dc_tgaconf == NULL)
  797                 panic("tga_console(%d, %d): unknown board configuration",
  798                     device, function);
  799 
  800         /*
  801          * Initialize the RAMDAC but DO NOT allocate any private storage.
  802          * Initialization includes disabling cursor, setting a sane
  803          * colormap, etc.  It will be reinitialized in tgaattach().
  804          */
  805         if (dcp->dc_tga2) {
  806                 if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
  807                         bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
  808                                      tga2_ramdac_rd);
  809                 else
  810                         ibm561_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
  811                                       tga2_ramdac_rd, tga_getdotclock(dcp));
  812         } else {
  813                 if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
  814                         bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr,
  815                                 tga_ramdac_rd);
  816                 else {
  817                         bt463_cninit(dcp, tga_sched_update, tga_bt463_wr,
  818                                 tga_bt463_rd);
  819                 }
  820         }
  821         dcp->dc_rinfo.ri_ops.alloc_attr(&dcp->dc_rinfo, 0, 0, 0, &defattr);
  822         wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rinfo, 0, 0, defattr);
  823         
  824         return(0);
  825 }
  826 
  827 /*
  828  * Functions to blank and unblank the display.
  829  */
  830 void
  831 tga_burner(v, on, flags)
  832         void *v;
  833         u_int on, flags;
  834 {
  835         struct tga_softc *sc = v;
  836 
  837         if (on) {
  838                 tga_unblank(sc->sc_dc);
  839         } else {
  840                 tga_blank(sc->sc_dc);
  841         }
  842 }
  843 
  844 void
  845 tga_blank(dc)
  846         struct tga_devconfig *dc;
  847 {
  848 
  849         if (!dc->dc_blanked) {
  850                 dc->dc_blanked = 1;
  851                 /* XXX */
  852                 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | VVR_BLANK);
  853         }
  854 }
  855 
  856 void
  857 tga_unblank(dc)
  858         struct tga_devconfig *dc;
  859 {
  860 
  861         if (dc->dc_blanked) {
  862                 dc->dc_blanked = 0;
  863                 /* XXX */
  864                 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~VVR_BLANK);
  865         }
  866 }
  867 
  868 /*
  869  * Functions to manipulate the built-in cursor handing hardware.
  870  */
  871 int
  872 tga_builtin_set_cursor(dc, cursorp)
  873         struct tga_devconfig *dc;
  874         struct wsdisplay_cursor *cursorp;
  875 {
  876         struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
  877         struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
  878         u_int count, v;
  879         int error;
  880 
  881         v = cursorp->which;
  882         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  883                 error = dcrf->ramdac_check_curcmap(dcrc, cursorp);
  884                 if (error)
  885                         return (error);
  886         }
  887         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  888                 if ((u_int)cursorp->size.x != 64 ||
  889                     (u_int)cursorp->size.y > 64)
  890                         return (EINVAL);
  891         }
  892         if (v & WSDISPLAY_CURSOR_DOHOT)         /* not supported */
  893                 return EINVAL;
  894 
  895         /* parameters are OK; do it */
  896         if (v & WSDISPLAY_CURSOR_DOCUR) {
  897                 if (cursorp->enable)
  898                         /* XXX */
  899                         TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 0x04);
  900                 else
  901                         /* XXX */
  902                         TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~0x04);
  903         }
  904         if (v & WSDISPLAY_CURSOR_DOPOS) {
  905                 TGAWREG(dc, TGA_REG_CXYR, 
  906                     ((cursorp->pos.y & 0xfff) << 12) | (cursorp->pos.x & 0xfff));
  907         }
  908         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  909                 /* can't fail. */
  910                 dcrf->ramdac_set_curcmap(dcrc, cursorp);
  911         }
  912         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  913                 /* The cursor is 2 bits deep, and there is no mask */
  914                 count = (cursorp->size.y * 64 * 2) / NBBY;
  915                 TGAWREG(dc, TGA_REG_CCBR,
  916                     (TGARREG(dc, TGA_REG_CCBR) & ~0xfc00) | (cursorp->size.y << 10));
  917                 if ((error = copyin(cursorp->image,(char *)(dc->dc_vaddr +
  918                     (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)), count)) != 0)
  919                         return (error);
  920         }
  921         return (0);
  922 }
  923 
  924 int
  925 tga_builtin_get_cursor(dc, cursorp)
  926         struct tga_devconfig *dc;
  927         struct wsdisplay_cursor *cursorp;
  928 {
  929         struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
  930         struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
  931         int error;
  932         u_int count;
  933 
  934         cursorp->which = WSDISPLAY_CURSOR_DOALL &
  935             ~(WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCMAP);
  936         cursorp->enable = (TGARREG(dc, TGA_REG_VVVR) & 0x04) != 0;
  937         cursorp->pos.x = TGARREG(dc, TGA_REG_CXYR) & 0xfff;
  938         cursorp->pos.y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff;
  939         cursorp->size.x = 64;
  940         cursorp->size.y = (TGARREG(dc, TGA_REG_CCBR) >> 10) & 0x3f;
  941 
  942         if (cursorp->image != NULL) {
  943                 count = (cursorp->size.y * 64 * 2) / NBBY;
  944                 error = copyout((char *)(dc->dc_vaddr +
  945                       (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)),
  946                     cursorp->image, count);
  947                 if (error)
  948                         return (error);
  949                 /* No mask */
  950         }
  951         error = dcrf->ramdac_get_curcmap(dcrc, cursorp);
  952         return (error);
  953 }
  954 
  955 int
  956 tga_builtin_set_curpos(dc, curposp)
  957         struct tga_devconfig *dc;
  958         struct wsdisplay_curpos *curposp;
  959 {
  960 
  961         TGAWREG(dc, TGA_REG_CXYR,
  962             ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff));
  963         return (0);
  964 }
  965 
  966 int
  967 tga_builtin_get_curpos(dc, curposp)
  968         struct tga_devconfig *dc;
  969         struct wsdisplay_curpos *curposp;
  970 {
  971 
  972         curposp->x = TGARREG(dc, TGA_REG_CXYR) & 0xfff;
  973         curposp->y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff;
  974         return (0);
  975 }
  976 
  977 int
  978 tga_builtin_get_curmax(dc, curposp)
  979         struct tga_devconfig *dc;
  980         struct wsdisplay_curpos *curposp;
  981 {
  982 
  983         curposp->x = curposp->y = 64;
  984         return (0);
  985 }
  986 
  987 /*
  988  * Copy columns (characters) in a row (line).
  989  */
  990 void
  991 tga_copycols(id, row, srccol, dstcol, ncols)
  992         void *id;
  993         int row, srccol, dstcol, ncols;
  994 {
  995         struct rasops_info *ri = id;
  996         int y, srcx, dstx, nx;
  997 
  998         y = ri->ri_font->fontheight * row;
  999         srcx = ri->ri_font->fontwidth * srccol;
 1000         dstx = ri->ri_font->fontwidth * dstcol;
 1001         nx = ri->ri_font->fontwidth * ncols;
 1002 
 1003         tga_rop(ri, dstx, y, nx, ri->ri_font->fontheight, ri, srcx, y);
 1004 }
 1005 
 1006 /*
 1007  * Copy rows (lines).
 1008  */
 1009 void
 1010 tga_copyrows(id, srcrow, dstrow, nrows)
 1011         void *id;
 1012         int srcrow, dstrow, nrows;
 1013 {
 1014         struct rasops_info *ri = id;
 1015         int srcy, dsty, ny;
 1016 
 1017         srcy = ri->ri_font->fontheight * srcrow;
 1018         dsty = ri->ri_font->fontheight * dstrow;
 1019         ny = ri->ri_font->fontheight * nrows;
 1020 
 1021         tga_rop(ri, 0, dsty, ri->ri_emuwidth, ny, ri, 0, srcy);
 1022 }
 1023 
 1024 /*
 1025  *  Generic TGA raster op.
 1026  *   This covers all possible raster ops, and
 1027  *   clips the sizes and all of that.
 1028  */
 1029 int
 1030 tga_rop(dst, dx, dy, w, h, src, sx, sy)
 1031         struct rasops_info *dst;
 1032         int dx, dy, w, h;
 1033         struct rasops_info *src;
 1034         int sx, sy;
 1035 {
 1036         if (dst == NULL || src == NULL)
 1037                 return -1;
 1038 
 1039         /* Clip against src */
 1040         if (sx < 0) {
 1041                 w += sx;
 1042                 sx = 0;
 1043         }
 1044         if (sy < 0) {
 1045                 h += sy;
 1046                 sy = 0;
 1047         }
 1048         if (sx + w > src->ri_emuwidth)
 1049                 w = src->ri_emuwidth - sx;
 1050         if (sy + h > src->ri_emuheight)
 1051                 h = src->ri_emuheight - sy;
 1052 
 1053         /* Clip against dst.  We modify src regardless of using it,
 1054          * since it really doesn't matter.
 1055          */
 1056         if (dx < 0) {
 1057                 w += dx;
 1058                 sx -= dx;
 1059                 dx = 0;
 1060         }
 1061         if (dy < 0) {
 1062                 h += dy;
 1063                 sy -= dy;
 1064                 dy = 0;
 1065         }
 1066         if (dx + w > dst->ri_emuwidth)
 1067                 w = dst->ri_emuwidth - dx;
 1068         if (dy + h > dst->ri_emuheight)
 1069                 h = dst->ri_emuheight - dy;
 1070         if (w <= 0 || h <= 0)
 1071                 return 0;       /* Vacuously true; */
 1072 
 1073         return tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy);
 1074 }
 1075 
 1076 
 1077 
 1078 /*
 1079  * Video to Video raster ops.
 1080  * This function deals with all raster ops that have a src and dst
 1081  * that are on the card.
 1082  */
 1083 int
 1084 tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy)
 1085         struct rasops_info *dst;
 1086         int dx, dy, w, h;
 1087         struct rasops_info *src;
 1088         int sx, sy;
 1089 {
 1090         struct tga_devconfig *dc = (struct tga_devconfig *)dst->ri_hw;
 1091         int srcb, dstb, tga_srcb, tga_dstb;
 1092         int x, y, wb;
 1093         int xstart, xend, xdir;
 1094         int ystart, yend, ydir, yinc;
 1095         int xleft, lastx, lastleft;
 1096         int offset = 1 * dc->dc_tgaconf->tgac_vvbr_units;
 1097 
 1098         /*
 1099          * I don't yet want to deal with unaligned guys, really.  And we don't
 1100          * deal with copies from one card to another.
 1101          */
 1102         if (dx % 8 != 0 || sx % 8 != 0 || src != dst) {
 1103                 /* XXX Punt! */
 1104                 /* XXX should never happen, since it's only being used to
 1105                  * XXX copy 8-pixel-wide characters.
 1106                  */
 1107                 return -1;
 1108         }
 1109 
 1110         wb = w * (dst->ri_depth / 8);
 1111         if (sy >= dy) {
 1112                 ystart = 0;
 1113                 yend = h;
 1114                 ydir = 1;
 1115         } else {
 1116                 ystart = h;
 1117                 yend = 0;
 1118                 ydir = -1;
 1119         }
 1120         if (sx >= dx) {      /* moving to the left */
 1121                 xstart = 0;
 1122                 xend = w * (dst->ri_depth / 8) - 4;
 1123                 xdir = 1;
 1124         } else {             /* moving to the right */
 1125                 xstart = wb - ( wb >= 4*64 ? 4*64 : wb >= 64 ? 64 : 4 );
 1126                 xend = 0;
 1127                 xdir = -1;
 1128         }
 1129 #define XINC4   4
 1130 #define XINC64  64
 1131 #define XINC256 (64*4)
 1132         yinc = ydir * dst->ri_stride;
 1133         ystart *= dst->ri_stride;
 1134         yend *= dst->ri_stride;
 1135 
 1136         srcb = sy * src->ri_stride + sx * (src->ri_depth/8);
 1137         dstb = dy * dst->ri_stride + dx * (dst->ri_depth/8);
 1138         tga_srcb = offset + (sy + src->ri_yorigin) * src->ri_stride + 
 1139                 (sx + src->ri_xorigin) * (src->ri_depth/8);
 1140         tga_dstb = offset + (dy + dst->ri_yorigin) * dst->ri_stride + 
 1141                 (dx + dst->ri_xorigin) * (dst->ri_depth/8);
 1142 
 1143         TGAWALREG(dc, TGA_REG_GMOR, 3, 0x0007); /* Copy mode */
 1144         TGAWALREG(dc, TGA_REG_GOPR, 3, 0x0003); /* SRC */
 1145 
 1146         /*
 1147          * we have 3 sizes of pixels to move in X direction:
 1148          * 4 * 64   (unrolled TGA ops)
 1149          *     64   (single TGA op)
 1150          *      4   (CPU, using long word)
 1151          */
 1152 
 1153         if (xdir == 1) {   /* move to the left */
 1154 
 1155                 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
 1156 
 1157                         /* 4*64 byte chunks */
 1158                         for (xleft = wb, x = xstart;
 1159                              x <= xend && xleft >= 4*64;
 1160                              x += XINC256, xleft -= XINC256) {
 1161 
 1162                                 /* XXX XXX Eight writes to different addresses should fill 
 1163                                  * XXX XXX up the write buffers on 21064 and 21164 chips,
 1164                                  * XXX XXX but later CPUs might have larger write buffers which
 1165                                  * XXX XXX require further unrolling of this loop, or the
 1166                                  * XXX XXX insertion of memory barriers.
 1167                                  */
 1168                                 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
 1169                                 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
 1170                                 TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 1 * 64);
 1171                                 TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 1 * 64);
 1172                                 TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 2 * 64);
 1173                                 TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 2 * 64);
 1174                                 TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 3 * 64);
 1175                                 TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 3 * 64);
 1176                         }
 1177 
 1178                         /* 64 byte chunks */
 1179                         for ( ; x <= xend && xleft >= 64;
 1180                               x += XINC64, xleft -= XINC64) {
 1181                                 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
 1182                                 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
 1183                         }
 1184                         lastx = x; lastleft = xleft;  /* remember for CPU loop */
 1185 
 1186                 }
 1187                 TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */
 1188                 TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */
 1189 
 1190                 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
 1191                         /* 4 byte granularity */
 1192                         for (x = lastx, xleft = lastleft;
 1193                              x <= xend && xleft >= 4;
 1194                              x += XINC4, xleft -= XINC4) {
 1195                                 *(uint32_t *)(dst->ri_bits + dstb + y + x) =
 1196                                         *(uint32_t *)(dst->ri_bits + srcb + y + x);
 1197                         }
 1198                 }
 1199         }
 1200         else {    /* above move to the left, below move to the right */
 1201 
 1202                 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
 1203 
 1204                         /* 4*64 byte chunks */
 1205                         for (xleft = wb, x = xstart;
 1206                              x >= xend && xleft >= 4*64;
 1207                              x -= XINC256, xleft -= XINC256) {
 1208 
 1209                                 /* XXX XXX Eight writes to different addresses should fill 
 1210                                  * XXX XXX up the write buffers on 21064 and 21164 chips,
 1211                                  * XXX XXX but later CPUs might have larger write buffers which
 1212                                  * XXX XXX require further unrolling of this loop, or the
 1213                                  * XXX XXX insertion of memory barriers.
 1214                                  */
 1215                                 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 3 * 64);
 1216                                 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 3 * 64);
 1217                                 TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 2 * 64);
 1218                                 TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 2 * 64);
 1219                                 TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 1 * 64);
 1220                                 TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 1 * 64);
 1221                                 TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 0 * 64);
 1222                                 TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 0 * 64);
 1223                         }
 1224 
 1225                         if (xleft) x += XINC256 - XINC64;
 1226 
 1227                         /* 64 byte chunks */
 1228                         for ( ; x >= xend && xleft >= 64;
 1229                               x -= XINC64, xleft -= XINC64) {
 1230                                 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
 1231                                 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
 1232                         }
 1233                         if (xleft) x += XINC64 - XINC4;
 1234                         lastx = x; lastleft = xleft;  /* remember for CPU loop */
 1235                 }
 1236                 TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */
 1237                 TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */
 1238 
 1239                 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
 1240                         /* 4 byte granularity */
 1241                         for (x = lastx, xleft = lastleft;
 1242                              x >= xend && xleft >= 4;
 1243                              x -= XINC4, xleft -= XINC4) {
 1244                                 *(uint32_t *)(dst->ri_bits + dstb + y + x) =
 1245                                         *(uint32_t *)(dst->ri_bits + srcb + y + x);
 1246                         }
 1247                 }
 1248         }
 1249         return 0;
 1250 }
 1251 
 1252 
 1253 void
 1254 tga_putchar(c, row, col, uc, attr)
 1255         void *c;
 1256         int row, col;
 1257         u_int uc;
 1258         long attr;
 1259 {
 1260         struct rasops_info *ri = c;
 1261         struct tga_devconfig *dc = ri->ri_hw;
 1262         int fs, height, width;
 1263         int fg, bg, ul;
 1264         u_char *fr;
 1265         int32_t *rp;
 1266 
 1267         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
 1268 
 1269         height = ri->ri_font->fontheight;
 1270         width = ri->ri_font->fontwidth;
 1271 
 1272         uc -= ri->ri_font->firstchar;
 1273         fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
 1274         fs = ri->ri_font->stride;
 1275 
 1276         /* Set foreground and background color. XXX memoize this somehow?
 1277          * The rasops code has already expanded the color entry to 32 bits
 1278          * for us, even for 8-bit displays, so we don't have to do anything.
 1279          */
 1280         ri->ri_ops.unpack_attr(c, attr, &fg, &bg, &ul);
 1281         TGAWREG(dc, TGA_REG_GFGR, ri->ri_devcmap[fg]);
 1282         TGAWREG(dc, TGA_REG_GBGR, ri->ri_devcmap[bg]);
 1283         
 1284         /* Set raster operation to "copy"... */
 1285         if (ri->ri_depth == 8)
 1286                 TGAWREG(dc, TGA_REG_GOPR, 0x3);
 1287         else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
 1288                 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
 1289 
 1290         /* Set which pixels we're drawing (of a possible 32). */
 1291         TGAWREG(dc, TGA_REG_GPXR_P, (1 << width) - 1);
 1292 
 1293         /* Set drawing mode to opaque stipple. */
 1294         TGAWREG(dc, TGA_REG_GMOR, 0x1);
 1295         
 1296         /* Insert write barrier before actually sending data */
 1297         /* XXX Abuses the fact that there is only one write barrier on Alphas */
 1298         TGAREGWB(dc, TGA_REG_GMOR, 1);
 1299 
 1300         while (height--) {
 1301                 /* The actual stipple write */
 1302                 *rp = fr[0] | (fr[1] << 8) | (fr[2] << 16) | (fr[3] << 24); 
 1303                                                   
 1304                 fr += fs;
 1305                 rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
 1306         }
 1307 
 1308         /* Do underline */
 1309         if (ul) {
 1310                 rp = (int32_t *)((caddr_t)rp - (ri->ri_stride << 1));
 1311                 *rp = 0xffffffff;
 1312         }
 1313 
 1314         /* Set grapics mode back to normal. */
 1315         TGAWREG(dc, TGA_REG_GMOR, 0);
 1316         TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff);
 1317 }
 1318 
 1319 void
 1320 tga_eraserows(c, row, num, attr)
 1321         void *c;
 1322         int row, num;
 1323         long attr;
 1324 {
 1325         struct rasops_info *ri = c;
 1326         struct tga_devconfig *dc = ri->ri_hw;
 1327         int32_t color, lines, pixels;
 1328         int fg, bg;
 1329         int32_t *rp;
 1330 
 1331         ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL);
 1332         color = ri->ri_devcmap[bg];
 1333         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale);
 1334         lines = num * ri->ri_font->fontheight;
 1335         pixels = ri->ri_emuwidth - 1;
 1336 
 1337         /* Set fill color in block-color registers */
 1338         TGAWREG(dc, TGA_REG_GBCR0, color);
 1339         TGAWREG(dc, TGA_REG_GBCR1, color);
 1340         if (ri->ri_depth != 8) {
 1341                 TGAWREG(dc, TGA_REG_GBCR2, color);
 1342                 TGAWREG(dc, TGA_REG_GBCR3, color);
 1343                 TGAWREG(dc, TGA_REG_GBCR4, color);
 1344                 TGAWREG(dc, TGA_REG_GBCR5, color);
 1345                 TGAWREG(dc, TGA_REG_GBCR6, color);
 1346                 TGAWREG(dc, TGA_REG_GBCR7, color);
 1347         }
 1348 
 1349         /* Set raster operation to "copy"... */
 1350         if (ri->ri_depth == 8)
 1351                 TGAWREG(dc, TGA_REG_GOPR, 0x3);
 1352         else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
 1353                 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
 1354 
 1355         /* Set which pixels we're drawing (of a possible 32). */
 1356         TGAWREG(dc, TGA_REG_GDAR, 0xffffffff);
 1357 
 1358         /* Set drawing mode to block fill. */
 1359         TGAWREG(dc, TGA_REG_GMOR, 0x2d);
 1360         
 1361         /* Insert write barrier before actually sending data */
 1362         /* XXX Abuses the fact that there is only one write barrier on Alphas */
 1363         TGAREGWB(dc, TGA_REG_GMOR, 1);
 1364 
 1365         while (lines--) {
 1366                 *rp = pixels;
 1367                 rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
 1368         }
 1369 
 1370         /* Set grapics mode back to normal. */
 1371         TGAWREG(dc, TGA_REG_GMOR, 0);
 1372         
 1373 }
 1374 
 1375 void
 1376 tga_erasecols (c, row, col, num, attr)
 1377         void *c;
 1378         int row, col, num;
 1379         long attr;
 1380 {
 1381         struct rasops_info *ri = c;
 1382         struct tga_devconfig *dc = ri->ri_hw;
 1383         int32_t color, lines, pixels;
 1384         int fg, bg;
 1385         int32_t *rp;
 1386 
 1387         ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL);
 1388         color = ri->ri_devcmap[bg];
 1389         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
 1390         lines = ri->ri_font->fontheight;
 1391         pixels = (num * ri->ri_font->fontwidth) - 1;
 1392 
 1393         /* Set fill color in block-color registers */
 1394         TGAWREG(dc, TGA_REG_GBCR0, color);
 1395         TGAWREG(dc, TGA_REG_GBCR1, color);
 1396         if (ri->ri_depth != 8) {
 1397                 TGAWREG(dc, TGA_REG_GBCR2, color);
 1398                 TGAWREG(dc, TGA_REG_GBCR3, color);
 1399                 TGAWREG(dc, TGA_REG_GBCR4, color);
 1400                 TGAWREG(dc, TGA_REG_GBCR5, color);
 1401                 TGAWREG(dc, TGA_REG_GBCR6, color);
 1402                 TGAWREG(dc, TGA_REG_GBCR7, color);
 1403         }
 1404 
 1405         /* Set raster operation to "copy"... */
 1406         if (ri->ri_depth == 8)
 1407                 TGAWREG(dc, TGA_REG_GOPR, 0x3);
 1408         else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
 1409                 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
 1410 
 1411         /* Set which pixels we're drawing (of a possible 32). */
 1412         TGAWREG(dc, TGA_REG_GDAR, 0xffffffff);
 1413 
 1414         /* Set drawing mode to block fill. */
 1415         TGAWREG(dc, TGA_REG_GMOR, 0x2d);
 1416         
 1417         /* Insert write barrier before actually sending data */
 1418         /* XXX Abuses the fact that there is only one write barrier on Alphas */
 1419         TGAREGWB(dc, TGA_REG_GMOR, 1);
 1420 
 1421         while (lines--) {
 1422                 *rp = pixels;
 1423                 rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
 1424         }
 1425 
 1426         /* Set grapics mode back to normal. */
 1427         TGAWREG(dc, TGA_REG_GMOR, 0);
 1428 }
 1429 
 1430 
 1431 void
 1432 tga_ramdac_wr(v, btreg, val)
 1433         void *v;
 1434         u_int btreg;
 1435         u_int8_t val;
 1436 {
 1437         struct tga_devconfig *dc = v;
 1438 
 1439         if (btreg > BT485_REG_MAX)
 1440                 panic("tga_ramdac_wr: reg %d out of range", btreg);
 1441 
 1442         TGAWREG(dc, TGA_REG_EPDR, (btreg << 9) | (0 << 8 ) | val); /* XXX */
 1443         TGAREGWB(dc, TGA_REG_EPDR, 1);
 1444 }
 1445 
 1446 void
 1447 tga2_ramdac_wr(v, btreg, val)
 1448         void *v;
 1449         u_int btreg;
 1450         u_int8_t val;
 1451 {
 1452         struct tga_devconfig *dc = v;
 1453         bus_space_handle_t ramdac;
 1454 
 1455         if (btreg > BT485_REG_MAX)
 1456                 panic("tga_ramdac_wr: reg %d out of range", btreg);
 1457 
 1458         bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC + 
 1459                 (0xe << 12) + (btreg << 8), 4, &ramdac);
 1460         bus_space_write_4(dc->dc_memt, ramdac, 0, val & 0xff);
 1461         bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE);
 1462 }
 1463 
 1464 u_int8_t
 1465 tga_bt463_rd(v, btreg)
 1466         void *v;
 1467         u_int btreg;
 1468 {
 1469         struct tga_devconfig *dc = v;
 1470         tga_reg_t rdval;
 1471 
 1472         /* 
 1473          * Strobe CE# (high->low->high) since status and data are latched on 
 1474          * the falling and rising edges (repsectively) of this active-low signal.
 1475          */
 1476         
 1477         TGAREGWB(dc, TGA_REG_EPSR, 1);
 1478         TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
 1479         TGAREGWB(dc, TGA_REG_EPSR, 1);
 1480         TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 0);
 1481 
 1482         TGAREGRB(dc, TGA_REG_EPSR, 1);
 1483 
 1484         rdval = TGARREG(dc, TGA_REG_EPDR);
 1485         TGAREGWB(dc, TGA_REG_EPSR, 1);
 1486         TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
 1487 
 1488         return (rdval >> 16) & 0xff;
 1489 }
 1490 
 1491 void
 1492 tga_bt463_wr(v, btreg, val)
 1493         void *v;
 1494         u_int btreg;
 1495         u_int8_t val;
 1496 {
 1497         struct tga_devconfig *dc = v;
 1498 
 1499         /* 
 1500          * In spite of the 21030 documentation, to set the MPU bus bits for
 1501          * a write, you set them in the upper bits of EPDR, not EPSR.
 1502          */
 1503         
 1504         /* 
 1505          * Strobe CE# (high->low->high) since status and data are latched on
 1506          * the falling and rising edges of this active-low signal.
 1507          */
 1508 
 1509         TGAREGWB(dc, TGA_REG_EPDR, 1);
 1510         TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
 1511         TGAREGWB(dc, TGA_REG_EPDR, 1);
 1512         TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x000 | val);
 1513         TGAREGWB(dc, TGA_REG_EPDR, 1);
 1514         TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
 1515 
 1516 }
 1517 
 1518 u_int8_t
 1519 tga_ramdac_rd(v, btreg)
 1520         void *v;
 1521         u_int btreg;
 1522 {
 1523         struct tga_devconfig *dc = v;
 1524         tga_reg_t rdval;
 1525 
 1526         if (btreg > BT485_REG_MAX)
 1527                 panic("tga_ramdac_rd: reg %d out of range", btreg);
 1528 
 1529         TGAWREG(dc, TGA_REG_EPSR, (btreg << 1) | 0x1); /* XXX */
 1530         TGAREGWB(dc, TGA_REG_EPSR, 1);
 1531 
 1532         rdval = TGARREG(dc, TGA_REG_EPDR);
 1533         return (rdval >> 16) & 0xff;                            /* XXX */
 1534 }
 1535 
 1536 u_int8_t
 1537 tga2_ramdac_rd(v, btreg)
 1538         void *v;
 1539         u_int btreg;
 1540 {
 1541         struct tga_devconfig *dc = v;
 1542         bus_space_handle_t ramdac;
 1543         u_int8_t retval;
 1544 
 1545         if (btreg > BT485_REG_MAX)
 1546                 panic("tga_ramdac_rd: reg %d out of range", btreg);
 1547 
 1548         bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC + 
 1549                 (0xe << 12) + (btreg << 8), 4, &ramdac);
 1550         retval = bus_space_read_4(dc->dc_memt, ramdac, 0) & 0xff;
 1551         bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_READ);
 1552         return retval;
 1553 }
 1554 
 1555 #include <dev/ic/decmonitors.c>
 1556 void tga2_ics9110_wr(
 1557         struct tga_devconfig *dc,
 1558         int dotclock
 1559 );
 1560 
 1561 struct monitor *tga_getmonitor(struct tga_devconfig *dc);
 1562 
 1563 void
 1564 tga2_init(dc)
 1565         struct tga_devconfig *dc;
 1566 {
 1567         struct  monitor *m = tga_getmonitor(dc);
 1568 
 1569 
 1570         /* Deal with the dot clocks.
 1571          */
 1572         if (dc->dc_tga_type == TGA_TYPE_POWERSTORM_4D20) {
 1573                 /* Set this up as a reference clock for the
 1574                  * ibm561's PLL.
 1575                  */
 1576                 tga2_ics9110_wr(dc, 14300000);
 1577                 /* XXX Can't set up the dotclock properly, until such time
 1578                  * as the RAMDAC is configured.
 1579                  */
 1580         } else {
 1581                 /* otherwise the ics9110 is our clock. */
 1582                 tga2_ics9110_wr(dc, m->dotclock);
 1583         }
 1584 #if 0
 1585         TGAWREG(dc, TGA_REG_VHCR, 
 1586              ((m->hbp / 4) << 21) |
 1587              ((m->hsync / 4) << 14) |
 1588             (((m->hfp - 4) / 4) << 9) |
 1589              ((m->cols + 4) / 4));
 1590 #else
 1591         TGAWREG(dc, TGA_REG_VHCR, 
 1592              ((m->hbp / 4) << 21) |
 1593              ((m->hsync / 4) << 14) |
 1594             (((m->hfp) / 4) << 9) |
 1595              ((m->cols) / 4));
 1596 #endif
 1597         TGAWREG(dc, TGA_REG_VVCR, 
 1598             (m->vbp << 22) |
 1599             (m->vsync << 16) |
 1600             (m->vfp << 11) |
 1601             (m->rows));
 1602         TGAWREG(dc, TGA_REG_VVBR, 1);
 1603         TGAREGRWB(dc, TGA_REG_VHCR, 3);
 1604         TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 1);
 1605         TGAREGRWB(dc, TGA_REG_VVVR, 1);
 1606         TGAWREG(dc, TGA_REG_GPMR, 0xffffffff);
 1607         TGAREGRWB(dc, TGA_REG_GPMR, 1);
 1608 }
 1609 
 1610 void
 1611 tga2_ics9110_wr(dc, dotclock)
 1612         struct tga_devconfig *dc;
 1613         int dotclock;
 1614 {
 1615         bus_space_handle_t clock;
 1616         u_int32_t valU;
 1617         int N, M, R, V, X;
 1618         int i;
 1619 
 1620         switch (dotclock) {
 1621         case 130808000:
 1622                 N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break;
 1623         case 119840000:
 1624                 N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break;
 1625         case 108180000:
 1626                 N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break;
 1627         case 103994000:
 1628                 N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break;
 1629         case 175000000:
 1630                 N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break;
 1631         case  75000000:
 1632                 N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break;
 1633         case  74000000:
 1634                 N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break;
 1635         case  69000000:
 1636                 N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break;
 1637         case  65000000:
 1638                 N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break;
 1639         case  50000000:
 1640                 N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break;
 1641         case  40000000:
 1642                 N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break;
 1643         case  31500000:
 1644                 N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break;
 1645         case  25175000:
 1646                 N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break;
 1647         case 135000000:
 1648                 N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break;
 1649         case 110000000:
 1650                 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
 1651         case 202500000:
 1652                 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
 1653        case  14300000:         /* this one is just a ref clock */
 1654                N = 0x03; M = 0x03; V = 0x1; X = 0x1; R = 0x3; break;
 1655         default:
 1656                 panic("unrecognized clock rate %d", dotclock);
 1657         }
 1658 
 1659         /* XXX -- hard coded, bad */
 1660         valU  = N | ( M << 7 ) | (V << 14);
 1661         valU |= (X << 15) | (R << 17);
 1662         valU |= 0x17 << 19;
 1663 
 1664         bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV +
 1665             TGA2_MEM_CLOCK + (0xe << 12), 4, &clock); /* XXX */
 1666 
 1667         for (i = 24; i > 0; i--) {
 1668                 u_int32_t writeval;
 1669                 
 1670                 writeval = valU & 0x1;
 1671                 if (i == 1)  
 1672                         writeval |= 0x2; 
 1673                 valU >>= 1;
 1674                 bus_space_write_4(dc->dc_memt, clock, 0, writeval);
 1675                 bus_space_barrier(dc->dc_memt, clock, 0, 4, BUS_SPACE_BARRIER_WRITE);
 1676         }       
 1677         bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV +
 1678             TGA2_MEM_CLOCK + (0xe << 12) + (0x1 << 11) + (0x1 << 11), 4,
 1679                 &clock); /* XXX */
 1680         bus_space_write_4(dc->dc_memt, clock, 0, 0x0);
 1681         bus_space_barrier(dc->dc_memt, clock, 0, 0, BUS_SPACE_BARRIER_WRITE);
 1682 }
 1683 
 1684 struct monitor *
 1685 tga_getmonitor(dc)
 1686        struct tga_devconfig *dc;
 1687 {
 1688        return &decmonitors[(~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f];
 1689 }
 1690 
 1691 unsigned
 1692 tga_getdotclock(dc)
 1693        struct tga_devconfig *dc;
 1694 {
 1695        return tga_getmonitor(dc)->dotclock;
 1696 }

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