Home | History | Annotate | Line # | Download | only in dev
fb.c revision 1.6.4.1
      1  1.6.4.1  thorpej /*	$NetBSD: fb.c,v 1.6.4.1 2002/01/10 19:49:45 thorpej Exp $ */
      2      1.1      gwr 
      3      1.1      gwr /*
      4      1.1      gwr  * Copyright (c) 1992, 1993
      5      1.1      gwr  *	The Regents of the University of California.  All rights reserved.
      6      1.1      gwr  *
      7      1.1      gwr  * This software was developed by the Computer Systems Engineering group
      8      1.1      gwr  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
      9      1.1      gwr  * contributed to Berkeley.
     10      1.1      gwr  *
     11      1.1      gwr  * All advertising materials mentioning features or use of this software
     12      1.1      gwr  * must display the following acknowledgement:
     13      1.1      gwr  *	This product includes software developed by the University of
     14      1.1      gwr  *	California, Lawrence Berkeley Laboratory.
     15      1.1      gwr  *
     16      1.1      gwr  * Redistribution and use in source and binary forms, with or without
     17      1.1      gwr  * modification, are permitted provided that the following conditions
     18      1.1      gwr  * are met:
     19      1.1      gwr  * 1. Redistributions of source code must retain the above copyright
     20      1.1      gwr  *    notice, this list of conditions and the following disclaimer.
     21      1.1      gwr  * 2. Redistributions in binary form must reproduce the above copyright
     22      1.1      gwr  *    notice, this list of conditions and the following disclaimer in the
     23      1.1      gwr  *    documentation and/or other materials provided with the distribution.
     24      1.1      gwr  * 3. All advertising materials mentioning features or use of this software
     25      1.1      gwr  *    must display the following acknowledgement:
     26      1.1      gwr  *	This product includes software developed by the University of
     27      1.1      gwr  *	California, Berkeley and its contributors.
     28      1.1      gwr  * 4. Neither the name of the University nor the names of its contributors
     29      1.1      gwr  *    may be used to endorse or promote products derived from this software
     30      1.1      gwr  *    without specific prior written permission.
     31      1.1      gwr  *
     32      1.1      gwr  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     33      1.1      gwr  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     34      1.1      gwr  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     35      1.1      gwr  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     36      1.1      gwr  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37      1.1      gwr  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38      1.1      gwr  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39      1.1      gwr  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     40      1.1      gwr  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     41      1.1      gwr  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     42      1.1      gwr  * SUCH DAMAGE.
     43      1.1      gwr  *
     44      1.1      gwr  *	@(#)fb.c	8.1 (Berkeley) 6/11/93
     45      1.1      gwr  */
     46      1.1      gwr 
     47      1.1      gwr /*
     48      1.1      gwr  * /dev/fb (indirect frame buffer driver).
     49      1.1      gwr  */
     50      1.1      gwr 
     51      1.1      gwr #include <sys/param.h>
     52      1.4      gwr #include <sys/systm.h>
     53      1.1      gwr #include <sys/conf.h>
     54      1.1      gwr #include <sys/device.h>
     55      1.1      gwr #include <sys/ioctl.h>
     56      1.1      gwr #include <sys/proc.h>
     57      1.1      gwr 
     58      1.5      gwr #include <machine/eeprom.h>
     59  1.6.4.1  thorpej #include <dev/sun/fbio.h>
     60      1.1      gwr 
     61      1.5      gwr #include <sun3/dev/fbvar.h>
     62      1.5      gwr #include <sun3/dev/p4reg.h>
     63      1.1      gwr 
     64      1.4      gwr cdev_decl(fb);
     65      1.4      gwr 
     66      1.1      gwr static struct fbdevice *devfb;
     67      1.2      gwr static int fbpriority;
     68      1.1      gwr 
     69      1.1      gwr /*
     70      1.1      gwr  * This is called by the real driver (i.e. bw2, cg3, ...)
     71      1.2      gwr  * to declare itself as a potential default frame buffer.
     72      1.1      gwr  */
     73      1.1      gwr void
     74      1.2      gwr fb_attach(fb, newpri)
     75      1.1      gwr 	struct fbdevice *fb;
     76      1.2      gwr 	int newpri;
     77      1.1      gwr {
     78      1.2      gwr 	if (fbpriority < newpri) {
     79      1.2      gwr 		fbpriority = newpri;
     80      1.2      gwr 		devfb = fb;
     81      1.2      gwr 	}
     82      1.1      gwr }
     83      1.1      gwr 
     84      1.1      gwr int
     85      1.1      gwr fbopen(dev, flags, mode, p)
     86      1.1      gwr 	dev_t dev;
     87      1.1      gwr 	int flags, mode;
     88      1.1      gwr 	struct proc *p;
     89      1.1      gwr {
     90      1.1      gwr 
     91      1.1      gwr 	if (devfb == NULL)
     92      1.1      gwr 		return (ENXIO);
     93      1.1      gwr 	return ((*devfb->fb_driver->fbd_open)(dev, flags, mode, p));
     94      1.1      gwr }
     95      1.1      gwr 
     96      1.1      gwr int
     97      1.1      gwr fbclose(dev, flags, mode, p)
     98      1.1      gwr 	dev_t dev;
     99      1.1      gwr 	int flags, mode;
    100      1.1      gwr 	struct proc *p;
    101      1.1      gwr {
    102      1.1      gwr 
    103      1.1      gwr 	return ((*devfb->fb_driver->fbd_close)(dev, flags, mode, p));
    104      1.1      gwr }
    105      1.1      gwr 
    106      1.1      gwr int
    107      1.1      gwr fbioctl(dev, cmd, data, flags, p)
    108      1.1      gwr 	dev_t dev;
    109      1.1      gwr 	u_long cmd;
    110      1.1      gwr 	caddr_t data;
    111      1.1      gwr 	int flags;
    112      1.1      gwr 	struct proc *p;
    113      1.1      gwr {
    114      1.1      gwr 	return (fbioctlfb(devfb, cmd, data));
    115      1.1      gwr }
    116      1.1      gwr 
    117      1.6   simonb paddr_t
    118      1.3  mycroft fbmmap(dev, off, prot)
    119      1.1      gwr 	dev_t dev;
    120      1.6   simonb 	off_t off;
    121      1.6   simonb 	int prot;
    122      1.1      gwr {
    123      1.1      gwr 	return ((*devfb->fb_driver->fbd_mmap)(dev, off, prot));
    124      1.1      gwr }
    125      1.1      gwr 
    126      1.1      gwr /*
    127      1.1      gwr  * Common fb ioctl function
    128      1.1      gwr  */
    129      1.1      gwr int
    130      1.1      gwr fbioctlfb(fb, cmd, data)
    131      1.1      gwr 	struct fbdevice *fb;
    132      1.1      gwr 	u_long cmd;
    133      1.1      gwr 	caddr_t data;
    134      1.1      gwr {
    135      1.1      gwr 	struct fbdriver *fbd = fb->fb_driver;
    136      1.4      gwr 	void *vp = (void *)data;
    137      1.1      gwr 	int error;
    138      1.1      gwr 
    139      1.1      gwr 	switch (cmd) {
    140      1.1      gwr 
    141      1.1      gwr 	case FBIOGTYPE:
    142      1.4      gwr 		*(struct fbtype *)vp = fb->fb_fbtype;
    143      1.1      gwr 		error = 0;
    144      1.1      gwr 		break;
    145      1.1      gwr 
    146      1.1      gwr 	case FBIOGATTR:
    147      1.4      gwr 		error = (*fbd->fbd_gattr)(fb, vp);
    148      1.1      gwr 		break;
    149      1.1      gwr 
    150      1.1      gwr 	case FBIOGVIDEO:
    151      1.4      gwr 		error = (*fbd->fbd_gvideo)(fb, vp);
    152      1.1      gwr 		break;
    153      1.1      gwr 
    154      1.1      gwr 	case FBIOSVIDEO:
    155      1.4      gwr 		error = (*fbd->fbd_svideo)(fb, vp);
    156      1.1      gwr 		break;
    157      1.1      gwr 
    158      1.1      gwr 	case FBIOGETCMAP:
    159      1.4      gwr 		error = (*fbd->fbd_getcmap)(fb, vp);
    160      1.1      gwr 		break;
    161      1.1      gwr 
    162      1.1      gwr 	case FBIOPUTCMAP:
    163      1.4      gwr 		error = (*fbd->fbd_putcmap)(fb, vp);
    164      1.1      gwr 		break;
    165      1.1      gwr 
    166      1.1      gwr 	default:
    167      1.1      gwr 		error = ENOTTY;
    168      1.1      gwr 	}
    169      1.1      gwr 	return (error);
    170      1.1      gwr }
    171      1.4      gwr 
    172      1.4      gwr void
    173      1.4      gwr fb_unblank()
    174      1.4      gwr {
    175      1.4      gwr 	int on = 1;
    176      1.4      gwr 
    177      1.4      gwr 	if (devfb == NULL)
    178      1.4      gwr 		return;
    179      1.4      gwr 
    180      1.4      gwr 	(*devfb->fb_driver->fbd_svideo)(devfb, (void *)&on);
    181      1.4      gwr }
    182      1.4      gwr 
    183      1.4      gwr /*
    184      1.4      gwr  * Default ioctl function to put in struct fbdriver
    185      1.4      gwr  * for functions that are not supported.
    186      1.4      gwr  */
    187      1.4      gwr int
    188      1.4      gwr fb_noioctl(fbd, vp)
    189      1.4      gwr 	struct fbdevice *fbd;
    190      1.4      gwr 	void *vp;
    191      1.4      gwr {
    192      1.4      gwr 	return ENOTTY;
    193      1.4      gwr }
    194      1.4      gwr 
    195      1.5      gwr /****************************************************************
    196      1.5      gwr  * Misc. helpers...
    197      1.5      gwr  */
    198      1.5      gwr 
    199      1.5      gwr /* Set FB size based on EEPROM screen shape code. */
    200      1.5      gwr void
    201      1.5      gwr fb_eeprom_setsize(fb)
    202      1.5      gwr 	struct fbdevice *fb;
    203      1.5      gwr {
    204      1.5      gwr 	int szcode;
    205      1.5      gwr 	int w, h;
    206      1.5      gwr 
    207      1.5      gwr 	/* Go get the EEPROM screen size byte. */
    208      1.5      gwr 	szcode = eeprom_copy->eeScreenSize;
    209      1.5      gwr 
    210      1.5      gwr 	w = h = 0;
    211      1.5      gwr 	switch (szcode) {
    212      1.5      gwr 	case EE_SCR_1152X900:
    213      1.5      gwr 		w = 1152;
    214      1.5      gwr 		h = 900;
    215      1.5      gwr 		break;
    216      1.5      gwr 	case EE_SCR_1024X1024:
    217      1.5      gwr 		w = 1024;
    218      1.5      gwr 		h = 1024;
    219      1.5      gwr 		break;
    220      1.5      gwr 	case EE_SCR_1600X1280:
    221      1.5      gwr 		w = 1600;
    222      1.5      gwr 		h = 1280;
    223      1.5      gwr 		break;
    224      1.5      gwr 	case EE_SCR_1440X1440:
    225      1.5      gwr 		w = 1440;
    226      1.5      gwr 		h = 1440;
    227      1.5      gwr 		break;
    228      1.5      gwr 	default:
    229      1.5      gwr 		break;
    230      1.5      gwr 	}
    231      1.5      gwr 
    232      1.5      gwr 	if (w && h) {
    233      1.5      gwr 		fb->fb_fbtype.fb_width  = w;
    234      1.5      gwr 		fb->fb_fbtype.fb_height = h;
    235      1.5      gwr 	} else {
    236      1.5      gwr 		printf("%s: EE size code %d unknown\n",
    237      1.5      gwr 			   fb->fb_name, szcode);
    238      1.5      gwr 	}
    239      1.5      gwr }
    240      1.5      gwr 
    241      1.5      gwr /*
    242      1.5      gwr  * Probe for a P4 register at the passed virtual address.
    243      1.5      gwr  * Returns P4 ID value, or -1 if no P4 register.
    244      1.5      gwr  */
    245      1.5      gwr int
    246      1.5      gwr fb_pfour_id(va)
    247      1.5      gwr 	void *va;
    248      1.5      gwr {
    249      1.5      gwr 	volatile u_int32_t val, save, *pfour = va;
    250      1.5      gwr 
    251      1.5      gwr 	/* Read the P4 register. */
    252      1.5      gwr 	save = *pfour;
    253      1.5      gwr 
    254      1.5      gwr 	/*
    255      1.5      gwr 	 * Try to modify the type code.  If it changes, put the
    256      1.5      gwr 	 * original value back, and tell the caller that the
    257      1.5      gwr 	 * framebuffer does not have a P4 register.
    258      1.5      gwr 	 */
    259      1.5      gwr 	val = save & ~P4_REG_RESET;
    260      1.5      gwr 	*pfour = (val ^ P4_FBTYPE_MASK);
    261      1.5      gwr 	if ((*pfour ^ val) & P4_FBTYPE_MASK) {
    262      1.5      gwr 		*pfour = save;
    263      1.5      gwr 		return (-1);
    264      1.5      gwr 	}
    265      1.5      gwr 
    266      1.5      gwr 	return (P4_ID(val));
    267      1.5      gwr }
    268      1.5      gwr 
    269      1.5      gwr /*
    270      1.5      gwr  * Return the status of the video enable.
    271      1.5      gwr  */
    272      1.5      gwr int
    273      1.5      gwr fb_pfour_get_video(fb)
    274      1.5      gwr 	struct fbdevice *fb;
    275      1.5      gwr {
    276      1.5      gwr 
    277      1.5      gwr 	return ((*fb->fb_pfour & P4_REG_VIDEO) != 0);
    278      1.5      gwr }
    279      1.5      gwr 
    280      1.5      gwr /*
    281      1.5      gwr  * Turn video on or off using the P4 register.
    282      1.5      gwr  */
    283      1.5      gwr void
    284      1.5      gwr fb_pfour_set_video(fb, on)
    285      1.5      gwr 	struct fbdevice *fb;
    286      1.5      gwr 	int on;
    287      1.5      gwr {
    288      1.5      gwr 	int pfour;
    289      1.5      gwr 
    290      1.5      gwr 	pfour = *fb->fb_pfour & ~(P4_REG_INTCLR|P4_REG_VIDEO);
    291      1.5      gwr 	*fb->fb_pfour = pfour | (on ? P4_REG_VIDEO : 0);
    292      1.5      gwr }
    293      1.5      gwr 
    294      1.5      gwr static const struct {
    295      1.5      gwr 	int w, h;
    296      1.5      gwr } fb_p4sizedecode[P4_SIZE_MASK+1] = {
    297      1.5      gwr 	{ 1600, 1280 },
    298      1.5      gwr 	{ 1152,  900 },
    299      1.5      gwr 	{ 1024, 1024 },
    300      1.5      gwr 	{ 1280, 1024 },
    301      1.5      gwr 	{ 1440, 1440 },
    302      1.5      gwr 	{  640,  480 },
    303      1.5      gwr };
    304      1.5      gwr 
    305      1.5      gwr /*
    306      1.5      gwr  * Use the P4 register to determine the screen size.
    307      1.5      gwr  */
    308      1.5      gwr void
    309      1.5      gwr fb_pfour_setsize(fb)
    310      1.5      gwr 	struct fbdevice *fb;
    311      1.5      gwr {
    312      1.5      gwr 	int p4, p4type, p4size;
    313      1.5      gwr 	int h, w;
    314      1.5      gwr 
    315      1.5      gwr 	if (fb->fb_pfour == 0)
    316      1.5      gwr 		return;
    317      1.5      gwr 
    318      1.5      gwr 	p4 = *fb->fb_pfour;
    319      1.5      gwr 	p4type = P4_FBTYPE(p4);
    320      1.5      gwr 
    321      1.5      gwr 	/* These do not encode the screen size. */
    322      1.5      gwr 	if (p4type == P4_ID_COLOR24)
    323      1.5      gwr 		return;
    324      1.5      gwr 	if ((p4type & P4_ID_MASK) == P4_ID_FASTCOLOR)
    325      1.5      gwr 		return;
    326      1.5      gwr 
    327      1.5      gwr 	p4size = p4type & P4_SIZE_MASK;
    328      1.5      gwr 	w = fb_p4sizedecode[p4size].w;
    329      1.5      gwr 	h = fb_p4sizedecode[p4size].h;
    330      1.5      gwr 	if (w && h) {
    331      1.5      gwr 		fb->fb_fbtype.fb_width  = w;
    332      1.5      gwr 		fb->fb_fbtype.fb_height = h;
    333      1.5      gwr 	} else {
    334      1.5      gwr 		printf("%s: P4 size code %d unknown\n",
    335      1.5      gwr 			   fb->fb_name, p4size);
    336      1.5      gwr 	}
    337      1.5      gwr }
    338