diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-08-11 05:35:37 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-08-11 05:35:37 +0000 |
commit | e511a52691ddb2290f5d3c9ca6e9f0fc3b320289 (patch) | |
tree | f68510b774a71e2a0879cb013e3abd7a15665abc /sys/arch/sparc/dev/fb.c | |
parent | fc98d7c9a0046f274410f903f952ef6224f68e10 (diff) |
netbsd port, now we merge our changes back in
Diffstat (limited to 'sys/arch/sparc/dev/fb.c')
-rw-r--r-- | sys/arch/sparc/dev/fb.c | 275 |
1 files changed, 231 insertions, 44 deletions
diff --git a/sys/arch/sparc/dev/fb.c b/sys/arch/sparc/dev/fb.c index ade9db9dbe6..836bc7dbdad 100644 --- a/sys/arch/sparc/dev/fb.c +++ b/sys/arch/sparc/dev/fb.c @@ -1,4 +1,4 @@ -/* $NetBSD: fb.c,v 1.11 1995/10/08 01:39:19 pk Exp $ */ +/* $NetBSD: fb.c,v 1.18 1996/04/01 17:29:54 christos Exp $ */ /* * Copyright (c) 1992, 1993 @@ -50,19 +50,24 @@ */ #include <sys/param.h> -#include <sys/conf.h> +#include <sys/systm.h> #include <sys/device.h> #include <sys/proc.h> +#include <sys/conf.h> #include <machine/autoconf.h> #include <machine/fbio.h> +#include <machine/kbd.h> #include <machine/fbvar.h> +#include <machine/conf.h> #if defined(SUN4) #include <machine/eeprom.h> +#include <sparc/dev/pfourreg.h> #endif static struct fbdevice *devfb; + void fb_unblank() { @@ -72,13 +77,71 @@ fb_unblank() } void -fb_attach(fb) +fb_attach(fb, isconsole) struct fbdevice *fb; + int isconsole; { + static int no_replace, seen_force; + + /* + * We've already had a framebuffer forced into /dev/fb. Don't + * allow any more, even if this is the console. + */ + if (seen_force) { + if (devfb) { /* sanity */ + printf("%s: /dev/fb already full\n", + fb->fb_device->dv_xname); + return; + } else + seen_force = 0; + } + + /* + * Check to see if we're being forced into /dev/fb. + */ + if (fb->fb_flags & FB_FORCE) { + if (devfb) + printf("%s: forcefully replacing %s\n", + fb->fb_device->dv_xname, + devfb->fb_device->dv_xname); + devfb = fb; + seen_force = no_replace = 1; + goto attached; + } + + /* + * Check to see if we're the console. If we are, then replace + * any currently existing framebuffer. + */ + if (isconsole) { + if (devfb) + printf("%s: replacing %s\n", fb->fb_device->dv_xname, + devfb->fb_device->dv_xname); + devfb = fb; + no_replace = 1; + goto attached; + } + + /* + * For the final case, we check to see if we can replace an + * existing framebuffer, if not, say so and return. + */ + if (no_replace) { + if (devfb) { /* sanity */ + printf("%s: /dev/fb already full\n", + fb->fb_device->dv_xname); + return; + } else + no_replace = 0; + } if (devfb) - printf("warning: multiple /dev/fb declarers\n"); + printf("%s: replacing %s\n", fb->fb_device->dv_xname, + devfb->fb_device->dv_xname); devfb = fb; + + attached: + printf("%s: attached to /dev/fb\n", devfb->fb_device->dv_xname); } int @@ -138,25 +201,18 @@ fb_setsize(fb, depth, def_width, def_height, node, bustype) * to be correct as defaults go... */ switch (bustype) { - case BUS_PFOUR: - fb->fb_type.fb_width = def_width; - fb->fb_type.fb_height = def_height; - fb->fb_linebytes = (fb->fb_type.fb_width * depth) / 8; - break; case BUS_VME16: case BUS_VME32: case BUS_OBIO: -#if defined(SUN4M) - if (cputyp == CPU_SUN4M) { /* 4m has framebuffer on obio */ - fb->fb_type.fb_width = getpropint(node, "width", - def_width); + if (CPU_ISSUN4M) { /* 4m has framebuffer on obio */ + fb->fb_type.fb_width = getpropint(node, "width", + def_width); fb->fb_type.fb_height = getpropint(node, "height", - def_height); + def_height); fb->fb_linebytes = getpropint(node, "linebytes", (fb->fb_type.fb_width * depth) / 8); break; } -#endif /* Set up some defaults. */ fb->fb_type.fb_width = def_width; fb->fb_type.fb_height = def_height; @@ -165,39 +221,104 @@ fb_setsize(fb, depth, def_width, def_height, node, bustype) * This is not particularly useful on Sun 4 VME framebuffers. * The EEPROM only contains info about the built-in. */ - if (cputyp == CPU_SUN4 && (bustype == BUS_VME16 || + if (CPU_ISSUN4 && (bustype == BUS_VME16 || bustype == BUS_VME32)) goto donesize; #if defined(SUN4) - if (cputyp==CPU_SUN4) { + if (CPU_ISSUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; - if (eep != NULL) { - switch (eep->ee_diag.eed_scrsize) { - case EED_SCR_1152X900: + + if (fb->fb_flags & FB_PFOUR) { + volatile u_int32_t pfour; + + /* + * Some pfour framebuffers, e.g. the + * cgsix, don't encode resolution the + * same, so the driver handles that. + * The driver can let us know that it + * needs to do this by not mapping in + * the pfour register by the time this + * routine is called. + */ + if (fb->fb_pfour == NULL) + goto donesize; + + pfour = *fb->fb_pfour; + + /* + * Use the pfour register to determine + * the size. Note that the cgsix and + * cgeight don't use this size encoding. + * In this case, we have to settle + * for the defaults we were provided + * with. + */ + if ((PFOUR_ID(pfour) == PFOUR_ID_COLOR24) || + (PFOUR_ID(pfour) == PFOUR_ID_FASTCOLOR)) + goto donesize; + + switch (PFOUR_SIZE(pfour)) { + case PFOUR_SIZE_1152X900: fb->fb_type.fb_width = 1152; fb->fb_type.fb_height = 900; break; - case EED_SCR_1024X1024: + + case PFOUR_SIZE_1024X1024: fb->fb_type.fb_width = 1024; fb->fb_type.fb_height = 1024; break; - case EED_SCR_1600X1280: + + case PFOUR_SIZE_1280X1024: + fb->fb_type.fb_width = 1280; + fb->fb_type.fb_height = 1024; + break; + + case PFOUR_SIZE_1600X1280: fb->fb_type.fb_width = 1600; fb->fb_type.fb_height = 1280; break; - case EED_SCR_1440X1440: + + case PFOUR_SIZE_1440X1440: fb->fb_type.fb_width = 1440; fb->fb_type.fb_height = 1440; break; - case EED_SCR_640X480: + + case PFOUR_SIZE_640X480: fb->fb_type.fb_width = 640; fb->fb_type.fb_height = 480; break; - case EED_SCR_1280X1024: - fb->fb_type.fb_width = 1280; + + default: + /* + * XXX: Do nothing, I guess. + * Should we print a warning about + * an unknown value? --thorpej + */ + break; + } + } else if (eep != NULL) { + switch (eep->eeScreenSize) { + case EE_SCR_1152X900: + fb->fb_type.fb_width = 1152; + fb->fb_type.fb_height = 900; + break; + + case EE_SCR_1024X1024: + fb->fb_type.fb_width = 1024; fb->fb_type.fb_height = 1024; break; + + case EE_SCR_1600X1280: + fb->fb_type.fb_width = 1600; + fb->fb_type.fb_height = 1280; + break; + + case EE_SCR_1440X1440: + fb->fb_type.fb_width = 1440; + fb->fb_type.fb_height = 1440; + break; + default: /* * XXX: Do nothing, I guess. @@ -210,20 +331,22 @@ fb_setsize(fb, depth, def_width, def_height, node, bustype) } #endif /* SUN4 */ #if defined(SUN4M) - if (cputyp==CPU_SUN4M) { + if (CPU_ISSUN4M) { /* XXX: need code to find 4/600 vme screen size */ } #endif /* SUN4M */ -donesize: + donesize: fb->fb_linebytes = (fb->fb_type.fb_width * depth) / 8; break; + case BUS_SBUS: - fb->fb_type.fb_width = getpropint(node, "width", 1152); - fb->fb_type.fb_height = getpropint(node, "height", 900); + fb->fb_type.fb_width = getpropint(node, "width", def_width); + fb->fb_type.fb_height = getpropint(node, "height", def_height); fb->fb_linebytes = getpropint(node, "linebytes", (fb->fb_type.fb_width * depth) / 8); break; + default: panic("fb_setsize: inappropriate bustype"); /* NOTREACHED */ @@ -233,7 +356,8 @@ donesize: #ifdef RASTERCONSOLE #include <machine/kbd.h> -extern int (*v_putc) __P((int)); +static int a2int __P((char *, int)); +static void fb_bell __P((int)); static int a2int(cp, deflt) @@ -278,40 +402,103 @@ fbrcons_init(fb) #if defined(RASTERCONS_FULLSCREEN) || defined(RASTERCONS_SMALLFONT) rc->rc_maxcol = rc->rc_width / rc->rc_font->width; - rc->rc_maxrow = rc->rc_height / rc->rc_font->height; + rc->rc_maxrow = rc->rc_height / rc->rc_font->height; #else #if defined(SUN4) - if (cputyp == CPU_SUN4) { + if (CPU_ISSUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; if (eep == NULL) { rc->rc_maxcol = 80; rc->rc_maxrow = 34; } else { - rc->rc_maxcol = eep->ee_diag.eed_colsize; - rc->rc_maxrow = eep->ee_diag.eed_rowsize; + rc->rc_maxcol = eep->eeTtyCols; + rc->rc_maxrow = eep->eeTtyRows; } } #endif /* SUN4 */ -#if defined(SUN4C) || defined(SUN4M) - if (cputyp != CPU_SUN4) { - rc->rc_maxcol = a2int(getpropstring(optionsnode, - "screen-#columns"), 80); - rc->rc_maxrow = a2int(getpropstring(optionsnode, - "screen-#rows"), 34); + + if (!CPU_ISSUN4) { + rc->rc_maxcol = + a2int(getpropstring(optionsnode, "screen-#columns"), 80); + rc->rc_maxrow = + a2int(getpropstring(optionsnode, "screen-#rows"), 34); } -#endif /* SUN4C || SUN4M */ #endif /* RASTERCONS_FULLSCREEN || RASTERCONS_SMALLFONT */ #if !(defined(RASTERCONS_FULLSCREEN) || defined(RASTERCONS_SMALLFONT)) /* Determine addresses of prom emulator row and column */ - if (cputyp == CPU_SUN4 || romgetcursoraddr(&rc->rc_row, &rc->rc_col)) + if (CPU_ISSUN4 || + romgetcursoraddr(&rc->rc_row, &rc->rc_col)) #endif rc->rc_row = rc->rc_col = NULL; rc->rc_bell = fb_bell; rcons_init(rc); /* Hook up virtual console */ - v_putc = (int (*) __P((int)))rcons_cnputc; + v_putc = rcons_cnputc; } #endif + +#if defined(SUN4) +/* + * Support routines for pfour framebuffers. + */ + +/* + * Probe for a pfour framebuffer. Return values: + * + * PFOUR_NOTPFOUR framebuffer is not a pfour + * framebuffer + * + * otherwise returns pfour ID + */ +int +fb_pfour_id(va) + void *va; +{ + volatile u_int32_t val, save, *pfour = va; + + /* Read the pfour register. */ + save = *pfour; + + /* + * Try to modify the type code. If it changes, put the + * original value back, and notify the caller that it's + * not a pfour framebuffer. + */ + val = save & ~PFOUR_REG_RESET; + *pfour = (val ^ PFOUR_FBTYPE_MASK); + if ((*pfour ^ val) & PFOUR_FBTYPE_MASK) { + *pfour = save; + return (PFOUR_NOTPFOUR); + } + + return (PFOUR_ID(val)); +} + +/* + * Return the status of the video enable. + */ +int +fb_pfour_get_video(fb) + struct fbdevice *fb; +{ + + return ((*fb->fb_pfour & PFOUR_REG_VIDEO) != 0); +} + +/* + * Enable or disable the framebuffer. + */ +void +fb_pfour_set_video(fb, enable) + struct fbdevice *fb; + int enable; +{ + volatile u_int32_t pfour; + + pfour = *fb->fb_pfour & ~(PFOUR_REG_INTCLR|PFOUR_REG_VIDEO); + *fb->fb_pfour = pfour | (enable ? PFOUR_REG_VIDEO : 0); +} +#endif /* SUN4 */ |