File:  [DragonFly] / src / sys / dev / agp / agp_intel.c
Revision 1.3: download - view: text, annotated - select for diffs
Thu Aug 7 21:16:48 2003 UTC (11 years, 3 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_intel.c,v 1.1.2.5 2003/06/02 17:38:19 jhb Exp $
   27:  *	$DragonFly: src/sys/dev/agp/agp_intel.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: #define	MAX_APSIZE	0x3f		/* 256 MB */
   50: 
   51: struct agp_intel_softc {
   52: 	struct agp_softc agp;
   53: 	u_int32_t	initial_aperture; /* aperture size at startup */
   54: 	struct agp_gatt *gatt;
   55: 	u_int		aperture_mask;
   56: };
   57: 
   58: static const char*
   59: agp_intel_match(device_t dev)
   60: {
   61: 	if (pci_get_class(dev) != PCIC_BRIDGE
   62: 	    || pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
   63: 		return NULL;
   64: 
   65: 	if (agp_find_caps(dev) == 0)
   66: 		return NULL;
   67: 
   68: 	switch (pci_get_devid(dev)) {
   69: 	/* Intel -- vendor 0x8086 */
   70: 	case 0x71808086:
   71: 		return ("Intel 82443LX (440 LX) host to PCI bridge");
   72: 
   73: 	case 0x71908086:
   74: 		return ("Intel 82443BX (440 BX) host to PCI bridge");
   75: 
   76:  	case 0x71a08086:
   77:  		return ("Intel 82443GX host to PCI bridge");
   78: 
   79:  	case 0x71a18086:
   80:  		return ("Intel 82443GX host to AGP bridge");
   81: 
   82: 	case 0x11308086:
   83: 		return ("Intel 82815 (i815 GMCH) host to PCI bridge");
   84: 
   85: 	case 0x25008086:
   86: 	case 0x25018086:
   87: 		return ("Intel 82820 host to AGP bridge");
   88: 
   89: 	case 0x35758086:
   90: 		return ("Intel 82830 host to AGP bridge");
   91: 
   92: 	case 0x1a218086:
   93: 		return ("Intel 82840 host to AGP bridge");
   94: 
   95: 	case 0x1a308086:
   96: 		return ("Intel 82845 host to AGP bridge");
   97: 
   98: 	case 0x25308086:
   99: 		return ("Intel 82850 host to AGP bridge");
  100: 
  101: 	case 0x25318086:
  102: 		return ("Intel 82860 host to AGP bridge");
  103: 
  104: 	case 0x25708086:
  105: 		return ("Intel 82865 host to AGP bridge");
  106: 	};
  107: 
  108: 	if (pci_get_vendor(dev) == 0x8086)
  109: 		return ("Intel Generic host to PCI bridge");
  110: 
  111: 	return NULL;
  112: }
  113: 
  114: static int
  115: agp_intel_probe(device_t dev)
  116: {
  117: 	const char *desc;
  118: 
  119: 	desc = agp_intel_match(dev);
  120: 	if (desc) {
  121: 		device_verbose(dev);
  122: 		device_set_desc(dev, desc);
  123: 		return 0;
  124: 	}
  125: 
  126: 	return ENXIO;
  127: }
  128: 
  129: static int
  130: agp_intel_attach(device_t dev)
  131: {
  132: 	struct agp_intel_softc *sc = device_get_softc(dev);
  133: 	struct agp_gatt *gatt;
  134: 	u_int32_t type = pci_get_devid(dev);
  135: 	u_int32_t value;
  136: 	int error;
  137: 
  138: 	error = agp_generic_attach(dev);
  139: 	if (error)
  140: 		return error;
  141: 
  142: 	/* Determine maximum supported aperture size. */
  143: 	value = pci_read_config(dev, AGP_INTEL_APSIZE, 1);
  144: 	pci_write_config(dev, AGP_INTEL_APSIZE, MAX_APSIZE, 1);
  145: 	sc->aperture_mask = pci_read_config(dev, AGP_INTEL_APSIZE, 1) &
  146: 	    MAX_APSIZE;
  147: 	pci_write_config(dev, AGP_INTEL_APSIZE, value, 1);
  148: 	sc->initial_aperture = AGP_GET_APERTURE(dev);
  149: 
  150: 	for (;;) {
  151: 		gatt = agp_alloc_gatt(dev);
  152: 		if (gatt)
  153: 			break;
  154: 
  155: 		/*
  156: 		 * Probably contigmalloc failure. Try reducing the
  157: 		 * aperture so that the gatt size reduces.
  158: 		 */
  159: 		if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
  160: 			agp_generic_detach(dev);
  161: 			return ENOMEM;
  162: 		}
  163: 	}
  164: 	sc->gatt = gatt;
  165: 
  166: 	/* Install the gatt. */
  167: 	pci_write_config(dev, AGP_INTEL_ATTBASE, gatt->ag_physical, 4);
  168: 
  169: 	/* Enable the GLTB and setup the control register. */
  170: 	switch (type) {
  171: 	case 0x71908086: /* 440LX/EX */
  172: 		pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2080, 4);
  173: 		break;
  174: 	case 0x71808086: /* 440BX */
  175: 		/*
  176: 		 * XXX: Should be 0xa080?  Bit 9 is undefined, and
  177: 		 * bit 13 being on and bit 15 being clear is illegal.
  178: 		 */
  179: 		pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2280, 4);
  180: 		break;
  181: 	default:
  182: 		value = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4);
  183: 		pci_write_config(dev, AGP_INTEL_AGPCTRL, value | 0x80, 4);
  184: 	}
  185: 
  186: 	/* Enable things, clear errors etc. */
  187: 	switch (type) {
  188: 	case 0x1a218086: /* i840 */
  189: 	case 0x25308086: /* i850 */
  190: 	case 0x25318086: /* i860 */
  191: 		pci_write_config(dev, AGP_INTEL_MCHCFG,
  192: 				 (pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
  193: 				  | (1 << 9)), 2);
  194: 		break;
  195: 
  196: 	case 0x25008086: /* i820 */
  197: 	case 0x25018086: /* i820 */
  198: 		pci_write_config(dev, AGP_INTEL_I820_RDCR,
  199: 				 (pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
  200: 				  | (1 << 1)), 1);
  201: 		break;
  202: 
  203: 	case 0x1a308086: /* i845 */
  204: 	case 0x25708086: /* i865 */
  205: 		pci_write_config(dev, AGP_INTEL_I845_MCHCFG,
  206: 				 (pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
  207: 				  | (1 << 1)), 1);
  208: 		break;
  209: 
  210: 	default: /* Intel Generic (maybe) */
  211: 		pci_write_config(dev, AGP_INTEL_NBXCFG,
  212: 				 (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
  213: 				  & ~(1 << 10)) | (1 << 9), 4);
  214: 	}
  215: 
  216: 	switch (type) {
  217: 	case 0x1a218086: /* i840 */
  218: 		pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0xc000, 2);
  219: 		break;
  220: 
  221: 	case 0x25008086: /* i820 */
  222: 	case 0x25018086: /* i820 */
  223: 	case 0x1a308086: /* i845 */
  224: 	case 0x25308086: /* i850 */
  225: 	case 0x25318086: /* i860 */
  226: 	case 0x25708086: /* i865 */
  227: 		pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0x00ff, 2);
  228: 		break;
  229: 
  230: 	default: /* Intel Generic (maybe) */
  231: 		pci_write_config(dev, AGP_INTEL_ERRSTS + 1, 7, 1);
  232: 	}
  233: 
  234: 	return 0;
  235: }
  236: 
  237: static int
  238: agp_intel_detach(device_t dev)
  239: {
  240: 	struct agp_intel_softc *sc = device_get_softc(dev);
  241: 	u_int32_t type = pci_get_devid(dev);
  242: 	int error;
  243: 
  244: 	error = agp_generic_detach(dev);
  245: 	if (error)
  246: 		return error;
  247: 
  248: 	switch (type) {
  249: 	case 0x1a218086: /* i840 */
  250: 	case 0x25308086: /* i850 */
  251: 	case 0x25318086: /* i860 */
  252: 		printf("%s: set MCHCFG to %x\n", __FUNCTION__, (unsigned)
  253: 				(pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
  254: 				& ~(1 << 9)));
  255: 		pci_write_config(dev, AGP_INTEL_MCHCFG,
  256: 				(pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
  257: 				& ~(1 << 9)), 2);
  258: 
  259: 	case 0x25008086: /* i820 */
  260: 	case 0x25018086: /* i820 */
  261: 		printf("%s: set RDCR to %x\n", __FUNCTION__, (unsigned)
  262: 				(pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
  263: 				& ~(1 << 1)));
  264: 		pci_write_config(dev, AGP_INTEL_I820_RDCR,
  265: 				(pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
  266: 				& ~(1 << 1)), 1);
  267: 
  268: 	case 0x1a308086: /* i845 */
  269: 	case 0x25708086: /* i865 */
  270: 		printf("%s: set MCHCFG to %x\n", __FUNCTION__, (unsigned)
  271: 				(pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
  272: 				& ~(1 << 1)));
  273: 		pci_write_config(dev, AGP_INTEL_MCHCFG,
  274: 				(pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
  275: 				& ~(1 << 1)), 1);
  276: 
  277: 	default: /* Intel Generic (maybe) */
  278: 		printf("%s: set NBXCFG to %x\n", __FUNCTION__,
  279: 				 (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
  280: 				  & ~(1 << 9)));
  281: 		pci_write_config(dev, AGP_INTEL_NBXCFG,
  282: 				 (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
  283: 				  & ~(1 << 9)), 4);
  284: 	}
  285: 	pci_write_config(dev, AGP_INTEL_ATTBASE, 0, 4);
  286: 	AGP_SET_APERTURE(dev, sc->initial_aperture);
  287: 	agp_free_gatt(sc->gatt);
  288: 
  289: 	return 0;
  290: }
  291: 
  292: static u_int32_t
  293: agp_intel_get_aperture(device_t dev)
  294: {
  295: 	struct agp_intel_softc *sc = device_get_softc(dev);
  296: 	u_int32_t apsize;
  297: 
  298: 	apsize = pci_read_config(dev, AGP_INTEL_APSIZE, 1) & sc->aperture_mask;
  299: 
  300: 	/*
  301: 	 * The size is determined by the number of low bits of
  302: 	 * register APBASE which are forced to zero. The low 22 bits
  303: 	 * are always forced to zero and each zero bit in the apsize
  304: 	 * field just read forces the corresponding bit in the 27:22
  305: 	 * to be zero. We calculate the aperture size accordingly.
  306: 	 */
  307: 	return (((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1;
  308: }
  309: 
  310: static int
  311: agp_intel_set_aperture(device_t dev, u_int32_t aperture)
  312: {
  313: 	struct agp_intel_softc *sc = device_get_softc(dev);
  314: 	u_int32_t apsize;
  315: 
  316: 	/*
  317: 	 * Reverse the magic from get_aperture.
  318: 	 */
  319: 	apsize = ((aperture - 1) >> 22) ^ sc->aperture_mask;
  320: 
  321: 	/*
  322: 	 * Double check for sanity.
  323: 	 */
  324: 	if ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1 != aperture)
  325: 		return EINVAL;
  326: 
  327: 	pci_write_config(dev, AGP_INTEL_APSIZE, apsize, 1);
  328: 
  329: 	return 0;
  330: }
  331: 
  332: static int
  333: agp_intel_bind_page(device_t dev, int offset, vm_offset_t physical)
  334: {
  335: 	struct agp_intel_softc *sc = device_get_softc(dev);
  336: 
  337: 	if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
  338: 		return EINVAL;
  339: 
  340: 	sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 0x17;
  341: 	return 0;
  342: }
  343: 
  344: static int
  345: agp_intel_unbind_page(device_t dev, int offset)
  346: {
  347: 	struct agp_intel_softc *sc = device_get_softc(dev);
  348: 
  349: 	if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
  350: 		return EINVAL;
  351: 
  352: 	sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
  353: 	return 0;
  354: }
  355: 
  356: static void
  357: agp_intel_flush_tlb(device_t dev)
  358: {
  359: 	u_int32_t val;
  360: 
  361: 	val = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4);
  362: 	pci_write_config(dev, AGP_INTEL_AGPCTRL, val & ~(1 << 8), 4);
  363: 	pci_write_config(dev, AGP_INTEL_AGPCTRL, val, 4);
  364: }
  365: 
  366: static device_method_t agp_intel_methods[] = {
  367: 	/* Device interface */
  368: 	DEVMETHOD(device_probe,		agp_intel_probe),
  369: 	DEVMETHOD(device_attach,	agp_intel_attach),
  370: 	DEVMETHOD(device_detach,	agp_intel_detach),
  371: 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
  372: 	DEVMETHOD(device_suspend,	bus_generic_suspend),
  373: 	DEVMETHOD(device_resume,	bus_generic_resume),
  374: 
  375: 	/* AGP interface */
  376: 	DEVMETHOD(agp_get_aperture,	agp_intel_get_aperture),
  377: 	DEVMETHOD(agp_set_aperture,	agp_intel_set_aperture),
  378: 	DEVMETHOD(agp_bind_page,	agp_intel_bind_page),
  379: 	DEVMETHOD(agp_unbind_page,	agp_intel_unbind_page),
  380: 	DEVMETHOD(agp_flush_tlb,	agp_intel_flush_tlb),
  381: 	DEVMETHOD(agp_enable,		agp_generic_enable),
  382: 	DEVMETHOD(agp_alloc_memory,	agp_generic_alloc_memory),
  383: 	DEVMETHOD(agp_free_memory,	agp_generic_free_memory),
  384: 	DEVMETHOD(agp_bind_memory,	agp_generic_bind_memory),
  385: 	DEVMETHOD(agp_unbind_memory,	agp_generic_unbind_memory),
  386: 
  387: 	{ 0, 0 }
  388: };
  389: 
  390: static driver_t agp_intel_driver = {
  391: 	"agp",
  392: 	agp_intel_methods,
  393: 	sizeof(struct agp_intel_softc),
  394: };
  395: 
  396: static devclass_t agp_devclass;
  397: 
  398: DRIVER_MODULE(agp_intel, pci, agp_intel_driver, agp_devclass, 0, 0);