diff options
Diffstat (limited to 'hw/arm')
| -rw-r--r-- | hw/arm/Kconfig | 1 | ||||
| -rw-r--r-- | hw/arm/npcm7xx.c | 68 | ||||
| -rw-r--r-- | hw/arm/npcm7xx_boards.c | 46 |
3 files changed, 99 insertions, 16 deletions
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index be017b997a..4e6f4ffe90 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -370,6 +370,7 @@ config NPCM7XX bool select A9MPCORE select ARM_GIC + select AT24C # EEPROM select PL310 # cache controller select SERIAL select SSI diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c index d1fe9bd1df..f8950f9470 100644 --- a/hw/arm/npcm7xx.c +++ b/hw/arm/npcm7xx.c @@ -102,6 +102,22 @@ enum NPCM7xxInterrupt { NPCM7XX_WDG2_IRQ, /* Timer Module 2 Watchdog */ NPCM7XX_EHCI_IRQ = 61, NPCM7XX_OHCI_IRQ = 62, + NPCM7XX_SMBUS0_IRQ = 64, + NPCM7XX_SMBUS1_IRQ, + NPCM7XX_SMBUS2_IRQ, + NPCM7XX_SMBUS3_IRQ, + NPCM7XX_SMBUS4_IRQ, + NPCM7XX_SMBUS5_IRQ, + NPCM7XX_SMBUS6_IRQ, + NPCM7XX_SMBUS7_IRQ, + NPCM7XX_SMBUS8_IRQ, + NPCM7XX_SMBUS9_IRQ, + NPCM7XX_SMBUS10_IRQ, + NPCM7XX_SMBUS11_IRQ, + NPCM7XX_SMBUS12_IRQ, + NPCM7XX_SMBUS13_IRQ, + NPCM7XX_SMBUS14_IRQ, + NPCM7XX_SMBUS15_IRQ, NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */ NPCM7XX_PWM1_IRQ, /* PWM module 1 */ NPCM7XX_GPIO0_IRQ = 116, @@ -152,6 +168,26 @@ static const hwaddr npcm7xx_pwm_addr[] = { 0xf0104000, }; +/* Direct memory-mapped access to each SMBus Module. */ +static const hwaddr npcm7xx_smbus_addr[] = { + 0xf0080000, + 0xf0081000, + 0xf0082000, + 0xf0083000, + 0xf0084000, + 0xf0085000, + 0xf0086000, + 0xf0087000, + 0xf0088000, + 0xf0089000, + 0xf008a000, + 0xf008b000, + 0xf008c000, + 0xf008d000, + 0xf008e000, + 0xf008f000, +}; + static const struct { hwaddr regs_addr; uint32_t unconnected_pins; @@ -353,6 +389,11 @@ static void npcm7xx_init(Object *obj) object_initialize_child(obj, "gpio[*]", &s->gpio[i], TYPE_NPCM7XX_GPIO); } + for (i = 0; i < ARRAY_SIZE(s->smbus); i++) { + object_initialize_child(obj, "smbus[*]", &s->smbus[i], + TYPE_NPCM7XX_SMBUS); + } + object_initialize_child(obj, "ehci", &s->ehci, TYPE_NPCM7XX_EHCI); object_initialize_child(obj, "ohci", &s->ohci, TYPE_SYSBUS_OHCI); @@ -509,6 +550,17 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp) npcm7xx_irq(s, NPCM7XX_GPIO0_IRQ + i)); } + /* SMBus modules. Cannot fail. */ + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_smbus_addr) != ARRAY_SIZE(s->smbus)); + for (i = 0; i < ARRAY_SIZE(s->smbus); i++) { + Object *obj = OBJECT(&s->smbus[i]); + + sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_smbus_addr[i]); + sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0, + npcm7xx_irq(s, NPCM7XX_SMBUS0_IRQ + i)); + } + /* USB Host */ object_property_set_bool(OBJECT(&s->ehci), "companion-enable", true, &error_abort); @@ -576,22 +628,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp) create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB); create_unimplemented_device("npcm7xx.kcs", 0xf0007000, 4 * KiB); create_unimplemented_device("npcm7xx.gfxi", 0xf000e000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[0]", 0xf0080000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[1]", 0xf0081000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[2]", 0xf0082000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[3]", 0xf0083000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[4]", 0xf0084000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[5]", 0xf0085000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[6]", 0xf0086000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[7]", 0xf0087000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[8]", 0xf0088000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[9]", 0xf0089000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[10]", 0xf008a000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[11]", 0xf008b000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[12]", 0xf008c000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[13]", 0xf008d000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[14]", 0xf008e000, 4 * KiB); - create_unimplemented_device("npcm7xx.smbus[15]", 0xf008f000, 4 * KiB); create_unimplemented_device("npcm7xx.espi", 0xf009f000, 4 * KiB); create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB); create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB); diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c index 3fdd5cab01..fbf6ce8e02 100644 --- a/hw/arm/npcm7xx_boards.c +++ b/hw/arm/npcm7xx_boards.c @@ -19,6 +19,7 @@ #include "exec/address-spaces.h" #include "hw/arm/npcm7xx.h" #include "hw/core/cpu.h" +#include "hw/i2c/smbus_eeprom.h" #include "hw/loader.h" #include "hw/qdev-properties.h" #include "qapi/error.h" @@ -98,6 +99,49 @@ static NPCM7xxState *npcm7xx_create_soc(MachineState *machine, return NPCM7XX(obj); } +static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, uint32_t num) +{ + g_assert(num < ARRAY_SIZE(soc->smbus)); + return I2C_BUS(qdev_get_child_bus(DEVICE(&soc->smbus[num]), "i2c-bus")); +} + +static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr, + uint32_t rsize) +{ + I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus); + I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr); + DeviceState *dev = DEVICE(i2c_dev); + + qdev_prop_set_uint32(dev, "rom-size", rsize); + i2c_slave_realize_and_unref(i2c_dev, i2c_bus, &error_abort); +} + +static void npcm750_evb_i2c_init(NPCM7xxState *soc) +{ + /* lm75 temperature sensor on SVB, tmp105 is compatible */ + i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 0), "tmp105", 0x48); + /* lm75 temperature sensor on EB, tmp105 is compatible */ + i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x48); + /* tmp100 temperature sensor on EB, tmp105 is compatible */ + i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x48); + /* tmp100 temperature sensor on SVB, tmp105 is compatible */ + i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48); +} + +static void quanta_gsj_i2c_init(NPCM7xxState *soc) +{ + /* GSJ machine have 4 max31725 temperature sensors, tmp105 is compatible. */ + i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x5c); + i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x5c); + i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c); + i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c); + + at24c_eeprom_init(soc, 9, 0x55, 8192); + at24c_eeprom_init(soc, 10, 0x55, 8192); + + /* TODO: Add additional i2c devices. */ +} + static void npcm750_evb_init(MachineState *machine) { NPCM7xxState *soc; @@ -108,6 +152,7 @@ static void npcm750_evb_init(MachineState *machine) npcm7xx_load_bootrom(machine, soc); npcm7xx_connect_flash(&soc->fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0)); + npcm750_evb_i2c_init(soc); npcm7xx_load_kernel(machine, soc); } @@ -122,6 +167,7 @@ static void quanta_gsj_init(MachineState *machine) npcm7xx_load_bootrom(machine, soc); npcm7xx_connect_flash(&soc->fiu[0], 0, "mx25l25635e", drive_get(IF_MTD, 0, 0)); + quanta_gsj_i2c_init(soc); npcm7xx_load_kernel(machine, soc); } |