xref: /dflybsd-src/sys/bus/pci/fixup_pci.c (revision 2267fd784e8a7d1ca13e6d3541caa91f36c9e9fb)
14d28e78fSSepherosa Ziehau /*-
24d28e78fSSepherosa Ziehau  * Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
34d28e78fSSepherosa Ziehau  * Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
44d28e78fSSepherosa Ziehau  * Copyright (c) 2000 BSDi
54d28e78fSSepherosa Ziehau  * All rights reserved.
64d28e78fSSepherosa Ziehau  *
74d28e78fSSepherosa Ziehau  * Redistribution and use in source and binary forms, with or without
84d28e78fSSepherosa Ziehau  * modification, are permitted provided that the following conditions
94d28e78fSSepherosa Ziehau  * are met:
104d28e78fSSepherosa Ziehau  * 1. Redistributions of source code must retain the above copyright
114d28e78fSSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer.
124d28e78fSSepherosa Ziehau  * 2. Redistributions in binary form must reproduce the above copyright
134d28e78fSSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer in the
144d28e78fSSepherosa Ziehau  *    documentation and/or other materials provided with the distribution.
154d28e78fSSepherosa Ziehau  * 3. The name of the author may not be used to endorse or promote products
164d28e78fSSepherosa Ziehau  *    derived from this software without specific prior written permission.
174d28e78fSSepherosa Ziehau  *
184d28e78fSSepherosa Ziehau  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
194d28e78fSSepherosa Ziehau  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
204d28e78fSSepherosa Ziehau  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
214d28e78fSSepherosa Ziehau  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
224d28e78fSSepherosa Ziehau  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
234d28e78fSSepherosa Ziehau  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
244d28e78fSSepherosa Ziehau  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
254d28e78fSSepherosa Ziehau  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
264d28e78fSSepherosa Ziehau  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
274d28e78fSSepherosa Ziehau  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
284d28e78fSSepherosa Ziehau  * SUCH DAMAGE.
2983c1faaaSSascha Wildner  *
3083c1faaaSSascha Wildner  * $FreeBSD: src/sys/dev/pci/fixup_pci.c,v 1.7.8.1 2009/04/15 03:14:26 kensmith Exp $
314d28e78fSSepherosa Ziehau  */
324d28e78fSSepherosa Ziehau 
334d28e78fSSepherosa Ziehau #include <sys/param.h>
344d28e78fSSepherosa Ziehau #include <sys/kernel.h>
354d28e78fSSepherosa Ziehau #include <sys/malloc.h>
364d28e78fSSepherosa Ziehau #include <sys/module.h>
374d28e78fSSepherosa Ziehau #include <sys/systm.h>
384d28e78fSSepherosa Ziehau #include <sys/bus.h>
394d28e78fSSepherosa Ziehau #include <sys/types.h>
404d28e78fSSepherosa Ziehau 
414d28e78fSSepherosa Ziehau #include <bus/pci/pcivar.h>
424d28e78fSSepherosa Ziehau #include <bus/pci/pcireg.h>
434d28e78fSSepherosa Ziehau 
444d28e78fSSepherosa Ziehau /*
454d28e78fSSepherosa Ziehau  * Chipset fixups.
464d28e78fSSepherosa Ziehau  *
474d28e78fSSepherosa Ziehau  * These routines are invoked during the probe phase for devices which
484d28e78fSSepherosa Ziehau  * typically don't have specific device drivers, but which require
494d28e78fSSepherosa Ziehau  * some cleaning up.
504d28e78fSSepherosa Ziehau  */
514d28e78fSSepherosa Ziehau 
524d28e78fSSepherosa Ziehau static int	fixup_pci_probe(device_t dev);
534d28e78fSSepherosa Ziehau static void	fixwsc_natoma(device_t dev);
544d28e78fSSepherosa Ziehau static void	fixc1_nforce2(device_t dev);
554d28e78fSSepherosa Ziehau 
564d28e78fSSepherosa Ziehau static device_method_t fixup_pci_methods[] = {
574d28e78fSSepherosa Ziehau     /* Device interface */
584d28e78fSSepherosa Ziehau     DEVMETHOD(device_probe,		fixup_pci_probe),
594d28e78fSSepherosa Ziehau     DEVMETHOD(device_attach,		bus_generic_attach),
60*d3c9c58eSSascha Wildner     DEVMETHOD_END
614d28e78fSSepherosa Ziehau };
624d28e78fSSepherosa Ziehau 
634d28e78fSSepherosa Ziehau static driver_t fixup_pci_driver = {
644d28e78fSSepherosa Ziehau     "fixup_pci",
654d28e78fSSepherosa Ziehau     fixup_pci_methods,
664d28e78fSSepherosa Ziehau     0,
674d28e78fSSepherosa Ziehau };
684d28e78fSSepherosa Ziehau 
694d28e78fSSepherosa Ziehau static devclass_t fixup_pci_devclass;
704d28e78fSSepherosa Ziehau 
71aa2b9d05SSascha Wildner DRIVER_MODULE(fixup_pci, pci, fixup_pci_driver, fixup_pci_devclass, NULL, NULL);
724d28e78fSSepherosa Ziehau 
734d28e78fSSepherosa Ziehau static int
fixup_pci_probe(device_t dev)744d28e78fSSepherosa Ziehau fixup_pci_probe(device_t dev)
754d28e78fSSepherosa Ziehau {
764d28e78fSSepherosa Ziehau     switch (pci_get_devid(dev)) {
774d28e78fSSepherosa Ziehau     case 0x12378086:		/* Intel 82440FX (Natoma) */
784d28e78fSSepherosa Ziehau 	fixwsc_natoma(dev);
794d28e78fSSepherosa Ziehau 	break;
804d28e78fSSepherosa Ziehau     case 0x01e010de:		/* nVidia nForce2 */
814d28e78fSSepherosa Ziehau 	fixc1_nforce2(dev);
824d28e78fSSepherosa Ziehau 	break;
834d28e78fSSepherosa Ziehau     }
844d28e78fSSepherosa Ziehau     return(ENXIO);
854d28e78fSSepherosa Ziehau }
864d28e78fSSepherosa Ziehau 
874d28e78fSSepherosa Ziehau static void
fixwsc_natoma(device_t dev)884d28e78fSSepherosa Ziehau fixwsc_natoma(device_t dev)
894d28e78fSSepherosa Ziehau {
904d28e78fSSepherosa Ziehau     int		pmccfg;
914d28e78fSSepherosa Ziehau 
924d28e78fSSepherosa Ziehau     pmccfg = pci_read_config(dev, 0x50, 2);
934d28e78fSSepherosa Ziehau     if (pmccfg & 0x8000) {
944d28e78fSSepherosa Ziehau 	kprintf("Correcting Natoma config for SMP\n");
954d28e78fSSepherosa Ziehau 	pmccfg &= ~0x8000;
964d28e78fSSepherosa Ziehau 	pci_write_config(dev, 0x50, pmccfg, 2);
974d28e78fSSepherosa Ziehau     }
984d28e78fSSepherosa Ziehau }
994d28e78fSSepherosa Ziehau 
1004d28e78fSSepherosa Ziehau /*
1014d28e78fSSepherosa Ziehau  * Set the SYSTEM_IDLE_TIMEOUT to 80 ns on nForce2 systems to work
1024d28e78fSSepherosa Ziehau  * around a hang that is triggered when the CPU generates a very fast
1034d28e78fSSepherosa Ziehau  * CONNECT/HALT cycle sequence.  Specifically, the hang can result in
1044d28e78fSSepherosa Ziehau  * the lapic timer being stopped.
1054d28e78fSSepherosa Ziehau  *
1064d28e78fSSepherosa Ziehau  * This requires changing the value for config register at offset 0x6c
1074d28e78fSSepherosa Ziehau  * for the Host-PCI bridge at bus/dev/function 0/0/0:
1084d28e78fSSepherosa Ziehau  *
1094d28e78fSSepherosa Ziehau  * Chip	Current Value	New Value
1104d28e78fSSepherosa Ziehau  * ----	----------	----------
1114d28e78fSSepherosa Ziehau  * C17	0x1F0FFF01	0x1F01FF01
1124d28e78fSSepherosa Ziehau  * C18D	0x9F0FFF01	0x9F01FF01
1134d28e78fSSepherosa Ziehau  *
1144d28e78fSSepherosa Ziehau  * We do this by always clearing the bits in 0x000e0000.
1154d28e78fSSepherosa Ziehau  *
1164d28e78fSSepherosa Ziehau  * See also: http://lkml.org/lkml/2004/5/3/157
1174d28e78fSSepherosa Ziehau  */
1184d28e78fSSepherosa Ziehau static void
fixc1_nforce2(device_t dev)1194d28e78fSSepherosa Ziehau fixc1_nforce2(device_t dev)
1204d28e78fSSepherosa Ziehau {
1214d28e78fSSepherosa Ziehau 	uint32_t val;
1224d28e78fSSepherosa Ziehau 
1234d28e78fSSepherosa Ziehau 	if (pci_get_bus(dev) == 0 && pci_get_slot(dev) == 0 &&
1244d28e78fSSepherosa Ziehau 	    pci_get_function(dev) == 0) {
1254d28e78fSSepherosa Ziehau 		val = pci_read_config(dev, 0x6c, 4);
1264d28e78fSSepherosa Ziehau 		if (val & 0x000e0000) {
1274d28e78fSSepherosa Ziehau 			kprintf("Correcting nForce2 C1 CPU disconnect hangs\n");
1284d28e78fSSepherosa Ziehau 			val &= ~0x000e0000;
1294d28e78fSSepherosa Ziehau 			pci_write_config(dev, 0x6c, val, 4);
1304d28e78fSSepherosa Ziehau 		}
1314d28e78fSSepherosa Ziehau 	}
1324d28e78fSSepherosa Ziehau }
133