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