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