File:  [DragonFly] / src / sys / dev / agp / agp_sis.c
Revision 1.3: download - view: text, annotated - select for diffs
Thu Aug 7 21:16:48 2003 UTC (11 years, 2 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
kernel tree reorganization stage 1: Major cvs repository work (not logged as
commits) plus a major reworking of the #include's to accomodate the
relocations.

    * CVS repository files manually moved.  Old directories left intact
      and empty (temporary).

    * Reorganize all filesystems into vfs/, most devices into dev/,
      sub-divide devices by function.

    * Begin to move device-specific architecture files to the device
      subdirs rather then throwing them all into, e.g. i386/include

    * Reorganize files related to system busses, placing the related code
      in a new bus/ directory.  Also move cam to bus/cam though this may
      not have been the best idea in retrospect.

    * Reorganize emulation code and place it in a new emulation/ directory.

    * Remove the -I- compiler option in order to allow #include file
      localization, rename all config generated X.h files to use_X.h to
      clean up the conflicts.

    * Remove /usr/src/include (or /usr/include) dependancies during the
      kernel build, beyond what is normally needed to compile helper
      programs.

    * Make config create 'machine' softlinks for architecture specific
      directories outside of the standard <arch>/include.

    * Bump the config rev.

    WARNING! after this commit /usr/include and /usr/src/sys/compile/*
    should be regenerated from scratch.

    1: /*-
    2:  * Copyright (c) 2000 Doug Rabson
    3:  * All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  *
   14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24:  * SUCH DAMAGE.
   25:  *
   26:  *	$FreeBSD: src/sys/pci/agp_sis.c,v 1.1.2.1 2000/07/19 09:48:04 ru Exp $
   27:  *	$DragonFly: src/sys/dev/agp/agp_sis.c,v 1.3 2003/08/07 21:16:48 dillon Exp $
   28:  */
   29: 
   30: #include "opt_bus.h"
   31: #include "opt_pci.h"
   32: 
   33: #include <sys/param.h>
   34: #include <sys/systm.h>
   35: #include <sys/malloc.h>
   36: #include <sys/kernel.h>
   37: #include <sys/bus.h>
   38: #include <sys/lock.h>
   39: 
   40: #include <bus/pci/pcivar.h>
   41: #include <bus/pci/pcireg.h>
   42: #include "agppriv.h"
   43: #include "agpreg.h"
   44: 
   45: #include <vm/vm.h>
   46: #include <vm/vm_object.h>
   47: #include <vm/pmap.h>
   48: 
   49: struct agp_sis_softc {
   50: 	struct agp_softc agp;
   51: 	u_int32_t	initial_aperture; /* aperture size at startup */
   52: 	struct agp_gatt *gatt;
   53: };
   54: 
   55: static const char*
   56: agp_sis_match(device_t dev)
   57: {
   58: 	if (pci_get_class(dev) != PCIC_BRIDGE
   59: 	    || pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
   60: 		return NULL;
   61: 
   62: 	if (agp_find_caps(dev) == 0)
   63: 		return NULL;
   64: 
   65: 	switch (pci_get_devid(dev)) {
   66: 	case 0x00011039:
   67: 		return ("SiS 5591 host to AGP bridge");
   68: 	};
   69: 
   70: 	if (pci_get_vendor(dev) == 0x1039)
   71: 		return ("SIS Generic host to PCI bridge");
   72: 
   73: 	return NULL;
   74: }
   75: 
   76: static int
   77: agp_sis_probe(device_t dev)
   78: {
   79: 	const char *desc;
   80: 
   81: 	desc = agp_sis_match(dev);
   82: 	if (desc) {
   83: 		device_verbose(dev);
   84: 		device_set_desc(dev, desc);
   85: 		return 0;
   86: 	}
   87: 
   88: 	return ENXIO;
   89: }
   90: 
   91: static int
   92: agp_sis_attach(device_t dev)
   93: {
   94: 	struct agp_sis_softc *sc = device_get_softc(dev);
   95: 	struct agp_gatt *gatt;
   96: 	int error;
   97: 
   98: 	error = agp_generic_attach(dev);
   99: 	if (error)
  100: 		return error;
  101: 
  102: 	sc->initial_aperture = AGP_GET_APERTURE(dev);
  103: 
  104: 	for (;;) {
  105: 		gatt = agp_alloc_gatt(dev);
  106: 		if (gatt)
  107: 			break;
  108: 
  109: 		/*
  110: 		 * Probably contigmalloc failure. Try reducing the
  111: 		 * aperture so that the gatt size reduces.
  112: 		 */
  113: 		if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
  114: 			agp_generic_detach(dev);
  115: 			return ENOMEM;
  116: 		}
  117: 	}
  118: 	sc->gatt = gatt;
  119: 
  120: 	/* Install the gatt. */
  121: 	pci_write_config(dev, AGP_SIS_ATTBASE, gatt->ag_physical, 4);
  122: 	
  123: 	/* Enable the aperture. */
  124: 	pci_write_config(dev, AGP_SIS_WINCTRL,
  125: 			 pci_read_config(dev, AGP_SIS_WINCTRL, 1) | 3, 1);
  126: 
  127: 	/*
  128: 	 * Enable the TLB and make it automatically invalidate entries
  129: 	 * when the GATT is written.
  130: 	 */
  131: 	pci_write_config(dev, AGP_SIS_TLBCTRL, 0x05, 1);
  132: 
  133: 	return 0;
  134: }
  135: 
  136: static int
  137: agp_sis_detach(device_t dev)
  138: {
  139: 	struct agp_sis_softc *sc = device_get_softc(dev);
  140: 	int error;
  141: 
  142: 	error = agp_generic_detach(dev);
  143: 	if (error)
  144: 		return error;
  145: 
  146: 	/* Disable the aperture.. */
  147: 	pci_write_config(dev, AGP_SIS_WINCTRL,
  148: 			 pci_read_config(dev, AGP_SIS_WINCTRL, 1) & ~3, 1);
  149: 
  150: 	/* and the TLB. */
  151: 	pci_write_config(dev, AGP_SIS_TLBCTRL, 0, 1);
  152: 
  153: 	/* Put the aperture back the way it started. */
  154: 	AGP_SET_APERTURE(dev, sc->initial_aperture);
  155: 
  156: 	agp_free_gatt(sc->gatt);
  157: 	return 0;
  158: }
  159: 
  160: static u_int32_t
  161: agp_sis_get_aperture(device_t dev)
  162: {
  163: 	int gws;
  164: 
  165: 	/*
  166: 	 * The aperture size is equal to 4M<<gws.
  167: 	 */
  168: 	gws = (pci_read_config(dev, AGP_SIS_WINCTRL, 1) & 0x70) >> 4;
  169: 	return (4*1024*1024) << gws;
  170: }
  171: 
  172: static int
  173: agp_sis_set_aperture(device_t dev, u_int32_t aperture)
  174: {
  175: 	int gws;
  176: 
  177: 	/*
  178: 	 * Check for a power of two and make sure its within the
  179: 	 * programmable range.
  180: 	 */
  181: 	if (aperture & (aperture - 1)
  182: 	    || aperture < 4*1024*1024
  183: 	    || aperture > 256*1024*1024)
  184: 		return EINVAL;
  185: 
  186: 	gws = ffs(aperture / 4*1024*1024) - 1;
  187: 	
  188: 	pci_write_config(dev, AGP_SIS_WINCTRL,
  189: 			 ((pci_read_config(dev, AGP_SIS_WINCTRL, 1) & ~0x70)
  190: 			  | gws << 4), 1);
  191: 
  192: 	return 0;
  193: }
  194: 
  195: static int
  196: agp_sis_bind_page(device_t dev, int offset, vm_offset_t physical)
  197: {
  198: 	struct agp_sis_softc *sc = device_get_softc(dev);
  199: 
  200: 	if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
  201: 		return EINVAL;
  202: 
  203: 	sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
  204: 	return 0;
  205: }
  206: 
  207: static int
  208: agp_sis_unbind_page(device_t dev, int offset)
  209: {
  210: 	struct agp_sis_softc *sc = device_get_softc(dev);
  211: 
  212: 	if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
  213: 		return EINVAL;
  214: 
  215: 	sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
  216: 	return 0;
  217: }
  218: 
  219: static void
  220: agp_sis_flush_tlb(device_t dev)
  221: {
  222: 	pci_write_config(dev, AGP_SIS_TLBFLUSH, 0x02, 1);
  223: }
  224: 
  225: static device_method_t agp_sis_methods[] = {
  226: 	/* Device interface */
  227: 	DEVMETHOD(device_probe,		agp_sis_probe),
  228: 	DEVMETHOD(device_attach,	agp_sis_attach),
  229: 	DEVMETHOD(device_detach,	agp_sis_detach),
  230: 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
  231: 	DEVMETHOD(device_suspend,	bus_generic_suspend),
  232: 	DEVMETHOD(device_resume,	bus_generic_resume),
  233: 
  234: 	/* AGP interface */
  235: 	DEVMETHOD(agp_get_aperture,	agp_sis_get_aperture),
  236: 	DEVMETHOD(agp_set_aperture,	agp_sis_set_aperture),
  237: 	DEVMETHOD(agp_bind_page,	agp_sis_bind_page),
  238: 	DEVMETHOD(agp_unbind_page,	agp_sis_unbind_page),
  239: 	DEVMETHOD(agp_flush_tlb,	agp_sis_flush_tlb),
  240: 	DEVMETHOD(agp_enable,		agp_generic_enable),
  241: 	DEVMETHOD(agp_alloc_memory,	agp_generic_alloc_memory),
  242: 	DEVMETHOD(agp_free_memory,	agp_generic_free_memory),
  243: 	DEVMETHOD(agp_bind_memory,	agp_generic_bind_memory),
  244: 	DEVMETHOD(agp_unbind_memory,	agp_generic_unbind_memory),
  245: 
  246: 	{ 0, 0 }
  247: };
  248: 
  249: static driver_t agp_sis_driver = {
  250: 	"agp",
  251: 	agp_sis_methods,
  252: 	sizeof(struct agp_sis_softc),
  253: };
  254: 
  255: static devclass_t agp_devclass;
  256: 
  257: DRIVER_MODULE(agp_sis, pci, agp_sis_driver, agp_devclass, 0, 0);