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