summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/aspeed.c100
-rw-r--r--hw/arm/aspeed_ast2600.c2
-rw-r--r--hw/arm/aspeed_soc.c2
-rw-r--r--hw/block/m25p80.c1
-rw-r--r--hw/gpio/aspeed_gpio.c2
-rw-r--r--hw/ssi/aspeed_smc.c53
6 files changed, 113 insertions, 47 deletions
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 11558b327b..d205384d98 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -167,6 +167,11 @@ struct AspeedMachineState {
 #define FUJI_BMC_HW_STRAP1    0x00000000
 #define FUJI_BMC_HW_STRAP2    0x00000000
 
+/* Bletchley hardware value */
+/* TODO: Leave same as EVB for now. */
+#define BLETCHLEY_BMC_HW_STRAP1 AST2600_EVB_HW_STRAP1
+#define BLETCHLEY_BMC_HW_STRAP2 AST2600_EVB_HW_STRAP2
+
 /*
  * The max ram region is for firmwares that scan the address space
  * with load/store to guess how much RAM the SoC has.
@@ -246,7 +251,7 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
                            Error **errp)
 {
     BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-    uint8_t *storage;
+    g_autofree void *storage = NULL;
     int64_t size;
 
     /* The block backend size should have already been 'validated' by
@@ -262,23 +267,25 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
         rom_size = size;
     }
 
-    storage = g_new0(uint8_t, rom_size);
+    storage = g_malloc0(rom_size);
     if (blk_pread(blk, 0, storage, rom_size) < 0) {
         error_setg(errp, "failed to read the initial flash content");
         return;
     }
 
     rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
-    g_free(storage);
 }
 
-static void aspeed_board_init_flashes(AspeedSMCState *s,
-                                      const char *flashtype,
-                                      int unit0)
+static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
+                                      unsigned int count, int unit0)
 {
-    int i ;
+    int i;
+
+    if (!flashtype) {
+        return;
+    }
 
-    for (i = 0; i < s->num_cs; ++i) {
+    for (i = 0; i < count; ++i) {
         DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
         qemu_irq cs_line;
         DeviceState *dev;
@@ -345,8 +352,6 @@ static void aspeed_machine_init(MachineState *machine)
                             &error_abort);
     object_property_set_int(OBJECT(&bmc->soc), "hw-strap2", amc->hw_strap2,
                             &error_abort);
-    object_property_set_int(OBJECT(&bmc->soc), "num-cs", amc->num_cs,
-                            &error_abort);
     object_property_set_link(OBJECT(&bmc->soc), "dram",
                              OBJECT(machine->ram), &error_abort);
     if (machine->kernel_filename) {
@@ -374,10 +379,10 @@ static void aspeed_machine_init(MachineState *machine)
 
     aspeed_board_init_flashes(&bmc->soc.fmc,
                               bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
-                              0);
+                              amc->num_cs, 0);
     aspeed_board_init_flashes(&bmc->soc.spi[0],
                               bmc->spi_model ? bmc->spi_model : amc->spi_model,
-                              bmc->soc.fmc.num_cs);
+                              1, amc->num_cs);
 
     /* Install first FMC flash content as a boot rom. */
     if (drive0) {
@@ -897,6 +902,54 @@ static void fuji_bmc_i2c_init(AspeedMachineState *bmc)
     }
 }
 
+#define TYPE_TMP421 "tmp421"
+
+static void bletchley_bmc_i2c_init(AspeedMachineState *bmc)
+{
+    AspeedSoCState *soc = &bmc->soc;
+    I2CBus *i2c[13] = {};
+    for (int i = 0; i < 13; i++) {
+        if ((i == 8) || (i == 11)) {
+            continue;
+        }
+        i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i);
+    }
+
+    /* Bus 0 - 5 all have the same config. */
+    for (int i = 0; i < 6; i++) {
+        /* Missing model: ti,ina230 @ 0x45 */
+        /* Missing model: mps,mp5023 @ 0x40 */
+        i2c_slave_create_simple(i2c[i], TYPE_TMP421, 0x4f);
+        /* Missing model: nxp,pca9539 @ 0x76, but PCA9552 works enough */
+        i2c_slave_create_simple(i2c[i], TYPE_PCA9552, 0x76);
+        i2c_slave_create_simple(i2c[i], TYPE_PCA9552, 0x67);
+        /* Missing model: fsc,fusb302 @ 0x22 */
+    }
+
+    /* Bus 6 */
+    at24c_eeprom_init(i2c[6], 0x56, 65536);
+    /* Missing model: nxp,pcf85263 @ 0x51 , but ds1338 works enough */
+    i2c_slave_create_simple(i2c[6], "ds1338", 0x51);
+
+
+    /* Bus 7 */
+    at24c_eeprom_init(i2c[7], 0x54, 65536);
+
+    /* Bus 9 */
+    i2c_slave_create_simple(i2c[9], TYPE_TMP421, 0x4f);
+
+    /* Bus 10 */
+    i2c_slave_create_simple(i2c[10], TYPE_TMP421, 0x4f);
+    /* Missing model: ti,hdc1080 @ 0x40 */
+    i2c_slave_create_simple(i2c[10], TYPE_PCA9552, 0x67);
+
+    /* Bus 12 */
+    /* Missing model: adi,adm1278 @ 0x11 */
+    i2c_slave_create_simple(i2c[12], TYPE_TMP421, 0x4c);
+    i2c_slave_create_simple(i2c[12], TYPE_TMP421, 0x4d);
+    i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67);
+}
+
 static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
 {
     return ASPEED_MACHINE(obj)->mmio_exec;
@@ -1220,6 +1273,25 @@ static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data)
         aspeed_soc_num_cpus(amc->soc_name);
 };
 
+static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+    mc->desc       = "Facebook Bletchley BMC (Cortex-A7)";
+    amc->soc_name  = "ast2600-a3";
+    amc->hw_strap1 = BLETCHLEY_BMC_HW_STRAP1;
+    amc->hw_strap2 = BLETCHLEY_BMC_HW_STRAP2;
+    amc->fmc_model = "w25q01jvq";
+    amc->spi_model = NULL;
+    amc->num_cs    = 2;
+    amc->macs_mask = ASPEED_MAC2_ON;
+    amc->i2c_init  = bletchley_bmc_i2c_init;
+    mc->default_ram_size = 512 * MiB;
+    mc->default_cpus = mc->min_cpus = mc->max_cpus =
+        aspeed_soc_num_cpus(amc->soc_name);
+}
+
 static const TypeInfo aspeed_machine_types[] = {
     {
         .name          = MACHINE_TYPE_NAME("palmetto-bmc"),
@@ -1274,6 +1346,10 @@ static const TypeInfo aspeed_machine_types[] = {
         .parent        = TYPE_ASPEED_MACHINE,
         .class_init    = aspeed_machine_fuji_class_init,
     }, {
+        .name          = MACHINE_TYPE_NAME("bletchley-bmc"),
+        .parent        = TYPE_ASPEED_MACHINE,
+        .class_init    = aspeed_machine_bletchley_class_init,
+    }, {
         .name          = TYPE_ASPEED_MACHINE,
         .parent        = TYPE_MACHINE,
         .instance_size = sizeof(AspeedMachineState),
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 21cd3342c5..c1e15e3773 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -163,7 +163,6 @@ static void aspeed_soc_ast2600_init(Object *obj)
 
     snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
     object_initialize_child(obj, "fmc", &s->fmc, typename);
-    object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
 
     for (i = 0; i < sc->spis_num; i++) {
         snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
@@ -383,7 +382,6 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
     for (i = 0; i < sc->spis_num; i++) {
         object_property_set_link(OBJECT(&s->spi[i]), "dram",
                                  OBJECT(s->dram_mr), &error_abort);
-        object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort);
         if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
             return;
         }
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 7d53cf2f51..58714cb2a0 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -170,7 +170,6 @@ static void aspeed_soc_init(Object *obj)
 
     snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
     object_initialize_child(obj, "fmc", &s->fmc, typename);
-    object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
 
     for (i = 0; i < sc->spis_num; i++) {
         snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
@@ -327,7 +326,6 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
 
     /* SPI */
     for (i = 0; i < sc->spis_num; i++) {
-        object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort);
         if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
             return;
         }
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index c6bf3c6bfa..7d3d8b12e0 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -340,6 +340,7 @@ static const FlashPartInfo known_devices[] = {
     { INFO("w25q80bl",    0xef4014,      0,  64 << 10,  16, ER_4K) },
     { INFO("w25q256",     0xef4019,      0,  64 << 10, 512, ER_4K) },
     { INFO("w25q512jv",   0xef4020,      0,  64 << 10, 1024, ER_4K) },
+    { INFO("w25q01jvq",   0xef4021,      0,  64 << 10, 2048, ER_4K) },
 };
 
 typedef enum {
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index 911d21c8cf..c63634d3d3 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -571,7 +571,7 @@ static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
         qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
                       HWADDR_PRIx"\n", __func__, offset);
         return 0;
-    };
+    }
 }
 
 static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index d899be17fd..48305e1574 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -224,7 +224,7 @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
     AspeedSegments seg;
     int i;
 
-    for (i = 0; i < asc->max_peripherals; i++) {
+    for (i = 0; i < asc->cs_num_max; i++) {
         if (i == cs) {
             continue;
         }
@@ -290,7 +290,7 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
      */
     if ((asc->segments == aspeed_2500_spi1_segments ||
          asc->segments == aspeed_2500_spi2_segments) &&
-        cs == asc->max_peripherals &&
+        cs == asc->cs_num_max &&
         seg.addr + seg.size != asc->segments[cs].addr +
         asc->segments[cs].size) {
         aspeed_smc_error("Tried to change CS%d end address to 0x%"
@@ -327,7 +327,7 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
 static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
                                               unsigned size)
 {
-    aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u" PRIx64, addr, size);
+    aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u", addr, size);
     return 0;
 }
 
@@ -693,13 +693,13 @@ static void aspeed_smc_reset(DeviceState *d)
     }
 
     /* Unselect all peripherals */
-    for (i = 0; i < s->num_cs; ++i) {
+    for (i = 0; i < asc->cs_num_max; ++i) {
         s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
         qemu_set_irq(s->cs_lines[i], true);
     }
 
     /* setup the default segment register values and regions for all */
-    for (i = 0; i < asc->max_peripherals; ++i) {
+    for (i = 0; i < asc->cs_num_max; ++i) {
         aspeed_smc_flash_set_segment_region(s, i,
                     asc->segment_to_reg(s, &asc->segments[i]));
     }
@@ -729,8 +729,8 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
         (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
         (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
         (addr >= R_SEG_ADDR0 &&
-         addr < R_SEG_ADDR0 + asc->max_peripherals) ||
-        (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->max_peripherals)) {
+         addr < R_SEG_ADDR0 + asc->cs_num_max) ||
+        (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max)) {
 
         trace_aspeed_smc_read(addr << 2, size, s->regs[addr]);
 
@@ -1042,11 +1042,11 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
          addr < s->r_timings + asc->nregs_timings) ||
         addr == s->r_ce_ctrl) {
         s->regs[addr] = value;
-    } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
+    } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max) {
         int cs = addr - s->r_ctrl0;
         aspeed_smc_flash_update_ctrl(&s->flashes[cs], value);
     } else if (addr >= R_SEG_ADDR0 &&
-               addr < R_SEG_ADDR0 + asc->max_peripherals) {
+               addr < R_SEG_ADDR0 + asc->cs_num_max) {
         int cs = addr - R_SEG_ADDR0;
 
         if (value != s->regs[R_SEG_ADDR0 + cs]) {
@@ -1090,7 +1090,7 @@ static void aspeed_smc_instance_init(Object *obj)
     AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
     int i;
 
-    for (i = 0; i < asc->max_peripherals; i++) {
+    for (i = 0; i < asc->cs_num_max; i++) {
         object_initialize_child(obj, "flash[*]", &s->flashes[i],
                                 TYPE_ASPEED_SMC_FLASH);
     }
@@ -1127,21 +1127,15 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
     s->r_timings = asc->r_timings;
     s->conf_enable_w0 = asc->conf_enable_w0;
 
-    /* Enforce some real HW limits */
-    if (s->num_cs > asc->max_peripherals) {
-        aspeed_smc_error("num_cs cannot exceed: %d", asc->max_peripherals);
-        s->num_cs = asc->max_peripherals;
-    }
-
     /* DMA irq. Keep it first for the initialization in the SoC */
     sysbus_init_irq(sbd, &s->irq);
 
-    s->spi = ssi_create_bus(dev, "spi");
+    s->spi = ssi_create_bus(dev, NULL);
 
     /* Setup cs_lines for peripherals */
-    s->cs_lines = g_new0(qemu_irq, s->num_cs);
+    s->cs_lines = g_new0(qemu_irq, asc->cs_num_max);
 
-    for (i = 0; i < s->num_cs; ++i) {
+    for (i = 0; i < asc->cs_num_max; ++i) {
         sysbus_init_irq(sbd, &s->cs_lines[i]);
     }
 
@@ -1174,7 +1168,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
      * module behind to handle the memory accesses. This depends on
      * the board configuration.
      */
-    for (i = 0; i < asc->max_peripherals; ++i) {
+    for (i = 0; i < asc->cs_num_max; ++i) {
         AspeedSMCFlash *fl = &s->flashes[i];
 
         if (!object_property_set_link(OBJECT(fl), "controller", OBJECT(s),
@@ -1211,7 +1205,6 @@ static const VMStateDescription vmstate_aspeed_smc = {
 };
 
 static Property aspeed_smc_properties[] = {
-    DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
     DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
     DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
                      TYPE_MEMORY_REGION, MemoryRegion *),
@@ -1321,7 +1314,7 @@ static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_TIMINGS;
     asc->nregs_timings     = 1;
     asc->conf_enable_w0    = CONF_ENABLE_W0;
-    asc->max_peripherals   = 1;
+    asc->cs_num_max        = 1;
     asc->segments          = aspeed_2400_smc_segments;
     asc->flash_window_base = 0x10000000;
     asc->flash_window_size = 0x6000000;
@@ -1366,7 +1359,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_TIMINGS;
     asc->nregs_timings     = 1;
     asc->conf_enable_w0    = CONF_ENABLE_W0;
-    asc->max_peripherals   = 5;
+    asc->cs_num_max        = 5;
     asc->segments          = aspeed_2400_fmc_segments;
     asc->segment_addr_mask = 0xffff0000;
     asc->resets            = aspeed_2400_fmc_resets;
@@ -1408,7 +1401,7 @@ static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_SPI_TIMINGS;
     asc->nregs_timings     = 1;
     asc->conf_enable_w0    = SPI_CONF_ENABLE_W0;
-    asc->max_peripherals   = 1;
+    asc->cs_num_max        = 1;
     asc->segments          = aspeed_2400_spi1_segments;
     asc->flash_window_base = 0x30000000;
     asc->flash_window_size = 0x10000000;
@@ -1449,7 +1442,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_TIMINGS;
     asc->nregs_timings     = 1;
     asc->conf_enable_w0    = CONF_ENABLE_W0;
-    asc->max_peripherals   = 3;
+    asc->cs_num_max        = 3;
     asc->segments          = aspeed_2500_fmc_segments;
     asc->segment_addr_mask = 0xffff0000;
     asc->resets            = aspeed_2500_fmc_resets;
@@ -1487,7 +1480,7 @@ static void aspeed_2500_spi1_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_TIMINGS;
     asc->nregs_timings     = 1;
     asc->conf_enable_w0    = CONF_ENABLE_W0;
-    asc->max_peripherals   = 2;
+    asc->cs_num_max        = 2;
     asc->segments          = aspeed_2500_spi1_segments;
     asc->segment_addr_mask = 0xffff0000;
     asc->flash_window_base = 0x30000000;
@@ -1522,7 +1515,7 @@ static void aspeed_2500_spi2_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_TIMINGS;
     asc->nregs_timings     = 1;
     asc->conf_enable_w0    = CONF_ENABLE_W0;
-    asc->max_peripherals   = 2;
+    asc->cs_num_max        = 2;
     asc->segments          = aspeed_2500_spi2_segments;
     asc->segment_addr_mask = 0xffff0000;
     asc->flash_window_base = 0x38000000;
@@ -1604,7 +1597,7 @@ static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_TIMINGS;
     asc->nregs_timings     = 1;
     asc->conf_enable_w0    = CONF_ENABLE_W0;
-    asc->max_peripherals   = 3;
+    asc->cs_num_max        = 3;
     asc->segments          = aspeed_2600_fmc_segments;
     asc->segment_addr_mask = 0x0ff00ff0;
     asc->resets            = aspeed_2600_fmc_resets;
@@ -1643,7 +1636,7 @@ static void aspeed_2600_spi1_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_TIMINGS;
     asc->nregs_timings     = 2;
     asc->conf_enable_w0    = CONF_ENABLE_W0;
-    asc->max_peripherals   = 2;
+    asc->cs_num_max        = 2;
     asc->segments          = aspeed_2600_spi1_segments;
     asc->segment_addr_mask = 0x0ff00ff0;
     asc->flash_window_base = 0x30000000;
@@ -1682,7 +1675,7 @@ static void aspeed_2600_spi2_class_init(ObjectClass *klass, void *data)
     asc->r_timings         = R_TIMINGS;
     asc->nregs_timings     = 3;
     asc->conf_enable_w0    = CONF_ENABLE_W0;
-    asc->max_peripherals   = 3;
+    asc->cs_num_max        = 3;
     asc->segments          = aspeed_2600_spi2_segments;
     asc->segment_addr_mask = 0x0ff00ff0;
     asc->flash_window_base = 0x50000000;