[LinuxBIOS] I2c MUX -- pca9544 versus pca9548

Steve Isaacs yasteve at gmail.com
Thu Dec 6 20:09:08 CET 2007


I was dealing with a strange first-time issue that would cause problems
on power on but appear fine after that. I'm working with a dual Opteron
board with two banks of DIMMs on separate I2C buses connected to a
pca9544 I2C mux.

This problem manifested itself as a series of "no memory" messages
during startup after power on. Calling dump_smbus_registers would appear
to correct the problem since reading registers from the mux would leave
the last channel enabled which would allow reading of the second bank of
DIMMs. Which in turn meant that the second bank of DIMMs was being
detected twice and created other mysterious problems with RAM.

The issue was that unlike other 8 channel muxes the pca9544 is a 4
channel mux using a channel number and an enable bit to enable specific
channels. Most other muxes I've seen use a bit mask -- one bit per
channel -- to select channels and allow multiple channels to be selected
at one time which appears to be the way the LinuxBIOS code assumes a mux
to work.

I was able to work around this problem by adding code to my
cache_as_ram_auto.c:

static inline void activate_spd_rom(const struct mem_controller *ctrl)
{
#define SMBUS_HUB 0x71
        int ret,i;
        unsigned device=(ctrl->channel0[0])>>8;
        smbus_send_byte(SMBUS_HUB, device | 0x04);
}

The OR of 0x04 ensures that the channel is properly enabled.

To work fully this also required the following table be defined:

#define RC0 (2<<8)
#define RC1 (3<<8)

#define DIMM0 0x50
#define DIMM1 0x51
#define DIMM2 0x52
#define DIMM3 0x53

	static const uint16_t spd_addr[] = {
        	RC0|DIMM0, RC0|DIMM2, 0, 0,
                RC0|DIMM1, RC0|DIMM3, 0, 0,
#if CONFIG_MAX_PHYSICAL_CPUS > 1
                RC1|DIMM0, RC1|DIMM2, 0, 0,
                RC1|DIMM1, RC1|DIMM3, 0, 0,
#endif
		};

I have the feeling that this might be a viable work-around for me but
not very generic. Looking at the code I could not find a better place to
make these changes. Can someone point me to a better place if there is
one? The reason I ask is I'm unsure if the channels need to be properly
selected at a later time. Anything that uses I2C will need to select a
channel. This fixes things for SPD ROMs but what about other devices.
Suggestions?

Thanks,

Steve






More information about the coreboot mailing list