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