diff options
author | Dale S. Rahn <rahnds@cvs.openbsd.org> | 2000-09-06 02:12:16 +0000 |
---|---|---|
committer | Dale S. Rahn <rahnds@cvs.openbsd.org> | 2000-09-06 02:12:16 +0000 |
commit | 718bc35a3f6871a578a50f52a9ddc382d4be6a7d (patch) | |
tree | c525a5c21d4782932817d545040509f5e5e3efc6 | |
parent | cf7329ef2a79c45d2fd0312719e16fafb8360649 (diff) |
Add machine specific vga framebuffer code. Probably should be machine
independant, but not now.
-rw-r--r-- | sys/arch/powerpc/pci/vgafb.c | 469 | ||||
-rw-r--r-- | sys/arch/powerpc/pci/vgafb_pci.c | 442 | ||||
-rw-r--r-- | sys/arch/powerpc/pci/vgafb_pcivar.h | 41 | ||||
-rw-r--r-- | sys/arch/powerpc/pci/vgafbvar.h | 67 |
4 files changed, 1019 insertions, 0 deletions
diff --git a/sys/arch/powerpc/pci/vgafb.c b/sys/arch/powerpc/pci/vgafb.c new file mode 100644 index 00000000000..4cda4b33275 --- /dev/null +++ b/sys/arch/powerpc/pci/vgafb.c @@ -0,0 +1,469 @@ +/* $OpenBSD: vgafb.c,v 1.1 2000/09/06 02:12:14 rahnds Exp $ */ +/* $NetBSD: vga.c,v 1.3 1996/12/02 22:24:54 cgd Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * 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 the + * rights to redistribute these changes. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <machine/bus.h> +#include <dev/cons.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/wscons/wscons_raster.h> +#include <dev/rcons/raster.h> + +#include <arch/powerpc/pci/vgafbvar.h> + +/* parameters set by OF to detect console */ +extern int cons_displaytype; +extern bus_space_tag_t cons_membus; +extern bus_space_handle_t cons_display_mem_h; +extern bus_space_handle_t cons_display_ctl_h; +extern int cons_width; +extern int cons_linebytes; +extern int cons_height; +extern int cons_depth; + +struct cfdriver vgafb_cd = { + NULL, "vgafb", DV_DULL, +}; + +void vgafb_cursor __P((void *, int, int, int)); +void vgafb_putchar __P((void *, int, int, u_int, long)); +void vgafb_copycols __P((void *, int, int, int, int)); +void vgafb_erasecols __P((void *, int, int, int)); +void vgafb_copyrows __P((void *, int, int, int)); +void vgafb_eraserows __P((void *, int, int)); +void vgafb_alloc_attr __P((void *c, int fg, int bg, int flags, long *)); + +static void drawChar ( struct vgafb_config *vc, char ch, int cx, + int cy, char at); +static void setPixel( struct vgafb_config *vc, int x, int y, int v); +static void vgafb_invert_char ( struct vgafb_config *vc, int cx, int cy); +extern const char fontdata_8x16[]; + +struct vgafb_devconfig { + struct rcons dc_ri; +}; +struct raster vgafb_raster; + + +struct vgafb_devconfig vgafb_console_dc; + +struct wsscreen_descr vgafb_stdscreen = { + "std", + 0, 0, /* will be filled in -- XXX shouldn't, it's global */ + 0, + 0, 0, + WSSCREEN_REVERSE +}; +const struct wsscreen_descr *vgafb_scrlist[] = { + &vgafb_stdscreen, + /* XXX other formats, graphics screen? */ +}; + +struct wsscreen_list vgafb_screenlist = { + sizeof(vgafb_scrlist) / sizeof(struct wsscreen_descr *), vgafb_scrlist +}; + + +struct wsdisplay_emulops vgafb_emulops = { + rcons_cursor, + rcons_mapchar, + rcons_putchar, + rcons_copycols, + rcons_erasecols, + rcons_copyrows, + rcons_eraserows, + rcons_alloc_attr +}; + +int vgafb_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); +int vgafb_mmap __P((void *, off_t, int)); +int vgafb_alloc_screen __P((void *, const struct wsscreen_descr *, + void **, int *, int *, long *)); +void vgafb_free_screen __P((void *, void *)); +int vgafb_show_screen __P((void *, void *, int, + void (*) (void *, int, int), void *)); + +struct wsdisplay_accessops vgafb_accessops = { + vgafb_ioctl, + vgafb_mmap, + vgafb_alloc_screen, + vgafb_free_screen, + vgafb_show_screen, + 0 /* load_font */ +}; + + +int vgafb_print __P((void *, const char *)); + +#define FONT_WIDTH 8 +#define FONT_HEIGHT 16 + +/* + * The following functions implement back-end configuration grabbing + * and attachment. + */ +int +vgafb_common_probe(iot, memt, iobase, iosize, membase, memsize, mmiobase, mmiosize) + bus_space_tag_t iot, memt; + u_int32_t iobase, membase, mmiobase; + size_t iosize, memsize, mmiosize; +{ + bus_space_handle_t ioh_b, ioh_c, ioh_d, memh, mmioh; + u_int16_t vgadata; + int gotio_b, gotio_c, gotio_d, gotmem, gotmmio, rv; + int width; + + gotio_b = gotio_c = gotio_d = gotmem = gotmmio = rv = 0; + + if (iosize != 0) { + if (bus_space_map(iot, iobase+0x3b0, 0xc, 0, &ioh_b)) + goto bad; + gotio_b = 1; + if (bus_space_map(iot, iobase+0x3c0, 0x10, 0, &ioh_c)) + goto bad; + gotio_c = 1; + if (bus_space_map(iot, iobase+0x3d0, 0x10, 0, &ioh_d)) + goto bad; + gotio_d = 1; + } + if (mmiosize != 0) { + printf("vgafb_common_probe, mmio base %x size %x\n", + mmiobase, mmiosize); + if (bus_space_map(iot, mmiobase, mmiosize, 0, &mmioh)) + goto bad; + printf("vgafb_common_probe, mmio done\n"); + gotmmio = 1; + } + /* hack */ + if (memsize > 0x00010000) { + memsize = 0x00010000; + } + printf("vgafb_common_probe, mem base %x size %x memt %x\n", + membase, memsize, memt); + + if (bus_space_map(memt, membase, memsize, 0, &memh)) + goto bad; + printf("vgafb_common_probe, mmio done\n"); + gotmem = 1; + +#if 0 + /* CR1 - Horiz. Display End */ + bus_space_write_1(iot, ioh_d, 4, 0x1); + width = bus_space_read_1(iot, ioh_d, 5); + /* this is not bit width yet */ + + /* use CR17 - mode control for this?? */ + if ((width != 0xff) && (width < 600)) { + /* not accessable or in graphics mode? */ + goto bad; + } +#endif + + #if 0 + vgadata = bus_space_read_2(memt, memh, 0); + bus_space_write_2(memt, memh, 0, 0xa55a); + rv = (bus_space_read_2(memt, memh, 0) == 0xa55a); + bus_space_write_2(memt, memh, 0, vgadata); + #else + rv = 1; + #endif + + +bad: + if (gotio_b) + bus_space_unmap(iot, ioh_b, 0xc); + if (gotio_c) + bus_space_unmap(iot, ioh_c, 0x10); + if (gotio_d) + bus_space_unmap(iot, ioh_d, 0x10); + if (gotmmio) + bus_space_unmap(memt, mmioh, mmiosize); + if (gotmem) + bus_space_unmap(memt, memh, memsize); + + return (rv); +} + +void +vgafb_common_setup(iot, memt, vc, iobase, iosize, membase, memsize, mmiobase, mmiosize) + bus_space_tag_t iot, memt; + struct vgafb_config *vc; + u_int32_t iobase, membase, mmiobase; + size_t iosize, memsize, mmiosize; +{ + int cpos; + int width, height; + + vc->vc_iot = iot; + vc->vc_memt = memt; + printf("vgafb_common_setup\n"); + + if (iosize != 0) { + if (bus_space_map(vc->vc_iot, iobase+0x3b0, 0xc, 0, &vc->vc_ioh_b)) + panic("vgafb_common_setup: couldn't map io b"); + if (bus_space_map(vc->vc_iot, iobase+0x3c0, 0x10, 0, &vc->vc_ioh_c)) + panic("vgafb_common_setup: couldn't map io c"); + if (bus_space_map(vc->vc_iot, iobase+0x3d0, 0x10, 0, &vc->vc_ioh_d)) + panic("vgafb_common_setup: couldn't map io d"); + } + if (mmiosize != 0) { + if (bus_space_map(vc->vc_memt, mmiobase, mmiosize, 0, &vc->vc_mmioh)) + panic("vgafb_common_setup: couldn't map mmio"); + } + printf("commons setup mapping mem base %x size %x\n", membase, memsize); + if (bus_space_map(vc->vc_memt, membase, memsize, 0, &vc->vc_memh)) + panic("vgafb_common_setup: couldn't map memory"); + cons_display_mem_h = vc->vc_memh; + printf("display_mem_h %x\n", cons_display_mem_h ); + +#if 0 + if (iosize != 0) { + /* CR1 - Horiz. Display End */ + bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x1); + width = bus_space_read_1(iot, vc->vc_ioh_d, 5); + /* (stored value + 1) * depth -> pixel width */ + width = ( width + 1 ) * 8; + + /* CR1 - Horiz. Display End */ + bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x12); + { + u_int8_t t1, t2, t3; + bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x12); + t1 = bus_space_read_1(iot, vc->vc_ioh_d, 5); + + bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x7); + t2 = bus_space_read_1(iot, vc->vc_ioh_d, 5); + height = t1 + ((t2&0x40) << 3) + + ((t2&0x02) << 7) + 1; + bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x17); + t3 = bus_space_read_1(iot, vc->vc_ioh_d, 5); + if (t3 & 0x04) { + height *= 2; + } + if (t1 == 0xff && t2 == 0xff && t3 == 0xff) { + /* iospace not working??? */ + /* hope, better guess than 2048x2048 */ + width = 640; + height = 480; + } + } + vc->vc_ncol = width / FONT_WIDTH; + vc->vc_nrow = height / FONT_HEIGHT; + } else { + /* iosize == 0 + * default to 640x480 and hope + */ + vc->vc_ncol = 640 / FONT_WIDTH; + vc->vc_nrow = 480 / FONT_HEIGHT; + } + vc->vc_ncol = cons_width / FONT_WIDTH; + vc->vc_nrow = cons_height / FONT_HEIGHT; + printf(", %dx%d", vc->vc_ncol, vc->vc_nrow); +#endif + + vc->vc_crow = vc->vc_ccol = 0; /* Has to be some onscreen value */ + vc->vc_so = 0; + + /* clear screen, frob cursor, etc.? */ + rcons_eraserows(vc, 0, vc->vc_nrow, 0); + +#if defined(alpha) + /* + * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!! + * XXX Therefore, though the comments say "blue bg", the code uses + * XXX the value for a red background! + */ + vc->vc_at = 0x40 | 0x0f; /* blue bg|white fg */ + vc->vc_so_at = 0x40 | 0x0f | 0x80; /* blue bg|white fg|blink */ +#else + vc->vc_at = 0x00 | 0xf; /* black bg|white fg */ + vc->vc_so_at = 0x00 | 0xf | 0x80; /* black bg|white fg|blink */ +#endif +} + +void +vgafb_wsdisplay_attach(parent, vc, console) + struct device *parent; + struct vgafb_config *vc; + int console; +{ + struct wsemuldisplaydev_attach_args aa; + struct wscons_odev_spec *wo; + + aa.console = console; + aa.scrdata = &vgafb_screenlist; + aa.accessops = &vgafb_accessops; + aa.accesscookie = vc; + + config_found(parent, &aa, wsemuldisplaydevprint); +} + + +int +vgafb_print(aux, pnp) + void *aux; + const char *pnp; +{ + + if (pnp) + printf("wsdisplay at %s", pnp); + return (UNCONF); +} + +int +vgafb_ioctl(v, cmd, data, flag, p) + void *v; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + /*struct vgafb_config *vc = v;*/ + + /* XXX */ + return -1; +} + +int +vgafb_mmap(v, offset, prot) + void *v; + off_t offset; + int prot; +{ + struct vgafb_config *vc = v; + bus_space_handle_t h; + u_int32_t *port; + + /* memsize... */ + if (offset >= 0x00000 && offset < 0x800000) /* 8MB of mem??? */ + h = vc->vc_memh + offset; + else if (offset >= 0x10000000 && offset < 0x10040000 ) + /* 256KB of iohb */ + h = vc->vc_ioh_b; + else if (offset >= 0x10040000 && offset < 0x10080000) + /* 256KB of iohc */ + h = vc->vc_ioh_c; + else if (offset >= 0x18880000 && offset < 0x100c0000) + /* 256KB of iohd */ + h = vc->vc_ioh_d; + else if (offset >= 0x20000000 && offset < 0x30000000) + /* mmiosize... */ + h = vc->vc_mmioh + (offset - 0x20000000); + else + return (-1); + +#ifdef alpha + port = (u_int32_t *)(h << 5); + return alpha_btop(port); /* XXX */ +#elif defined(i386) + port = (u_int32_t *)(h << 5); + return i386_btop(port); +#elif defined(__powerpc__) + { + /* huh ??? */ + return h; + /* + return powerpc_btop(port); + */ + } +#endif +} + + +void +vgafb_cnprobe(cp) + struct consdev *cp; +{ + int i, j; + if (cons_displaytype != 1) { + cp->cn_pri = CN_DEAD; + return; + } + + cp->cn_pri = CN_REMOTE; + #if 0 + for (j = 0; j < 2; j++) { + for (i = 0; i < cons_width * cons_height; i++) { + bus_space_write_1(cons_membus, + cons_display_mem_h, i, j); + + } + } + #endif + +} + +extern struct raster_font fontdata8x16; +void +vgafb_cnattach(iot, memt, pc, bus, device, function) + void * pc; + bus_space_tag_t iot, memt; + int bus, device, function; +{ + long defattr; + + struct vgafb_devconfig *dc = &vgafb_console_dc; + struct rcons *ri = &dc->dc_ri; + ri->rc_sp = &vgafb_raster; + + printf("vgafb_cnattach called\n"); + + ri->rc_sp->width = cons_width; + ri->rc_sp->height = cons_height; + ri->rc_sp->depth = cons_depth; + ri->rc_sp->linelongs = cons_linebytes /4; /* XXX */ + ri->rc_sp->pixels = (void *)cons_display_mem_h; + + rcons_init(ri, 160, 160); + + vgafb_stdscreen.nrows = ri->rc_maxrow; + vgafb_stdscreen.ncols = ri->rc_maxcol; + vgafb_stdscreen.textops = &vgafb_emulops; + rcons_alloc_attr(ri, 0, 0, 0, &defattr); + printf("vgafb_cnattach screen paint start\n"); + printf("membus %x mem_h %x\n", + cons_membus->bus_base, cons_display_mem_h); + #if 0 + { + int i; + for (i = 0; i < cons_width * cons_height; i++) { + bus_space_write_1(cons_membus, + cons_display_mem_h, i, 0x1); + + } + } + #endif + printf("vgafb_cnattach screen painted\n"); + wsdisplay_cnattach(&vgafb_stdscreen, ri, 0, 0, defattr); +} diff --git a/sys/arch/powerpc/pci/vgafb_pci.c b/sys/arch/powerpc/pci/vgafb_pci.c new file mode 100644 index 00000000000..8787289a360 --- /dev/null +++ b/sys/arch/powerpc/pci/vgafb_pci.c @@ -0,0 +1,442 @@ +/* $OpenBSD: vgafb_pci.c,v 1.1 2000/09/06 02:12:15 rahnds Exp $ */ +/* $NetBSD: vga_pci.c,v 1.4 1996/12/05 01:39:38 cgd Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * 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 the + * rights to redistribute these changes. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#ifndef i386 +#include <machine/autoconf.h> +#endif +#include <machine/pte.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/rcons/raster.h> +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wscons_raster.h> + +#include <arch/powerpc/pci/vgafbvar.h> +#include <arch/powerpc/pci/vgafb_pcivar.h> + +#define PCI_VENDORID(x) ((x) & 0xFFFF) +#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF) + +struct vgafb_pci_softc { + struct device sc_dev; + + pcitag_t sc_pcitag; /* PCI tag, in case we need it. */ + struct vgafb_config *sc_vc; /* VGA configuration */ + int nscreens; +}; + +#ifdef __BROKEN_INDIRECT_CONFIG +int vgafb_pci_match __P((struct device *, void *, void *)); +#else +int vgafb_pci_match __P((struct device *, struct cfdata *, void *)); +#endif +void vgafb_pci_attach __P((struct device *, struct device *, void *)); + +int vgafbpcimmap __P((void *, off_t, int)); +int vgafbpciioctl __P((void *, u_long, caddr_t, int, struct proc *)); + +struct cfattach vgafb_pci_ca = { + sizeof(struct vgafb_pci_softc), (cfmatch_t)vgafb_pci_match, vgafb_pci_attach, +}; + +pcitag_t vgafb_pci_console_tag; +struct vgafb_config vgafb_pci_console_vc; + +#if 0 +#define DEBUG_VGAFB +#endif + +int +vgafb_pci_probe(pa, id, ioaddr, iosize, memaddr, memsize, cacheable, mmioaddr, mmiosize) + struct pci_attach_args *pa; + int id; + u_int32_t *ioaddr, *iosize; + u_int32_t *memaddr, *memsize, *cacheable; + u_int32_t *mmioaddr, *mmiosize; +{ + u_int32_t addr, size, tcacheable; + pci_chipset_tag_t pc = pa->pa_pc; + int retval; + int i; + + *iosize = 0x0; + *memsize = 0x0; + *mmiosize = 0x0; + for (i = 0x10; i < 0x18; i += 4) { +#ifdef DEBUG_VGAFB + printf("vgafb confread %x %x\n", + i, pci_conf_read(pc, pa->pa_tag, i)); +#endif + /* need to check more than just two base addresses? */ + if (0x1 & pci_conf_read(pc, pa->pa_tag, i) ) { + retval = pci_io_find(pc, pa->pa_tag, i, + &addr, &size); + if (retval) { + printf("vgafb_pci_probe: io %x addr %x size %x\n", i, addr, size); + return 0; + } + if (*iosize == 0) { + *ioaddr = addr; + *iosize = size; + } + + } else { + retval = pci_mem_find(pc, pa->pa_tag, i, + &addr, &size, &tcacheable); +#ifdef DEBUG_VGAFB + printf("vgafb_pci_probe: mem %x addr %x size %x\n", i, addr, size); +#endif + + if (retval) { + printf("vgafb_pci_probe: mem %x addr %x size %x\n", i, addr, size); + return 0; + } + if (size == 0) { + /* ignore this entry */ + }else if (size <= (64 * 1024)) { +#ifdef DEBUG_VGAFB + printf("vgafb_pci_probe: mem %x addr %x size %x iosize %x\n", + i, addr, size, *iosize); +#endif + if (*mmiosize == 0) { + /* this is mmio, not memory */ + *mmioaddr = addr; + *mmiosize = size; + /* need skew in here for io memspace */ + } + } else { + if (*memsize == 0) { + *memaddr = addr; + *memsize = size; + *cacheable = tcacheable; + } + } + } + } +#ifdef DEBUG_VGAFB + printf("vgafb_pci_probe: id %x ioaddr %x, iosize %x, memaddr %x,\n memsize %x, mmioaddr %x, mmiosize %x\n", + id, *ioaddr, *iosize, *memaddr, *memsize, *mmioaddr, *mmiosize); +#endif + if (*iosize == 0) { + if (id == 0) { +#ifdef powerpc + /* this is only used if on openfirmware system and + * the device does not have a iobase config register, + * eg CirrusLogic 5434 VGA. (they hardcode iobase to 0 + * thus giving standard PC addresses for the registers) + */ + int s; + u_int32_t sizedata; + + /* + * Open Firmware (yuck) shuts down devices before + * entering a program so we need to bring them back + * 'online' to respond to bus accesses... so far + * this is true on the power.4e. + */ + s = splhigh(); + sizedata = pci_conf_read(pc, pa->pa_tag, + PCI_COMMAND_STATUS_REG); + sizedata |= (PCI_COMMAND_MASTER_ENABLE | + PCI_COMMAND_IO_ENABLE | + PCI_COMMAND_PARITY_ENABLE | + PCI_COMMAND_SERR_ENABLE); + pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, + sizedata); + splx(s); + +#endif + /* if this is the first card, allow it + * to be accessed in vga iospace + */ + *ioaddr = 0; + *iosize = 0x10000; /* 64k, good as any */ + } else { + /* iospace not available, assume 640x480, pray */ + *ioaddr = 0; + *iosize=0; + } + } +#ifdef DEBUG_VGAFB + printf("vgafb_pci_probe: id %x ioaddr %x, iosize %x, memaddr %x,\n memsize %x, mmioaddr %x, mmiosize %x\n", + id, *ioaddr, *iosize, *memaddr, *memsize, *mmioaddr, *mmiosize); +#endif + return 1; +} +int +vgafb_pci_match(parent, match, aux) + struct device *parent; +#ifdef __BROKEN_INDIRECT_CONFIG + void *match; +#else + struct cfdata *match; +#endif + void *aux; +{ + struct pci_attach_args *pa = aux; + u_int32_t memaddr, memsize, cacheable; + u_int32_t ioaddr, iosize; + u_int32_t mmioaddr, mmiosize; + int potential; + int retval; + static int id = 0; + int myid; + + myid = id; + + potential = 0; + + /* + * If it's prehistoric/vga or display/vga, we might match. + * For the console device, this is jut a sanity check. + */ + if (PCI_CLASS(pa->pa_class) == PCI_CLASS_PREHISTORIC && + PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_PREHISTORIC_VGA) + potential = 1; + if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && + PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA) + potential = 1; + + if (!potential) + return (0); + + /* If it's the console, we have a winner! */ + if (!bcmp(&pa->pa_tag, &vgafb_pci_console_tag, sizeof(pa->pa_tag))) { + id++; + return (1); + } + +#ifdef DEBUG_VGAFB + { + int i; + pci_chipset_tag_t pc = pa->pa_pc; + for (i = 0x10; i < 0x24; i+=4) { + printf("vgafb confread %x %x\n", + i, pci_conf_read(pc, pa->pa_tag, i)); + } + } +#endif + + memaddr=0xb8000; /* default to isa addresses? */ + ioaddr = 0; /* default to isa addresses? */ + + retval = vgafb_pci_probe(pa, myid, &ioaddr, &iosize, + &memaddr, &memsize, &cacheable, &mmioaddr, &mmiosize); + if (retval == 0) { + return 0; + } +#if 1 + printf("ioaddr %x, iosize %x, memaddr %x, memsize %x mmioaddr %x mmiosize %x\n", + ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize); +#endif + + if (!vgafb_common_probe(pa->pa_iot, pa->pa_memt, ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize)) + { + printf("vgafb_pci_match: common_probe failed\n"); + return (0); + } + id++; + + return (1); +} + +void +vgafb_pci_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct pci_attach_args *pa = aux; + struct vgafb_pci_softc *sc = (struct vgafb_pci_softc *)self; + struct vgafb_config *vc; + u_int32_t memaddr, memsize, cacheable; + u_int32_t ioaddr, iosize; + u_int32_t mmioaddr, mmiosize; + int console; + static int id = 0; + int myid; + + myid = id; + + vgafb_pci_probe(pa, myid, &ioaddr, &iosize, + &memaddr, &memsize, &cacheable, &mmioaddr, &mmiosize); + + console = (!bcmp(&pa->pa_tag, &vgafb_pci_console_tag, sizeof(pa->pa_tag))); + if (console) + vc = sc->sc_vc = &vgafb_pci_console_vc; + else { + vc = sc->sc_vc = (struct vgafb_config *) + malloc(sizeof(struct vgafb_config), M_DEVBUF, M_WAITOK); + + /* set up bus-independent VGA configuration */ + vgafb_common_setup(pa->pa_iot, pa->pa_memt, vc, + ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize); + } + vc->vc_mmap = vgafbpcimmap; + vc->vc_ioctl = vgafbpciioctl; + + sc->sc_pcitag = pa->pa_tag; + + if (iosize == 0) { + printf (", no io"); + } + if (mmiosize != 0) { + printf (", mmio"); + } + printf("\n"); + + vgafb_wsdisplay_attach(self, vc, console); + id++; +} + +void +vgafb_pci_console(iot, ioaddr, iosize, memt, memaddr, memsize, + pc, bus, device, function) + bus_space_tag_t iot, memt; + u_int32_t memaddr, memsize; + u_int32_t ioaddr, iosize; + pci_chipset_tag_t pc; + int bus, device, function; +{ + extern bus_space_handle_t cons_display_mem_h; + struct vgafb_config *vc = &vgafb_pci_console_vc; + u_int32_t mmioaddr; + u_int32_t mmiosize; + int retval; + u_int32_t cacheable; + static struct pci_attach_args spa; + struct pci_attach_args *pa = &spa; + + /* for later recognition */ + vgafb_pci_console_tag = pci_make_tag(pc, bus, device, function); + + pa->pa_iot = iot; + pa->pa_memt = memt; + pa->pa_tag = vgafb_pci_console_tag; + /* + pa->pa_pc = XXX; + */ + +/* XXX probe pci before pci bus config? */ + + mmioaddr =0; + mmiosize =0; +#if 0 + vgafb_pci_probe(pa, 0, &ioaddr, &iosize, + &memaddr, &memsize, &cacheable, mmioaddr, mmiosize); +#endif + + + /* set up bus-independent VGA configuration */ + vgafb_common_setup(iot, memt, vc, + ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize); + + vgafb_cnattach(iot, memt, pc, bus, device, function); +} + +int +vgafbpciioctl(v, cmd, data, flag, p) + void *v; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + struct vgafb_pci_softc *sc = v; + + return (vgafb_ioctl(sc->sc_vc, cmd, data, flag, p)); +} + +int +vgafbpcimmap(v, offset, prot) + void *v; + off_t offset; + int prot; +{ + struct vgafb_pci_softc *sc = v; + + return (vgafb_mmap(sc->sc_vc, offset, prot)); +} + +int +vgafb_alloc_screen(v, type, cookiep, curxp, curyp, attrp) + void *v; + const struct wsscreen_descr *type; + void **cookiep; + int *curxp, *curyp; + long *attrp; +{ + struct vgafb_pci_softc *sc = v; + long defattr; + + if (sc->nscreens > 0) + return (ENOMEM); + + *cookiep = &sc->sc_vc->dc_rcons; /* one and only for now */ + *curxp = 0; + *curyp = 0; + rcons_alloc_attr(&sc->sc_vc->dc_rcons, 0, 0, 0, &defattr); + *attrp = defattr; + sc->nscreens++; + return (0); +} + +void +vgafb_free_screen(v, cookie) + void *v; + void *cookie; +{ + struct vgafb_pci_softc *sc = v; + + if (sc->sc_vc == &vgafb_pci_console_vc) + panic("vgafb_free_screen: console"); + + sc->nscreens--; +} + +int +vgafb_show_screen(v, cookie, waitok, cb, cbarg) + void *v; + void *cookie; + int waitok; + void (*cb) __P((void *, int, int)); + void *cbarg; +{ + + return (0); +} diff --git a/sys/arch/powerpc/pci/vgafb_pcivar.h b/sys/arch/powerpc/pci/vgafb_pcivar.h new file mode 100644 index 00000000000..ac6d110e893 --- /dev/null +++ b/sys/arch/powerpc/pci/vgafb_pcivar.h @@ -0,0 +1,41 @@ +/* $OpenBSD: vgafb_pcivar.h,v 1.1 2000/09/06 02:12:15 rahnds Exp $ */ +/* $NetBSD: vga_pcivar.h,v 1.1 1996/11/19 04:38:36 cgd Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * 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 the + * rights to redistribute these changes. + */ + +#define DEVICE_IS_VGA_PCI(class, id) \ + (((PCI_CLASS(class) == PCI_CLASS_DISPLAY && \ + PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) || \ + (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \ + PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0) + +void vgafb_pci_console __P((bus_space_tag_t, + u_int32_t ioaddr, u_int32_t iosize, + bus_space_tag_t, + u_int32_t memaddr, u_int32_t memsize, + pci_chipset_tag_t, int, int, int)); diff --git a/sys/arch/powerpc/pci/vgafbvar.h b/sys/arch/powerpc/pci/vgafbvar.h new file mode 100644 index 00000000000..6c6d41437da --- /dev/null +++ b/sys/arch/powerpc/pci/vgafbvar.h @@ -0,0 +1,67 @@ +/* $OpenBSD: vgafbvar.h,v 1.1 2000/09/06 02:12:15 rahnds Exp $ */ +/* $NetBSD: vgavar.h,v 1.2 1996/11/23 06:06:43 cgd Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * 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 the + * rights to redistribute these changes. + */ + +struct vgafb_config { + /* + * Filled in by front-ends. + */ + bus_space_tag_t vc_iot, vc_memt; + bus_space_handle_t vc_ioh_b, vc_ioh_c, vc_ioh_d, vc_memh, vc_mmioh; + + /* + * Private to back-end. + */ + int vc_ncol, vc_nrow; /* screen width & height */ + int vc_ccol, vc_crow; /* current cursor position */ + + char vc_so; /* in standout mode? */ + char vc_at; /* normal attributes */ + char vc_so_at; /* standout attributes */ + + int (*vc_ioctl) __P((void *, u_long, + caddr_t, int, struct proc *)); + int (*vc_mmap) __P((void *, off_t, int)); + #if 0 + struct raster dc_raster; /* raster description */ + #endif + struct rcons dc_rcons; /* raster blitter control info */ + + +}; + +int vgafb_common_probe __P((bus_space_tag_t, bus_space_tag_t, + u_int32_t, size_t, u_int32_t, size_t, u_int32_t, size_t )); +void vgafb_common_setup __P((bus_space_tag_t, bus_space_tag_t, + struct vgafb_config *, u_int32_t, size_t, u_int32_t, size_t, + u_int32_t, size_t)); +void vgafb_wscons_attach __P((struct device *, struct vgafb_config *, int)); +void vgafb_wscons_console __P((struct vgafb_config *)); +int vgafbioctl __P((void *, u_long, caddr_t, int, struct proc *)); +int vgafbmmap __P((void *, off_t, int)); |