vga_isa.c revision 142833
1139823Simp/*- 221259Swollman * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 321259Swollman * All rights reserved. 421259Swollman * 521259Swollman * Redistribution and use in source and binary forms, with or without 621259Swollman * modification, are permitted provided that the following conditions 721259Swollman * are met: 821259Swollman * 1. Redistributions of source code must retain the above copyright 921259Swollman * notice, this list of conditions and the following disclaimer as 1021259Swollman * the first lines of this file unmodified. 1121259Swollman * 2. Redistributions in binary form must reproduce the above copyright 1221259Swollman * notice, this list of conditions and the following disclaimer in the 1321259Swollman * documentation and/or other materials provided with the distribution. 1421259Swollman * 1521259Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 1621259Swollman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1721259Swollman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1821259Swollman * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 1921259Swollman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2021259Swollman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2121259Swollman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2221259Swollman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2321259Swollman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2421259Swollman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2521259Swollman */ 2621259Swollman 2721259Swollman#include <sys/cdefs.h> 2821259Swollman__FBSDID("$FreeBSD: head/sys/isa/vga_isa.c 142833 2005-02-28 21:06:14Z iedowse $"); 2921259Swollman 3050477Speter#include "opt_vga.h" 3121259Swollman#include "opt_fb.h" 3221259Swollman#include "opt_syscons.h" /* should be removed in the future, XXX */ 3321259Swollman 3421259Swollman#include <sys/param.h> 3521259Swollman#include <sys/systm.h> 3621259Swollman#include <sys/kernel.h> 3721259Swollman#include <sys/malloc.h> 3821259Swollman#include <sys/module.h> 3921259Swollman#include <sys/conf.h> 4021259Swollman#include <sys/bus.h> 4121259Swollman#include <sys/fbio.h> 4221259Swollman 4321259Swollman#include <machine/bus.h> 4421259Swollman#include <machine/resource.h> 4521259Swollman 4621259Swollman#include <sys/rman.h> 4721259Swollman 4821259Swollman#include <vm/vm.h> 4921259Swollman#include <vm/pmap.h> 5021259Swollman 51108533Sschweikh#include <machine/md_var.h> 5221259Swollman#ifdef __i386__ 5321259Swollman#include <machine/pc/bios.h> 5421259Swollman#endif 5521259Swollman 56108533Sschweikh#include <dev/fb/fbreg.h> 5721259Swollman#include <dev/fb/vgareg.h> 5821259Swollman 5921259Swollman#include <isa/isareg.h> 6021259Swollman#include <isa/isavar.h> 6121259Swollman 6221259Swollman#define VGA_SOFTC(unit) \ 6321259Swollman ((vga_softc_t *)devclass_get_softc(isavga_devclass, unit)) 6421259Swollman 6521259Swollmanstatic devclass_t isavga_devclass; 6683366Sjulian 6721259Swollman#ifdef FB_INSTALL_CDEV 6885074Sru 6921259Swollmanstatic d_open_t isavga_open; 7021259Swollmanstatic d_close_t isavga_close; 71142215Sglebiusstatic d_read_t isavga_read; 7221259Swollmanstatic d_write_t isavga_write; 7321259Swollmanstatic d_ioctl_t isavga_ioctl; 7421259Swollmanstatic d_mmap_t isavga_mmap; 7521259Swollman 7669224Sjlemonstatic struct cdevsw isavga_cdevsw = { 7769152Sjlemon .d_version = D_VERSION, 78126264Smlaier .d_flags = D_NEEDGIANT, 7969224Sjlemon .d_open = isavga_open, 8074914Sjhb .d_close = isavga_close, 8174914Sjhb .d_read = isavga_read, 8283130Sjlemon .d_write = isavga_write, 83132712Srwatson .d_ioctl = isavga_ioctl, 8469152Sjlemon .d_mmap = isavga_mmap, 85121816Sbrooks .d_name = VGA_DRIVER_NAME, 86121816Sbrooks}; 87130416Smlaier 88130416Smlaier#endif /* FB_INSTALL_CDEV */ 8960938Sjake 9060938Sjakestatic void 9160938Sjakeisavga_identify(driver_t *driver, device_t parent) 9272084Sphk{ 9321259Swollman BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, VGA_DRIVER_NAME, 0); 9421259Swollman} 9521259Swollman 9621259Swollmanstatic int 9721259Swollmanisavga_probe(device_t dev) 9821259Swollman{ 9921259Swollman video_adapter_t adp; 10021259Swollman int error; 10121259Swollman 10221259Swollman /* No pnp support */ 10369152Sjlemon if (isa_get_vendorid(dev)) 10421259Swollman return (ENXIO); 10521259Swollman 10621259Swollman device_set_desc(dev, "Generic ISA VGA"); 10721259Swollman error = vga_probe_unit(device_get_unit(dev), &adp, device_get_flags(dev)); 10821259Swollman if (error == 0) { 10921259Swollman bus_set_resource(dev, SYS_RES_IOPORT, 0, 11021259Swollman adp.va_io_base, adp.va_io_size); 11184380Smjacob bus_set_resource(dev, SYS_RES_MEMORY, 0, 11221259Swollman adp.va_mem_base, adp.va_mem_size); 11321259Swollman#if 0 114147256Sbrooks isa_set_port(dev, adp.va_io_base); 11560938Sjake isa_set_portsize(dev, adp.va_io_size); 116121816Sbrooks isa_set_maddr(dev, adp.va_mem_base); 117121816Sbrooks isa_set_msize(dev, adp.va_mem_size); 118121816Sbrooks#endif 11921259Swollman } 120128291Sluigi return error; 121128291Sluigi} 122128315Sluigi 123128315Sluigistatic int 124128315Sluigiisavga_attach(device_t dev) 125128315Sluigi{ 126128291Sluigi vga_softc_t *sc; 127128315Sluigi int unit; 128128315Sluigi int rid; 129128291Sluigi int error; 130133741Sjmg 13183130Sjlemon unit = device_get_unit(dev); 132142901Sglebius sc = device_get_softc(dev); 13321259Swollman 13421259Swollman rid = 0; 13521259Swollman bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 136106931Ssam 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE); 137102052Ssobomax rid = 0; 13883624Sjlemon bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 13983624Sjlemon 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE); 14021259Swollman 14121259Swollman error = vga_attach_unit(unit, sc, device_get_flags(dev)); 14221259Swollman if (error) 14321404Swollman return error; 14421404Swollman 14521259Swollman#ifdef FB_INSTALL_CDEV 14621259Swollman /* attach a virtual frame buffer device */ 14792725Salfred error = fb_attach(VGA_MKMINOR(unit), sc->adp, &isavga_cdevsw); 14892725Salfred if (error) 149106931Ssam return error; 150106931Ssam#endif /* FB_INSTALL_CDEV */ 15121259Swollman 15292725Salfred if (0 && bootverbose) 15321259Swollman (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose); 15492725Salfred 15521259Swollman#if experimental 15692725Salfred device_add_child(dev, "fb", -1); 15721259Swollman bus_generic_attach(dev); 15892725Salfred#endif 15921404Swollman 16092725Salfred return 0; 161137062Srwatson} 162137062Srwatson 163137062Srwatsonstatic int 164148265Srwatsonisavga_suspend(device_t dev) 165137062Srwatson{ 166130416Smlaier vga_softc_t *sc; 167123220Simp int err, nbytes; 168127828Sluigi 169146986Sthompsa sc = device_get_softc(dev); 170146986Sthompsa err = bus_generic_suspend(dev); 171127828Sluigi if (err) 172127828Sluigi return (err); 173122524Srwatson 174121161Sume /* Save the video state across the suspend. */ 175127828Sluigi if (sc->state_buf != NULL) { 176127828Sluigi free(sc->state_buf, M_TEMP); 177121161Sume sc->state_buf = NULL; 178121470Sume } 179121470Sume nbytes = (*vidsw[sc->adp->va_index]->save_state)(sc->adp, NULL, 0); 180132712Srwatson if (nbytes <= 0) 181145320Sglebius return (0); 182148640Srwatson sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT | M_ZERO); 183152209Sthompsa if (sc->state_buf == NULL) 18421259Swollman return (0); 18569152Sjlemon if (bootverbose) 18692725Salfred device_printf(dev, "saving %d bytes of video state\n", nbytes); 18721259Swollman if ((*vidsw[sc->adp->va_index]->save_state)(sc->adp, sc->state_buf, 188128376Sluigi nbytes) != 0) { 189128376Sluigi device_printf(dev, "failed to save state (nbytes=%d)\n", 190128376Sluigi nbytes); 191128376Sluigi free(sc->state_buf, M_TEMP); 19221259Swollman sc->state_buf = NULL; 19321259Swollman } 19421259Swollman return (0); 19521259Swollman} 19621259Swollman 19721259Swollmanstatic int 198128871Sandreisavga_resume(device_t dev) 19921259Swollman{ 20058698Sjlemon vga_softc_t *sc; 20121259Swollman 20221259Swollman sc = device_get_softc(dev); 20321259Swollman if (sc->state_buf != NULL) { 20421259Swollman if ((*vidsw[sc->adp->va_index]->load_state)(sc->adp, 20521259Swollman sc->state_buf) != 0) 20621259Swollman device_printf(dev, "failed to reload state\n"); 20721259Swollman free(sc->state_buf, M_TEMP); 20821259Swollman sc->state_buf = NULL; 20921259Swollman } 21021259Swollman 21121259Swollman bus_generic_resume(dev); 21221259Swollman return 0; 21321259Swollman} 21421259Swollman 215136950Sjmg#ifdef FB_INSTALL_CDEV 21621259Swollman 21753541Sshinstatic int 21853541Sshinisavga_open(struct cdev *dev, int flag, int mode, struct thread *td) 21953541Sshin{ 22053541Sshin return vga_open(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, td); 22121259Swollman} 222148640Srwatson 223148640Srwatsonstatic int 224148640Srwatsonisavga_close(struct cdev *dev, int flag, int mode, struct thread *td) 225148640Srwatson{ 226148640Srwatson return vga_close(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, td); 227148640Srwatson} 228148640Srwatson 229148640Srwatsonstatic int 230148640Srwatsonisavga_read(struct cdev *dev, struct uio *uio, int flag) 231148640Srwatson{ 23221259Swollman return vga_read(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag); 23321259Swollman} 23421259Swollman 23521259Swollmanstatic int 23621259Swollmanisavga_write(struct cdev *dev, struct uio *uio, int flag) 23772200Sbmilekic{ 23872200Sbmilekic return vga_write(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag); 239130416Smlaier} 24069152Sjlemon 24169152Sjlemonstatic int 24269152Sjlemonisavga_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) 24321259Swollman{ 24469152Sjlemon return vga_ioctl(dev, VGA_SOFTC(VGA_UNIT(dev)), cmd, arg, flag, td); 24569152Sjlemon} 24669152Sjlemon 24769152Sjlemonstatic int 24869152Sjlemonisavga_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int prot) 24969152Sjlemon{ 25069152Sjlemon return vga_mmap(dev, VGA_SOFTC(VGA_UNIT(dev)), offset, paddr, prot); 25169152Sjlemon} 25269152Sjlemon 25369152Sjlemon#endif /* FB_INSTALL_CDEV */ 25469152Sjlemon 25569152Sjlemonstatic device_method_t isavga_methods[] = { 25669152Sjlemon DEVMETHOD(device_identify, isavga_identify), 25769152Sjlemon DEVMETHOD(device_probe, isavga_probe), 25869152Sjlemon DEVMETHOD(device_attach, isavga_attach), 25969152Sjlemon DEVMETHOD(device_suspend, isavga_suspend), 26069152Sjlemon DEVMETHOD(device_resume, isavga_resume), 26169152Sjlemon 26269152Sjlemon DEVMETHOD(bus_print_child, bus_generic_print_child), 26369152Sjlemon { 0, 0 } 26469152Sjlemon}; 26569152Sjlemon 26669152Sjlemonstatic driver_t isavga_driver = { 26769152Sjlemon VGA_DRIVER_NAME, 26869152Sjlemon isavga_methods, 26969152Sjlemon sizeof(vga_softc_t), 27069152Sjlemon}; 27169152Sjlemon 27269152SjlemonDRIVER_MODULE(vga, isa, isavga_driver, isavga_devclass, 0, 0); 27369152Sjlemon