Subject: Re: NVIDIA nForce2/3/4 SMBus controller
To: None <current-users@NetBSD.org>
From: Bernd Ernesti <netbsd@lists.veego.de>
List: current-users
Date: 07/01/2007 08:12:52
--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sat, Jun 30, 2007 at 10:06:29PM +0900, KIYOHARA Takashi wrote:
> Hi! all,
> 
> 
> I wrote the nfsmb(4) driver for NVIDIA nForce2/3/4 SMBus controller.
> However, it might be difficult for me to verify that this source is
> correct.  I don't have the datasheet of nForce2/3/4, and do not know
> IC of what SMBus is mounted in my machine. 
> 
> This driver is looked and wrote to drivers/i2c/busses/i2c-nforce2.c of
> Linux.  Can this driver be verified?

I added the attached patch to amdpm where I ended up with:

amdpm0 at pci0 dev 1 function 1: NVIDIA nForce3 250 SMBus Controller (rev. 0xa1)
amdpm0: power management at 0x1c00
iic0 at amdpm0: I2C bus
amdpm0: random number generator enabled (apprx. 0ms)

But there is no i2c code for my it8712f, so I can't test it.

Bernd


--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="amdpm.patch"

Index: amdpm.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/amdpm.c,v
retrieving revision 1.25
diff -b -u -r1.25 amdpm.c
--- amdpm.c	5 Feb 2007 23:38:15 -0000	1.25
+++ amdpm.c	1 Jul 2007 06:06:02 -0000
@@ -85,6 +85,7 @@
 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NVIDIA) {
 		switch (PCI_PRODUCT(pa->pa_id)) {
 		case PCI_PRODUCT_NVIDIA_XBOX_SMBUS:
+		case PCI_PRODUCT_NVIDIA_NFORCE3_250_SMBUS:
 			return (1);
 		}
 	}
@@ -107,7 +108,7 @@
 	aprint_normal(": %s (rev. 0x%02x)\n", devinfo,
 	    PCI_REVISION(pa->pa_class));
 
-	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NVIDIA_XBOX_SMBUS)
+	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NVIDIA)
 		sc->sc_nforce = 1;
 	else
 		sc->sc_nforce = 0;
@@ -140,7 +141,28 @@
 	}
 
 	if (sc->sc_nforce) {
-		pmptrreg = pci_conf_read(pa->pa_pc, pa->pa_tag, NFORCE_PMPTR);
+		/*
+		 * The NForce SMBus has two I/O BAR regions + the one at BAR0.
+		 * At the moment we use the first non BAR0 for the attachment.
+		 */
+
+		/* Start at BAR1 */
+		for (i = PCI_MAPREG_START + 4; i < PCI_MAPREG_END; i += 4) {
+			if (pci_mapreg_type(pa->pa_pc, pa->pa_tag, i) ==
+			    PCI_MAPREG_TYPE_IO)
+				break;
+		}
+		if (i == PCI_MAPREG_END) {
+			/* Older NForce chipsets don't provide a valid BAR */
+			if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NVIDIA_NFORCE2_SMBUS) {
+				i = NFORCE_PMPTR_1;
+			} else {
+				aprint_error("%s: WARNING: unable to find I/O BAR\n",
+				    sc->sc_dev.dv_xname);
+				return;
+			}
+		}
+		pmptrreg = pci_conf_read(pa->pa_pc, pa->pa_tag, i);
 		aprint_normal("%s: power management at 0x%04x\n",
 		    sc->sc_dev.dv_xname, NFORCE_PMBASE(pmptrreg));
 		if (bus_space_map(sc->sc_iot, NFORCE_PMBASE(pmptrreg),
Index: amdpmreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/amdpmreg.h,v
retrieving revision 1.3
diff -b -u -r1.3 amdpmreg.h
--- amdpmreg.h	6 Jan 2007 00:14:21 -0000	1.3
+++ amdpmreg.h	1 Jul 2007 06:06:02 -0000
@@ -52,7 +52,8 @@
 
 #define	AMDPM_PMPTR	0x58		/* PMxx System Management IO space
 					   Pointer */
-#define	NFORCE_PMPTR	0x14		/* nForce System Management IO space */
+#define	NFORCE_PMPTR_1	0x50		/* nForce System Management IO space */
+#define	NFORCE_PMPTR_2	0x54		/* nForce System Management IO space */
 #define	AMDPM_PMBASE(x)	((x) & 0xff00)	/* PMxx base address */
 #define	NFORCE_PMBASE(x) ((x) & 0xfffc) /* nForce base address */
 #define	AMDPM_PMSIZE	256		/* PMxx space size */

--9amGYk9869ThD9tj--