Home | History | Annotate | Line # | Download | only in dev
fb.c revision 1.6.2.2
      1  1.6.2.2    fvdl /*	$NetBSD: fb.c,v 1.6.2.2 2001/10/10 11:56:38 fvdl 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.6.2.2    fvdl #include <sys/vnode.h>
     58      1.1     gwr 
     59      1.5     gwr #include <machine/eeprom.h>
     60  1.6.2.1    fvdl #include <dev/sun/fbio.h>
     61      1.1     gwr 
     62      1.5     gwr #include <sun3/dev/fbvar.h>
     63      1.5     gwr #include <sun3/dev/p4reg.h>
     64      1.1     gwr 
     65      1.4     gwr cdev_decl(fb);
     66      1.4     gwr 
     67      1.1     gwr static struct fbdevice *devfb;
     68      1.2     gwr static int fbpriority;
     69      1.1     gwr 
     70      1.1     gwr /*
     71      1.1     gwr  * This is called by the real driver (i.e. bw2, cg3, ...)
     72      1.2     gwr  * to declare itself as a potential default frame buffer.
     73      1.1     gwr  */
     74      1.1     gwr void
     75      1.2     gwr fb_attach(fb, newpri)
     76      1.1     gwr 	struct fbdevice *fb;
     77      1.2     gwr 	int newpri;
     78      1.1     gwr {
     79      1.2     gwr 	if (fbpriority < newpri) {
     80      1.2     gwr 		fbpriority = newpri;
     81      1.2     gwr 		devfb = fb;
     82      1.2     gwr 	}
     83      1.1     gwr }
     84      1.1     gwr 
     85      1.1     gwr int
     86  1.6.2.2    fvdl fbopen(devvp, flags, mode, p)
     87  1.6.2.2    fvdl 	struct vnode *devvp;
     88      1.1     gwr 	int flags, mode;
     89      1.1     gwr 	struct proc *p;
     90      1.1     gwr {
     91      1.1     gwr 
     92      1.1     gwr 	if (devfb == NULL)
     93      1.1     gwr 		return (ENXIO);
     94  1.6.2.2    fvdl 	return ((*devfb->fb_driver->fbd_open)(devvp, flags, mode, p));
     95      1.1     gwr }
     96      1.1     gwr 
     97      1.1     gwr int
     98  1.6.2.2    fvdl fbclose(devvp, flags, mode, p)
     99  1.6.2.2    fvdl 	struct vnode *devvp;
    100      1.1     gwr 	int flags, mode;
    101      1.1     gwr 	struct proc *p;
    102      1.1     gwr {
    103      1.1     gwr 
    104  1.6.2.2    fvdl 	return ((*devfb->fb_driver->fbd_close)(devvp, flags, mode, p));
    105      1.1     gwr }
    106      1.1     gwr 
    107      1.1     gwr int
    108  1.6.2.2    fvdl fbioctl(devvp, cmd, data, flags, p)
    109  1.6.2.2    fvdl 	struct vnode *devvp;
    110      1.1     gwr 	u_long cmd;
    111      1.1     gwr 	caddr_t data;
    112      1.1     gwr 	int flags;
    113      1.1     gwr 	struct proc *p;
    114      1.1     gwr {
    115      1.1     gwr 	return (fbioctlfb(devfb, cmd, data));
    116      1.1     gwr }
    117      1.1     gwr 
    118      1.6  simonb paddr_t
    119  1.6.2.2    fvdl fbmmap(devvp, off, prot)
    120  1.6.2.2    fvdl 	struct vnode *devvp;
    121      1.6  simonb 	off_t off;
    122      1.6  simonb 	int prot;
    123      1.1     gwr {
    124  1.6.2.2    fvdl 	return ((*devfb->fb_driver->fbd_mmap)(devvp, off, prot));
    125      1.1     gwr }
    126      1.1     gwr 
    127      1.1     gwr /*
    128      1.1     gwr  * Common fb ioctl function
    129      1.1     gwr  */
    130      1.1     gwr int
    131      1.1     gwr fbioctlfb(fb, cmd, data)
    132      1.1     gwr 	struct fbdevice *fb;
    133      1.1     gwr 	u_long cmd;
    134      1.1     gwr 	caddr_t data;
    135      1.1     gwr {
    136      1.1     gwr 	struct fbdriver *fbd = fb->fb_driver;
    137      1.4     gwr 	void *vp = (void *)data;
    138      1.1     gwr 	int error;
    139      1.1     gwr 
    140      1.1     gwr 	switch (cmd) {
    141      1.1     gwr 
    142      1.1     gwr 	case FBIOGTYPE:
    143      1.4     gwr 		*(struct fbtype *)vp = fb->fb_fbtype;
    144      1.1     gwr 		error = 0;
    145      1.1     gwr 		break;
    146      1.1     gwr 
    147      1.1     gwr 	case FBIOGATTR:
    148      1.4     gwr 		error = (*fbd->fbd_gattr)(fb, vp);
    149      1.1     gwr 		break;
    150      1.1     gwr 
    151      1.1     gwr 	case FBIOGVIDEO:
    152      1.4     gwr 		error = (*fbd->fbd_gvideo)(fb, vp);
    153      1.1     gwr 		break;
    154      1.1     gwr 
    155      1.1     gwr 	case FBIOSVIDEO:
    156      1.4     gwr 		error = (*fbd->fbd_svideo)(fb, vp);
    157      1.1     gwr 		break;
    158      1.1     gwr 
    159      1.1     gwr 	case FBIOGETCMAP:
    160      1.4     gwr 		error = (*fbd->fbd_getcmap)(fb, vp);
    161      1.1     gwr 		break;
    162      1.1     gwr 
    163      1.1     gwr 	case FBIOPUTCMAP:
    164      1.4     gwr 		error = (*fbd->fbd_putcmap)(fb, vp);
    165      1.1     gwr 		break;
    166      1.1     gwr 
    167      1.1     gwr 	default:
    168      1.1     gwr 		error = ENOTTY;
    169      1.1     gwr 	}
    170      1.1     gwr 	return (error);
    171      1.1     gwr }
    172      1.4     gwr 
    173      1.4     gwr void
    174      1.4     gwr fb_unblank()
    175      1.4     gwr {
    176      1.4     gwr 	int on = 1;
    177      1.4     gwr 
    178      1.4     gwr 	if (devfb == NULL)
    179      1.4     gwr 		return;
    180      1.4     gwr 
    181      1.4     gwr 	(*devfb->fb_driver->fbd_svideo)(devfb, (void *)&on);
    182      1.4     gwr }
    183      1.4     gwr 
    184      1.4     gwr /*
    185      1.4     gwr  * Default ioctl function to put in struct fbdriver
    186      1.4     gwr  * for functions that are not supported.
    187      1.4     gwr  */
    188      1.4     gwr int
    189      1.4     gwr fb_noioctl(fbd, vp)
    190      1.4     gwr 	struct fbdevice *fbd;
    191      1.4     gwr 	void *vp;
    192      1.4     gwr {
    193      1.4     gwr 	return ENOTTY;
    194      1.4     gwr }
    195      1.4     gwr 
    196      1.5     gwr /****************************************************************
    197      1.5     gwr  * Misc. helpers...
    198      1.5     gwr  */
    199      1.5     gwr 
    200      1.5     gwr /* Set FB size based on EEPROM screen shape code. */
    201      1.5     gwr void
    202      1.5     gwr fb_eeprom_setsize(fb)
    203      1.5     gwr 	struct fbdevice *fb;
    204      1.5     gwr {
    205      1.5     gwr 	int szcode;
    206      1.5     gwr 	int w, h;
    207      1.5     gwr 
    208      1.5     gwr 	/* Go get the EEPROM screen size byte. */
    209      1.5     gwr 	szcode = eeprom_copy->eeScreenSize;
    210      1.5     gwr 
    211      1.5     gwr 	w = h = 0;
    212      1.5     gwr 	switch (szcode) {
    213      1.5     gwr 	case EE_SCR_1152X900:
    214      1.5     gwr 		w = 1152;
    215      1.5     gwr 		h = 900;
    216      1.5     gwr 		break;
    217      1.5     gwr 	case EE_SCR_1024X1024:
    218      1.5     gwr 		w = 1024;
    219      1.5     gwr 		h = 1024;
    220      1.5     gwr 		break;
    221      1.5     gwr 	case EE_SCR_1600X1280:
    222      1.5     gwr 		w = 1600;
    223      1.5     gwr 		h = 1280;
    224      1.5     gwr 		break;
    225      1.5     gwr 	case EE_SCR_1440X1440:
    226      1.5     gwr 		w = 1440;
    227      1.5     gwr 		h = 1440;
    228      1.5     gwr 		break;
    229      1.5     gwr 	default:
    230      1.5     gwr 		break;
    231      1.5     gwr 	}
    232      1.5     gwr 
    233      1.5     gwr 	if (w && h) {
    234      1.5     gwr 		fb->fb_fbtype.fb_width  = w;
    235      1.5     gwr 		fb->fb_fbtype.fb_height = h;
    236      1.5     gwr 	} else {
    237      1.5     gwr 		printf("%s: EE size code %d unknown\n",
    238      1.5     gwr 			   fb->fb_name, szcode);
    239      1.5     gwr 	}
    240      1.5     gwr }
    241      1.5     gwr 
    242      1.5     gwr /*
    243      1.5     gwr  * Probe for a P4 register at the passed virtual address.
    244      1.5     gwr  * Returns P4 ID value, or -1 if no P4 register.
    245      1.5     gwr  */
    246      1.5     gwr int
    247      1.5     gwr fb_pfour_id(va)
    248      1.5     gwr 	void *va;
    249      1.5     gwr {
    250      1.5     gwr 	volatile u_int32_t val, save, *pfour = va;
    251      1.5     gwr 
    252      1.5     gwr 	/* Read the P4 register. */
    253      1.5     gwr 	save = *pfour;
    254      1.5     gwr 
    255      1.5     gwr 	/*
    256      1.5     gwr 	 * Try to modify the type code.  If it changes, put the
    257      1.5     gwr 	 * original value back, and tell the caller that the
    258      1.5     gwr 	 * framebuffer does not have a P4 register.
    259      1.5     gwr 	 */
    260      1.5     gwr 	val = save & ~P4_REG_RESET;
    261      1.5     gwr 	*pfour = (val ^ P4_FBTYPE_MASK);
    262      1.5     gwr 	if ((*pfour ^ val) & P4_FBTYPE_MASK) {
    263      1.5     gwr 		*pfour = save;
    264      1.5     gwr 		return (-1);
    265      1.5     gwr 	}
    266      1.5     gwr 
    267      1.5     gwr 	return (P4_ID(val));
    268      1.5     gwr }
    269      1.5     gwr 
    270      1.5     gwr /*
    271      1.5     gwr  * Return the status of the video enable.
    272      1.5     gwr  */
    273      1.5     gwr int
    274      1.5     gwr fb_pfour_get_video(fb)
    275      1.5     gwr 	struct fbdevice *fb;
    276      1.5     gwr {
    277      1.5     gwr 
    278      1.5     gwr 	return ((*fb->fb_pfour & P4_REG_VIDEO) != 0);
    279      1.5     gwr }
    280      1.5     gwr 
    281      1.5     gwr /*
    282      1.5     gwr  * Turn video on or off using the P4 register.
    283      1.5     gwr  */
    284      1.5     gwr void
    285      1.5     gwr fb_pfour_set_video(fb, on)
    286      1.5     gwr 	struct fbdevice *fb;
    287      1.5     gwr 	int on;
    288      1.5     gwr {
    289      1.5     gwr 	int pfour;
    290      1.5     gwr 
    291      1.5     gwr 	pfour = *fb->fb_pfour & ~(P4_REG_INTCLR|P4_REG_VIDEO);
    292      1.5     gwr 	*fb->fb_pfour = pfour | (on ? P4_REG_VIDEO : 0);
    293      1.5     gwr }
    294      1.5     gwr 
    295      1.5     gwr static const struct {
    296      1.5     gwr 	int w, h;
    297      1.5     gwr } fb_p4sizedecode[P4_SIZE_MASK+1] = {
    298      1.5     gwr 	{ 1600, 1280 },
    299      1.5     gwr 	{ 1152,  900 },
    300      1.5     gwr 	{ 1024, 1024 },
    301      1.5     gwr 	{ 1280, 1024 },
    302      1.5     gwr 	{ 1440, 1440 },
    303      1.5     gwr 	{  640,  480 },
    304      1.5     gwr };
    305      1.5     gwr 
    306      1.5     gwr /*
    307      1.5     gwr  * Use the P4 register to determine the screen size.
    308      1.5     gwr  */
    309      1.5     gwr void
    310      1.5     gwr fb_pfour_setsize(fb)
    311      1.5     gwr 	struct fbdevice *fb;
    312      1.5     gwr {
    313      1.5     gwr 	int p4, p4type, p4size;
    314      1.5     gwr 	int h, w;
    315      1.5     gwr 
    316      1.5     gwr 	if (fb->fb_pfour == 0)
    317      1.5     gwr 		return;
    318      1.5     gwr 
    319      1.5     gwr 	p4 = *fb->fb_pfour;
    320      1.5     gwr 	p4type = P4_FBTYPE(p4);
    321      1.5     gwr 
    322      1.5     gwr 	/* These do not encode the screen size. */
    323      1.5     gwr 	if (p4type == P4_ID_COLOR24)
    324      1.5     gwr 		return;
    325      1.5     gwr 	if ((p4type & P4_ID_MASK) == P4_ID_FASTCOLOR)
    326      1.5     gwr 		return;
    327      1.5     gwr 
    328      1.5     gwr 	p4size = p4type & P4_SIZE_MASK;
    329      1.5     gwr 	w = fb_p4sizedecode[p4size].w;
    330      1.5     gwr 	h = fb_p4sizedecode[p4size].h;
    331      1.5     gwr 	if (w && h) {
    332      1.5     gwr 		fb->fb_fbtype.fb_width  = w;
    333      1.5     gwr 		fb->fb_fbtype.fb_height = h;
    334      1.5     gwr 	} else {
    335      1.5     gwr 		printf("%s: P4 size code %d unknown\n",
    336      1.5     gwr 			   fb->fb_name, p4size);
    337      1.5     gwr 	}
    338      1.5     gwr }
    339