File:  [DragonFly] / src / sys / dev / agp / agp_intel.c
Revision 1.4: download - view: text, annotated - select for diffs
Tue Dec 9 19:40:56 2003 UTC (10 years, 10 months ago) by dillon
Branches: MAIN
CVS tags: HEAD, DragonFly_1_0_RC1
This patch adds a bunch of stuff from FreeBSD5.  It consistantly makes
vendor specific drivers depend on agp, consistantly checks the gart size
!= 0, changes agp_generic_enable to the FreeBSD5 function, initializing
the device as v2 or v3 accordingly, syncs up agpio.h, and adds a couple
PCI Ids from FreeBSD5.

Submitted-by: Craig Dooley <cd5697@albany.edu>

    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.4 2003/12/09 19:40:56 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 0x33408086:
  102: 		return ("Intel 82855 host to AGP bridge");
  103: 
  104: 	case 0x25318086:
  105: 		return ("Intel 82860 host to AGP bridge");
  106: 
  107: 	case 0x25708086:
  108: 		return ("Intel 82865 host to AGP bridge");
  109: 
  110: 	case 0x25788086:
  111: 		return ("Intel 82875P host to AGP bridge");
  112: 	};
  113: 
  114: 	if (pci_get_vendor(dev) == 0x8086)
  115: 		return ("Intel Generic host to PCI bridge");
  116: 
  117: 	return NULL;
  118: }
  119: 
  120: static int
  121: agp_intel_probe(device_t dev)
  122: {
  123: 	const char *desc;
  124: 
  125: 	desc = agp_intel_match(dev);
  126: 	if (desc) {
  127: 		device_verbose(dev);
  128: 		device_set_desc(dev, desc);
  129: 		return 0;
  130: 	}
  131: 
  132: 	return ENXIO;
  133: }
  134: 
  135: static int
  136: agp_intel_attach(device_t dev)
  137: {
  138: 	struct agp_intel_softc *sc = device_get_softc(dev);
  139: 	struct agp_gatt *gatt;
  140: 	u_int32_t type = pci_get_devid(dev);
  141: 	u_int32_t value;
  142: 	int error;
  143: 
  144: 	error = agp_generic_attach(dev);
  145: 	if (error)
  146: 		return error;
  147: 
  148: 	/* Determine maximum supported aperture size. */
  149: 	value = pci_read_config(dev, AGP_INTEL_APSIZE, 1);
  150: 	pci_write_config(dev, AGP_INTEL_APSIZE, MAX_APSIZE, 1);
  151: 	sc->aperture_mask = pci_read_config(dev, AGP_INTEL_APSIZE, 1) &
  152: 	    MAX_APSIZE;
  153: 	pci_write_config(dev, AGP_INTEL_APSIZE, value, 1);
  154: 	sc->initial_aperture = AGP_GET_APERTURE(dev);
  155: 	if (sc->initial_aperture == 0) {
  156: 		device_printf(dev, "bad initial aperture size, disabling\n");
  157: 		return ENXIO;
  158: 	}
  159: 
  160: 	for (;;) {
  161: 		gatt = agp_alloc_gatt(dev);
  162: 		if (gatt)
  163: 			break;
  164: 
  165: 		/*
  166: 		 * Probably contigmalloc failure. Try reducing the
  167: 		 * aperture so that the gatt size reduces.
  168: 		 */
  169: 		if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
  170: 			agp_generic_detach(dev);
  171: 			return ENOMEM;
  172: 		}
  173: 	}
  174: 	sc->gatt = gatt;
  175: 
  176: 	/* Install the gatt. */
  177: 	pci_write_config(dev, AGP_INTEL_ATTBASE, gatt->ag_physical, 4);
  178: 
  179: 	/* Enable the GLTB and setup the control register. */
  180: 	switch (type) {
  181: 	case 0x71908086: /* 440LX/EX */
  182: 		pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2080, 4);
  183: 		break;
  184: 	case 0x71808086: /* 440BX */
  185: 		/*
  186: 		 * XXX: Should be 0xa080?  Bit 9 is undefined, and
  187: 		 * bit 13 being on and bit 15 being clear is illegal.
  188: 		 */
  189: 		pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2280, 4);
  190: 		break;
  191: 	default:
  192: 		value = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4);
  193: 		pci_write_config(dev, AGP_INTEL_AGPCTRL, value | 0x80, 4);
  194: 	}
  195: 
  196: 	/* Enable things, clear errors etc. */
  197: 	switch (type) {
  198: 	case 0x1a218086: /* i840 */
  199: 	case 0x25308086: /* i850 */
  200: 	case 0x25318086: /* i860 */
  201: 		pci_write_config(dev, AGP_INTEL_MCHCFG,
  202: 				 (pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
  203: 				  | (1 << 9)), 2);
  204: 		break;
  205: 
  206: 	case 0x25008086: /* i820 */
  207: 	case 0x25018086: /* i820 */
  208: 		pci_write_config(dev, AGP_INTEL_I820_RDCR,
  209: 				 (pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
  210: 				  | (1 << 1)), 1);
  211: 		break;
  212: 
  213: 	case 0x1a308086: /* i845 */
  214: 	case 0x33408086: /* i855 */
  215: 	case 0x25708086: /* i865 */
  216: 	case 0x25788086: /* i875P */
  217: 		pci_write_config(dev, AGP_INTEL_I845_MCHCFG,
  218: 				 (pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
  219: 				  | (1 << 1)), 1);
  220: 		break;
  221: 
  222: 	default: /* Intel Generic (maybe) */
  223: 		pci_write_config(dev, AGP_INTEL_NBXCFG,
  224: 				 (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
  225: 				  & ~(1 << 10)) | (1 << 9), 4);
  226: 	}
  227: 
  228: 	switch (type) {
  229: 	case 0x1a218086: /* i840 */
  230: 		pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0xc000, 2);
  231: 		break;
  232: 
  233: 	case 0x25008086: /* i820 */
  234: 	case 0x25018086: /* i820 */
  235: 	case 0x1a308086: /* i845 */
  236: 	case 0x25308086: /* i850 */
  237: 	case 0x33408086: /* i855 */
  238: 	case 0x25318086: /* i860 */
  239: 	case 0x25708086: /* i865 */
  240: 	case 0x25788086: /* i875P */
  241: 		pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0x00ff, 2);
  242: 		break;
  243: 
  244: 	default: /* Intel Generic (maybe) */
  245: 		pci_write_config(dev, AGP_INTEL_ERRSTS + 1, 7, 1);
  246: 	}
  247: 
  248: 	return 0;
  249: }
  250: 
  251: static int
  252: agp_intel_detach(device_t dev)
  253: {
  254: 	struct agp_intel_softc *sc = device_get_softc(dev);
  255: 	u_int32_t type = pci_get_devid(dev);
  256: 	int error;
  257: 
  258: 	error = agp_generic_detach(dev);
  259: 	if (error)
  260: 		return error;
  261: 
  262: 	switch (type) {
  263: 	case 0x1a218086: /* i840 */
  264: 	case 0x25308086: /* i850 */
  265: 	case 0x25318086: /* i860 */
  266: 		printf("%s: set MCHCFG to %x\n", __FUNCTION__, (unsigned)
  267: 				(pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
  268: 				& ~(1 << 9)));
  269: 		pci_write_config(dev, AGP_INTEL_MCHCFG,
  270: 				(pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
  271: 				& ~(1 << 9)), 2);
  272: 
  273: 	case 0x25008086: /* i820 */
  274: 	case 0x25018086: /* i820 */
  275: 		printf("%s: set RDCR to %x\n", __FUNCTION__, (unsigned)
  276: 				(pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
  277: 				& ~(1 << 1)));
  278: 		pci_write_config(dev, AGP_INTEL_I820_RDCR,
  279: 				(pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
  280: 				& ~(1 << 1)), 1);
  281: 
  282: 	case 0x1a308086: /* i845 */
  283: 	case 0x33408086: /* i855 */
  284: 	case 0x25708086: /* i865 */
  285: 	case 0x25788086: /* i875P */
  286: 		printf("%s: set MCHCFG to %x\n", __FUNCTION__, (unsigned)
  287: 				(pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
  288: 				& ~(1 << 1)));
  289: 		pci_write_config(dev, AGP_INTEL_MCHCFG,
  290: 				(pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
  291: 				& ~(1 << 1)), 1);
  292: 
  293: 	default: /* Intel Generic (maybe) */
  294: 		printf("%s: set NBXCFG to %x\n", __FUNCTION__,
  295: 				 (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
  296: 				  & ~(1 << 9)));
  297: 		pci_write_config(dev, AGP_INTEL_NBXCFG,
  298: 				 (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
  299: 				  & ~(1 << 9)), 4);
  300: 	}
  301: 	pci_write_config(dev, AGP_INTEL_ATTBASE, 0, 4);
  302: 	AGP_SET_APERTURE(dev, sc->initial_aperture);
  303: 	agp_free_gatt(sc->gatt);
  304: 
  305: 	return 0;
  306: }
  307: 
  308: static u_int32_t
  309: agp_intel_get_aperture(device_t dev)
  310: {
  311: 	struct agp_intel_softc *sc = device_get_softc(dev);
  312: 	u_int32_t apsize;
  313: 
  314: 	apsize = pci_read_config(dev, AGP_INTEL_APSIZE, 1) & sc->aperture_mask;
  315: 
  316: 	/*
  317: 	 * The size is determined by the number of low bits of
  318: 	 * register APBASE which are forced to zero. The low 22 bits
  319: 	 * are always forced to zero and each zero bit in the apsize
  320: 	 * field just read forces the corresponding bit in the 27:22
  321: 	 * to be zero. We calculate the aperture size accordingly.
  322: 	 */
  323: 	return (((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1;
  324: }
  325: 
  326: static int
  327: agp_intel_set_aperture(device_t dev, u_int32_t aperture)
  328: {
  329: 	struct agp_intel_softc *sc = device_get_softc(dev);
  330: 	u_int32_t apsize;
  331: 
  332: 	/*
  333: 	 * Reverse the magic from get_aperture.
  334: 	 */
  335: 	apsize = ((aperture - 1) >> 22) ^ sc->aperture_mask;
  336: 
  337: 	/*
  338: 	 * Double check for sanity.
  339: 	 */
  340: 	if ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1 != aperture)
  341: 		return EINVAL;
  342: 
  343: 	pci_write_config(dev, AGP_INTEL_APSIZE, apsize, 1);
  344: 
  345: 	return 0;
  346: }
  347: 
  348: static int
  349: agp_intel_bind_page(device_t dev, int offset, vm_offset_t physical)
  350: {
  351: 	struct agp_intel_softc *sc = device_get_softc(dev);
  352: 
  353: 	if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
  354: 		return EINVAL;
  355: 
  356: 	sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 0x17;
  357: 	return 0;
  358: }
  359: 
  360: static int
  361: agp_intel_unbind_page(device_t dev, int offset)
  362: {
  363: 	struct agp_intel_softc *sc = device_get_softc(dev);
  364: 
  365: 	if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
  366: 		return EINVAL;
  367: 
  368: 	sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
  369: 	return 0;
  370: }
  371: 
  372: static void
  373: agp_intel_flush_tlb(device_t dev)
  374: {
  375: 	u_int32_t val;
  376: 
  377: 	val = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4);
  378: 	pci_write_config(dev, AGP_INTEL_AGPCTRL, val & ~(1 << 8), 4);
  379: 	pci_write_config(dev, AGP_INTEL_AGPCTRL, val, 4);
  380: }
  381: 
  382: static device_method_t agp_intel_methods[] = {
  383: 	/* Device interface */
  384: 	DEVMETHOD(device_probe,		agp_intel_probe),
  385: 	DEVMETHOD(device_attach,	agp_intel_attach),
  386: 	DEVMETHOD(device_detach,	agp_intel_detach),
  387: 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
  388: 	DEVMETHOD(device_suspend,	bus_generic_suspend),
  389: 	DEVMETHOD(device_resume,	bus_generic_resume),
  390: 
  391: 	/* AGP interface */
  392: 	DEVMETHOD(agp_get_aperture,	agp_intel_get_aperture),
  393: 	DEVMETHOD(agp_set_aperture,	agp_intel_set_aperture),
  394: 	DEVMETHOD(agp_bind_page,	agp_intel_bind_page),
  395: 	DEVMETHOD(agp_unbind_page,	agp_intel_unbind_page),
  396: 	DEVMETHOD(agp_flush_tlb,	agp_intel_flush_tlb),
  397: 	DEVMETHOD(agp_enable,		agp_generic_enable),
  398: 	DEVMETHOD(agp_alloc_memory,	agp_generic_alloc_memory),
  399: 	DEVMETHOD(agp_free_memory,	agp_generic_free_memory),
  400: 	DEVMETHOD(agp_bind_memory,	agp_generic_bind_memory),
  401: 	DEVMETHOD(agp_unbind_memory,	agp_generic_unbind_memory),
  402: 
  403: 	{ 0, 0 }
  404: };
  405: 
  406: static driver_t agp_intel_driver = {
  407: 	"agp",
  408: 	agp_intel_methods,
  409: 	sizeof(struct agp_intel_softc),
  410: };
  411: 
  412: static devclass_t agp_devclass;
  413: 
  414: DRIVER_MODULE(agp_intel, pci, agp_intel_driver, agp_devclass, 0, 0);
  415: MODULE_DEPEND(agp_intel, agp, 1, 1, 1);
  416: MODULE_DEPEND(agp_intel, pci, 1, 1, 1);