xref: /freebsd/sys/isa/vga_isa.c (revision fe0d4089)
18a997770SDoug Rabson /*-
28a997770SDoug Rabson  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
38a997770SDoug Rabson  * All rights reserved.
48a997770SDoug Rabson  *
58a997770SDoug Rabson  * Redistribution and use in source and binary forms, with or without
68a997770SDoug Rabson  * modification, are permitted provided that the following conditions
78a997770SDoug Rabson  * are met:
88a997770SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
98a997770SDoug Rabson  *    notice, this list of conditions and the following disclaimer as
108a997770SDoug Rabson  *    the first lines of this file unmodified.
118a997770SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
128a997770SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
138a997770SDoug Rabson  *    documentation and/or other materials provided with the distribution.
148a997770SDoug Rabson  *
158a997770SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
168a997770SDoug Rabson  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
178a997770SDoug Rabson  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
188a997770SDoug Rabson  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
198a997770SDoug Rabson  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
208a997770SDoug Rabson  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
218a997770SDoug Rabson  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
228a997770SDoug Rabson  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
238a997770SDoug Rabson  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
248a997770SDoug Rabson  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
258a997770SDoug Rabson  *
26c3aac50fSPeter Wemm  * $FreeBSD$
278a997770SDoug Rabson  */
288a997770SDoug Rabson 
298a997770SDoug Rabson #include "vga.h"
308a997770SDoug Rabson #include "opt_vga.h"
318a997770SDoug Rabson #include "opt_fb.h"
328a997770SDoug Rabson #include "opt_syscons.h"	/* should be removed in the future, XXX */
338a997770SDoug Rabson 
348a997770SDoug Rabson #if NVGA > 0
358a997770SDoug Rabson 
368a997770SDoug Rabson #include <sys/param.h>
378a997770SDoug Rabson #include <sys/systm.h>
388a997770SDoug Rabson #include <sys/kernel.h>
396e8394b8SKazutaka YOKOTA #include <sys/conf.h>
408a997770SDoug Rabson #include <sys/bus.h>
416e8394b8SKazutaka YOKOTA #include <sys/fbio.h>
426e8394b8SKazutaka YOKOTA 
436e8394b8SKazutaka YOKOTA #include <machine/bus.h>
446e8394b8SKazutaka YOKOTA #include <machine/resource.h>
456e8394b8SKazutaka YOKOTA 
466e8394b8SKazutaka YOKOTA #include <sys/rman.h>
478a997770SDoug Rabson 
488a997770SDoug Rabson #include <vm/vm.h>
498a997770SDoug Rabson #include <vm/pmap.h>
508a997770SDoug Rabson 
518a997770SDoug Rabson #include <machine/md_var.h>
528a997770SDoug Rabson #include <machine/pc/bios.h>
538a997770SDoug Rabson 
548a997770SDoug Rabson #include <dev/fb/fbreg.h>
558a997770SDoug Rabson #include <dev/fb/vgareg.h>
568a997770SDoug Rabson 
578a997770SDoug Rabson #include <isa/isareg.h>
588a997770SDoug Rabson #include <isa/isavar.h>
598a997770SDoug Rabson 
606e8394b8SKazutaka YOKOTA #define VGA_SOFTC(unit)		\
616e8394b8SKazutaka YOKOTA 	((vga_softc_t *)devclass_get_softc(isavga_devclass, unit))
628a997770SDoug Rabson 
636e8394b8SKazutaka YOKOTA static devclass_t	isavga_devclass;
648a997770SDoug Rabson 
658a997770SDoug Rabson static int		isavga_probe(device_t dev);
668a997770SDoug Rabson static int		isavga_attach(device_t dev);
678a997770SDoug Rabson 
688a997770SDoug Rabson static device_method_t isavga_methods[] = {
698a997770SDoug Rabson 	DEVMETHOD(device_probe,		isavga_probe),
708a997770SDoug Rabson 	DEVMETHOD(device_attach,	isavga_attach),
716e8394b8SKazutaka YOKOTA 
726e8394b8SKazutaka YOKOTA 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
738a997770SDoug Rabson 	{ 0, 0 }
748a997770SDoug Rabson };
758a997770SDoug Rabson 
768a997770SDoug Rabson static driver_t isavga_driver = {
776e8394b8SKazutaka YOKOTA 	VGA_DRIVER_NAME,
788a997770SDoug Rabson 	isavga_methods,
796e8394b8SKazutaka YOKOTA 	sizeof(vga_softc_t),
808a997770SDoug Rabson };
818a997770SDoug Rabson 
828a997770SDoug Rabson DRIVER_MODULE(vga, isa, isavga_driver, isavga_devclass, 0, 0);
838a997770SDoug Rabson 
848a997770SDoug Rabson #ifdef FB_INSTALL_CDEV
858a997770SDoug Rabson 
866e8394b8SKazutaka YOKOTA static d_open_t		isavga_open;
876e8394b8SKazutaka YOKOTA static d_close_t	isavga_close;
886e8394b8SKazutaka YOKOTA static d_read_t		isavga_read;
896e8394b8SKazutaka YOKOTA static d_write_t	isavga_write;
906e8394b8SKazutaka YOKOTA static d_ioctl_t	isavga_ioctl;
916e8394b8SKazutaka YOKOTA static d_mmap_t		isavga_mmap;
928a997770SDoug Rabson 
936e8394b8SKazutaka YOKOTA static struct cdevsw isavga_cdevsw = {
946e8394b8SKazutaka YOKOTA 	/* open */	isavga_open,
956e8394b8SKazutaka YOKOTA 	/* close */	isavga_close,
966e8394b8SKazutaka YOKOTA 	/* read */	isavga_read,
976e8394b8SKazutaka YOKOTA 	/* write */	isavga_write,
986e8394b8SKazutaka YOKOTA 	/* ioctl */	isavga_ioctl,
994e2f199eSPoul-Henning Kamp 	/* poll */	nopoll,
1006e8394b8SKazutaka YOKOTA 	/* mmap */	isavga_mmap,
1014e2f199eSPoul-Henning Kamp 	/* strategy */	nostrategy,
1026e8394b8SKazutaka YOKOTA 	/* name */	VGA_DRIVER_NAME,
1034e2f199eSPoul-Henning Kamp 	/* maj */	-1,
1044e2f199eSPoul-Henning Kamp 	/* dump */	nodump,
1054e2f199eSPoul-Henning Kamp 	/* psize */	nopsize,
1064e2f199eSPoul-Henning Kamp 	/* flags */	0,
1074e2f199eSPoul-Henning Kamp 	/* bmaj */	-1
1088a997770SDoug Rabson };
1098a997770SDoug Rabson 
1108a997770SDoug Rabson #endif /* FB_INSTALL_CDEV */
1118a997770SDoug Rabson 
1128a997770SDoug Rabson static int
1138a997770SDoug Rabson isavga_probe(device_t dev)
1148a997770SDoug Rabson {
1156e8394b8SKazutaka YOKOTA 	video_adapter_t adp;
1166e8394b8SKazutaka YOKOTA 	device_t bus;
1176e8394b8SKazutaka YOKOTA 	int error;
1188a997770SDoug Rabson 
119f7f2df54SDoug Rabson 	/* No pnp support */
120f7f2df54SDoug Rabson 	if (isa_get_vendorid(dev))
121f7f2df54SDoug Rabson 		return (ENXIO);
122f7f2df54SDoug Rabson 
1238a997770SDoug Rabson 	device_set_desc(dev, "Generic ISA VGA");
124062acdb7SDoug Rabson 	error = vga_probe_unit(device_get_unit(dev), &adp, device_get_flags(dev));
1256e8394b8SKazutaka YOKOTA 	if (error == 0) {
1266e8394b8SKazutaka YOKOTA 		bus = device_get_parent(dev);
12725afb89bSDoug Rabson 		bus_set_resource(dev, SYS_RES_IOPORT, 0,
1286e8394b8SKazutaka YOKOTA 				 adp.va_io_base, adp.va_io_size);
12925afb89bSDoug Rabson 		bus_set_resource(dev, SYS_RES_MEMORY, 0,
1306e8394b8SKazutaka YOKOTA 				 adp.va_mem_base, adp.va_mem_size);
1316e8394b8SKazutaka YOKOTA #if 0
1326e8394b8SKazutaka YOKOTA 		isa_set_port(dev, adp.va_io_base);
1336e8394b8SKazutaka YOKOTA 		isa_set_portsize(dev, adp.va_io_size);
1346e8394b8SKazutaka YOKOTA 		isa_set_maddr(dev, adp.va_mem_base);
1356e8394b8SKazutaka YOKOTA 		isa_set_msize(dev, adp.va_mem_size);
1366e8394b8SKazutaka YOKOTA #endif
1376e8394b8SKazutaka YOKOTA 	}
1386e8394b8SKazutaka YOKOTA 	return error;
1398a997770SDoug Rabson }
1408a997770SDoug Rabson 
1418a997770SDoug Rabson static int
1428a997770SDoug Rabson isavga_attach(device_t dev)
1438a997770SDoug Rabson {
1446e8394b8SKazutaka YOKOTA 	vga_softc_t *sc;
1456e8394b8SKazutaka YOKOTA 	struct resource *port;
1466e8394b8SKazutaka YOKOTA 	struct resource *mem;
1476e8394b8SKazutaka YOKOTA 	int unit;
1486e8394b8SKazutaka YOKOTA 	int rid;
1498a997770SDoug Rabson 	int error;
1508a997770SDoug Rabson 
1516e8394b8SKazutaka YOKOTA 	unit = device_get_unit(dev);
1526e8394b8SKazutaka YOKOTA 	sc = device_get_softc(dev);
1538a997770SDoug Rabson 
1546e8394b8SKazutaka YOKOTA 	rid = 0;
1556e8394b8SKazutaka YOKOTA 	port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
1566e8394b8SKazutaka YOKOTA 				  0, ~0, 0, RF_ACTIVE | RF_SHAREABLE);
1576e8394b8SKazutaka YOKOTA 	rid = 0;
1586e8394b8SKazutaka YOKOTA 	mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
1596e8394b8SKazutaka YOKOTA 				 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE);
1606e8394b8SKazutaka YOKOTA 
161062acdb7SDoug Rabson 	error = vga_attach_unit(unit, sc, device_get_flags(dev));
1628a997770SDoug Rabson 	if (error)
1636e8394b8SKazutaka YOKOTA 		return error;
1648a997770SDoug Rabson 
1658a997770SDoug Rabson #ifdef FB_INSTALL_CDEV
1668a997770SDoug Rabson 	/* attach a virtual frame buffer device */
1676e8394b8SKazutaka YOKOTA 	error = fb_attach(makedev(0, VGA_MKMINOR(unit)), sc->adp, &isavga_cdevsw);
1688a997770SDoug Rabson 	if (error)
1698a997770SDoug Rabson 		return error;
1708a997770SDoug Rabson #endif /* FB_INSTALL_CDEV */
1718a997770SDoug Rabson 
1728a997770SDoug Rabson 	if (bootverbose)
1731c27745fSKazutaka YOKOTA 		(*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose);
1748a997770SDoug Rabson 
1756e8394b8SKazutaka YOKOTA #if experimental
176fe0d4089SMatthew N. Dodd 	device_add_child(dev, "fb", -1);
1776e8394b8SKazutaka YOKOTA 	bus_generic_attach(dev);
1788a997770SDoug Rabson #endif
1798a997770SDoug Rabson 
1808a997770SDoug Rabson 	return 0;
1818a997770SDoug Rabson }
1828a997770SDoug Rabson 
1836e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV
1846e8394b8SKazutaka YOKOTA 
1858a997770SDoug Rabson static int
1866e8394b8SKazutaka YOKOTA isavga_open(dev_t dev, int flag, int mode, struct proc *p)
1878a997770SDoug Rabson {
1886e8394b8SKazutaka YOKOTA 	return vga_open(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, p);
1898a997770SDoug Rabson }
1908a997770SDoug Rabson 
1918a997770SDoug Rabson static int
1926e8394b8SKazutaka YOKOTA isavga_close(dev_t dev, int flag, int mode, struct proc *p)
1938a997770SDoug Rabson {
1946e8394b8SKazutaka YOKOTA 	return vga_close(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, p);
1958a997770SDoug Rabson }
1968a997770SDoug Rabson 
1978a997770SDoug Rabson static int
1986e8394b8SKazutaka YOKOTA isavga_read(dev_t dev, struct uio *uio, int flag)
1998a997770SDoug Rabson {
2006e8394b8SKazutaka YOKOTA 	return vga_read(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag);
2018a997770SDoug Rabson }
2028a997770SDoug Rabson 
2038a997770SDoug Rabson static int
2046e8394b8SKazutaka YOKOTA isavga_write(dev_t dev, struct uio *uio, int flag)
2058a997770SDoug Rabson {
2066e8394b8SKazutaka YOKOTA 	return vga_write(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag);
2078a997770SDoug Rabson }
2088a997770SDoug Rabson 
2098a997770SDoug Rabson static int
2106e8394b8SKazutaka YOKOTA isavga_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
2118a997770SDoug Rabson {
2126e8394b8SKazutaka YOKOTA 	return vga_ioctl(dev, VGA_SOFTC(VGA_UNIT(dev)), cmd, arg, flag, p);
2138a997770SDoug Rabson }
2148a997770SDoug Rabson 
2158a997770SDoug Rabson static int
2166e8394b8SKazutaka YOKOTA isavga_mmap(dev_t dev, vm_offset_t offset, int prot)
2178a997770SDoug Rabson {
2186e8394b8SKazutaka YOKOTA 	return vga_mmap(dev, VGA_SOFTC(VGA_UNIT(dev)), offset, prot);
2198a997770SDoug Rabson }
2208a997770SDoug Rabson 
2216e8394b8SKazutaka YOKOTA #endif /* FB_INSTALL_CDEV */
2228a997770SDoug Rabson 
2238a997770SDoug Rabson #endif /* NVGA > 0 */
224