diff options
Diffstat (limited to 'chips/sfb_hdw.c')
-rw-r--r-- | chips/sfb_hdw.c | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/chips/sfb_hdw.c b/chips/sfb_hdw.c new file mode 100644 index 00000000..ff2b1f6d --- /dev/null +++ b/chips/sfb_hdw.c @@ -0,0 +1,253 @@ +/* + * Mach Operating System + * Copyright (c) 1992 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * File: sfb_hdw.c + * Author: Alessandro Forin, Carnegie Mellon University + * Date: 11/92 + * + * Driver for the Smart Color Frame Buffer Display, + * hardware-level operations. + */ + +#include <sfb.h> +#if (NSFB > 0) +#include <platforms.h> + +#include <machine/machspl.h> +#include <mach/std_types.h> +#include <chips/busses.h> +#include <chips/screen_defs.h> +#include <chips/pm_defs.h> +#include <machine/machspl.h> + +typedef pm_softc_t sfb_softc_t; + +#ifdef DECSTATION +#include <mips/PMAX/pmagb_ba.h> +#include <mips/PMAX/tc.h> +#endif + +#ifdef FLAMINGO +#include <mips/PMAX/pmagb_ba.h> /* XXXX fixme */ +#include <alpha/DEC/tc.h> +#define sparsify(x) ((1L << 28) | (((x) & 0x7ffffff) << 1) | \ + ((x) & ~0x7ffffffL)) +#endif + +#ifndef sparsify +#define sparsify(x) x +#endif + +/* + * Definition of the driver for the auto-configuration program. + */ + +int sfb_probe(), sfb_intr(); +void sfb_attach(); + +vm_offset_t sfb_std[NSFB] = { 0 }; +struct bus_device *sfb_info[NSFB]; +struct bus_driver sfb_driver = + { sfb_probe, 0, sfb_attach, 0, sfb_std, "sfb", sfb_info, + 0, 0, BUS_INTR_DISABLED}; + +/* + * Probe/Attach functions + */ + +sfb_probe( + vm_offset_t addr, + struct bus_device *device) +{ + static probed_once = 0; + + /* + * Probing was really done sweeping the TC long ago + */ + if (tc_probe("sfb") == 0) + return 0; + if (probed_once++ > 1) { + printf("[mappable] "); + device->address = addr; + } + return 1; +} + +void sfb_attach( + struct bus_device *ui) +{ + /* ... */ + printf(": smart frame buffer"); +} + + +/* + * Interrupt routine + */ + +sfb_intr( + int unit, + spl_t spllevel) +{ + register volatile char *ack; + + /* acknowledge interrupt */ + ack = (volatile char *) sfb_info[unit]->address + SFB_OFFSET_ICLR; + *ack = 0; + +#if mips + splx(spllevel); +#endif + lk201_led(unit); +} + +sfb_vretrace( + sfb_softc_t *sfb, + boolean_t on) +{ + sfb_regs *regs; + + regs = (sfb_regs *) ((char *)sfb->framebuffer - SFB_OFFSET_VRAM + SFB_OFFSET_REGS); + + regs->intr_enable = (on) ? 1 : 0; +} + +/* + * Boot time initialization: must make device + * usable as console asap. + */ +#define sfb_set_status cfb_set_status + +extern int + sfb_soft_reset(), sfb_set_status(), + sfb_pos_cursor(), bt459_video_on(), + bt459_video_off(), sfb_vretrace(), + pm_get_status(), pm_char_paint(), + pm_insert_line(), pm_remove_line(), + pm_clear_bitmap(), pm_map_page(); + +static struct screen_switch sfb_sw = { + screen_noop, /* graphic_open */ + sfb_soft_reset, /* graphic_close */ + sfb_set_status, /* set_status */ + pm_get_status, /* get_status */ + pm_char_paint, /* char_paint */ + sfb_pos_cursor, /* pos_cursor */ + pm_insert_line, /* insert_line */ + pm_remove_line, /* remove_line */ + pm_clear_bitmap, /* clear_bitmap */ + bt459_video_on, /* video_on */ + bt459_video_off, /* video_off */ + sfb_vretrace, /* intr_enable */ + pm_map_page /* map_page */ +}; + +sfb_cold_init( + int unit, + user_info_t *up) +{ + sfb_softc_t *sfb; + screen_softc_t sc = screen(unit); + vm_offset_t base = tc_probe("sfb"); + int hor_p, ver_p; + boolean_t makes_sense; + + bcopy(&sfb_sw, &sc->sw, sizeof(sc->sw)); + sc->flags |= COLOR_SCREEN; + + /* + * I am confused here by the documentation. One document + * sez there are three boards: + * "PMAGB-BA" can do 1280x1024 @66Hz or @72Hz + * "PMAGB-BC" can do 1024x864 @60Hz or 1280x1024 @72Hz + * "PMAGB-BE" can do 1024x768 @72Hz or 1280x1024 @72Hz + * Another document sez things differently: + * "PMAGB-BB" can do 1024x768 @72Hz + * "PMAGB-BD" can do 1024x864 @60Hz or 1280x1024 @72Hz + * + * I would be inclined to believe the first one, which came + * with an actual piece of hardware attached (a PMAGB-BA). + * But I could swear I got a first board (which blew up + * instantly) and it was calling itself PMAGB-BB... + * + * Since I have not seen any other hardware I will make + * this code as hypothetical as I can. Should work :-)) + */ + + makes_sense = FALSE; + + { + sfb_regs *regs; + + regs = (sfb_regs *) ((char *)base + SFB_OFFSET_REGS); + hor_p = (regs->vhor_setup & 0x1ff) * 4; + ver_p = regs->vvert_setup & 0x7ff; + + if (((hor_p == 1280) && (ver_p == 1024)) || + ((hor_p == 1024) && (ver_p == 864)) || + ((hor_p == 1024) && (ver_p == 768))) + makes_sense = TRUE; + } + + if (makes_sense) { + sc->frame_scanline_width = hor_p; + sc->frame_height = ver_p; + sc->frame_visible_width = hor_p; + sc->frame_visible_height = ver_p; + } else { + sc->frame_scanline_width = 1280; + sc->frame_height = 1024; + sc->frame_visible_width = 1280; + sc->frame_visible_height = 1024; + } + + pm_init_screen_params(sc,up); + (void) screen_up(unit, up); + + sfb = pm_alloc( unit, sparsify(base + SFB_OFFSET_BT459), + base + SFB_OFFSET_VRAM, -1); + + screen_default_colors(up); + + sfb_soft_reset(sc); + + /* + * Clearing the screen at boot saves from scrolling + * much, and speeds up booting quite a bit. + */ + screen_blitc( unit, 'C'-'@');/* clear screen */ +} + +#if 0 /* this is how you find out about a new screen */ +fill(addr,n,c) + char *addr; +{ + while (n-- > 0) *addr++ = c; +} +#endif + + +#endif (NSFB > 0) |