aspeed queue:
* I2C support for AST2700 * Coverity fixes -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmbofzEACgkQUaNDx8/7 7KHo4g//RtzY1oM+5xbX7LA4Nb45EJtAs9+UvbvDF7++NF9Nd4VThdoyBSvzyqd8 9Z35Mfoh1xce7+Qz/QtobbRkPLKtq7rfmj4lCkXZRGR/0nbDteqyLOqDM/E/GSBc mEaMG9sT2L1t9SrKOYIhgoPSpS0kpJ0YHfMLt5DcTjLQ1g8OB7ByzOPoPSBzTPAf QLL/v0GTxdqQPRhcZJKGclkjeVwBtFpo1rbDe/tHfFKC51g3cROGyQEswuPxRqDB Y3CQ0WC7awqSg7WAUwTfyb6LNSmYoiycGKv/gi06kc/mxjpf2qQ2khX4diiPoOj0 Ak1b/dv2DWKE8LDYw7ew44UdPyIhGhgFeYeJ1olz5oLUcdcd4PuBWBvLUgpJKEfk HRXcJyhat3rwWGYzrdCJbBPN6CPncWjyifg1X6jK6Eu4wnfdpB9m64xFg8TpALaz SRZGg0ahldBwU6jjDO3x/RMWzKCtzwAjDuLfxSlqDGPx5OL+0dDDEa+xj45VzzBZ aT5Kcy9ga9DgRUw4wds3NHz9uCxwXoktDkW3vKMeMdftAf6er+Inhe8FHer/JSh4 wuCxUDYIUSate5QoVucHAAM3DqOCQ1ascugufluXAR4StJ/u2b3SXU881C7v4crP NDncQEsWgya+Ykv9lXgulDxZrc8qsSmj4aoRNtJHaGsxmb4RwSY= =NyK5 -----END PGP SIGNATURE----- Merge tag 'pull-aspeed-20240916' of https://github.com/legoater/qemu into staging aspeed queue: * I2C support for AST2700 * Coverity fixes # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmbofzEACgkQUaNDx8/7 # 7KHo4g//RtzY1oM+5xbX7LA4Nb45EJtAs9+UvbvDF7++NF9Nd4VThdoyBSvzyqd8 # 9Z35Mfoh1xce7+Qz/QtobbRkPLKtq7rfmj4lCkXZRGR/0nbDteqyLOqDM/E/GSBc # mEaMG9sT2L1t9SrKOYIhgoPSpS0kpJ0YHfMLt5DcTjLQ1g8OB7ByzOPoPSBzTPAf # QLL/v0GTxdqQPRhcZJKGclkjeVwBtFpo1rbDe/tHfFKC51g3cROGyQEswuPxRqDB # Y3CQ0WC7awqSg7WAUwTfyb6LNSmYoiycGKv/gi06kc/mxjpf2qQ2khX4diiPoOj0 # Ak1b/dv2DWKE8LDYw7ew44UdPyIhGhgFeYeJ1olz5oLUcdcd4PuBWBvLUgpJKEfk # HRXcJyhat3rwWGYzrdCJbBPN6CPncWjyifg1X6jK6Eu4wnfdpB9m64xFg8TpALaz # SRZGg0ahldBwU6jjDO3x/RMWzKCtzwAjDuLfxSlqDGPx5OL+0dDDEa+xj45VzzBZ # aT5Kcy9ga9DgRUw4wds3NHz9uCxwXoktDkW3vKMeMdftAf6er+Inhe8FHer/JSh4 # wuCxUDYIUSate5QoVucHAAM3DqOCQ1ascugufluXAR4StJ/u2b3SXU881C7v4crP # NDncQEsWgya+Ykv9lXgulDxZrc8qsSmj4aoRNtJHaGsxmb4RwSY= # =NyK5 # -----END PGP SIGNATURE----- # gpg: Signature made Mon 16 Sep 2024 19:55:45 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 * tag 'pull-aspeed-20240916' of https://github.com/legoater/qemu: machine_aspeed.py: Update to test I2C for AST2700 aspeed: Add tmp105 in i2c bus 0 for AST2700 aspeed/soc: Support I2C for AST2700 aspeed/soc: Introduce a new API to get the device irq hw/i2c/aspeed: Add support for 64 bit addresses hw/i2c/aspeed: Add support for Tx/Rx buffer 64 bit addresses hw/i2c/aspeed: Add AST2700 support hw/i2c/aspeed: Introduce a new dma_dram_offset attribute in AspeedI2Cbus hw/i2c/aspeed: Support discontinuous poll buffer memory region of I2C bus hw/i2c/aspeed: Introduce a new bus pool buffer attribute in AspeedI2Cbus hw/i2c/aspeed: Support discontinuous register memory region of I2C bus hw/gpio/aspeed_gpio: Avoid shift into sign bit Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6fe7fc96e7
@ -1650,6 +1650,15 @@ static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
|
||||
}
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
static void ast2700_evb_i2c_init(AspeedMachineState *bmc)
|
||||
{
|
||||
AspeedSoCState *soc = bmc->soc;
|
||||
|
||||
/* LM75 is compatible with TMP105 driver */
|
||||
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0),
|
||||
TYPE_TMP105, 0x4d);
|
||||
}
|
||||
|
||||
static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
@ -1664,6 +1673,7 @@ static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc, void *data)
|
||||
amc->num_cs = 2;
|
||||
amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON;
|
||||
amc->uart_default = ASPEED_DEV_UART12;
|
||||
amc->i2c_init = ast2700_evb_i2c_init;
|
||||
mc->default_ram_size = 1 * GiB;
|
||||
aspeed_machine_class_init_cpus_defaults(mc);
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
|
||||
[ASPEED_GIC_DIST] = 0x12200000,
|
||||
[ASPEED_GIC_REDIST] = 0x12280000,
|
||||
[ASPEED_DEV_ADC] = 0x14C00000,
|
||||
[ASPEED_DEV_I2C] = 0x14C0F000,
|
||||
};
|
||||
|
||||
#define AST2700_MAX_IRQ 288
|
||||
@ -193,6 +194,27 @@ static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev)
|
||||
return qdev_get_gpio_in(DEVICE(&a->gic), sc->irqmap[dev]);
|
||||
}
|
||||
|
||||
static qemu_irq aspeed_soc_ast2700_get_irq_index(AspeedSoCState *s, int dev,
|
||||
int index)
|
||||
{
|
||||
Aspeed27x0SoCState *a = ASPEED27X0_SOC(s);
|
||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(aspeed_soc_ast2700_gic_intcmap); i++) {
|
||||
if (sc->irqmap[dev] == aspeed_soc_ast2700_gic_intcmap[i].irq) {
|
||||
assert(aspeed_soc_ast2700_gic_intcmap[i].ptr);
|
||||
return qdev_get_gpio_in(DEVICE(&a->intc.orgates[i]),
|
||||
aspeed_soc_ast2700_gic_intcmap[i].ptr[dev] + index);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalid orgate index, device irq should be 128 to 136.
|
||||
*/
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,
|
||||
unsigned int size)
|
||||
{
|
||||
@ -348,6 +370,9 @@ static void aspeed_soc_ast2700_init(Object *obj)
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname);
|
||||
object_initialize_child(obj, "adc", &s->adc, typename);
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
|
||||
object_initialize_child(obj, "i2c", &s->i2c, typename);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -431,6 +456,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
|
||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||
AspeedINTCClass *ic = ASPEED_INTC_GET_CLASS(&a->intc);
|
||||
g_autofree char *sram_name = NULL;
|
||||
qemu_irq irq;
|
||||
|
||||
/* Default boot region (SPI memory or ROMs) */
|
||||
memory_region_init(&s->spi_boot_container, OBJECT(s),
|
||||
@ -613,6 +639,25 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
|
||||
|
||||
/* I2C */
|
||||
object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
|
||||
&error_abort);
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
|
||||
return;
|
||||
}
|
||||
aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
|
||||
for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
|
||||
/*
|
||||
* The AST2700 I2C controller has one source INTC per bus.
|
||||
* I2C buses interrupt are connected to GICINT130_INTC
|
||||
* from bit 0 to bit 15.
|
||||
* I2C bus 0 is connected to GICINT130_INTC at bit 0.
|
||||
* I2C bus 15 is connected to GICINT130_INTC at bit 15.
|
||||
*/
|
||||
irq = aspeed_soc_ast2700_get_irq_index(s, ASPEED_DEV_I2C, i);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
|
||||
}
|
||||
|
||||
create_unimplemented_device("ast2700.dpmcu", 0x11000000, 0x40000);
|
||||
create_unimplemented_device("ast2700.iomem0", 0x12000000, 0x01000000);
|
||||
create_unimplemented_device("ast2700.iomem1", 0x14000000, 0x01000000);
|
||||
|
@ -281,7 +281,7 @@ static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
|
||||
diff &= mode_mask;
|
||||
if (diff) {
|
||||
for (gpio = 0; gpio < ASPEED_GPIOS_PER_SET; gpio++) {
|
||||
uint32_t mask = 1 << gpio;
|
||||
uint32_t mask = 1U << gpio;
|
||||
|
||||
/* If the gpio needs to be updated... */
|
||||
if (!(diff & mask)) {
|
||||
|
@ -114,7 +114,10 @@ static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
|
||||
if (!aic->has_dma) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
|
||||
value = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
value = extract64(bus->dma_dram_offset, 0, 32);
|
||||
break;
|
||||
case A_I2CD_DMA_LEN:
|
||||
if (!aic->has_dma) {
|
||||
@ -137,6 +140,7 @@ static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
|
||||
static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
|
||||
unsigned size)
|
||||
{
|
||||
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
|
||||
uint64_t value = bus->regs[offset / sizeof(*bus->regs)];
|
||||
|
||||
switch (offset) {
|
||||
@ -150,9 +154,7 @@ static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
|
||||
case A_I2CM_DMA_TX_ADDR:
|
||||
case A_I2CM_DMA_RX_ADDR:
|
||||
case A_I2CM_DMA_LEN_STS:
|
||||
case A_I2CC_DMA_ADDR:
|
||||
case A_I2CC_DMA_LEN:
|
||||
|
||||
case A_I2CS_DEV_ADDR:
|
||||
case A_I2CS_DMA_RX_ADDR:
|
||||
case A_I2CS_DMA_LEN:
|
||||
@ -161,11 +163,24 @@ static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
|
||||
case A_I2CS_DMA_LEN_STS:
|
||||
/* Value is already set, don't do anything. */
|
||||
break;
|
||||
case A_I2CC_DMA_ADDR:
|
||||
value = extract64(bus->dma_dram_offset, 0, 32);
|
||||
break;
|
||||
case A_I2CS_INTR_STS:
|
||||
break;
|
||||
case A_I2CM_CMD:
|
||||
value = SHARED_FIELD_DP32(value, BUS_BUSY_STS, i2c_bus_busy(bus->bus));
|
||||
break;
|
||||
case A_I2CM_DMA_TX_ADDR_HI:
|
||||
case A_I2CM_DMA_RX_ADDR_HI:
|
||||
case A_I2CS_DMA_TX_ADDR_HI:
|
||||
case A_I2CS_DMA_RX_ADDR_HI:
|
||||
if (!aic->has_dma64) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA 64 bits support\n",
|
||||
__func__);
|
||||
value = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
|
||||
@ -210,18 +225,18 @@ static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
|
||||
{
|
||||
MemTxResult result;
|
||||
AspeedI2CState *s = bus->controller;
|
||||
uint32_t reg_dma_addr = aspeed_i2c_bus_dma_addr_offset(bus);
|
||||
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
|
||||
|
||||
result = address_space_read(&s->dram_as, bus->regs[reg_dma_addr],
|
||||
result = address_space_read(&s->dram_as, bus->dma_dram_offset,
|
||||
MEMTXATTRS_UNSPECIFIED, data, 1);
|
||||
if (result != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
|
||||
__func__, bus->regs[reg_dma_addr]);
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: DRAM read failed @%" PRIx64 "\n",
|
||||
__func__, bus->dma_dram_offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bus->regs[reg_dma_addr]++;
|
||||
bus->dma_dram_offset++;
|
||||
bus->regs[reg_dma_len]--;
|
||||
return 0;
|
||||
}
|
||||
@ -291,7 +306,6 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
|
||||
uint32_t reg_pool_ctrl = aspeed_i2c_bus_pool_ctrl_offset(bus);
|
||||
uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
|
||||
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
|
||||
uint32_t reg_dma_addr = aspeed_i2c_bus_dma_addr_offset(bus);
|
||||
int pool_rx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl,
|
||||
RX_SIZE) + 1;
|
||||
|
||||
@ -323,14 +337,17 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
|
||||
data = i2c_recv(bus->bus);
|
||||
trace_aspeed_i2c_bus_recv("DMA", bus->regs[reg_dma_len],
|
||||
bus->regs[reg_dma_len], data);
|
||||
result = address_space_write(&s->dram_as, bus->regs[reg_dma_addr],
|
||||
|
||||
result = address_space_write(&s->dram_as, bus->dma_dram_offset,
|
||||
MEMTXATTRS_UNSPECIFIED, &data, 1);
|
||||
if (result != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
|
||||
__func__, bus->regs[reg_dma_addr]);
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: DRAM write failed @%" PRIx64 "\n",
|
||||
__func__, bus->dma_dram_offset);
|
||||
return;
|
||||
}
|
||||
bus->regs[reg_dma_addr]++;
|
||||
|
||||
bus->dma_dram_offset++;
|
||||
bus->regs[reg_dma_len]--;
|
||||
/* In new mode, keep track of how many bytes we RXed */
|
||||
if (aspeed_i2c_is_new_mode(bus->controller)) {
|
||||
@ -636,14 +653,18 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
|
||||
case A_I2CM_DMA_TX_ADDR:
|
||||
bus->regs[R_I2CM_DMA_TX_ADDR] = FIELD_EX32(value, I2CM_DMA_TX_ADDR,
|
||||
ADDR);
|
||||
bus->regs[R_I2CC_DMA_ADDR] = FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR);
|
||||
bus->dma_dram_offset =
|
||||
deposit64(bus->dma_dram_offset, 0, 32,
|
||||
FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR));
|
||||
bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN,
|
||||
TX_BUF_LEN) + 1;
|
||||
break;
|
||||
case A_I2CM_DMA_RX_ADDR:
|
||||
bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value, I2CM_DMA_RX_ADDR,
|
||||
ADDR);
|
||||
bus->regs[R_I2CC_DMA_ADDR] = FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR);
|
||||
bus->dma_dram_offset =
|
||||
deposit64(bus->dma_dram_offset, 0, 32,
|
||||
FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR));
|
||||
bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN,
|
||||
RX_BUF_LEN) + 1;
|
||||
break;
|
||||
@ -721,6 +742,56 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
|
||||
qemu_log_mask(LOG_UNIMP, "%s: Slave mode DMA TX is not implemented\n",
|
||||
__func__);
|
||||
break;
|
||||
|
||||
/*
|
||||
* The AST2700 support the maximum DRAM size is 8 GB.
|
||||
* The DRAM offset range is from 0x0_0000_0000 to
|
||||
* 0x1_FFFF_FFFF and it is enough to use bits [33:0]
|
||||
* saving the dram offset.
|
||||
* Therefore, save the high part physical address bit[1:0]
|
||||
* of Tx/Rx buffer address as dma_dram_offset bit[33:32].
|
||||
*/
|
||||
case A_I2CM_DMA_TX_ADDR_HI:
|
||||
if (!aic->has_dma64) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA 64 bits support\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
bus->regs[R_I2CM_DMA_TX_ADDR_HI] = FIELD_EX32(value,
|
||||
I2CM_DMA_TX_ADDR_HI,
|
||||
ADDR_HI);
|
||||
bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32,
|
||||
extract32(value, 0, 2));
|
||||
break;
|
||||
case A_I2CM_DMA_RX_ADDR_HI:
|
||||
if (!aic->has_dma64) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA 64 bits support\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
bus->regs[R_I2CM_DMA_RX_ADDR_HI] = FIELD_EX32(value,
|
||||
I2CM_DMA_RX_ADDR_HI,
|
||||
ADDR_HI);
|
||||
bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32,
|
||||
extract32(value, 0, 2));
|
||||
break;
|
||||
case A_I2CS_DMA_TX_ADDR_HI:
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"%s: Slave mode DMA TX Addr high is not implemented\n",
|
||||
__func__);
|
||||
break;
|
||||
case A_I2CS_DMA_RX_ADDR_HI:
|
||||
if (!aic->has_dma64) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA 64 bits support\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
bus->regs[R_I2CS_DMA_RX_ADDR_HI] = FIELD_EX32(value,
|
||||
I2CS_DMA_RX_ADDR_HI,
|
||||
ADDR_HI);
|
||||
bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32,
|
||||
extract32(value, 0, 2));
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
@ -811,7 +882,8 @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus *bus, hwaddr offset,
|
||||
break;
|
||||
}
|
||||
|
||||
bus->regs[R_I2CD_DMA_ADDR] = value & 0x3ffffffc;
|
||||
bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32,
|
||||
value & 0x3ffffffc);
|
||||
break;
|
||||
|
||||
case A_I2CD_DMA_LEN:
|
||||
@ -941,12 +1013,49 @@ static const MemoryRegionOps aspeed_i2c_share_pool_ops = {
|
||||
},
|
||||
};
|
||||
|
||||
static uint64_t aspeed_i2c_bus_pool_read(void *opaque, hwaddr offset,
|
||||
unsigned size)
|
||||
{
|
||||
AspeedI2CBus *s = opaque;
|
||||
uint64_t ret = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
ret |= (uint64_t) s->pool[offset + i] << (8 * i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aspeed_i2c_bus_pool_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
AspeedI2CBus *s = opaque;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
s->pool[offset + i] = (value >> (8 * i)) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps aspeed_i2c_bus_pool_ops = {
|
||||
.read = aspeed_i2c_bus_pool_read,
|
||||
.write = aspeed_i2c_bus_pool_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
};
|
||||
|
||||
static const VMStateDescription aspeed_i2c_bus_vmstate = {
|
||||
.name = TYPE_ASPEED_I2C,
|
||||
.version_id = 5,
|
||||
.minimum_version_id = 5,
|
||||
.version_id = 6,
|
||||
.minimum_version_id = 6,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, AspeedI2CBus, ASPEED_I2C_NEW_NUM_REG),
|
||||
VMSTATE_UINT8_ARRAY(pool, AspeedI2CBus, ASPEED_I2C_BUS_POOL_SIZE),
|
||||
VMSTATE_UINT64(dma_dram_offset, AspeedI2CBus),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
@ -996,7 +1105,21 @@ static void aspeed_i2c_instance_init(Object *obj)
|
||||
* 0x140 ... 0x17F: Device 5
|
||||
* 0x180 ... 0x1BF: Device 6
|
||||
* 0x1C0 ... 0x1FF: Device 7
|
||||
* 0x200 ... 0x2FF: Buffer Pool (AST2500 unused in linux driver)
|
||||
* 0x200 ... 0x20F: Device 1 buffer (AST2500 unused in linux driver)
|
||||
* 0x210 ... 0x21F: Device 2 buffer
|
||||
* 0x220 ... 0x22F: Device 3 buffer
|
||||
* 0x230 ... 0x23F: Device 4 buffer
|
||||
* 0x240 ... 0x24F: Device 5 buffer
|
||||
* 0x250 ... 0x25F: Device 6 buffer
|
||||
* 0x260 ... 0x26F: Device 7 buffer
|
||||
* 0x270 ... 0x27F: Device 8 buffer
|
||||
* 0x280 ... 0x28F: Device 9 buffer
|
||||
* 0x290 ... 0x29F: Device 10 buffer
|
||||
* 0x2A0 ... 0x2AF: Device 11 buffer
|
||||
* 0x2B0 ... 0x2BF: Device 12 buffer
|
||||
* 0x2C0 ... 0x2CF: Device 13 buffer
|
||||
* 0x2D0 ... 0x2DF: Device 14 buffer
|
||||
* 0x2E0 ... 0x2FF: Reserved
|
||||
* 0x300 ... 0x33F: Device 8
|
||||
* 0x340 ... 0x37F: Device 9
|
||||
* 0x380 ... 0x3BF: Device 10
|
||||
@ -1005,6 +1128,76 @@ static void aspeed_i2c_instance_init(Object *obj)
|
||||
* 0x440 ... 0x47F: Device 13
|
||||
* 0x480 ... 0x4BF: Device 14
|
||||
* 0x800 ... 0xFFF: Buffer Pool (AST2400 unused in linux driver)
|
||||
*
|
||||
* Address Definitions (AST2600 and AST1030)
|
||||
* 0x000 ... 0x07F: Global Register
|
||||
* 0x080 ... 0x0FF: Device 1
|
||||
* 0x100 ... 0x17F: Device 2
|
||||
* 0x180 ... 0x1FF: Device 3
|
||||
* 0x200 ... 0x27F: Device 4
|
||||
* 0x280 ... 0x2FF: Device 5
|
||||
* 0x300 ... 0x37F: Device 6
|
||||
* 0x380 ... 0x3FF: Device 7
|
||||
* 0x400 ... 0x47F: Device 8
|
||||
* 0x480 ... 0x4FF: Device 9
|
||||
* 0x500 ... 0x57F: Device 10
|
||||
* 0x580 ... 0x5FF: Device 11
|
||||
* 0x600 ... 0x67F: Device 12
|
||||
* 0x680 ... 0x6FF: Device 13
|
||||
* 0x700 ... 0x77F: Device 14
|
||||
* 0x780 ... 0x7FF: Device 15 (15 and 16 unused in AST1030)
|
||||
* 0x800 ... 0x87F: Device 16
|
||||
* 0xC00 ... 0xC1F: Device 1 buffer
|
||||
* 0xC20 ... 0xC3F: Device 2 buffer
|
||||
* 0xC40 ... 0xC5F: Device 3 buffer
|
||||
* 0xC60 ... 0xC7F: Device 4 buffer
|
||||
* 0xC80 ... 0xC9F: Device 5 buffer
|
||||
* 0xCA0 ... 0xCBF: Device 6 buffer
|
||||
* 0xCC0 ... 0xCDF: Device 7 buffer
|
||||
* 0xCE0 ... 0xCFF: Device 8 buffer
|
||||
* 0xD00 ... 0xD1F: Device 9 buffer
|
||||
* 0xD20 ... 0xD3F: Device 10 buffer
|
||||
* 0xD40 ... 0xD5F: Device 11 buffer
|
||||
* 0xD60 ... 0xD7F: Device 12 buffer
|
||||
* 0xD80 ... 0xD9F: Device 13 buffer
|
||||
* 0xDA0 ... 0xDBF: Device 14 buffer
|
||||
* 0xDC0 ... 0xDDF: Device 15 buffer (15 and 16 unused in AST1030)
|
||||
* 0xDE0 ... 0xDFF: Device 16 buffer
|
||||
*
|
||||
* Address Definitions (AST2700)
|
||||
* 0x000 ... 0x0FF: Global Register
|
||||
* 0x100 ... 0x17F: Device 0
|
||||
* 0x1A0 ... 0x1BF: Device 0 buffer
|
||||
* 0x200 ... 0x27F: Device 1
|
||||
* 0x2A0 ... 0x2BF: Device 1 buffer
|
||||
* 0x300 ... 0x37F: Device 2
|
||||
* 0x3A0 ... 0x3BF: Device 2 buffer
|
||||
* 0x400 ... 0x47F: Device 3
|
||||
* 0x4A0 ... 0x4BF: Device 3 buffer
|
||||
* 0x500 ... 0x57F: Device 4
|
||||
* 0x5A0 ... 0x5BF: Device 4 buffer
|
||||
* 0x600 ... 0x67F: Device 5
|
||||
* 0x6A0 ... 0x6BF: Device 5 buffer
|
||||
* 0x700 ... 0x77F: Device 6
|
||||
* 0x7A0 ... 0x7BF: Device 6 buffer
|
||||
* 0x800 ... 0x87F: Device 7
|
||||
* 0x8A0 ... 0x8BF: Device 7 buffer
|
||||
* 0x900 ... 0x97F: Device 8
|
||||
* 0x9A0 ... 0x9BF: Device 8 buffer
|
||||
* 0xA00 ... 0xA7F: Device 9
|
||||
* 0xAA0 ... 0xABF: Device 9 buffer
|
||||
* 0xB00 ... 0xB7F: Device 10
|
||||
* 0xBA0 ... 0xBBF: Device 10 buffer
|
||||
* 0xC00 ... 0xC7F: Device 11
|
||||
* 0xCA0 ... 0xCBF: Device 11 buffer
|
||||
* 0xD00 ... 0xD7F: Device 12
|
||||
* 0xDA0 ... 0xDBF: Device 12 buffer
|
||||
* 0xE00 ... 0xE7F: Device 13
|
||||
* 0xEA0 ... 0xEBF: Device 13 buffer
|
||||
* 0xF00 ... 0xF7F: Device 14
|
||||
* 0xFA0 ... 0xFBF: Device 14 buffer
|
||||
* 0x1000 ... 0x107F: Device 15
|
||||
* 0x10A0 ... 0x10BF: Device 15 buffer
|
||||
*/
|
||||
static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
@ -1012,6 +1205,8 @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
AspeedI2CState *s = ASPEED_I2C(dev);
|
||||
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
|
||||
uint32_t reg_offset = aic->reg_size + aic->reg_gap_size;
|
||||
uint32_t pool_offset = aic->pool_size + aic->pool_gap_size;
|
||||
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_i2c_ctrl_ops, s,
|
||||
@ -1034,14 +1229,23 @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
|
||||
memory_region_add_subregion(&s->iomem, reg_offset * (i + offset),
|
||||
&s->busses[i].mr);
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->pool_iomem, OBJECT(s),
|
||||
&aspeed_i2c_share_pool_ops, s,
|
||||
"aspeed.i2c-share-pool", aic->pool_size);
|
||||
memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
|
||||
if (aic->has_share_pool) {
|
||||
memory_region_init_io(&s->pool_iomem, OBJECT(s),
|
||||
&aspeed_i2c_share_pool_ops, s,
|
||||
"aspeed.i2c-share-pool", aic->pool_size);
|
||||
memory_region_add_subregion(&s->iomem, aic->pool_base,
|
||||
&s->pool_iomem);
|
||||
} else {
|
||||
for (i = 0; i < aic->num_busses; i++) {
|
||||
memory_region_add_subregion(&s->iomem,
|
||||
aic->pool_base + (pool_offset * i),
|
||||
&s->busses[i].mr_pool);
|
||||
}
|
||||
}
|
||||
|
||||
if (aic->has_dma) {
|
||||
if (!s->dram_mr) {
|
||||
@ -1092,8 +1296,9 @@ static int aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
|
||||
return -1;
|
||||
}
|
||||
ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN, 0);
|
||||
bus->regs[R_I2CC_DMA_ADDR] =
|
||||
ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_RX_ADDR, ADDR);
|
||||
bus->dma_dram_offset =
|
||||
deposit64(bus->dma_dram_offset, 0, 32,
|
||||
ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_RX_ADDR, ADDR));
|
||||
bus->regs[R_I2CC_DMA_LEN] =
|
||||
ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_LEN, RX_BUF_LEN) + 1;
|
||||
i2c_ack(bus->bus);
|
||||
@ -1159,10 +1364,10 @@ static int aspeed_i2c_bus_slave_event(I2CSlave *slave, enum i2c_event event)
|
||||
static void aspeed_i2c_bus_new_slave_send_async(AspeedI2CBus *bus, uint8_t data)
|
||||
{
|
||||
assert(address_space_write(&bus->controller->dram_as,
|
||||
bus->regs[R_I2CC_DMA_ADDR],
|
||||
bus->dma_dram_offset,
|
||||
MEMTXATTRS_UNSPECIFIED, &data, 1) == MEMTX_OK);
|
||||
|
||||
bus->regs[R_I2CC_DMA_ADDR]++;
|
||||
bus->dma_dram_offset++;
|
||||
bus->regs[R_I2CC_DMA_LEN]--;
|
||||
ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN,
|
||||
ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN) + 1);
|
||||
@ -1217,6 +1422,7 @@ static void aspeed_i2c_bus_realize(DeviceState *dev, Error **errp)
|
||||
AspeedI2CBus *s = ASPEED_I2C_BUS(dev);
|
||||
AspeedI2CClass *aic;
|
||||
g_autofree char *name = g_strdup_printf(TYPE_ASPEED_I2C_BUS ".%d", s->id);
|
||||
g_autofree char *pool_name = g_strdup_printf("%s.pool", name);
|
||||
|
||||
if (!s->controller) {
|
||||
error_setg(errp, TYPE_ASPEED_I2C_BUS ": 'controller' link not set");
|
||||
@ -1234,6 +1440,10 @@ static void aspeed_i2c_bus_realize(DeviceState *dev, Error **errp)
|
||||
memory_region_init_io(&s->mr, OBJECT(s), &aspeed_i2c_bus_ops,
|
||||
s, name, aic->reg_size);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr);
|
||||
|
||||
memory_region_init_io(&s->mr_pool, OBJECT(s), &aspeed_i2c_bus_pool_ops,
|
||||
s, pool_name, aic->pool_size);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr_pool);
|
||||
}
|
||||
|
||||
static Property aspeed_i2c_bus_properties[] = {
|
||||
@ -1286,6 +1496,7 @@ static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
|
||||
aic->reg_size = 0x40;
|
||||
aic->gap = 7;
|
||||
aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq;
|
||||
aic->has_share_pool = true;
|
||||
aic->pool_size = 0x800;
|
||||
aic->pool_base = 0x800;
|
||||
aic->bus_pool_base = aspeed_2400_i2c_bus_pool_base;
|
||||
@ -1305,7 +1516,7 @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus)
|
||||
|
||||
static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus)
|
||||
{
|
||||
return &bus->controller->share_pool[bus->id * 0x10];
|
||||
return bus->pool;
|
||||
}
|
||||
|
||||
static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
|
||||
@ -1319,7 +1530,7 @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
|
||||
aic->reg_size = 0x40;
|
||||
aic->gap = 7;
|
||||
aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq;
|
||||
aic->pool_size = 0x100;
|
||||
aic->pool_size = 0x10;
|
||||
aic->pool_base = 0x200;
|
||||
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
|
||||
aic->check_sram = true;
|
||||
@ -1338,11 +1549,6 @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
|
||||
return bus->irq;
|
||||
}
|
||||
|
||||
static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus)
|
||||
{
|
||||
return &bus->controller->share_pool[bus->id * 0x20];
|
||||
}
|
||||
|
||||
static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
@ -1354,9 +1560,9 @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
|
||||
aic->reg_size = 0x80;
|
||||
aic->gap = -1; /* no gap */
|
||||
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
|
||||
aic->pool_size = 0x200;
|
||||
aic->pool_size = 0x20;
|
||||
aic->pool_base = 0xC00;
|
||||
aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
|
||||
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
|
||||
aic->has_dma = true;
|
||||
aic->mem_size = 0x1000;
|
||||
}
|
||||
@ -1378,9 +1584,9 @@ static void aspeed_1030_i2c_class_init(ObjectClass *klass, void *data)
|
||||
aic->reg_size = 0x80;
|
||||
aic->gap = -1; /* no gap */
|
||||
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
|
||||
aic->pool_size = 0x200;
|
||||
aic->pool_size = 0x20;
|
||||
aic->pool_base = 0xC00;
|
||||
aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
|
||||
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
|
||||
aic->has_dma = true;
|
||||
aic->mem_size = 0x10000;
|
||||
}
|
||||
@ -1391,6 +1597,33 @@ static const TypeInfo aspeed_1030_i2c_info = {
|
||||
.class_init = aspeed_1030_i2c_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_2700_i2c_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2700 I2C Controller";
|
||||
|
||||
aic->num_busses = 16;
|
||||
aic->reg_size = 0x80;
|
||||
aic->reg_gap_size = 0x80;
|
||||
aic->gap = -1; /* no gap */
|
||||
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
|
||||
aic->pool_size = 0x20;
|
||||
aic->pool_gap_size = 0xe0;
|
||||
aic->pool_base = 0x1a0;
|
||||
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
|
||||
aic->has_dma = true;
|
||||
aic->mem_size = 0x2000;
|
||||
aic->has_dma64 = true;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2700_i2c_info = {
|
||||
.name = TYPE_ASPEED_2700_I2C,
|
||||
.parent = TYPE_ASPEED_I2C,
|
||||
.class_init = aspeed_2700_i2c_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_i2c_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_i2c_bus_info);
|
||||
@ -1400,6 +1633,7 @@ static void aspeed_i2c_register_types(void)
|
||||
type_register_static(&aspeed_2500_i2c_info);
|
||||
type_register_static(&aspeed_2600_i2c_info);
|
||||
type_register_static(&aspeed_1030_i2c_info);
|
||||
type_register_static(&aspeed_2700_i2c_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_i2c_register_types)
|
||||
|
@ -31,12 +31,14 @@
|
||||
#define TYPE_ASPEED_2500_I2C TYPE_ASPEED_I2C "-ast2500"
|
||||
#define TYPE_ASPEED_2600_I2C TYPE_ASPEED_I2C "-ast2600"
|
||||
#define TYPE_ASPEED_1030_I2C TYPE_ASPEED_I2C "-ast1030"
|
||||
#define TYPE_ASPEED_2700_I2C TYPE_ASPEED_I2C "-ast2700"
|
||||
OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C)
|
||||
|
||||
#define ASPEED_I2C_NR_BUSSES 16
|
||||
#define ASPEED_I2C_SHARE_POOL_SIZE 0x800
|
||||
#define ASPEED_I2C_BUS_POOL_SIZE 0x20
|
||||
#define ASPEED_I2C_OLD_NUM_REG 11
|
||||
#define ASPEED_I2C_NEW_NUM_REG 22
|
||||
#define ASPEED_I2C_NEW_NUM_REG 28
|
||||
|
||||
#define A_I2CD_M_STOP_CMD BIT(5)
|
||||
#define A_I2CD_M_RX_CMD BIT(3)
|
||||
@ -225,6 +227,15 @@ REG32(I2CS_DMA_LEN_STS, 0x4c)
|
||||
FIELD(I2CS_DMA_LEN_STS, TX_LEN, 0, 13)
|
||||
REG32(I2CC_DMA_ADDR, 0x50)
|
||||
REG32(I2CC_DMA_LEN, 0x54)
|
||||
/* DMA 64bits */
|
||||
REG32(I2CM_DMA_TX_ADDR_HI, 0x60)
|
||||
FIELD(I2CM_DMA_TX_ADDR_HI, ADDR_HI, 0, 7)
|
||||
REG32(I2CM_DMA_RX_ADDR_HI, 0x64)
|
||||
FIELD(I2CM_DMA_RX_ADDR_HI, ADDR_HI, 0, 7)
|
||||
REG32(I2CS_DMA_TX_ADDR_HI, 0x68)
|
||||
FIELD(I2CS_DMA_TX_ADDR_HI, ADDR_HI, 0, 7)
|
||||
REG32(I2CS_DMA_RX_ADDR_HI, 0x6c)
|
||||
FIELD(I2CS_DMA_RX_ADDR_HI, ADDR_HI, 0, 7)
|
||||
|
||||
struct AspeedI2CState;
|
||||
|
||||
@ -239,12 +250,15 @@ struct AspeedI2CBus {
|
||||
I2CSlave *slave;
|
||||
|
||||
MemoryRegion mr;
|
||||
MemoryRegion mr_pool;
|
||||
|
||||
I2CBus *bus;
|
||||
uint8_t id;
|
||||
qemu_irq irq;
|
||||
|
||||
uint32_t regs[ASPEED_I2C_NEW_NUM_REG];
|
||||
uint8_t pool[ASPEED_I2C_BUS_POOL_SIZE];
|
||||
uint64_t dma_dram_offset;
|
||||
};
|
||||
|
||||
struct AspeedI2CState {
|
||||
@ -275,15 +289,19 @@ struct AspeedI2CClass {
|
||||
|
||||
uint8_t num_busses;
|
||||
uint8_t reg_size;
|
||||
uint32_t reg_gap_size;
|
||||
uint8_t gap;
|
||||
qemu_irq (*bus_get_irq)(AspeedI2CBus *);
|
||||
|
||||
uint64_t pool_size;
|
||||
hwaddr pool_base;
|
||||
uint32_t pool_gap_size;
|
||||
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
|
||||
bool check_sram;
|
||||
bool has_dma;
|
||||
bool has_share_pool;
|
||||
uint64_t mem_size;
|
||||
bool has_dma64;
|
||||
};
|
||||
|
||||
static inline bool aspeed_i2c_is_new_mode(AspeedI2CState *s)
|
||||
@ -363,14 +381,6 @@ static inline uint32_t aspeed_i2c_bus_dma_len_offset(AspeedI2CBus *bus)
|
||||
return R_I2CD_DMA_LEN;
|
||||
}
|
||||
|
||||
static inline uint32_t aspeed_i2c_bus_dma_addr_offset(AspeedI2CBus *bus)
|
||||
{
|
||||
if (aspeed_i2c_is_new_mode(bus->controller)) {
|
||||
return R_I2CC_DMA_ADDR;
|
||||
}
|
||||
return R_I2CD_DMA_ADDR;
|
||||
}
|
||||
|
||||
static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus)
|
||||
{
|
||||
return SHARED_ARRAY_FIELD_EX32(bus->regs, aspeed_i2c_bus_ctrl_offset(bus),
|
||||
|
@ -433,9 +433,25 @@ class AST2x00MachineSDK(QemuSystemTest, LinuxSSHMixIn):
|
||||
f'loader,addr=0x430000000,cpu-num={i}')
|
||||
|
||||
self.vm.add_args('-smp', str(num_cpu))
|
||||
self.vm.add_args('-device',
|
||||
'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
|
||||
self.do_test_aarch64_aspeed_sdk_start(image_dir + 'image-bmc')
|
||||
self.wait_for_console_pattern('nodistro.0 ast2700-default ttyS12')
|
||||
|
||||
self.ssh_connect('root', '0penBmc', False)
|
||||
self.ssh_command('dmesg -c > /dev/null')
|
||||
|
||||
self.ssh_command_output_contains(
|
||||
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device '
|
||||
'&& dmesg -c',
|
||||
'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d');
|
||||
|
||||
self.ssh_command_output_contains(
|
||||
'cat /sys/class/hwmon/hwmon20/temp1_input', '0')
|
||||
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
|
||||
property='temperature', value=18000)
|
||||
self.ssh_command_output_contains(
|
||||
'cat /sys/class/hwmon/hwmon20/temp1_input', '18000')
|
||||
|
||||
class AST2x00MachineMMC(QemuSystemTest):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user