Subject: Re: NVIDIA nForce2/3/4 SMBus controller
To: KIYOHARA Takashi <kiyohara@kk.iij4u.or.jp>
From: Nicolas Joly <njoly@pasteur.fr>
List: current-users
Date: 07/14/2007 22:56:59
On Thu, Jul 05, 2007 at 02:33:07PM +0200, Nicolas Joly wrote:
> On Sat, Jun 30, 2007 at 04:06:00PM -0700, Paul Goyette wrote:
> >
> > It successfully probes the devices. I'm not sure if it does anything
> > useful, since I don't have anything to actually access the I2C bus...
>
> You should see the memory modules, using the small (attached) driver
> `spdmem' i wrote when i was trying to add support for some SMBus
> controllers.
>
> It simply tries to detect memory modules using `Serial Presence
> Detect' (SPD) datas found on modules eeproms (i2c addr 0x50,0x51,...).
>
> The first memory module (this machine has 32GB (16 x 2GB) of RAM)
> seems to be correctly detected :
>
> nfsmbc0 at pci0 dev 1 function 1: NVIDIA nForce4 SMBus (rev. 0xa2)
> nfsmb0 at nfsmbc0 SMBus 1
> iic0 at nfsmb0: I2C bus
> spdmem0 at iic0 addr 0x50: DDR2 SDRAM memory module
> nfsmb1 at nfsmbc0 SMBus 2
> iic1 at nfsmb1: I2C bus
For the record, i forgot to say that i needed a slightly patched
version of nfsmb_check_done() to make it work (taken from FreeBSD):
Index: sys/dev/pci/nfsmb.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/nfsmb.c,v
retrieving revision 1.1
diff -u -r1.1 nfsmb.c
--- sys/dev/pci/nfsmb.c 11 Jul 2007 07:53:29 -0000 1.1
+++ sys/dev/pci/nfsmb.c 14 Jul 2007 20:46:37 -0000
@@ -291,21 +291,19 @@
static int
nfsmb_check_done(struct nfsmb_softc *sc)
{
+ int i;
uint8_t stat;
- stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, NFORCE_SMB_STATUS);
-
- if (~stat & NFORCE_SMB_STATUS_DONE) {
+ for (i = 10000; i > 0; i--) {
+ stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, NFORCE_SMB_PROTOCOL);
+ if (stat == 0)
+ break;
delay(500);
- stat =
- bus_space_read_1(sc->sc_iot, sc->sc_ioh, NFORCE_SMB_STATUS);
- }
- if (~stat & NFORCE_SMB_STATUS_DONE) {
- tsleep(sc, PCATCH, "nfsmb", hz / 100);
- stat =
- bus_space_read_1(sc->sc_iot, sc->sc_ioh, NFORCE_SMB_STATUS);
}
+ if (i == 0)
+ return -1;
+ stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, NFORCE_SMB_STATUS);
if ((stat & NFORCE_SMB_STATUS_DONE) &&
!(stat & NFORCE_SMB_STATUS_STATUS))
return 0;
Here is the output with some i2c device adresses scanning :
nfsmbc0 at pci0 dev 1 function 1: NVIDIA nForce4 SMBus (rev. 0xa2)
nfsmb0 at nfsmbc0 SMBus 1
iic0 at nfsmb0: I2C bus
iic0: devices at 0x18 0x30 0x31 0x32 0x33 0x50 0x51 0x52 0x53
spdmem0 at iic0 addr 0x50: DDR2 SDRAM memory module
spdmem1 at iic0 addr 0x51: DDR2 SDRAM memory module
spdmem2 at iic0 addr 0x52: DDR2 SDRAM memory module
spdmem3 at iic0 addr 0x53: DDR2 SDRAM memory module
nfsmb1 at nfsmbc0 SMBus 2
iic1 at nfsmb1: I2C bus
iic1: devices at 0x19 0x2d 0x48
Thanks for working on it.
--
Nicolas Joly
Biological Software and Databanks.
Institut Pasteur, Paris.