Set SMBIOS mainboard version based on i2c eeprom

In the field there are different hardware revisions and some
of them have problems with UDMA as a resistor is missing. We can
detect this situation in coreboot and e.g. the linux kernel
can take this knowledge and disable UDMA.

Change-Id: Ib75cad7acedbc1dc65378bb9bfc3f353cbe21427
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Reviewed-on: http://review.coreboot.org/1512
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
This commit is contained in:
Christian Gmeiner 2012-09-14 16:29:10 +02:00
parent ea8011b21d
commit a59a9f7943
1 changed files with 52 additions and 0 deletions

View File

@ -18,7 +18,59 @@
*/
#include <device/device.h>
#include <device/smbus.h>
#include <smbios.h>
#include <console/console.h>
/* overwrite a weak function to fill SMBIOS table with a custom value */
static u8 hw_rev = 0;
static char mb_rev_str[2] = { '0' };
const char *smbios_mainboard_version(void)
{
/* UDMA is not working on all supported devices */
if (hw_rev < 113) {
mb_rev_str[0] = '1';
} else {
mb_rev_str[0] = '2';
}
return mb_rev_str;
}
static void init(struct device *dev)
{
unsigned int i;
u32 chksum = 0;
char block[20];
device_t eeprom_dev = dev_find_slot_on_smbus(1, 0x52);
if (eeprom_dev == 0) {
printk(BIOS_WARNING, "eeprom not found\n");
return;
}
/* read the whole block and check if checksum is okay */
for (i = 0; i < 20; i++) {
block[i] = smbus_read_byte(eeprom_dev, i);
chksum += block[i];
}
if (chksum != 0) {
printk(BIOS_WARNING, "wrong checksum: 0x%0x\n", chksum);
}
hw_rev = block[5];
printk(BIOS_DEBUG, "hw revision: %u\n", hw_rev);
}
static void enable_dev(struct device *dev)
{
dev->ops->init = init;
}
struct chip_operations mainboard_ops = {
CHIP_NAME(CONFIG_MAINBOARD_VENDOR " " CONFIG_MAINBOARD_PART_NUMBER)
.enable_dev = enable_dev,
};