1/*	$NetBSD: pchb.c,v 1.32 2011/08/20 20:01:08 jakllsch Exp $ */
2
3/*-
4 * Copyright (c) 1996, 1998, 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.32 2011/08/20 20:01:08 jakllsch Exp $");
34
35#include <sys/types.h>
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/device.h>
39
40#include <sys/bus.h>
41
42#include <dev/pci/pcivar.h>
43#include <dev/pci/pcireg.h>
44
45#include <dev/pci/pcidevs.h>
46
47#include <dev/pci/agpreg.h>
48#include <dev/pci/agpvar.h>
49
50#include <arch/x86/pci/pchbvar.h>
51
52#define PCISET_BRIDGETYPE_MASK	0x3
53#define PCISET_TYPE_COMPAT	0x1
54#define PCISET_TYPE_AUX		0x2
55
56#define PCISET_BUSCONFIG_REG	0x48
57#define PCISET_BRIDGE_NUMBER(reg)	(((reg) >> 8) & 0xff)
58#define PCISET_PCI_BUS_NUMBER(reg)	(((reg) >> 16) & 0xff)
59
60/* XXX should be in dev/ic/i82443reg.h */
61#define	I82443BX_SDRAMC_REG	0x74 /* upper 16 bits */
62
63/* XXX should be in dev/ic/i82424{reg.var}.h */
64#define I82424_CPU_BCTL_REG		0x53
65#define I82424_PCI_BCTL_REG		0x54
66
67#define I82424_BCTL_CPUMEM_POSTEN	0x01
68#define I82424_BCTL_CPUPCI_POSTEN	0x02
69#define I82424_BCTL_PCIMEM_BURSTEN	0x01
70#define I82424_BCTL_PCI_BURSTEN		0x02
71
72static int	pchbmatch(device_t, cfdata_t, void *);
73static void	pchbattach(device_t, device_t, void *);
74static int	pchbdetach(device_t, int);
75static int	pchbrescan(device_t, const char *, const int *);
76static void	pchbchilddet(device_t, device_t);
77
78static bool	pchb_resume(device_t, const pmf_qual_t *);
79static bool	pchb_suspend(device_t, const pmf_qual_t *);
80
81static void	pchb_amdtempbus_configure(struct pchb_softc *);
82
83CFATTACH_DECL3_NEW(pchb, sizeof(struct pchb_softc),
84    pchbmatch, pchbattach, pchbdetach, NULL, pchbrescan, pchbchilddet, DVF_DETACH_SHUTDOWN);
85
86static int
87pchbmatch(device_t parent, cfdata_t match, void *aux)
88{
89	struct pci_attach_args *pa = aux;
90
91	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
92	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST)
93		return 1;
94
95	return 0;
96}
97
98int
99pchb_get_bus_number(pci_chipset_tag_t pc, pcitag_t tag)
100{
101	pcireg_t dev_id;
102	int bus, dev, func;
103	int bcreg, pbnum;
104
105	pci_decompose_tag(pc, tag, &bus, &dev, &func);
106
107	dev_id = pci_conf_read(pc, tag, PCI_ID_REG);
108	switch (PCI_VENDOR(dev_id)) {
109	case PCI_VENDOR_SERVERWORKS:
110		return pci_conf_read(pc, tag, 0x44) & 0xff;
111	case PCI_VENDOR_INTEL:
112		switch (PCI_PRODUCT(dev_id)) {
113		case PCI_PRODUCT_INTEL_82452_PB:
114			bcreg = pci_conf_read(pc, tag, 0x40);
115			pbnum = PCISET_BRIDGE_NUMBER(bcreg);
116			if (pbnum != 0xff)
117				return pbnum + 1;
118
119			break;
120		case PCI_PRODUCT_INTEL_PCI450_PB:
121			bcreg = pci_conf_read(pc, tag, PCISET_BUSCONFIG_REG);
122			return PCISET_PCI_BUS_NUMBER(bcreg);
123		case PCI_PRODUCT_INTEL_82451NX_PXB:
124			pbnum = 0;
125			switch (dev) {
126			case 18: /* PXB 0 bus A - primary bus */
127				break;
128			case 19: /* PXB 0 bus B */
129				/* read SUBA0 from MIOC */
130				tag = pci_make_tag(pc, 0, 16, 0);
131				bcreg = pci_conf_read(pc, tag, 0xd0);
132				pbnum = ((bcreg & 0x0000ff00) >> 8) + 1;
133				break;
134			case 20: /* PXB 1 bus A */
135				/* read BUSNO1 from MIOC */
136				tag = pci_make_tag(pc, 0, 16, 0);
137				bcreg = pci_conf_read(pc, tag, 0xd0);
138				pbnum = (bcreg & 0xff000000) >> 24;
139				break;
140			case 21: /* PXB 1 bus B */
141				/* read SUBA1 from MIOC */
142				tag = pci_make_tag(pc, 0, 16, 0);
143				bcreg = pci_conf_read(pc, tag, 0xd4);
144				pbnum = (bcreg & 0x000000ff) + 1;
145				break;
146			}
147			return pbnum;
148		}
149	}
150	return -1;
151}
152
153static void
154pchbattach(device_t parent, device_t self, void *aux)
155{
156	struct pchb_softc *sc = device_private(self);
157	const struct pci_attach_args *pa = aux;
158	struct pcibus_attach_args pba;
159	struct agpbus_attach_args apa;
160	pcireg_t bcreg;
161	u_char bdnum, pbnum = 0; /* XXX: gcc */
162	pcitag_t tag;
163	int doattach, attachflags, has_agp;
164
165	doattach = 0;
166	has_agp = 0;
167	attachflags = pa->pa_flags;
168
169	sc->sc_dev = self;
170	sc->sc_pa = *pa;
171
172	/*
173	 * Print out a description, and configure certain chipsets which
174	 * have auxiliary PCI buses.
175	 */
176
177	pci_aprint_devinfo(pa, NULL);
178
179	switch (PCI_VENDOR(pa->pa_id)) {
180	/*
181	 * i386 stuff.
182	 */
183	case PCI_VENDOR_SERVERWORKS:
184		pbnum = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xff;
185
186		if (pbnum == 0)
187			break;
188
189		/*
190		 * This host bridge has a second PCI bus.
191		 * Configure it.
192		 */
193		switch (PCI_PRODUCT(pa->pa_id)) {
194		case PCI_PRODUCT_SERVERWORKS_CSB5:
195		case PCI_PRODUCT_SERVERWORKS_CSB6:
196			/* These devices show up as host bridges, but are
197			   really southbridges. */
198			break;
199		case PCI_PRODUCT_SERVERWORKS_CMIC_HE:
200		case PCI_PRODUCT_SERVERWORKS_CMIC_LE:
201		case PCI_PRODUCT_SERVERWORKS_CMIC_SL:
202			/* CNBs and CIOBs are connected to these using a
203			   private bus.  The bus number register is that of
204			   the first PCI bus hanging off the CIOB.  We let
205			   the CIOB attachment handle configuring the PCI
206			   buses. */
207			break;
208		default:
209			aprint_error_dev(self,
210			    "unknown ServerWorks chip ID 0x%04x; trying "
211			    "to attach PCI buses behind it\n",
212			    PCI_PRODUCT(pa->pa_id));
213			/* FALLTHROUGH */
214		case PCI_PRODUCT_SERVERWORKS_CNB20_LE_AGP:
215		case PCI_PRODUCT_SERVERWORKS_CNB30_LE_PCI:
216		case PCI_PRODUCT_SERVERWORKS_CNB20_LE_PCI:
217		case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI:
218		case PCI_PRODUCT_SERVERWORKS_CNB20_HE_AGP:
219		case PCI_PRODUCT_SERVERWORKS_CIOB_X:
220		case PCI_PRODUCT_SERVERWORKS_CNB30_HE:
221		case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI2:
222		case PCI_PRODUCT_SERVERWORKS_CIOB_X2:
223		case PCI_PRODUCT_SERVERWORKS_CIOB_E:
224			switch (attachflags &
225			    (PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY)) {
226			case 0:
227				/* Doesn't smell like there's anything there. */
228				break;
229			case PCI_FLAGS_MEM_OKAY:
230				attachflags |= PCI_FLAGS_IO_OKAY;
231				/* FALLTHROUGH */
232			default:
233				doattach = 1;
234				break;
235			}
236			break;
237		}
238		break;
239	case PCI_VENDOR_INTEL:
240		switch (PCI_PRODUCT(pa->pa_id)) {
241		case PCI_PRODUCT_INTEL_82452_PB:
242			bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
243			pbnum = PCISET_BRIDGE_NUMBER(bcreg);
244			if (pbnum != 0xff) {
245				pbnum++;
246				doattach = 1;
247			}
248			break;
249		case PCI_PRODUCT_INTEL_82443BX_AGP:
250		case PCI_PRODUCT_INTEL_82443BX_NOAGP:
251		/*
252		 * http://www.intel.com/design/chipsets/specupdt/290639.htm
253		 * says this bug is fixed in steppings >= C0 (erratum 11),
254		 * so don't tweak the bits in that case.
255		 */
256			if (!(PCI_REVISION(pa->pa_class) >= 0x03)) {
257				/*
258				 * BIOS BUG WORKAROUND!  The 82443BX
259				 * datasheet indicates that the only
260				 * legal setting for the "Idle/Pipeline
261				 * DRAM Leadoff Timing (IPLDT)" parameter
262				 * (bits 9:8) is 01.  Unfortunately, some
263				 * BIOSs do not set these bits properly.
264				 */
265				bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
266				    I82443BX_SDRAMC_REG);
267				if ((bcreg & 0x03000000) != 0x01000000) {
268					aprint_verbose_dev(self, "fixing "
269					    "Idle/Pipeline DRAM "
270					    "Leadoff Timing\n");
271					bcreg &= ~0x03000000;
272					bcreg |=  0x01000000;
273					pci_conf_write(pa->pa_pc, pa->pa_tag,
274					    I82443BX_SDRAMC_REG, bcreg);
275				}
276			}
277			break;
278
279		case PCI_PRODUCT_INTEL_PCI450_PB:
280			bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
281					      PCISET_BUSCONFIG_REG);
282			bdnum = PCISET_BRIDGE_NUMBER(bcreg);
283			pbnum = PCISET_PCI_BUS_NUMBER(bcreg);
284			switch (bdnum & PCISET_BRIDGETYPE_MASK) {
285			default:
286				aprint_error_dev(self, "bdnum=%x (reserved)\n",
287				       bdnum);
288				break;
289			case PCISET_TYPE_COMPAT:
290				aprint_verbose_dev(self,
291				    "Compatibility PB (bus %d)\n", pbnum);
292				break;
293			case PCISET_TYPE_AUX:
294				aprint_verbose_dev(self,
295				    "Auxiliary PB (bus %d)\n",pbnum);
296				/*
297				 * This host bridge has a second PCI bus.
298				 * Configure it.
299				 */
300				doattach = 1;
301				break;
302			}
303			break;
304		case PCI_PRODUCT_INTEL_CDC:
305			bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
306					      I82424_CPU_BCTL_REG);
307			if (bcreg & I82424_BCTL_CPUPCI_POSTEN) {
308				bcreg &= ~I82424_BCTL_CPUPCI_POSTEN;
309				pci_conf_write(pa->pa_pc, pa->pa_tag,
310					       I82424_CPU_BCTL_REG, bcreg);
311				aprint_verbose_dev(self,
312				    "disabled CPU-PCI write posting\n");
313			}
314			break;
315		case PCI_PRODUCT_INTEL_82451NX_PXB:
316			/*
317			 * The NX chipset supports up to 2 "PXB" chips
318			 * which can drive 2 PCI buses each. Each bus
319			 * shows up as logical PCI device, with fixed
320			 * device numbers between 18 and 21.
321			 * See the datasheet at
322		ftp://download.intel.com/design/chipsets/datashts/24377102.pdf
323			 * for details.
324			 * (It would be easier to attach all the buses
325			 * at the MIOC, but less aesthetical imho.)
326			 */
327			if ((attachflags &
328			    (PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY)) ==
329			    PCI_FLAGS_MEM_OKAY)
330				attachflags |= PCI_FLAGS_IO_OKAY;
331
332			pbnum = 0;
333			switch (pa->pa_device) {
334			case 18: /* PXB 0 bus A - primary bus */
335				break;
336			case 19: /* PXB 0 bus B */
337				/* read SUBA0 from MIOC */
338				tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
339				bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
340				pbnum = ((bcreg & 0x0000ff00) >> 8) + 1;
341				break;
342			case 20: /* PXB 1 bus A */
343				/* read BUSNO1 from MIOC */
344				tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
345				bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
346				pbnum = (bcreg & 0xff000000) >> 24;
347				break;
348			case 21: /* PXB 1 bus B */
349				/* read SUBA1 from MIOC */
350				tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
351				bcreg = pci_conf_read(pa->pa_pc, tag, 0xd4);
352				pbnum = (bcreg & 0x000000ff) + 1;
353				break;
354			}
355			if (pbnum != 0)
356				doattach = 1;
357			break;
358
359		/*
360		 * i386 and amd64 stuff.
361		 */
362		case PCI_PRODUCT_INTEL_82810_MCH:
363		case PCI_PRODUCT_INTEL_82810_DC100_MCH:
364		case PCI_PRODUCT_INTEL_82810E_MCH:
365		case PCI_PRODUCT_INTEL_82815_FULL_HUB:
366		case PCI_PRODUCT_INTEL_82830MP_IO_1:
367		case PCI_PRODUCT_INTEL_82845G_DRAM:
368		case PCI_PRODUCT_INTEL_82855GM_MCH:
369		case PCI_PRODUCT_INTEL_82865_HB:
370		case PCI_PRODUCT_INTEL_82915G_HB:
371		case PCI_PRODUCT_INTEL_82915GM_HB:
372		case PCI_PRODUCT_INTEL_82945P_MCH:
373		case PCI_PRODUCT_INTEL_82945GM_HB:
374		case PCI_PRODUCT_INTEL_82945GME_HB:
375		case PCI_PRODUCT_INTEL_82946GZ_HB:
376		case PCI_PRODUCT_INTEL_82965Q_HB:
377		case PCI_PRODUCT_INTEL_82965G_HB:
378		case PCI_PRODUCT_INTEL_82965PM_HB:
379		case PCI_PRODUCT_INTEL_82Q35_HB:
380		case PCI_PRODUCT_INTEL_82G33_HB:
381		case PCI_PRODUCT_INTEL_82Q33_HB:
382		case PCI_PRODUCT_INTEL_82G35_HB:
383		case PCI_PRODUCT_INTEL_82GM45_HB:
384		case PCI_PRODUCT_INTEL_82IGD_E_HB:
385		case PCI_PRODUCT_INTEL_82Q45_HB:
386		case PCI_PRODUCT_INTEL_82G45_HB:
387		case PCI_PRODUCT_INTEL_82G41_HB:
388		case PCI_PRODUCT_INTEL_E7221_HB:
389		case PCI_PRODUCT_INTEL_82965GME_HB:
390		case PCI_PRODUCT_INTEL_82B43_HB:
391		case PCI_PRODUCT_INTEL_IRONLAKE_D_HB:
392		case PCI_PRODUCT_INTEL_IRONLAKE_M_HB:
393		case PCI_PRODUCT_INTEL_IRONLAKE_MA_HB:
394		case PCI_PRODUCT_INTEL_IRONLAKE_MC2_HB:
395		case PCI_PRODUCT_INTEL_PINEVIEW_HB:
396		case PCI_PRODUCT_INTEL_PINEVIEW_M_HB:
397			/*
398			 * The host bridge is either in GFX mode (internal
399			 * graphics) or in AGP mode. In GFX mode, we pretend
400			 * to have AGP because the graphics memory access
401			 * is very similar and the AGP GATT code will
402			 * deal with this. In the latter case, the
403			 * pci_get_capability(PCI_CAP_AGP) test below will
404			 * fire, so we do no harm by already setting the flag.
405			 */
406			has_agp = 1;
407			break;
408		}
409		break;
410	}
411
412	if (!pmf_device_register(self, pchb_suspend, pchb_resume))
413		aprint_error_dev(self, "couldn't establish power handler\n");
414
415	/*
416	 * If we haven't detected AGP yet (via a product ID),
417	 * then check for AGP capability on the device.
418	 */
419	if (has_agp ||
420	    pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
421			       NULL, NULL) != 0) {
422		apa.apa_pci_args = *pa;
423		config_found_ia(self, "agpbus", &apa, agpbusprint);
424	}
425
426	if (doattach) {
427		pba.pba_iot = pa->pa_iot;
428		pba.pba_memt = pa->pa_memt;
429		pba.pba_dmat = pa->pa_dmat;
430		pba.pba_dmat64 = pa->pa_dmat64;
431		pba.pba_pc = pa->pa_pc;
432		pba.pba_flags = attachflags;
433		pba.pba_bus = pbnum;
434		pba.pba_bridgetag = NULL;
435		pba.pba_pc = pa->pa_pc;
436		pba.pba_intrswiz = 0;
437		memset(&pba.pba_intrtag, 0, sizeof(pba.pba_intrtag));
438		config_found_ia(self, "pcibus", &pba, pcibusprint);
439	}
440
441	pchb_amdtempbus_configure(sc);
442}
443
444static int
445pchbdetach(device_t self, int flags)
446{
447	int rc;
448
449	if ((rc = config_detach_children(self, flags)) != 0)
450		return rc;
451
452	pmf_device_deregister(self);
453
454	return 0;
455}
456
457static int
458pchbrescan(device_t self, const char *ifattr, const int *locators)
459{
460	struct pchb_softc *sc = device_private(self);
461
462	if (ifattr_match(ifattr, "amdtempbus"))
463		pchb_amdtempbus_configure(sc);
464
465	return 0;
466}
467
468static void
469pchbchilddet(device_t self, device_t child)
470{
471	struct pchb_softc *sc = device_private(self);
472
473	if (sc->sc_amdtempbus == child) {
474		sc->sc_amdtempbus = NULL;
475		return;
476	}
477}
478
479static bool
480pchb_suspend(device_t dv, const pmf_qual_t *qual)
481{
482	struct pchb_softc *sc = device_private(dv);
483	pci_chipset_tag_t pc;
484	pcitag_t tag;
485	int off;
486
487	pc = sc->sc_pa.pa_pc;
488	tag = sc->sc_pa.pa_tag;
489
490	for (off = 0x40; off <= 0xff; off += 4)
491		sc->sc_pciconfext[(off - 0x40) / 4] = pci_conf_read(pc, tag, off);
492
493	return true;
494}
495
496static bool
497pchb_resume(device_t dv, const pmf_qual_t *qual)
498{
499	struct pchb_softc *sc = device_private(dv);
500	pci_chipset_tag_t pc;
501	pcitag_t tag;
502	int off;
503
504	pc = sc->sc_pa.pa_pc;
505	tag = sc->sc_pa.pa_tag;
506
507	for (off = 0x40; off <= 0xff; off += 4)
508		pci_conf_write(pc, tag, off, sc->sc_pciconfext[(off - 0x40) / 4]);
509
510	return true;
511}
512
513static void
514pchb_amdtempbus_configure(struct pchb_softc *sc)
515{
516	if (sc->sc_amdtempbus != NULL)
517		return;
518
519	sc->sc_amdtempbus = config_found_ia(sc->sc_dev, "amdtempbus", &sc->sc_pa, NULL);
520}
521