The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sun/fb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: fb.c,v 1.19 2004/03/19 16:05:25 pk Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1992, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * This software was developed by the Computer Systems Engineering group
    8  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
    9  * contributed to Berkeley.
   10  *
   11  * All advertising materials mentioning features or use of this software
   12  * must display the following acknowledgement:
   13  *      This product includes software developed by the University of
   14  *      California, Lawrence Berkeley Laboratory.
   15  *
   16  * Redistribution and use in source and binary forms, with or without
   17  * modification, are permitted provided that the following conditions
   18  * are met:
   19  * 1. Redistributions of source code must retain the above copyright
   20  *    notice, this list of conditions and the following disclaimer.
   21  * 2. Redistributions in binary form must reproduce the above copyright
   22  *    notice, this list of conditions and the following disclaimer in the
   23  *    documentation and/or other materials provided with the distribution.
   24  * 3. Neither the name of the University nor the names of its contributors
   25  *    may be used to endorse or promote products derived from this software
   26  *    without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   38  * SUCH DAMAGE.
   39  *
   40  *      @(#)fb.c        8.1 (Berkeley) 6/11/93
   41  */
   42 
   43 /*
   44  * /dev/fb (indirect frame buffer driver).  This is gross; we should
   45  * just build cdevsw[] dynamically.
   46  */
   47 
   48 #include <sys/cdefs.h>
   49 __KERNEL_RCSID(0, "$NetBSD: fb.c,v 1.19 2004/03/19 16:05:25 pk Exp $");
   50 
   51 #include <sys/param.h>
   52 #include <sys/systm.h>
   53 #include <sys/device.h>
   54 #include <sys/proc.h>
   55 #include <sys/conf.h>
   56 
   57 #include <machine/promlib.h>
   58 #include <machine/autoconf.h>
   59 #include <machine/kbd.h>
   60 #include <machine/eeprom.h>
   61 #include <sparc/dev/cons.h>
   62 
   63 #include <dev/sun/fbio.h>
   64 #include <dev/sun/fbvar.h>
   65 
   66 #include "kbd.h"
   67 #include "pfour.h"
   68 
   69 static struct fbdevice *devfb;
   70 
   71 dev_type_open(fbopen);
   72 dev_type_close(fbclose);
   73 dev_type_ioctl(fbioctl);
   74 dev_type_poll(fbpoll);
   75 dev_type_mmap(fbmmap);
   76 dev_type_kqfilter(fbkqfilter);
   77 
   78 const struct cdevsw fb_cdevsw = {
   79         fbopen, fbclose, noread, nowrite, fbioctl,
   80         nostop, notty, fbpoll, fbmmap, fbkqfilter,
   81 };
   82 
   83 void
   84 fb_unblank()
   85 {
   86 
   87         if (devfb)
   88                 (*devfb->fb_driver->fbd_unblank)(devfb->fb_device);
   89 }
   90 
   91 /*
   92  * Helper function for frame buffer devices. Decides whether
   93  * the device can be the console output device according to
   94  * PROM info. The result from this function may not be conclusive
   95  * on machines with old PROMs; in that case, drivers should consult
   96  * other sources of configuration information (e.g. EEPROM entries).
   97  */
   98 int
   99 fb_is_console(node)
  100         int node;
  101 {
  102 #if !defined(SUN4U)
  103         int fbnode;
  104 
  105         switch (prom_version()) {
  106         case PROM_OLDMON:
  107                 /* `node' is not valid; just check for any fb device */
  108                 return (prom_stdout() == PROMDEV_SCREEN);
  109 
  110         case PROM_OBP_V0:
  111                 /*
  112                  * First, check if prom_stdout() represents a frame buffer,
  113                  * then match on the `fb' property on the root node, if any.
  114                  */
  115                 if (prom_stdout() != PROMDEV_SCREEN)
  116                         return (0);
  117 
  118                 fbnode = prom_getpropint(findroot(), "fb", 0);
  119                 return (fbnode == 0 || node == fbnode);
  120 
  121         case PROM_OBP_V2:
  122         case PROM_OBP_V3:
  123         case PROM_OPENFIRM:
  124                 /* Just match the nodes */
  125                 return (node == prom_stdout_node);
  126         }
  127 
  128         return (0);
  129 #else
  130                 return (node == prom_stdout_node);
  131 #endif
  132 }
  133 
  134 void
  135 fb_attach(fb, isconsole)
  136         struct fbdevice *fb;
  137         int isconsole;
  138 {
  139         static int no_replace, seen_force;
  140 
  141         /*
  142          * We've already had a framebuffer forced into /dev/fb.  Don't
  143          * allow any more, even if this is the console.
  144          */
  145         if (seen_force) {
  146                 if (devfb) {    /* sanity */
  147                         printf("%s: /dev/fb already full\n",
  148                                 fb->fb_device->dv_xname);
  149                         return;
  150                 } else
  151                         seen_force = 0;
  152         }
  153 
  154         /*
  155          * Check to see if we're being forced into /dev/fb.
  156          */
  157         if (fb->fb_flags & FB_FORCE) {
  158                 if (devfb)
  159                         printf("%s: forcefully replacing %s\n",
  160                                 fb->fb_device->dv_xname,
  161                                 devfb->fb_device->dv_xname);
  162                 devfb = fb;
  163                 seen_force = no_replace = 1;
  164                 goto attached;
  165         }
  166 
  167         /*
  168          * Check to see if we're the console.  If we are, then replace
  169          * any currently existing framebuffer.
  170          */
  171         if (isconsole) {
  172                 if (devfb)
  173                         printf("%s: replacing %s\n", fb->fb_device->dv_xname,
  174                                 devfb->fb_device->dv_xname);
  175                 devfb = fb;
  176                 no_replace = 1;
  177                 goto attached;
  178         }
  179 
  180         /*
  181          * For the final case, we check to see if we can replace an
  182          * existing framebuffer, if not, say so and return.
  183          */
  184         if (no_replace) {
  185                 if (devfb) {    /* sanity */
  186                         printf("%s: /dev/fb already full\n",
  187                                 fb->fb_device->dv_xname);
  188                         return;
  189                 } else
  190                         no_replace = 0;
  191         }
  192 
  193         if (devfb)
  194                 printf("%s: replacing %s\n", fb->fb_device->dv_xname,
  195                         devfb->fb_device->dv_xname);
  196         devfb = fb;
  197 
  198  attached:
  199         printf("%s: attached to /dev/fb\n", devfb->fb_device->dv_xname);
  200 }
  201 
  202 int
  203 fbopen(dev, flags, mode, p)
  204         dev_t dev;
  205         int flags, mode;
  206         struct proc *p;
  207 {
  208 
  209         if (devfb == NULL)
  210                 return (ENXIO);
  211         return (devfb->fb_driver->fbd_open)(dev, flags, mode, p);
  212 }
  213 
  214 int
  215 fbclose(dev, flags, mode, p)
  216         dev_t dev;
  217         int flags, mode;
  218         struct proc *p;
  219 {
  220 
  221         return (devfb->fb_driver->fbd_close)(dev, flags, mode, p);
  222 }
  223 
  224 int
  225 fbioctl(dev, cmd, data, flags, p)
  226         dev_t dev;
  227         u_long cmd;
  228         caddr_t data;
  229         int flags;
  230         struct proc *p;
  231 {
  232 
  233         return (devfb->fb_driver->fbd_ioctl)(dev, cmd, data, flags, p);
  234 }
  235 
  236 int
  237 fbpoll(dev, events, p)
  238         dev_t dev;
  239         int events;
  240         struct proc *p;
  241 {
  242 
  243         return (devfb->fb_driver->fbd_poll)(dev, events, p);
  244 }
  245 
  246 int
  247 fbkqfilter(dev, kn)
  248         dev_t dev;
  249         struct knote *kn;
  250 {
  251 
  252         return (devfb->fb_driver->fbd_kqfilter)(dev, kn);
  253 }
  254 
  255 paddr_t
  256 fbmmap(dev, off, prot)
  257         dev_t dev;
  258         off_t off;
  259         int prot;
  260 {
  261         paddr_t (*map)__P((dev_t, off_t, int)) = devfb->fb_driver->fbd_mmap;
  262 
  263         if (map == NULL)
  264                 return (-1);
  265         return (map(dev, off, prot));
  266 }
  267 
  268 void
  269 fb_setsize_obp(fb, depth, def_width, def_height, node)
  270         struct fbdevice *fb;
  271         int depth, def_width, def_height, node;
  272 {
  273         fb->fb_type.fb_width = prom_getpropint(node, "width", def_width);
  274         fb->fb_type.fb_height = prom_getpropint(node, "height", def_height);
  275         fb->fb_linebytes = prom_getpropint(node, "linebytes",
  276                                      (fb->fb_type.fb_width * depth) / 8);
  277 }
  278 
  279 void
  280 fb_setsize_eeprom(fb, depth, def_width, def_height)
  281         struct fbdevice *fb;
  282         int depth, def_width, def_height;
  283 {
  284 #if !defined(SUN4U)
  285         struct eeprom *eep = (struct eeprom *)eeprom_va;
  286 
  287         if (!CPU_ISSUN4) {
  288                 printf("fb_setsize_eeprom: not sun4\n");
  289                 return;
  290         }
  291 
  292         /* Set up some defaults. */
  293         fb->fb_type.fb_width = def_width;
  294         fb->fb_type.fb_height = def_height;
  295 
  296         if (fb->fb_flags & FB_PFOUR) {
  297 #if NPFOUR > 0
  298                 fb_setsize_pfour(fb);
  299 #endif
  300         } else if (eep != NULL) {
  301                 switch (eep->eeScreenSize) {
  302                 case EE_SCR_1152X900:
  303                         fb->fb_type.fb_width = 1152;
  304                         fb->fb_type.fb_height = 900;
  305                         break;
  306 
  307                 case EE_SCR_1024X1024:
  308                         fb->fb_type.fb_width = 1024;
  309                         fb->fb_type.fb_height = 1024;
  310                         break;
  311 
  312                 case EE_SCR_1600X1280:
  313                         fb->fb_type.fb_width = 1600;
  314                         fb->fb_type.fb_height = 1280;
  315                         break;
  316 
  317                 case EE_SCR_1440X1440:
  318                         fb->fb_type.fb_width = 1440;
  319                         fb->fb_type.fb_height = 1440;
  320                         break;
  321 
  322                 default:
  323                         /*
  324                          * XXX: Do nothing, I guess.
  325                          * Should we print a warning about
  326                          * an unknown value? --thorpej
  327                          */
  328                         break;
  329                 }
  330         }
  331 
  332         fb->fb_linebytes = (fb->fb_type.fb_width * depth) / 8;
  333 #endif /* !SUN4U */
  334 }
  335 
  336 
  337 
  338 #ifdef RASTERCONSOLE
  339 #include <machine/kbd.h>
  340 
  341 static void fb_bell __P((int));
  342 
  343 static void
  344 fb_bell(on)
  345         int on;
  346 {
  347 #if NKBD > 0
  348         kbd_bell(on);
  349 #endif
  350 }
  351 
  352 void
  353 fbrcons_init(fb)
  354         struct fbdevice *fb;
  355 {
  356         struct rconsole *rc = &fb->fb_rcons;
  357         struct rasops_info *ri = &fb->fb_rinfo;
  358         int maxrow, maxcol;
  359 #if !defined(RASTERCONS_FULLSCREEN)
  360         int *row, *col;
  361 #endif
  362 
  363         /* Set up what rasops needs to know about */
  364         bzero(ri, sizeof *ri);
  365         ri->ri_stride = fb->fb_linebytes;
  366         ri->ri_bits = (caddr_t)fb->fb_pixels;
  367         ri->ri_depth = fb->fb_type.fb_depth;
  368         ri->ri_width = fb->fb_type.fb_width;
  369         ri->ri_height = fb->fb_type.fb_height;
  370         maxrow = 5000;
  371         maxcol = 5000;
  372 
  373 #if !defined(RASTERCONS_FULLSCREEN)
  374 #if !defined(SUN4U)
  375         if (CPU_ISSUN4) {
  376                 struct eeprom *eep = (struct eeprom *)eeprom_va;
  377 
  378                 if (eep == NULL) {
  379                         maxcol = 80;
  380                         maxrow = 34;
  381                 } else {
  382                         maxcol = eep->eeTtyCols;
  383                         maxrow = eep->eeTtyRows;
  384                 }
  385         }
  386 #endif /* !SUN4U */
  387         if (!CPU_ISSUN4) {
  388                 char buf[6+1];  /* Enough for six digits */
  389                 maxcol = (prom_getoption("screen-#columns", buf, sizeof buf) == 0)
  390                         ? strtoul(buf, NULL, 10)
  391                         : 80;
  392 
  393                 maxrow = (prom_getoption("screen-#rows", buf, sizeof buf) != 0)
  394                         ? strtoul(buf, NULL, 10)
  395                         : 34;
  396 
  397         }
  398 #endif /* !RASTERCONS_FULLSCREEN */
  399         /*
  400          * - force monochrome output
  401          * - eraserows() hack to clear the *entire* display
  402          * - cursor is currently enabled
  403          * - center output
  404          */
  405         ri->ri_flg = RI_FULLCLEAR | RI_CURSOR | RI_CENTER;
  406 
  407         /* Get operations set and connect to rcons */
  408         if (rasops_init(ri, maxrow, maxcol))
  409                 panic("fbrcons_init: rasops_init failed!");
  410 
  411         if (ri->ri_depth == 8) {
  412                 int i;
  413                 for (i = 0; i < 16; i++) {
  414 
  415                         /*
  416                          * Cmap entries are repeated four times in the
  417                          * 32 bit wide `devcmap' entries for optimization
  418                          * purposes; see rasops(9)
  419                          */
  420 #define I_TO_DEVCMAP(i) ((i) | ((i)<<8) | ((i)<<16) | ((i)<<24))
  421 
  422                         /*
  423                          * Use existing colormap entries for black and white
  424                          */
  425                         if ((i & 7) == WSCOL_BLACK) {
  426                                 ri->ri_devcmap[i] = I_TO_DEVCMAP(255);
  427                                 continue;
  428                         }
  429 
  430                         if ((i & 7) == WSCOL_WHITE) {
  431                                 ri->ri_devcmap[i] = I_TO_DEVCMAP(0);
  432                                 continue;
  433                         }
  434                         /*
  435                          * Other entries refer to ANSI map, which for now
  436                          * is setup in bt_subr.c
  437                          */
  438                         ri->ri_devcmap[i] = I_TO_DEVCMAP(i + 1);
  439 #undef I_TO_DEVCMAP
  440                 }
  441         }
  442 
  443         rc->rc_row = rc->rc_col = 0;
  444 #if !defined(RASTERCONS_FULLSCREEN)
  445         /* Determine addresses of prom emulator row and column */
  446         if (!CPU_ISSUN4 && !romgetcursoraddr(&row, &col)) {
  447                 rc->rc_row = *row;
  448                 rc->rc_col = *col;
  449         }
  450 #endif
  451         ri->ri_crow = rc->rc_row;
  452         ri->ri_ccol = rc->rc_col;
  453 
  454         rc->rc_ops = &ri->ri_ops;
  455         rc->rc_cookie = ri;
  456         rc->rc_bell = fb_bell;
  457         rc->rc_maxcol = ri->ri_cols;
  458         rc->rc_maxrow = ri->ri_rows;
  459         rc->rc_width = ri->ri_emuwidth;
  460         rc->rc_height = ri->ri_emuheight;
  461         rc->rc_deffgcolor = WSCOL_BLACK;
  462         rc->rc_defbgcolor = WSCOL_WHITE;
  463         rcons_init(rc, 0);
  464 
  465         /* Hook up virtual console */
  466         v_putc = rcons_cnputc;
  467 }
  468 
  469 int
  470 fbrcons_rows()
  471 {
  472         return (devfb ? devfb->fb_rcons.rc_maxrow : 0);
  473 }
  474 
  475 int
  476 fbrcons_cols()
  477 {
  478         return (devfb ? devfb->fb_rcons.rc_maxcol : 0);
  479 }
  480 #endif /* RASTERCONSOLE */

Cache object: 387bebb3834c8697f61c2fbfaba61a6a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.