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