Aspeed patches :

* MAC enablement fixes (Guenter)
 * Watchdog  and pca9552 fixes (Andrew)
 * GPIO fixes (Joel)
 * AST2600A3 SoC and DPS310 models (Joel)
 * New Fuji BMC machine (Peter)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmFIL2sACgkQUaNDx8/7
 7KF4vQ//bNPQQjvGEOEVcRKJXIhL2BW8UTMMJXSNSM0TyA2IygDn3jWrnZDy/Y77
 bp0J56nNNvnw51f1mA5aYU9ETWddLE88+r03Pwx/9nkWlXEPl2CFP7hkiVgzdLoV
 QcssuhxY9GWRkTEpZ64NaF3sBwqQSIQ1BEqBKyEkK8RG57ouDTxKpgQiV4+/cluy
 FRWF6/ax5pAIlchs1XWQI6Lhjif8SRAXwiRzE7Hl7miInaaA8GPkw6p4q7L1SM7y
 LStiYW2L/FVi5DyeG8UbR7vaT0D3zRsKsYZcSJGTcGMinuRK8/9syNmZqwDOG3be
 y6MKaWujcjT1lW/jMxF4Z+qJl4wI3+4KECd5DbziNq2Tx28oPgoVBrVISZUkiU5j
 4E3imKPegwxJCGbCh1ptZ51SHLVOQAAiynNeMw352OymtE6odyHQHz8HxBOHsmuY
 Yr/WJOS/0En8CEmxrdsjFLXVDXmWCX9F4Cyme7wgjVl/eCpHA+bOT1VAsC0UFBIm
 I3OETwjuQnPsRb/zWTxaODglfEHYur5ITpe7iCBIu9btI+Nfs0ygTR4DVPC/0Z9N
 Ul9HBqkIkgn8sNUECpSoxlsY78fDh/5udoZYQGiJhUXtmtUNDIWYsazbVLAqptT0
 r4+xCklBW4zVt7KtCZPds9hQbGyKysZkPgcUlji0IBZ3hkEyCIg=
 =F0zk
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/legoater/tags/pull-aspeed-20210920' into staging

Aspeed patches :

* MAC enablement fixes (Guenter)
* Watchdog  and pca9552 fixes (Andrew)
* GPIO fixes (Joel)
* AST2600A3 SoC and DPS310 models (Joel)
* New Fuji BMC machine (Peter)

# gpg: Signature made Mon 20 Sep 2021 07:51:23 BST
# gpg:                using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: A0F6 6548 F048 95EB FE6B  0B60 51A3 43C7 CFFB ECA1

* remotes/legoater/tags/pull-aspeed-20210920:
  hw/arm/aspeed: Add Fuji machine type
  hw/arm/aspeed: Allow machine to set UART default
  hw/arm/aspeed: Initialize AST2600 UART clock selection registers
  arm/aspeed: Add DPS310 to Witherspoon and Rainier
  hw/misc: Add Infineon DPS310 sensor model
  aspeed: Emulate the AST2600A3
  arm/aspeed: rainier: Add i2c eeproms and muxes
  misc/pca9552: Fix LED status register indexing in pca955x_get_led()
  hw: aspeed_gpio: Clarify GPIO controller name
  hw: aspeed_gpio: Simplify 1.8V defines
  watchdog: aspeed: Fix sequential control writes
  watchdog: aspeed: Sanitize control register values
  hw: arm: aspeed: Enable mac0/1 instead of mac1/2 for g220a
  hw: arm: aspeed: Enable eth0 interface for aspeed-ast2600-evb

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-09-21 13:58:09 +01:00
commit 1c81a38c5a
15 changed files with 529 additions and 76 deletions

View file

@ -428,6 +428,7 @@ config ASPEED_SOC
select DS1338
select FTGMAC100
select I2C
select DPS310
select PCA9552
select SERIAL
select SMBUS_EEPROM

View file

@ -159,6 +159,10 @@ struct AspeedMachineState {
#define RAINIER_BMC_HW_STRAP1 0x00000000
#define RAINIER_BMC_HW_STRAP2 0x00000000
/* Fuji hardware value */
#define FUJI_BMC_HW_STRAP1 0x00000000
#define FUJI_BMC_HW_STRAP2 0x00000000
/*
* The max ram region is for firmwares that scan the address space
* with load/store to guess how much RAM the SoC has.
@ -350,6 +354,8 @@ static void aspeed_machine_init(MachineState *machine)
object_property_set_int(OBJECT(&bmc->soc), "hw-prot-key",
ASPEED_SCU_PROT_KEY, &error_abort);
}
qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
amc->uart_default);
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
memory_region_add_subregion(get_system_memory(),
@ -602,7 +608,6 @@ static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
/* Bus 3: TODO bmp280@77 */
/* Bus 3: TODO max31785@52 */
/* Bus 3: TODO dps310@76 */
dev = DEVICE(i2c_slave_new(TYPE_PCA9552, 0x60));
qdev_prop_set_string(dev, "description", "pca1");
i2c_slave_realize_and_unref(I2C_SLAVE(dev),
@ -617,6 +622,7 @@ static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
qdev_connect_gpio_out(dev, pca1_leds[i].gpio_id,
qdev_get_gpio_in(DEVICE(led), 0));
}
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 3), "dps310", 0x76);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), "tmp423", 0x4c);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), "tmp423", 0x4c);
@ -674,9 +680,21 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
eeprom_buf);
}
static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
{
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, bus, &error_abort);
}
static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
I2CSlave *i2c_mux;
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 0), 0x51, 32 * KiB);
/* The rainier expects a TMP275 but a TMP105 is compatible */
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), TYPE_TMP105,
@ -685,11 +703,20 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
0x49);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), TYPE_TMP105,
0x4a);
i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4),
"pca9546", 0x70);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), TYPE_TMP105,
0x48);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), TYPE_TMP105,
0x49);
i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5),
"pca9546", 0x70);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), TYPE_TMP105,
0x48);
@ -697,18 +724,28 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
0x4a);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), TYPE_TMP105,
0x4b);
i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6),
"pca9546", 0x70);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
/* Bus 7: TODO dps310@76 */
/* Bus 7: TODO max31785@52 */
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "pca9552", 0x61);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "dps310", 0x76);
/* Bus 7: TODO si7021-a20@20 */
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), TYPE_TMP105,
0x48);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 7), 0x50, 64 * KiB);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 7), 0x51, 64 * KiB);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), TYPE_TMP105,
0x48);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), TYPE_TMP105,
0x4a);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 8), 0x50, 64 * KiB);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 8), 0x51, 64 * KiB);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "pca9552", 0x61);
/* Bus 8: ucd90320@11 */
/* Bus 8: ucd90320@b */
@ -716,14 +753,112 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "tmp423", 0x4c);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "tmp423", 0x4d);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 9), 0x50, 128 * KiB);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10), "tmp423", 0x4c);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10), "tmp423", 0x4d);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 10), 0x50, 128 * KiB);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 11), TYPE_TMP105,
0x48);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 11), TYPE_TMP105,
0x49);
i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 11),
"pca9546", 0x70);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 13), 0x50, 64 * KiB);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 14), 0x50, 64 * KiB);
aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 15), 0x50, 64 * KiB);
}
static void get_pca9548_channels(I2CBus *bus, uint8_t mux_addr,
I2CBus **channels)
{
I2CSlave *mux = i2c_slave_create_simple(bus, "pca9548", mux_addr);
for (int i = 0; i < 8; i++) {
channels[i] = pca954x_i2c_get_bus(mux, i);
}
}
#define TYPE_LM75 TYPE_TMP105
#define TYPE_TMP75 TYPE_TMP105
#define TYPE_TMP422 "tmp422"
static void fuji_bmc_i2c_init(AspeedMachineState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
I2CBus *i2c[144] = {};
for (int i = 0; i < 16; i++) {
i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i);
}
I2CBus *i2c180 = i2c[2];
I2CBus *i2c480 = i2c[8];
I2CBus *i2c600 = i2c[11];
get_pca9548_channels(i2c180, 0x70, &i2c[16]);
get_pca9548_channels(i2c480, 0x70, &i2c[24]);
/* NOTE: The device tree skips [32, 40) in the alias numbering */
get_pca9548_channels(i2c600, 0x77, &i2c[40]);
get_pca9548_channels(i2c[24], 0x71, &i2c[48]);
get_pca9548_channels(i2c[25], 0x72, &i2c[56]);
get_pca9548_channels(i2c[26], 0x76, &i2c[64]);
get_pca9548_channels(i2c[27], 0x76, &i2c[72]);
for (int i = 0; i < 8; i++) {
get_pca9548_channels(i2c[40 + i], 0x76, &i2c[80 + i * 8]);
}
i2c_slave_create_simple(i2c[17], TYPE_LM75, 0x4c);
i2c_slave_create_simple(i2c[17], TYPE_LM75, 0x4d);
aspeed_eeprom_init(i2c[19], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[20], 0x50, 2 * KiB);
aspeed_eeprom_init(i2c[22], 0x52, 2 * KiB);
i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x48);
i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x49);
i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x4a);
i2c_slave_create_simple(i2c[3], TYPE_TMP422, 0x4c);
aspeed_eeprom_init(i2c[8], 0x51, 64 * KiB);
i2c_slave_create_simple(i2c[8], TYPE_LM75, 0x4a);
i2c_slave_create_simple(i2c[50], TYPE_LM75, 0x4c);
aspeed_eeprom_init(i2c[50], 0x52, 64 * KiB);
i2c_slave_create_simple(i2c[51], TYPE_TMP75, 0x48);
i2c_slave_create_simple(i2c[52], TYPE_TMP75, 0x49);
i2c_slave_create_simple(i2c[59], TYPE_TMP75, 0x48);
i2c_slave_create_simple(i2c[60], TYPE_TMP75, 0x49);
aspeed_eeprom_init(i2c[65], 0x53, 64 * KiB);
i2c_slave_create_simple(i2c[66], TYPE_TMP75, 0x49);
i2c_slave_create_simple(i2c[66], TYPE_TMP75, 0x48);
aspeed_eeprom_init(i2c[68], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[69], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[70], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[71], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[73], 0x53, 64 * KiB);
i2c_slave_create_simple(i2c[74], TYPE_TMP75, 0x49);
i2c_slave_create_simple(i2c[74], TYPE_TMP75, 0x48);
aspeed_eeprom_init(i2c[76], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[77], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[78], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[79], 0x52, 64 * KiB);
aspeed_eeprom_init(i2c[28], 0x50, 2 * KiB);
for (int i = 0; i < 8; i++) {
aspeed_eeprom_init(i2c[81 + i * 8], 0x56, 64 * KiB);
i2c_slave_create_simple(i2c[82 + i * 8], TYPE_TMP75, 0x48);
i2c_slave_create_simple(i2c[83 + i * 8], TYPE_TMP75, 0x4b);
i2c_slave_create_simple(i2c[84 + i * 8], TYPE_TMP75, 0x4a);
}
}
static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
@ -804,6 +939,7 @@ static void aspeed_machine_class_init(ObjectClass *oc, void *data)
mc->no_parallel = 1;
mc->default_ram_id = "ram";
amc->macs_mask = ASPEED_MAC0_ON;
amc->uart_default = ASPEED_DEV_UART5;
aspeed_machine_class_props_init(oc);
}
@ -953,13 +1089,14 @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
mc->desc = "Aspeed AST2600 EVB (Cortex-A7)";
amc->soc_name = "ast2600-a1";
amc->soc_name = "ast2600-a3";
amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
amc->fmc_model = "w25q512jv";
amc->spi_model = "mx66u51235f";
amc->num_cs = 1;
amc->macs_mask = ASPEED_MAC1_ON | ASPEED_MAC2_ON | ASPEED_MAC3_ON;
amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON |
ASPEED_MAC3_ON;
amc->i2c_init = ast2600_evb_i2c_init;
mc->default_ram_size = 1 * GiB;
mc->default_cpus = mc->min_cpus = mc->max_cpus =
@ -972,7 +1109,7 @@ static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
mc->desc = "OpenPOWER Tacoma BMC (Cortex-A7)";
amc->soc_name = "ast2600-a1";
amc->soc_name = "ast2600-a3";
amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
amc->fmc_model = "mx66l1g45g";
@ -996,7 +1133,7 @@ static void aspeed_machine_g220a_class_init(ObjectClass *oc, void *data)
amc->fmc_model = "n25q512a";
amc->spi_model = "mx25l25635e";
amc->num_cs = 2;
amc->macs_mask = ASPEED_MAC1_ON | ASPEED_MAC2_ON;
amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON;
amc->i2c_init = g220a_bmc_i2c_init;
mc->default_ram_size = 1024 * MiB;
mc->default_cpus = mc->min_cpus = mc->max_cpus =
@ -1009,7 +1146,7 @@ static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data)
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
mc->desc = "IBM Rainier BMC (Cortex-A7)";
amc->soc_name = "ast2600-a1";
amc->soc_name = "ast2600-a3";
amc->hw_strap1 = RAINIER_BMC_HW_STRAP1;
amc->hw_strap2 = RAINIER_BMC_HW_STRAP2;
amc->fmc_model = "mx66l1g45g";
@ -1022,6 +1159,33 @@ static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data)
aspeed_soc_num_cpus(amc->soc_name);
};
/* On 32-bit hosts, lower RAM to 1G because of the 2047 MB limit */
#if HOST_LONG_BITS == 32
#define FUJI_BMC_RAM_SIZE (1 * GiB)
#else
#define FUJI_BMC_RAM_SIZE (2 * GiB)
#endif
static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
mc->desc = "Facebook Fuji BMC (Cortex-A7)";
amc->soc_name = "ast2600-a3";
amc->hw_strap1 = FUJI_BMC_HW_STRAP1;
amc->hw_strap2 = FUJI_BMC_HW_STRAP2;
amc->fmc_model = "mx66l1g45g";
amc->spi_model = "mx66l1g45g";
amc->num_cs = 2;
amc->macs_mask = ASPEED_MAC3_ON;
amc->i2c_init = fuji_bmc_i2c_init;
amc->uart_default = ASPEED_DEV_UART1;
mc->default_ram_size = FUJI_BMC_RAM_SIZE;
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"),
@ -1071,6 +1235,10 @@ static const TypeInfo aspeed_machine_types[] = {
.name = MACHINE_TYPE_NAME("rainier-bmc"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_rainier_class_init,
}, {
.name = MACHINE_TYPE_NAME("fuji-bmc"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_fuji_class_init,
}, {
.name = TYPE_ASPEED_MACHINE,
.parent = TYPE_MACHINE,

View file

@ -322,10 +322,10 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
}
/* UART - attach an 8250 to the IO space as our UART5 */
serial_mm_init(get_system_memory(), sc->memmap[ASPEED_DEV_UART5], 2,
aspeed_soc_get_irq(s, ASPEED_DEV_UART5),
38400, serial_hd(0), DEVICE_LITTLE_ENDIAN);
/* UART - attach an 8250 to the IO space as our UART */
serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
aspeed_soc_get_irq(s, s->uart_default), 38400,
serial_hd(0), DEVICE_LITTLE_ENDIAN);
/* I2C */
object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
@ -516,9 +516,9 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
dc->realize = aspeed_soc_ast2600_realize;
sc->name = "ast2600-a1";
sc->name = "ast2600-a3";
sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
sc->silicon_rev = AST2600_A1_SILICON_REV;
sc->silicon_rev = AST2600_A3_SILICON_REV;
sc->sram_size = 0x16400;
sc->spis_num = 2;
sc->ehcis_num = 2;
@ -530,7 +530,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
}
static const TypeInfo aspeed_soc_ast2600_type_info = {
.name = "ast2600-a1",
.name = "ast2600-a3",
.parent = TYPE_ASPEED_SOC,
.instance_size = sizeof(AspeedSoCState),
.instance_init = aspeed_soc_ast2600_init,

View file

@ -287,9 +287,9 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
}
/* UART - attach an 8250 to the IO space as our UART5 */
serial_mm_init(get_system_memory(), sc->memmap[ASPEED_DEV_UART5], 2,
aspeed_soc_get_irq(s, ASPEED_DEV_UART5), 38400,
/* UART - attach an 8250 to the IO space as our UART */
serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
aspeed_soc_get_irq(s, s->uart_default), 38400,
serial_hd(0), DEVICE_LITTLE_ENDIAN);
/* I2C */
@ -439,6 +439,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
static Property aspeed_soc_properties[] = {
DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
MemoryRegion *),
DEFINE_PROP_UINT32("uart-default", AspeedSoCState, uart_default,
ASPEED_DEV_UART5),
DEFINE_PROP_END_OF_LIST(),
};

View file

@ -164,49 +164,48 @@
#define GPIO_YZAAAB_DIRECTION (0x1E4 >> 2)
#define GPIO_AC_DATA_VALUE (0x1E8 >> 2)
#define GPIO_AC_DIRECTION (0x1EC >> 2)
#define GPIO_3_6V_MEM_SIZE 0x1F0
#define GPIO_3_6V_REG_ARRAY_SIZE (GPIO_3_6V_MEM_SIZE >> 2)
#define GPIO_3_3V_MEM_SIZE 0x1F0
#define GPIO_3_3V_REG_ARRAY_SIZE (GPIO_3_3V_MEM_SIZE >> 2)
/* AST2600 only - 1.8V gpios */
/*
* The AST2600 has same 3.6V gpios as the AST2400 (memory offsets 0x0-0x198)
* and additional 1.8V gpios (memory offsets 0x800-0x9D4).
* The AST2600 two copies of the GPIO controller: the same 3.3V gpios as the
* AST2400 (memory offsets 0x0-0x198) and a second controller with 1.8V gpios
* (memory offsets 0x800-0x9D4).
*/
#define GPIO_1_8V_REG_OFFSET 0x800
#define GPIO_1_8V_ABCD_DATA_VALUE ((0x800 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_DIRECTION ((0x804 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_INT_ENABLE ((0x808 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_INT_SENS_0 ((0x80C - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_INT_SENS_1 ((0x810 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_INT_SENS_2 ((0x814 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_INT_STATUS ((0x818 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_RESET_TOLERANT ((0x81C - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_DATA_VALUE ((0x820 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_DIRECTION ((0x824 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_INT_ENABLE ((0x828 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_INT_SENS_0 ((0x82C - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_INT_SENS_1 ((0x830 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_INT_SENS_2 ((0x834 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_INT_STATUS ((0x838 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_RESET_TOLERANT ((0x83C - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_DEBOUNCE_1 ((0x840 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_DEBOUNCE_2 ((0x844 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_DEBOUNCE_1 ((0x848 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_DEBOUNCE_2 ((0x84C - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_DEBOUNCE_TIME_1 ((0x850 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_DEBOUNCE_TIME_2 ((0x854 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_DEBOUNCE_TIME_3 ((0x858 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_COMMAND_SRC_0 ((0x860 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_COMMAND_SRC_1 ((0x864 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_COMMAND_SRC_0 ((0x868 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_COMMAND_SRC_1 ((0x86C - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_DATA_READ ((0x8C0 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_DATA_READ ((0x8C4 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_INPUT_MASK ((0x9D0 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_E_INPUT_MASK ((0x9D4 - GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_MEM_SIZE 0x9D8
#define GPIO_1_8V_REG_ARRAY_SIZE ((GPIO_1_8V_MEM_SIZE - \
GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_1_8V_ABCD_DATA_VALUE (0x000 >> 2)
#define GPIO_1_8V_ABCD_DIRECTION (0x004 >> 2)
#define GPIO_1_8V_ABCD_INT_ENABLE (0x008 >> 2)
#define GPIO_1_8V_ABCD_INT_SENS_0 (0x00C >> 2)
#define GPIO_1_8V_ABCD_INT_SENS_1 (0x010 >> 2)
#define GPIO_1_8V_ABCD_INT_SENS_2 (0x014 >> 2)
#define GPIO_1_8V_ABCD_INT_STATUS (0x018 >> 2)
#define GPIO_1_8V_ABCD_RESET_TOLERANT (0x01C >> 2)
#define GPIO_1_8V_E_DATA_VALUE (0x020 >> 2)
#define GPIO_1_8V_E_DIRECTION (0x024 >> 2)
#define GPIO_1_8V_E_INT_ENABLE (0x028 >> 2)
#define GPIO_1_8V_E_INT_SENS_0 (0x02C >> 2)
#define GPIO_1_8V_E_INT_SENS_1 (0x030 >> 2)
#define GPIO_1_8V_E_INT_SENS_2 (0x034 >> 2)
#define GPIO_1_8V_E_INT_STATUS (0x038 >> 2)
#define GPIO_1_8V_E_RESET_TOLERANT (0x03C >> 2)
#define GPIO_1_8V_ABCD_DEBOUNCE_1 (0x040 >> 2)
#define GPIO_1_8V_ABCD_DEBOUNCE_2 (0x044 >> 2)
#define GPIO_1_8V_E_DEBOUNCE_1 (0x048 >> 2)
#define GPIO_1_8V_E_DEBOUNCE_2 (0x04C >> 2)
#define GPIO_1_8V_DEBOUNCE_TIME_1 (0x050 >> 2)
#define GPIO_1_8V_DEBOUNCE_TIME_2 (0x054 >> 2)
#define GPIO_1_8V_DEBOUNCE_TIME_3 (0x058 >> 2)
#define GPIO_1_8V_ABCD_COMMAND_SRC_0 (0x060 >> 2)
#define GPIO_1_8V_ABCD_COMMAND_SRC_1 (0x064 >> 2)
#define GPIO_1_8V_E_COMMAND_SRC_0 (0x068 >> 2)
#define GPIO_1_8V_E_COMMAND_SRC_1 (0x06C >> 2)
#define GPIO_1_8V_ABCD_DATA_READ (0x0C0 >> 2)
#define GPIO_1_8V_E_DATA_READ (0x0C4 >> 2)
#define GPIO_1_8V_ABCD_INPUT_MASK (0x1D0 >> 2)
#define GPIO_1_8V_E_INPUT_MASK (0x1D4 >> 2)
#define GPIO_1_8V_MEM_SIZE 0x1D8
#define GPIO_1_8V_REG_ARRAY_SIZE (GPIO_1_8V_MEM_SIZE >> 2)
static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio)
{
@ -381,7 +380,7 @@ static uint32_t update_value_control_source(GPIOSets *regs, uint32_t old_value,
return new_value;
}
static const AspeedGPIOReg aspeed_3_6v_gpios[GPIO_3_6V_REG_ARRAY_SIZE] = {
static const AspeedGPIOReg aspeed_3_3v_gpios[GPIO_3_3V_REG_ARRAY_SIZE] = {
/* Set ABCD */
[GPIO_ABCD_DATA_VALUE] = { 0, gpio_reg_data_value },
[GPIO_ABCD_DIRECTION] = { 0, gpio_reg_direction },
@ -801,7 +800,7 @@ static const GPIOSetProperties ast2500_set_props[] = {
[7] = {0x000000ff, 0x000000ff, {"AC"} },
};
static GPIOSetProperties ast2600_3_6v_set_props[] = {
static GPIOSetProperties ast2600_3_3v_set_props[] = {
[0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
[1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
[2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
@ -928,7 +927,7 @@ static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data)
agc->nr_gpio_pins = 216;
agc->nr_gpio_sets = 7;
agc->gap = 196;
agc->reg_table = aspeed_3_6v_gpios;
agc->reg_table = aspeed_3_3v_gpios;
}
static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
@ -939,17 +938,17 @@ static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
agc->nr_gpio_pins = 228;
agc->nr_gpio_sets = 8;
agc->gap = 220;
agc->reg_table = aspeed_3_6v_gpios;
agc->reg_table = aspeed_3_3v_gpios;
}
static void aspeed_gpio_ast2600_3_6v_class_init(ObjectClass *klass, void *data)
static void aspeed_gpio_ast2600_3_3v_class_init(ObjectClass *klass, void *data)
{
AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
agc->props = ast2600_3_6v_set_props;
agc->props = ast2600_3_3v_set_props;
agc->nr_gpio_pins = 208;
agc->nr_gpio_sets = 7;
agc->reg_table = aspeed_3_6v_gpios;
agc->reg_table = aspeed_3_3v_gpios;
}
static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass, void *data)
@ -985,10 +984,10 @@ static const TypeInfo aspeed_gpio_ast2500_info = {
.instance_init = aspeed_gpio_init,
};
static const TypeInfo aspeed_gpio_ast2600_3_6v_info = {
static const TypeInfo aspeed_gpio_ast2600_3_3v_info = {
.name = TYPE_ASPEED_GPIO "-ast2600",
.parent = TYPE_ASPEED_GPIO,
.class_init = aspeed_gpio_ast2600_3_6v_class_init,
.class_init = aspeed_gpio_ast2600_3_3v_class_init,
.instance_init = aspeed_gpio_init,
};
@ -1004,7 +1003,7 @@ static void aspeed_gpio_register_types(void)
type_register_static(&aspeed_gpio_info);
type_register_static(&aspeed_gpio_ast2400_info);
type_register_static(&aspeed_gpio_ast2500_info);
type_register_static(&aspeed_gpio_ast2600_3_6v_info);
type_register_static(&aspeed_gpio_ast2600_3_3v_info);
type_register_static(&aspeed_gpio_ast2600_1_8v_info);
}

View file

@ -101,14 +101,26 @@
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94)
#define AST2600_DEBUG_CTRL TO_REG(0xC8)
#define AST2600_DEBUG_CTRL2 TO_REG(0xD8)
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
#define AST2600_HPLL_PARAM TO_REG(0x200)
#define AST2600_HPLL_EXT TO_REG(0x204)
#define AST2600_APLL_PARAM TO_REG(0x210)
#define AST2600_APLL_EXT TO_REG(0x214)
#define AST2600_MPLL_PARAM TO_REG(0x220)
#define AST2600_MPLL_EXT TO_REG(0x224)
#define AST2600_EPLL_PARAM TO_REG(0x240)
#define AST2600_EPLL_EXT TO_REG(0x244)
#define AST2600_DPLL_PARAM TO_REG(0x260)
#define AST2600_DPLL_EXT TO_REG(0x264)
#define AST2600_CLK_SEL TO_REG(0x300)
#define AST2600_CLK_SEL2 TO_REG(0x304)
#define AST2600_CLK_SEL3 TO_REG(0x310)
#define AST2600_CLK_SEL3 TO_REG(0x308)
#define AST2600_CLK_SEL4 TO_REG(0x310)
#define AST2600_CLK_SEL5 TO_REG(0x314)
#define AST2600_UARTCLK TO_REG(0x338)
#define AST2600_HUARTCLK TO_REG(0x33C)
#define AST2600_HW_STRAP1 TO_REG(0x500)
#define AST2600_HW_STRAP1_CLR TO_REG(0x504)
#define AST2600_HW_STRAP1_PROT TO_REG(0x508)
@ -433,6 +445,8 @@ static uint32_t aspeed_silicon_revs[] = {
AST2500_A1_SILICON_REV,
AST2600_A0_SILICON_REV,
AST2600_A1_SILICON_REV,
AST2600_A2_SILICON_REV,
AST2600_A3_SILICON_REV,
};
bool is_supported_silicon_rev(uint32_t silicon_rev)
@ -651,16 +665,28 @@ static const MemoryRegionOps aspeed_ast2600_scu_ops = {
.valid.unaligned = false,
};
static const uint32_t ast2600_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = {
static const uint32_t ast2600_a3_resets[ASPEED_AST2600_SCU_NR_REGS] = {
[AST2600_SYS_RST_CTRL] = 0xF7C3FED8,
[AST2600_SYS_RST_CTRL2] = 0xFFFFFFFC,
[AST2600_SYS_RST_CTRL2] = 0x0DFFFFFC,
[AST2600_CLK_STOP_CTRL] = 0xFFFF7F8A,
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
[AST2600_DEBUG_CTRL] = 0x00000FFF,
[AST2600_DEBUG_CTRL2] = 0x000000FF,
[AST2600_SDRAM_HANDSHAKE] = 0x00000000,
[AST2600_HPLL_PARAM] = 0x1000405F,
[AST2600_HPLL_PARAM] = 0x1000408F,
[AST2600_APLL_PARAM] = 0x1000405F,
[AST2600_MPLL_PARAM] = 0x1008405F,
[AST2600_EPLL_PARAM] = 0x1004077F,
[AST2600_DPLL_PARAM] = 0x1078405F,
[AST2600_CLK_SEL] = 0xF3940000,
[AST2600_CLK_SEL2] = 0x00700000,
[AST2600_CLK_SEL3] = 0x00000000,
[AST2600_CLK_SEL4] = 0xF3F40000,
[AST2600_CLK_SEL5] = 0x30000000,
[AST2600_UARTCLK] = 0x00014506,
[AST2600_HUARTCLK] = 0x000145C0,
[AST2600_CHIP_ID0] = 0x1234ABCD,
[AST2600_CHIP_ID1] = 0x88884444,
};
static void aspeed_ast2600_scu_reset(DeviceState *dev)
@ -675,7 +701,7 @@ static void aspeed_ast2600_scu_reset(DeviceState *dev)
* of actual revision. QEMU and Linux only support A1 onwards so this is
* sufficient.
*/
s->regs[AST2600_SILICON_REV] = AST2600_A1_SILICON_REV;
s->regs[AST2600_SILICON_REV] = AST2600_A3_SILICON_REV;
s->regs[AST2600_SILICON_REV2] = s->silicon_rev;
s->regs[AST2600_HW_STRAP1] = s->hw_strap1;
s->regs[AST2600_HW_STRAP2] = s->hw_strap2;
@ -689,7 +715,7 @@ static void aspeed_2600_scu_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2600 System Control Unit";
dc->reset = aspeed_ast2600_scu_reset;
asc->resets = ast2600_a1_resets;
asc->resets = ast2600_a3_resets;
asc->calc_hpll = aspeed_2500_scu_calc_hpll; /* No change since AST2500 */
asc->apb_divider = 4;
asc->nr_regs = ASPEED_AST2600_SCU_NR_REGS;

View file

@ -272,7 +272,7 @@ static void pca955x_get_led(Object *obj, Visitor *v, const char *name,
* reading the INPUTx reg
*/
reg = PCA9552_LS0 + led / 4;
state = (pca955x_read(s, reg) >> (led % 8)) & 0x3;
state = (pca955x_read(s, reg) >> ((led % 4) * 2)) & 0x3;
visit_type_str(v, name, (char **)&led_state[state], errp);
}

View file

@ -6,6 +6,10 @@ config TMP421
bool
depends on I2C
config DPS310
bool
depends on I2C
config EMC141X
bool
depends on I2C

225
hw/sensor/dps310.c Normal file
View file

@ -0,0 +1,225 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2017-2021 Joel Stanley <joel@jms.id.au>, IBM Corporation
*
* Infineon DPS310 temperature and humidity sensor
*
* https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps310/
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/hw.h"
#include "hw/i2c/i2c.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "migration/vmstate.h"
#define NUM_REGISTERS 0x33
typedef struct DPS310State {
/*< private >*/
I2CSlave i2c;
/*< public >*/
uint8_t regs[NUM_REGISTERS];
uint8_t len;
uint8_t pointer;
} DPS310State;
#define TYPE_DPS310 "dps310"
#define DPS310(obj) OBJECT_CHECK(DPS310State, (obj), TYPE_DPS310)
#define DPS310_PRS_B2 0x00
#define DPS310_PRS_B1 0x01
#define DPS310_PRS_B0 0x02
#define DPS310_TMP_B2 0x03
#define DPS310_TMP_B1 0x04
#define DPS310_TMP_B0 0x05
#define DPS310_PRS_CFG 0x06
#define DPS310_TMP_CFG 0x07
#define DPS310_TMP_RATE_BITS (0x70)
#define DPS310_MEAS_CFG 0x08
#define DPS310_MEAS_CTRL_BITS (0x07)
#define DPS310_PRESSURE_EN BIT(0)
#define DPS310_TEMP_EN BIT(1)
#define DPS310_BACKGROUND BIT(2)
#define DPS310_PRS_RDY BIT(4)
#define DPS310_TMP_RDY BIT(5)
#define DPS310_SENSOR_RDY BIT(6)
#define DPS310_COEF_RDY BIT(7)
#define DPS310_CFG_REG 0x09
#define DPS310_RESET 0x0c
#define DPS310_RESET_MAGIC (BIT(0) | BIT(3))
#define DPS310_COEF_BASE 0x10
#define DPS310_COEF_LAST 0x21
#define DPS310_COEF_SRC 0x28
static void dps310_reset(DeviceState *dev)
{
DPS310State *s = DPS310(dev);
static const uint8_t regs_reset_state[sizeof(s->regs)] = {
0xfe, 0x2f, 0xee, 0x02, 0x69, 0xa6, 0x00, 0x80, 0xc7, 0x00, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00, 0x0e, 0x1e, 0xdd, 0x13, 0xca, 0x5f, 0x21, 0x52,
0xf9, 0xc6, 0x04, 0xd1, 0xdb, 0x47, 0x00, 0x5b, 0xfb, 0x3a, 0x00, 0x00,
0x20, 0x49, 0x4e, 0xa5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x15, 0x02
};
memcpy(s->regs, regs_reset_state, sizeof(s->regs));
s->pointer = 0;
/* TODO: assert these after some timeout ? */
s->regs[DPS310_MEAS_CFG] = DPS310_COEF_RDY | DPS310_SENSOR_RDY
| DPS310_TMP_RDY | DPS310_PRS_RDY;
}
static uint8_t dps310_read(DPS310State *s, uint8_t reg)
{
if (reg >= sizeof(s->regs)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: register 0x%02x out of bounds\n",
__func__, s->pointer);
return 0xFF;
}
switch (reg) {
case DPS310_PRS_B2:
case DPS310_PRS_B1:
case DPS310_PRS_B0:
case DPS310_TMP_B2:
case DPS310_TMP_B1:
case DPS310_TMP_B0:
case DPS310_PRS_CFG:
case DPS310_TMP_CFG:
case DPS310_MEAS_CFG:
case DPS310_CFG_REG:
case DPS310_COEF_BASE...DPS310_COEF_LAST:
case DPS310_COEF_SRC:
case 0x32: /* Undocumented register to indicate workaround not required */
return s->regs[reg];
default:
qemu_log_mask(LOG_UNIMP, "%s: register 0x%02x unimplemented\n",
__func__, reg);
return 0xFF;
}
}
static void dps310_write(DPS310State *s, uint8_t reg, uint8_t data)
{
if (reg >= sizeof(s->regs)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: register %d out of bounds\n",
__func__, s->pointer);
return;
}
switch (reg) {
case DPS310_RESET:
if (data == DPS310_RESET_MAGIC) {
device_cold_reset(DEVICE(s));
}
break;
case DPS310_PRS_CFG:
case DPS310_TMP_CFG:
case DPS310_MEAS_CFG:
case DPS310_CFG_REG:
s->regs[reg] = data;
break;
default:
qemu_log_mask(LOG_UNIMP, "%s: register 0x%02x unimplemented\n",
__func__, reg);
return;
}
}
static uint8_t dps310_rx(I2CSlave *i2c)
{
DPS310State *s = DPS310(i2c);
if (s->len == 1) {
return dps310_read(s, s->pointer++);
} else {
return 0xFF;
}
}
static int dps310_tx(I2CSlave *i2c, uint8_t data)
{
DPS310State *s = DPS310(i2c);
if (s->len == 0) {
/*
* first byte is the register pointer for a read or write
* operation
*/
s->pointer = data;
s->len++;
} else if (s->len == 1) {
dps310_write(s, s->pointer++, data);
}
return 0;
}
static int dps310_event(I2CSlave *i2c, enum i2c_event event)
{
DPS310State *s = DPS310(i2c);
switch (event) {
case I2C_START_SEND:
s->pointer = 0xFF;
s->len = 0;
break;
case I2C_START_RECV:
if (s->len != 1) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid recv sequence\n",
__func__);
}
break;
default:
break;
}
return 0;
}
static const VMStateDescription vmstate_dps310 = {
.name = "DPS310",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT8(len, DPS310State),
VMSTATE_UINT8_ARRAY(regs, DPS310State, NUM_REGISTERS),
VMSTATE_UINT8(pointer, DPS310State),
VMSTATE_I2C_SLAVE(i2c, DPS310State),
VMSTATE_END_OF_LIST()
}
};
static void dps310_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
k->event = dps310_event;
k->recv = dps310_rx;
k->send = dps310_tx;
dc->reset = dps310_reset;
dc->vmsd = &vmstate_dps310;
}
static const TypeInfo dps310_info = {
.name = TYPE_DPS310,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(DPS310State),
.class_init = dps310_class_init,
};
static void dps310_register_types(void)
{
type_register_static(&dps310_info);
}
type_init(dps310_register_types)

View file

@ -1,5 +1,6 @@
softmmu_ss.add(when: 'CONFIG_TMP105', if_true: files('tmp105.c'))
softmmu_ss.add(when: 'CONFIG_TMP421', if_true: files('tmp421.c'))
softmmu_ss.add(when: 'CONFIG_DPS310', if_true: files('dps310.c'))
softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
softmmu_ss.add(when: 'CONFIG_ADM1272', if_true: files('adm1272.c'))
softmmu_ss.add(when: 'CONFIG_MAX34451', if_true: files('max34451.c'))

View file

@ -118,13 +118,27 @@ static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
}
}
static uint64_t aspeed_2400_sanitize_ctrl(uint64_t data)
{
return data & 0xffff;
}
static uint64_t aspeed_2500_sanitize_ctrl(uint64_t data)
{
return (data & ~(0xfUL << 8)) | WDT_CTRL_1MHZ_CLK;
}
static uint64_t aspeed_2600_sanitize_ctrl(uint64_t data)
{
return data & ~(0x7UL << 7);
}
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
unsigned size)
{
AspeedWDTState *s = ASPEED_WDT(opaque);
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
bool enable = data & WDT_CTRL_ENABLE;
bool enable;
offset >>= 2;
@ -144,12 +158,16 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
}
break;
case WDT_CTRL:
data = awc->sanitize_ctrl(data);
enable = data & WDT_CTRL_ENABLE;
if (enable && !aspeed_wdt_is_enabled(s)) {
s->regs[WDT_CTRL] = data;
awc->wdt_reload(s);
} else if (!enable && aspeed_wdt_is_enabled(s)) {
s->regs[WDT_CTRL] = data;
timer_del(s->timer);
} else {
s->regs[WDT_CTRL] = data;
}
break;
case WDT_RESET_WIDTH:
@ -207,11 +225,12 @@ static const MemoryRegionOps aspeed_wdt_ops = {
static void aspeed_wdt_reset(DeviceState *dev)
{
AspeedWDTState *s = ASPEED_WDT(dev);
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
s->regs[WDT_STATUS] = 0x3EF1480;
s->regs[WDT_RELOAD_VALUE] = 0x03EF1480;
s->regs[WDT_RESTART] = 0;
s->regs[WDT_CTRL] = 0;
s->regs[WDT_CTRL] = awc->sanitize_ctrl(0);
s->regs[WDT_RESET_WIDTH] = 0xFF;
timer_del(s->timer);
@ -293,6 +312,7 @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
awc->ext_pulse_width_mask = 0xff;
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
awc->wdt_reload = aspeed_wdt_reload;
awc->sanitize_ctrl = aspeed_2400_sanitize_ctrl;
}
static const TypeInfo aspeed_2400_wdt_info = {
@ -328,6 +348,7 @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
awc->wdt_reload = aspeed_wdt_reload_1mhz;
awc->sanitize_ctrl = aspeed_2500_sanitize_ctrl;
}
static const TypeInfo aspeed_2500_wdt_info = {
@ -348,6 +369,7 @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
awc->wdt_reload = aspeed_wdt_reload_1mhz;
awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
}
static const TypeInfo aspeed_2600_wdt_info = {

View file

@ -38,6 +38,7 @@ struct AspeedMachineClass {
uint32_t num_cs;
uint32_t macs_mask;
void (*i2c_init)(AspeedMachineState *bmc);
uint32_t uart_default;
};

View file

@ -65,6 +65,7 @@ struct AspeedSoCState {
AspeedSDHCIState sdhci;
AspeedSDHCIState emmc;
AspeedLPCState lpc;
uint32_t uart_default;
};
#define TYPE_ASPEED_SOC "aspeed-soc"

View file

@ -43,6 +43,8 @@ struct AspeedSCUState {
#define AST2500_A1_SILICON_REV 0x04010303U
#define AST2600_A0_SILICON_REV 0x05000303U
#define AST2600_A1_SILICON_REV 0x05010303U
#define AST2600_A2_SILICON_REV 0x05020303U
#define AST2600_A3_SILICON_REV 0x05030303U
#define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04)

View file

@ -44,6 +44,7 @@ struct AspeedWDTClass {
uint32_t reset_ctrl_reg;
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
void (*wdt_reload)(AspeedWDTState *s);
uint64_t (*sanitize_ctrl)(uint64_t data);
};
#endif /* WDT_ASPEED_H */