From nobody Sun May 19 01:15:28 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1571215993; cv=none; d=zoho.com; s=zohoarc; b=A7mbMuOphm4JzmCbLWFS166vJWPiGES6pNa4HpfbNPBq5BqjXVNZyLMlHbpwXP+FFMdwXtpPnZyVqCLp3UvFGCpXdrcir8W0UBGIaYwElxHHFjgY1QWZjqq7HeSvb56NSMMUmtyzSWhm7haG/UkrL/r6xf8tBdYgiknWfY05VSo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571215993; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=RKCUE1z3083pao5z5zyIjj5f6ay/y85yZF3jGTKCXCU=; b=i7ewiXEOVWdA93bTQGxEcOcy7qmQiU8sxJf5e4nM/rW+sJS0n0treN03QBaaLojx4ZZNbTZ+OImJEZ/UBygRxs7BqxPRzOL4zB91YostV5/K2nQ/ZW/su1fD7NkFxlZc/kP0snQJQ6XcWS8BmniHMEPEtNyY0VbbXXJ+JpQCLA0= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 157121599337352.361132269535005; Wed, 16 Oct 2019 01:53:13 -0700 (PDT) Received: from localhost ([::1]:39342 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf3P-0007mS-MX for importer@patchew.org; Wed, 16 Oct 2019 04:53:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49760) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf1C-0005dR-6g for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iKf1A-0004lE-3m for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:54 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:8818) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iKf19-0004kU-SV for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:52 -0400 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x9G8lVv4034243 for ; Wed, 16 Oct 2019 04:50:51 -0400 Received: from e06smtp03.uk.ibm.com (e06smtp03.uk.ibm.com [195.75.94.99]) by mx0a-001b2d01.pphosted.com with ESMTP id 2vnyevhh4y-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 16 Oct 2019 04:50:50 -0400 Received: from localhost by e06smtp03.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 16 Oct 2019 09:50:47 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp03.uk.ibm.com (192.168.101.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 16 Oct 2019 09:50:43 +0100 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x9G8oh5I19660894 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 16 Oct 2019 08:50:43 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DF206AE055; Wed, 16 Oct 2019 08:50:42 +0000 (GMT) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BF8B0AE04D; Wed, 16 Oct 2019 08:50:42 +0000 (GMT) Received: from smtp.tls.ibm.com (unknown [9.101.4.1]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 16 Oct 2019 08:50:42 +0000 (GMT) Received: from yukon.kaod.org.com (sig-9-145-54-117.uk.ibm.com [9.145.54.117]) by smtp.tls.ibm.com (Postfix) with ESMTP id 0E2402201F3; Wed, 16 Oct 2019 10:50:42 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: Peter Maydell Subject: [PATCH 1/5] aspeed/i2c: Add support for pool buffer transfers Date: Wed, 16 Oct 2019 10:50:31 +0200 X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191016085035.12136-1-clg@kaod.org> References: <20191016085035.12136-1-clg@kaod.org> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19101608-0012-0000-0000-00000358819C X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19101608-0013-0000-0000-000021939A24 Message-Id: <20191016085035.12136-2-clg@kaod.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-10-16_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1910160079 Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mx0a-001b2d01.pphosted.com id x9G8lVv4034243 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jae Hyun Yoo , Andrew Jeffery , Eddie James , qemu-devel@nongnu.org, qemu-arm@nongnu.org, Joel Stanley , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The Aspeed I2C controller can operate in different transfer modes : - Byte Buffer mode, using a dedicated register to transfer a byte. This is what the model supports today. - Pool Buffer mode, using an internal SRAM to transfer multiple bytes in the same command sequence. Each SoC has different SRAM characteristics. On the AST2400, 2048 bytes of SRAM are available at offset 0x800 of the controller AHB window. The pool buffer can be configured from 1 to 256 bytes per bus. On the AST2500, the SRAM is at offset 0x200 and the pool buffer is of 16 bytes per bus. On the AST2600, the SRAM is at offset 0xC00 and the pool buffer is of 32 bytes per bus. It can be splitted in two for TX and RX but the current model does not add support for it as it it unused by known drivers. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: Joel Stanley Tested-by: Jae Hyun Yoo --- include/hw/i2c/aspeed_i2c.h | 8 ++ hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++---- 2 files changed, 186 insertions(+), 19 deletions(-) diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h index 13e01059189f..5313d07aa72f 100644 --- a/include/hw/i2c/aspeed_i2c.h +++ b/include/hw/i2c/aspeed_i2c.h @@ -32,6 +32,7 @@ OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C) =20 #define ASPEED_I2C_NR_BUSSES 16 +#define ASPEED_I2C_MAX_POOL_SIZE 0x800 =20 struct AspeedI2CState; =20 @@ -50,6 +51,7 @@ typedef struct AspeedI2CBus { uint32_t intr_status; uint32_t cmd; uint32_t buf; + uint32_t pool_ctrl; } AspeedI2CBus; =20 typedef struct AspeedI2CState { @@ -59,6 +61,8 @@ typedef struct AspeedI2CState { qemu_irq irq; =20 uint32_t intr_status; + MemoryRegion pool_iomem; + uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE]; =20 AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES]; } AspeedI2CState; @@ -75,6 +79,10 @@ typedef struct AspeedI2CClass { uint8_t reg_size; uint8_t gap; qemu_irq (*bus_get_irq)(AspeedI2CBus *); + + uint64_t pool_size; + hwaddr pool_base; + uint8_t *(*bus_pool_base)(AspeedI2CBus *); } AspeedI2CClass; =20 I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr); diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index 06c119f385b8..e21f45d96868 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -35,8 +35,7 @@ /* I2C Device (Bus) Register */ =20 #define I2CD_FUN_CTRL_REG 0x00 /* I2CD Function Control */ -#define I2CD_BUFF_SEL_MASK (0x7 << 20) -#define I2CD_BUFF_SEL(x) (x << 20) +#define I2CD_POOL_PAGE_SEL(x) (((x) >> 20) & 0x7) /* AST2400= */ #define I2CD_M_SDA_LOCK_EN (0x1 << 16) #define I2CD_MULTI_MASTER_DIS (0x1 << 15) #define I2CD_M_SCL_DRIVE_EN (0x1 << 14) @@ -113,10 +112,12 @@ #define I2CD_SCL_O_OUT_DIR (0x1 << 12) #define I2CD_BUS_RECOVER_CMD_EN (0x1 << 11) #define I2CD_S_ALT_EN (0x1 << 10) -#define I2CD_RX_DMA_ENABLE (0x1 << 9) -#define I2CD_TX_DMA_ENABLE (0x1 << 8) =20 /* Command Bit */ +#define I2CD_RX_DMA_ENABLE (0x1 << 9) +#define I2CD_TX_DMA_ENABLE (0x1 << 8) +#define I2CD_RX_BUFF_ENABLE (0x1 << 7) +#define I2CD_TX_BUFF_ENABLE (0x1 << 6) #define I2CD_M_STOP_CMD (0x1 << 5) #define I2CD_M_S_RX_CMD_LAST (0x1 << 4) #define I2CD_M_RX_CMD (0x1 << 3) @@ -125,7 +126,11 @@ #define I2CD_M_START_CMD (0x1) =20 #define I2CD_DEV_ADDR_REG 0x18 /* Slave Device Address */ -#define I2CD_BUF_CTRL_REG 0x1c /* Pool Buffer Control */ +#define I2CD_POOL_CTRL_REG 0x1c /* Pool Buffer Control */ +#define I2CD_POOL_RX_COUNT(x) (((x) >> 24) & 0xff) +#define I2CD_POOL_RX_SIZE(x) ((((x) >> 16) & 0xff) + 1) +#define I2CD_POOL_TX_COUNT(x) ((((x) >> 8) & 0xff) + 1) +#define I2CD_POOL_OFFSET(x) (((x) & 0x3f) << 2) /* AST2400= */ #define I2CD_BYTE_BUF_REG 0x20 /* Transmit/Receive Byte Buffer= */ #define I2CD_BYTE_BUF_TX_SHIFT 0 #define I2CD_BYTE_BUF_TX_MASK 0xff @@ -170,6 +175,8 @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwadd= r offset, return bus->intr_ctrl; case I2CD_INTR_STS_REG: return bus->intr_status; + case I2CD_POOL_CTRL_REG: + return bus->pool_ctrl; case I2CD_BYTE_BUF_REG: return bus->buf; case I2CD_CMD_REG: @@ -192,14 +199,58 @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus) return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK; } =20 -static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus) +static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start) +{ + AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(bus->controller); + int ret =3D -1; + int i; + + if (bus->cmd & I2CD_TX_BUFF_ENABLE) { + for (i =3D pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++= ) { + uint8_t *pool_base =3D aic->bus_pool_base(bus); + + ret =3D i2c_send(bus->bus, pool_base[i]); + if (ret) { + break; + } + } + bus->cmd &=3D ~I2CD_TX_BUFF_ENABLE; + } else { + ret =3D i2c_send(bus->bus, bus->buf); + } + + return ret; +} + +static void aspeed_i2c_bus_recv(AspeedI2CBus *bus) { - uint8_t ret; + AspeedI2CState *s =3D bus->controller; + AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(s); + uint8_t data; + int i; + + if (bus->cmd & I2CD_RX_BUFF_ENABLE) { + uint8_t *pool_base =3D aic->bus_pool_base(bus); =20 + for (i =3D 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) { + pool_base[i] =3D i2c_recv(bus->bus); + } + + /* Update RX count */ + bus->pool_ctrl &=3D ~(0xff << 24); + bus->pool_ctrl |=3D (i & 0xff) << 24; + bus->cmd &=3D ~I2CD_RX_BUFF_ENABLE; + } else { + data =3D i2c_recv(bus->bus); + bus->buf =3D (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SH= IFT; + } +} + +static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus) +{ aspeed_i2c_set_state(bus, I2CD_MRXD); - ret =3D i2c_recv(bus->bus); + aspeed_i2c_bus_recv(bus); bus->intr_status |=3D I2CD_INTR_RX_DONE; - bus->buf =3D (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT; if (bus->cmd & I2CD_M_S_RX_CMD_LAST) { i2c_nack(bus->bus); } @@ -207,31 +258,66 @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bu= s) aspeed_i2c_set_state(bus, I2CD_MACTIVE); } =20 +static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus) +{ + AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(bus->controller); + + if (bus->cmd & I2CD_TX_BUFF_ENABLE) { + uint8_t *pool_base =3D aic->bus_pool_base(bus); + + return pool_base[0]; + } else { + return bus->buf; + } +} + /* * The state machine needs some refinement. It is only used to track * invalid STOP commands for the moment. */ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value) { + uint8_t pool_start =3D 0; + bus->cmd &=3D ~0xFFFF; bus->cmd |=3D value & 0xFFFF; =20 if (bus->cmd & I2CD_M_START_CMD) { uint8_t state =3D aspeed_i2c_get_state(bus) & I2CD_MACTIVE ? I2CD_MSTARTR : I2CD_MSTART; + uint8_t addr; =20 aspeed_i2c_set_state(bus, state); =20 - if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7), - extract32(bus->buf, 0, 1))) { + addr =3D aspeed_i2c_get_addr(bus); + + if (i2c_start_transfer(bus->bus, extract32(addr, 1, 7), + extract32(addr, 0, 1))) { bus->intr_status |=3D I2CD_INTR_TX_NAK; } else { bus->intr_status |=3D I2CD_INTR_TX_ACK; } =20 - /* START command is also a TX command, as the slave address is - * sent on the bus */ - bus->cmd &=3D ~(I2CD_M_START_CMD | I2CD_M_TX_CMD); + bus->cmd &=3D ~I2CD_M_START_CMD; + + /* + * The START command is also a TX command, as the slave + * address is sent on the bus. Drop the TX flag if nothing + * else needs to be sent in this sequence. + */ + if (bus->cmd & I2CD_TX_BUFF_ENABLE) { + if (I2CD_POOL_TX_COUNT(bus->pool_ctrl) =3D=3D 1) { + bus->cmd &=3D ~I2CD_M_TX_CMD; + } else { + /* + * Increase the start index in the TX pool buffer to + * skip the address byte. + */ + pool_start++; + } + } else { + bus->cmd &=3D ~I2CD_M_TX_CMD; + } =20 /* No slave found */ if (!i2c_bus_busy(bus->bus)) { @@ -242,7 +328,7 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus= , uint64_t value) =20 if (bus->cmd & I2CD_M_TX_CMD) { aspeed_i2c_set_state(bus, I2CD_MTXD); - if (i2c_send(bus->bus, bus->buf)) { + if (aspeed_i2c_bus_send(bus, pool_start)) { bus->intr_status |=3D (I2CD_INTR_TX_NAK); i2c_end_transfer(bus->bus); } else { @@ -313,6 +399,11 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr = offset, qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n", __func__); break; + case I2CD_POOL_CTRL_REG: + bus->pool_ctrl &=3D ~0xffffff; + bus->pool_ctrl |=3D (value & 0xffffff); + break; + case I2CD_BYTE_BUF_REG: bus->buf =3D (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_S= HIFT; break; @@ -378,10 +469,45 @@ static const MemoryRegionOps aspeed_i2c_ctrl_ops =3D { .endianness =3D DEVICE_LITTLE_ENDIAN, }; =20 +static uint64_t aspeed_i2c_pool_read(void *opaque, hwaddr offset, + unsigned size) +{ + AspeedI2CState *s =3D opaque; + uint64_t ret =3D 0; + int i; + + for (i =3D 0; i < size; i++) { + ret |=3D (uint64_t) s->pool[offset + i] << (8 * i); + } + + return ret; +} + +static void aspeed_i2c_pool_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + AspeedI2CState *s =3D opaque; + int i; + + for (i =3D 0; i < size; i++) { + s->pool[offset + i] =3D (value >> (8 * i)) & 0xFF; + } +} + +static const MemoryRegionOps aspeed_i2c_pool_ops =3D { + .read =3D aspeed_i2c_pool_read, + .write =3D aspeed_i2c_pool_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 1, + .max_access_size =3D 4, + }, +}; + static const VMStateDescription aspeed_i2c_bus_vmstate =3D { .name =3D TYPE_ASPEED_I2C, - .version_id =3D 1, - .minimum_version_id =3D 1, + .version_id =3D 2, + .minimum_version_id =3D 2, .fields =3D (VMStateField[]) { VMSTATE_UINT8(id, AspeedI2CBus), VMSTATE_UINT32(ctrl, AspeedI2CBus), @@ -390,19 +516,21 @@ static const VMStateDescription aspeed_i2c_bus_vmstat= e =3D { VMSTATE_UINT32(intr_status, AspeedI2CBus), VMSTATE_UINT32(cmd, AspeedI2CBus), VMSTATE_UINT32(buf, AspeedI2CBus), + VMSTATE_UINT32(pool_ctrl, AspeedI2CBus), VMSTATE_END_OF_LIST() } }; =20 static const VMStateDescription aspeed_i2c_vmstate =3D { .name =3D TYPE_ASPEED_I2C, - .version_id =3D 1, - .minimum_version_id =3D 1, + .version_id =3D 2, + .minimum_version_id =3D 2, .fields =3D (VMStateField[]) { VMSTATE_UINT32(intr_status, AspeedI2CState), VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState, ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmsta= te, AspeedI2CBus), + VMSTATE_UINT8_ARRAY(pool, AspeedI2CState, ASPEED_I2C_MAX_POOL_SIZE= ), VMSTATE_END_OF_LIST() } }; @@ -472,6 +600,10 @@ static void aspeed_i2c_realize(DeviceState *dev, Error= **errp) memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset= ), &s->busses[i].mr); } + + memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops,= s, + "aspeed.i2c-pool", aic->pool_size); + memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem); } =20 static void aspeed_i2c_class_init(ObjectClass *klass, void *data) @@ -498,6 +630,14 @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CB= us *bus) return bus->controller->irq; } =20 +static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus) +{ + uint8_t *pool_page =3D + &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100]; + + return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)]; +} + static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -509,6 +649,9 @@ static void aspeed_2400_i2c_class_init(ObjectClass *kla= ss, void *data) aic->reg_size =3D 0x40; aic->gap =3D 7; aic->bus_get_irq =3D aspeed_2400_i2c_bus_get_irq; + aic->pool_size =3D 0x800; + aic->pool_base =3D 0x800; + aic->bus_pool_base =3D aspeed_2400_i2c_bus_pool_base; } =20 static const TypeInfo aspeed_2400_i2c_info =3D { @@ -522,6 +665,11 @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CB= us *bus) return bus->controller->irq; } =20 +static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus) +{ + return &bus->controller->pool[bus->id * 0x10]; +} + static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -533,6 +681,9 @@ static void aspeed_2500_i2c_class_init(ObjectClass *kla= ss, void *data) aic->reg_size =3D 0x40; aic->gap =3D 7; aic->bus_get_irq =3D aspeed_2500_i2c_bus_get_irq; + aic->pool_size =3D 0x100; + aic->pool_base =3D 0x200; + aic->bus_pool_base =3D aspeed_2500_i2c_bus_pool_base; } =20 static const TypeInfo aspeed_2500_i2c_info =3D { @@ -546,6 +697,11 @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CB= us *bus) return bus->irq; } =20 +static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus) +{ + return &bus->controller->pool[bus->id * 0x20]; +} + static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -557,6 +713,9 @@ static void aspeed_2600_i2c_class_init(ObjectClass *kla= ss, void *data) aic->reg_size =3D 0x80; aic->gap =3D -1; /* no gap */ aic->bus_get_irq =3D aspeed_2600_i2c_bus_get_irq; + aic->pool_size =3D 0x200; + aic->pool_base =3D 0xC00; + aic->bus_pool_base =3D aspeed_2600_i2c_bus_pool_base; } =20 static const TypeInfo aspeed_2600_i2c_info =3D { --=20 2.21.0 From nobody Sun May 19 01:15:28 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1571215982; cv=none; d=zoho.com; s=zohoarc; b=Ros9E1yh/KEIkwGuZEPzun0uZKDPx/gWethyYC2jArOW/Gj3y6x7KUJVupIWdd9BwM1WIkd+SxNsGct9lgR7ViIxacnG4gwyGVFMO1nQGflbVpXL07XNOB2zz8qwSsDtQg1r/JSMjG1N5vgxan4RiI0F1b6Ll7ClbbAeDortDa4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571215982; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ri2m/80rzEW/08gWKUt/OBNtAx2LDXIhud4qef0P+l0=; b=OnjYFFSFVsCY70dMGPTYwQwrCQMQNGdliJXM9GG+tFb8p5eH0QaTvpHIznNHhVMVrjdHkyTiZKPnDlJQiWrATYUCkcBoq0emj+Fo3N6F2mStL6NigLHmgnzmZ0t+FnhXYNWnrgkCG835dRDkaEjbupi6o64i9cnMSq7WGSa1r/U= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1571215982423934.5811134710913; Wed, 16 Oct 2019 01:53:02 -0700 (PDT) Received: from localhost ([::1]:39338 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf39-0007NG-QX for importer@patchew.org; Wed, 16 Oct 2019 04:52:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49714) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf1B-0005dM-4k for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iKf19-0004kZ-PT for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:53 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:37318 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iKf19-0004kE-KI for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:51 -0400 Received: from pps.filterd (m0098414.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x9G8lUYB089452 for ; Wed, 16 Oct 2019 04:50:49 -0400 Received: from e06smtp03.uk.ibm.com (e06smtp03.uk.ibm.com [195.75.94.99]) by mx0b-001b2d01.pphosted.com with ESMTP id 2vnxjhufcu-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 16 Oct 2019 04:50:49 -0400 Received: from localhost by e06smtp03.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 16 Oct 2019 09:50:47 +0100 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp03.uk.ibm.com (192.168.101.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 16 Oct 2019 09:50:44 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x9G8ohX533947770 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 16 Oct 2019 08:50:43 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8183211C04C; Wed, 16 Oct 2019 08:50:43 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6F3C011C05B; Wed, 16 Oct 2019 08:50:43 +0000 (GMT) Received: from smtp.tls.ibm.com (unknown [9.101.4.1]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 16 Oct 2019 08:50:43 +0000 (GMT) Received: from yukon.kaod.org.com (sig-9-145-54-117.uk.ibm.com [9.145.54.117]) by smtp.tls.ibm.com (Postfix) with ESMTP id B3F452201ED; Wed, 16 Oct 2019 10:50:42 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: Peter Maydell Subject: [PATCH 2/5] aspeed/i2c: Check SRAM enablement on A2500 Date: Wed, 16 Oct 2019 10:50:32 +0200 X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191016085035.12136-1-clg@kaod.org> References: <20191016085035.12136-1-clg@kaod.org> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19101608-0012-0000-0000-00000358819D X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19101608-0013-0000-0000-000021939A25 Message-Id: <20191016085035.12136-3-clg@kaod.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-10-16_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=829 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1910160079 Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mx0b-001b2d01.pphosted.com id x9G8lUYB089452 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jae Hyun Yoo , Andrew Jeffery , Eddie James , qemu-devel@nongnu.org, qemu-arm@nongnu.org, Joel Stanley , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The SRAM must be enabled before using the Buffer Pool mode or the DMA mode. This is not required on other SoCs. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: Joel Stanley Tested-by: Jae Hyun Yoo --- include/hw/i2c/aspeed_i2c.h | 3 +++ hw/i2c/aspeed_i2c.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h index 5313d07aa72f..7a555072dfbf 100644 --- a/include/hw/i2c/aspeed_i2c.h +++ b/include/hw/i2c/aspeed_i2c.h @@ -61,6 +61,7 @@ typedef struct AspeedI2CState { qemu_irq irq; =20 uint32_t intr_status; + uint32_t ctrl_global; MemoryRegion pool_iomem; uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE]; =20 @@ -83,6 +84,8 @@ typedef struct AspeedI2CClass { uint64_t pool_size; hwaddr pool_base; uint8_t *(*bus_pool_base)(AspeedI2CBus *); + bool check_sram; + } AspeedI2CClass; =20 I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr); diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index e21f45d96868..c7929aa2850f 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -31,6 +31,8 @@ #define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */ #define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target Assignment */ +#define I2C_CTRL_GLOBAL 0x0C /* Global Control Register */ +#define I2C_CTRL_SRAM_EN BIT(0) =20 /* I2C Device (Bus) Register */ =20 @@ -271,6 +273,29 @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus) } } =20 +static bool aspeed_i2c_check_sram(AspeedI2CBus *bus) +{ + AspeedI2CState *s =3D bus->controller; + AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(s); + + if (!aic->check_sram) { + return true; + } + + /* + * AST2500: SRAM must be enabled before using the Buffer Pool or + * DMA mode. + */ + if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) && + (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE | + I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func= __); + return false; + } + + return true; +} + /* * The state machine needs some refinement. It is only used to track * invalid STOP commands for the moment. @@ -282,6 +307,10 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bu= s, uint64_t value) bus->cmd &=3D ~0xFFFF; bus->cmd |=3D value & 0xFFFF; =20 + if (!aspeed_i2c_check_sram(bus)) { + return; + } + if (bus->cmd & I2CD_M_START_CMD) { uint8_t state =3D aspeed_i2c_get_state(bus) & I2CD_MACTIVE ? I2CD_MSTARTR : I2CD_MSTART; @@ -436,6 +465,8 @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwad= dr offset, switch (offset) { case I2C_CTRL_STATUS: return s->intr_status; + case I2C_CTRL_GLOBAL: + return s->ctrl_global; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\= n", __func__, offset); @@ -448,7 +479,12 @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwa= ddr offset, static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { + AspeedI2CState *s =3D opaque; + switch (offset) { + case I2C_CTRL_GLOBAL: + s->ctrl_global =3D value; + break; case I2C_CTRL_STATUS: default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\= n", @@ -684,6 +720,7 @@ static void aspeed_2500_i2c_class_init(ObjectClass *kla= ss, void *data) aic->pool_size =3D 0x100; aic->pool_base =3D 0x200; aic->bus_pool_base =3D aspeed_2500_i2c_bus_pool_base; + aic->check_sram =3D true; } =20 static const TypeInfo aspeed_2500_i2c_info =3D { --=20 2.21.0 From nobody Sun May 19 01:15:28 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1571216154; cv=none; d=zoho.com; s=zohoarc; b=Okp1UobJVurMMn5ILMyMDmP0tlKS3F5OUiaOxRwKt1NgKA7N0H1odcP1PVQeTzGbgqIc2Tjl4Dp/PSdxXX2Agh4rbf3vGP0tDGwLzV+SfGI+Balae55C1va8i9Vvj1rZ0g9+fm6nUZhQbp7LEjzr2uIumpFkOmzrw0bxIJjC4/8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571216154; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=u5VWor5I3OdoLYnQ8MvyoGBCnLOoa2Gi7tFhiberXgg=; b=kRngpMiw7ldqFGrQ5d2PR2FPz9Tmt7XWjQzspLF8BBNWE48Eti9lXKirXV8bxi3/TQdepxcSmD5vmCQneafB+PPt81fK2TwO9gjlJGA61MPahZhYBZgdjAEDomEL0Tvsu4d4Ysnaz+t0ExYQdTaKUEkKxLt4UILDjH8rSnndLDA= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1571216154205228.42622633370354; Wed, 16 Oct 2019 01:55:54 -0700 (PDT) Received: from localhost ([::1]:39432 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf60-0002k9-Ia for importer@patchew.org; Wed, 16 Oct 2019 04:55:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49713) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf1B-0005dL-5X for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iKf19-0004kf-Pp for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:53 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:60100 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iKf19-0004kF-KI for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:51 -0400 Received: from pps.filterd (m0098414.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x9G8lUYC089452 for ; Wed, 16 Oct 2019 04:50:50 -0400 Received: from e06smtp01.uk.ibm.com (e06smtp01.uk.ibm.com [195.75.94.97]) by mx0b-001b2d01.pphosted.com with ESMTP id 2vnxjhufd4-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 16 Oct 2019 04:50:50 -0400 Received: from localhost by e06smtp01.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 16 Oct 2019 09:50:48 +0100 Received: from b06avi18878370.portsmouth.uk.ibm.com (9.149.26.194) by e06smtp01.uk.ibm.com (192.168.101.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 16 Oct 2019 09:50:45 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06avi18878370.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x9G8oi0T46924094 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 16 Oct 2019 08:50:44 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3B5B54C04A; Wed, 16 Oct 2019 08:50:44 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1FBD74C044; Wed, 16 Oct 2019 08:50:44 +0000 (GMT) Received: from smtp.tls.ibm.com (unknown [9.101.4.1]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 16 Oct 2019 08:50:44 +0000 (GMT) Received: from yukon.kaod.org.com (sig-9-145-54-117.uk.ibm.com [9.145.54.117]) by smtp.tls.ibm.com (Postfix) with ESMTP id 64D4E2201F3; Wed, 16 Oct 2019 10:50:43 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: Peter Maydell Subject: [PATCH 3/5] aspeed: Add a DRAM memory region at the SoC level Date: Wed, 16 Oct 2019 10:50:33 +0200 X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191016085035.12136-1-clg@kaod.org> References: <20191016085035.12136-1-clg@kaod.org> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19101608-4275-0000-0000-0000037285EE X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19101608-4276-0000-0000-000038859A8E Message-Id: <20191016085035.12136-4-clg@kaod.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-10-16_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1910160079 Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mx0b-001b2d01.pphosted.com id x9G8lUYC089452 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jae Hyun Yoo , Andrew Jeffery , Eddie James , qemu-devel@nongnu.org, qemu-arm@nongnu.org, Joel Stanley , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Currently, we link the DRAM memory region to the FMC model (for DMAs) through a property alias at the SoC level. The I2C model will need a similar region for DMA support, add a DRAM region property at the SoC level for both model to use. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Jae Hyun Yoo --- include/hw/arm/aspeed_soc.h | 1 + hw/arm/aspeed_ast2600.c | 7 +++++-- hw/arm/aspeed_soc.c | 9 +++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index cccb684a19bb..3375ef91607f 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -40,6 +40,7 @@ typedef struct AspeedSoCState { ARMCPU cpu[ASPEED_CPUS_NUM]; uint32_t num_cpus; A15MPPrivState a7mpcore; + MemoryRegion *dram_mr; MemoryRegion sram; AspeedVICState vic; AspeedRtcState rtc; diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index 931887ac681f..a403c2aae067 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -158,8 +158,6 @@ static void aspeed_soc_ast2600_init(Object *obj) typename); object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", &error_abort); - object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram", - &error_abort); =20 for (i =3D 0; i < sc->spis_num; i++) { snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, soc= name); @@ -362,6 +360,11 @@ static void aspeed_soc_ast2600_realize(DeviceState *de= v, Error **errp) } =20 /* FMC, The number of CS is set at the board level */ + object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", = &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM], "sdram-base", &err); if (err) { diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index f4fe243458fd..dd1ee0e3336d 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -175,8 +175,6 @@ static void aspeed_soc_init(Object *obj) typename); object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", &error_abort); - object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram", - &error_abort); =20 for (i =3D 0; i < sc->spis_num; i++) { snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, soc= name); @@ -323,6 +321,11 @@ static void aspeed_soc_realize(DeviceState *dev, Error= **errp) aspeed_soc_get_irq(s, ASPEED_I2C)); =20 /* FMC, The number of CS is set at the board level */ + object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", = &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM], "sdram-base", &err); if (err) { @@ -429,6 +432,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error = **errp) } static Property aspeed_soc_properties[] =3D { DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0), + DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, + MemoryRegion *), DEFINE_PROP_END_OF_LIST(), }; =20 --=20 2.21.0 From nobody Sun May 19 01:15:28 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1571216241; cv=none; d=zoho.com; s=zohoarc; b=DTiKOiQ2UZljAbophFKRsFbR68iUBk6E2gG1RGYR42wEScV2U/qoz2K6dSKcEbb59fkwhCS9mI2e7QTNGFcKJY/fxgoJ2q6zNxBj0fyoD5Dv4xPehXDcQIaAH3D2y/CqWGKgneZsUW94omyoo/MuL7ZJZO1o4zuLiSMqEfK2Le0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571216241; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=L8bqhHnirAvsXsY9ZYrMQcpm04vYSYpGiBgxbHFTEBc=; b=UhaeOeuli/ToEJJ1T0FdJmxUF+P7Gr4dXc42DXGdD20agYzko9HWZkJFR4O0mazf0NgR7SV9ecWZI07dDzxQRwj6ygTQUetYJMem2pW5tJ4jnE0HdYkCY3R9LxC2k6evIsohm3VWg8VN0lQz6PnxblxOK9nX8oLqT4xwWL7NZ2o= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1571216241500337.63473067939174; Wed, 16 Oct 2019 01:57:21 -0700 (PDT) Received: from localhost ([::1]:39438 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf7Q-0004fg-8h for importer@patchew.org; Wed, 16 Oct 2019 04:57:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49774) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf1C-0005du-Ov for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iKf1A-0004lf-RP for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:54 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:1560) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iKf1A-0004l9-Ip for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:52 -0400 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x9G8lVLA034244 for ; Wed, 16 Oct 2019 04:50:51 -0400 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0a-001b2d01.pphosted.com with ESMTP id 2vnyevhh5r-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 16 Oct 2019 04:50:51 -0400 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 16 Oct 2019 09:50:49 +0100 Received: from b06avi18878370.portsmouth.uk.ibm.com (9.149.26.194) by e06smtp05.uk.ibm.com (192.168.101.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 16 Oct 2019 09:50:45 +0100 Received: from d06av24.portsmouth.uk.ibm.com (mk.ibm.com [9.149.105.60]) by b06avi18878370.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x9G8oj4Z46924102 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 16 Oct 2019 08:50:45 GMT Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E33FF42045; Wed, 16 Oct 2019 08:50:44 +0000 (GMT) Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C463E42042; Wed, 16 Oct 2019 08:50:44 +0000 (GMT) Received: from smtp.tls.ibm.com (unknown [9.101.4.1]) by d06av24.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 16 Oct 2019 08:50:44 +0000 (GMT) Received: from yukon.kaod.org.com (sig-9-145-54-117.uk.ibm.com [9.145.54.117]) by smtp.tls.ibm.com (Postfix) with ESMTP id 158842201ED; Wed, 16 Oct 2019 10:50:44 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: Peter Maydell Subject: [PATCH 4/5] aspeed/i2c: Add support for DMA transfers Date: Wed, 16 Oct 2019 10:50:34 +0200 X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191016085035.12136-1-clg@kaod.org> References: <20191016085035.12136-1-clg@kaod.org> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19101608-0020-0000-0000-000003798143 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19101608-0021-0000-0000-000021CFA3CB Message-Id: <20191016085035.12136-5-clg@kaod.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-10-16_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1910160079 Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mx0a-001b2d01.pphosted.com id x9G8lVLA034244 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jae Hyun Yoo , Andrew Jeffery , Eddie James , qemu-devel@nongnu.org, qemu-arm@nongnu.org, Joel Stanley , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA transfers to and from DRAM. A pair of registers defines the buffer address and the length of the DMA transfer. The address should be aligned on 4 bytes and the maximum length should not exceed 4K. The receive or transmit DMA transfer can then be initiated with specific bits in the Command/Status register of the controller. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: Joel Stanley Tested-by: Jae Hyun Yoo --- include/hw/i2c/aspeed_i2c.h | 5 ++ hw/arm/aspeed_ast2600.c | 5 ++ hw/arm/aspeed_soc.c | 5 ++ hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++- 4 files changed, 138 insertions(+), 3 deletions(-) diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h index 7a555072dfbf..f1b9e5bf91e2 100644 --- a/include/hw/i2c/aspeed_i2c.h +++ b/include/hw/i2c/aspeed_i2c.h @@ -52,6 +52,8 @@ typedef struct AspeedI2CBus { uint32_t cmd; uint32_t buf; uint32_t pool_ctrl; + uint32_t dma_addr; + uint32_t dma_len; } AspeedI2CBus; =20 typedef struct AspeedI2CState { @@ -66,6 +68,8 @@ typedef struct AspeedI2CState { uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE]; =20 AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES]; + MemoryRegion *dram_mr; + AddressSpace dram_as; } AspeedI2CState; =20 #define ASPEED_I2C_CLASS(klass) \ @@ -85,6 +89,7 @@ typedef struct AspeedI2CClass { hwaddr pool_base; uint8_t *(*bus_pool_base)(AspeedI2CBus *); bool check_sram; + bool has_dma; =20 } AspeedI2CClass; =20 diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index a403c2aae067..0881eb25983e 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -343,6 +343,11 @@ static void aspeed_soc_ast2600_realize(DeviceState *de= v, Error **errp) } =20 /* I2C */ + object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", = &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); if (err) { error_propagate(errp, err); diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index dd1ee0e3336d..b01c97744196 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -311,6 +311,11 @@ static void aspeed_soc_realize(DeviceState *dev, Error= **errp) } =20 /* I2C */ + object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", = &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); if (err) { error_propagate(errp, err); diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index c7929aa2850f..030d9c56be65 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -23,8 +23,11 @@ #include "migration/vmstate.h" #include "qemu/log.h" #include "qemu/module.h" +#include "qemu/error-report.h" +#include "qapi/error.h" #include "hw/i2c/aspeed_i2c.h" #include "hw/irq.h" +#include "hw/qdev-properties.h" =20 /* I2C Global Register */ =20 @@ -138,7 +141,8 @@ #define I2CD_BYTE_BUF_TX_MASK 0xff #define I2CD_BYTE_BUF_RX_SHIFT 8 #define I2CD_BYTE_BUF_RX_MASK 0xff - +#define I2CD_DMA_ADDR 0x24 /* DMA Buffer Address */ +#define I2CD_DMA_LEN 0x28 /* DMA Transfer Length < 4KB */ =20 static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus) { @@ -165,6 +169,7 @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwadd= r offset, unsigned size) { AspeedI2CBus *bus =3D opaque; + AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(bus->controller); =20 switch (offset) { case I2CD_FUN_CTRL_REG: @@ -183,6 +188,18 @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwad= dr offset, return bus->buf; case I2CD_CMD_REG: return bus->cmd | (i2c_bus_busy(bus->bus) << 16); + case I2CD_DMA_ADDR: + if (!aic->has_dma) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func= __); + return -1; + } + return bus->dma_addr; + case I2CD_DMA_LEN: + if (!aic->has_dma) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func= __); + return -1; + } + return bus->dma_len; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, off= set); @@ -201,6 +218,24 @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus) return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK; } =20 +static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data) +{ + MemTxResult result; + AspeedI2CState *s =3D bus->controller; + + result =3D address_space_read(&s->dram_as, bus->dma_addr, + MEMTXATTRS_UNSPECIFIED, data, 1); + if (result !=3D MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n", + __func__, bus->dma_addr); + return -1; + } + + bus->dma_addr++; + bus->dma_len--; + return 0; +} + static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start) { AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(bus->controller); @@ -217,6 +252,16 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint= 8_t pool_start) } } bus->cmd &=3D ~I2CD_TX_BUFF_ENABLE; + } else if (bus->cmd & I2CD_TX_DMA_ENABLE) { + while (bus->dma_len) { + uint8_t data; + aspeed_i2c_dma_read(bus, &data); + ret =3D i2c_send(bus->bus, data); + if (ret) { + break; + } + } + bus->cmd &=3D ~I2CD_TX_DMA_ENABLE; } else { ret =3D i2c_send(bus->bus, bus->buf); } @@ -242,6 +287,24 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus) bus->pool_ctrl &=3D ~(0xff << 24); bus->pool_ctrl |=3D (i & 0xff) << 24; bus->cmd &=3D ~I2CD_RX_BUFF_ENABLE; + } else if (bus->cmd & I2CD_RX_DMA_ENABLE) { + uint8_t data; + + while (bus->dma_len) { + MemTxResult result; + + data =3D i2c_recv(bus->bus); + result =3D address_space_write(&s->dram_as, bus->dma_addr, + MEMTXATTRS_UNSPECIFIED, &data, 1); + if (result !=3D MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08= x\n", + __func__, bus->dma_addr); + return; + } + bus->dma_addr++; + bus->dma_len--; + } + bus->cmd &=3D ~I2CD_RX_DMA_ENABLE; } else { data =3D i2c_recv(bus->bus); bus->buf =3D (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SH= IFT; @@ -268,6 +331,11 @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus) uint8_t *pool_base =3D aic->bus_pool_base(bus); =20 return pool_base[0]; + } else if (bus->cmd & I2CD_TX_DMA_ENABLE) { + uint8_t data; + + aspeed_i2c_dma_read(bus, &data); + return data; } else { return bus->buf; } @@ -344,6 +412,10 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bu= s, uint64_t value) */ pool_start++; } + } else if (bus->cmd & I2CD_TX_DMA_ENABLE) { + if (bus->dma_len =3D=3D 0) { + bus->cmd &=3D ~I2CD_M_TX_CMD; + } } else { bus->cmd &=3D ~I2CD_M_TX_CMD; } @@ -447,9 +519,35 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr = offset, break; } =20 + if (!aic->has_dma && + value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func= __); + break; + } + aspeed_i2c_bus_handle_cmd(bus, value); aspeed_i2c_bus_raise_interrupt(bus); break; + case I2CD_DMA_ADDR: + if (!aic->has_dma) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func= __); + break; + } + + bus->dma_addr =3D value & 0xfffffffc; + break; + + case I2CD_DMA_LEN: + if (!aic->has_dma) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func= __); + break; + } + + bus->dma_len =3D value & 0xfff; + if (!bus->dma_len) { + qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__= ); + } + break; =20 default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\= n", @@ -542,8 +640,8 @@ static const MemoryRegionOps aspeed_i2c_pool_ops =3D { =20 static const VMStateDescription aspeed_i2c_bus_vmstate =3D { .name =3D TYPE_ASPEED_I2C, - .version_id =3D 2, - .minimum_version_id =3D 2, + .version_id =3D 3, + .minimum_version_id =3D 3, .fields =3D (VMStateField[]) { VMSTATE_UINT8(id, AspeedI2CBus), VMSTATE_UINT32(ctrl, AspeedI2CBus), @@ -553,6 +651,8 @@ static const VMStateDescription aspeed_i2c_bus_vmstate = =3D { VMSTATE_UINT32(cmd, AspeedI2CBus), VMSTATE_UINT32(buf, AspeedI2CBus), VMSTATE_UINT32(pool_ctrl, AspeedI2CBus), + VMSTATE_UINT32(dma_addr, AspeedI2CBus), + VMSTATE_UINT32(dma_len, AspeedI2CBus), VMSTATE_END_OF_LIST() } }; @@ -584,6 +684,8 @@ static void aspeed_i2c_reset(DeviceState *dev) s->busses[i].intr_status =3D 0; s->busses[i].cmd =3D 0; s->busses[i].buf =3D 0; + s->busses[i].dma_addr =3D 0; + s->busses[i].dma_len =3D 0; i2c_end_transfer(s->busses[i].bus); } } @@ -640,14 +742,30 @@ static void aspeed_i2c_realize(DeviceState *dev, Erro= r **errp) memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops,= s, "aspeed.i2c-pool", aic->pool_size); memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem); + + if (aic->has_dma) { + if (!s->dram_mr) { + error_setg(errp, TYPE_ASPEED_I2C ": 'dram' link not set"); + return; + } + + address_space_init(&s->dram_as, s->dram_mr, "dma-dram"); + } } =20 +static Property aspeed_i2c_properties[] =3D { + DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr, + TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_END_OF_LIST(), +}; + static void aspeed_i2c_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); =20 dc->vmsd =3D &aspeed_i2c_vmstate; dc->reset =3D aspeed_i2c_reset; + dc->props =3D aspeed_i2c_properties; dc->realize =3D aspeed_i2c_realize; dc->desc =3D "Aspeed I2C Controller"; } @@ -721,6 +839,7 @@ static void aspeed_2500_i2c_class_init(ObjectClass *kla= ss, void *data) aic->pool_base =3D 0x200; aic->bus_pool_base =3D aspeed_2500_i2c_bus_pool_base; aic->check_sram =3D true; + aic->has_dma =3D true; } =20 static const TypeInfo aspeed_2500_i2c_info =3D { @@ -753,6 +872,7 @@ static void aspeed_2600_i2c_class_init(ObjectClass *kla= ss, void *data) aic->pool_size =3D 0x200; aic->pool_base =3D 0xC00; aic->bus_pool_base =3D aspeed_2600_i2c_bus_pool_base; + aic->has_dma =3D true; } =20 static const TypeInfo aspeed_2600_i2c_info =3D { --=20 2.21.0 From nobody Sun May 19 01:15:28 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1571215980; cv=none; d=zoho.com; s=zohoarc; b=fLoJryaN42Chk/VflKUOpjc1CB3bdhS5h5YiJgeDXhCJHlNtyFVxE8nBN1Ndlsx4gRSMPUfM4rxxlAkHTN1kcdg4DKyTXs1aw3/Cfx0COFObJVkDiAydxgaCVRVS2lF3L4xUVC+/q2YobN76JjfF+jRCFEmoQUCxu7EN5WlVzKg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571215980; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=DjVN34F0pcCppwTDuAd0tad3xPYMs0VK8evh+hcVn60=; b=lji6Uf18AkXQr/b/ua2CX2Jcbn65RZ/+6uNbrNBqXASu6JAg4Xyp2ci5x1n2wTzVp5d8a+np5tD9xi/pYA7e2Bl4A0u470WYxwup0O2dywF19J9nyqjQXw7i2JRq08J6KC5GXXLusy7kH1/3UoDmwGJemfFaA0r5DlM55c5+YW0= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1571215980736622.6755265213645; Wed, 16 Oct 2019 01:53:00 -0700 (PDT) Received: from localhost ([::1]:39340 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf3C-0007SU-UM for importer@patchew.org; Wed, 16 Oct 2019 04:52:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49773) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKf1C-0005dt-OX for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iKf1A-0004lr-UQ for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:54 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:4548 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iKf1A-0004lQ-P5 for qemu-devel@nongnu.org; Wed, 16 Oct 2019 04:50:52 -0400 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x9G8lYGh023084 for ; Wed, 16 Oct 2019 04:50:52 -0400 Received: from e06smtp03.uk.ibm.com (e06smtp03.uk.ibm.com [195.75.94.99]) by mx0b-001b2d01.pphosted.com with ESMTP id 2vnvpy72js-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 16 Oct 2019 04:50:51 -0400 Received: from localhost by e06smtp03.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 16 Oct 2019 09:50:49 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp03.uk.ibm.com (192.168.101.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 16 Oct 2019 09:50:46 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x9G8ojD352297930 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 16 Oct 2019 08:50:45 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9453211C05B; Wed, 16 Oct 2019 08:50:45 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7560311C04A; Wed, 16 Oct 2019 08:50:45 +0000 (GMT) Received: from smtp.tls.ibm.com (unknown [9.101.4.1]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 16 Oct 2019 08:50:45 +0000 (GMT) Received: from yukon.kaod.org.com (sig-9-145-54-117.uk.ibm.com [9.145.54.117]) by smtp.tls.ibm.com (Postfix) with ESMTP id BAC382201F3; Wed, 16 Oct 2019 10:50:44 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: Peter Maydell Subject: [PATCH 5/5] aspeed/i2c: Add trace events Date: Wed, 16 Oct 2019 10:50:35 +0200 X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191016085035.12136-1-clg@kaod.org> References: <20191016085035.12136-1-clg@kaod.org> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19101608-0012-0000-0000-0000035881A0 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19101608-0013-0000-0000-000021939A26 Message-Id: <20191016085035.12136-6-clg@kaod.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-10-16_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=734 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1910160079 Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mx0b-001b2d01.pphosted.com id x9G8lYGh023084 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jae Hyun Yoo , Andrew Jeffery , Eddie James , qemu-devel@nongnu.org, qemu-arm@nongnu.org, Joel Stanley , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Jae Hyun Yoo --- hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++------- hw/i2c/trace-events | 9 +++++ 2 files changed, 89 insertions(+), 13 deletions(-) diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index 030d9c56be65..2da04a4bff30 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -28,6 +28,7 @@ #include "hw/i2c/aspeed_i2c.h" #include "hw/irq.h" #include "hw/qdev-properties.h" +#include "trace.h" =20 /* I2C Global Register */ =20 @@ -158,6 +159,13 @@ static inline void aspeed_i2c_bus_raise_interrupt(Aspe= edI2CBus *bus) { AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(bus->controller); =20 + trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status, + bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "", + bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "", + bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "", + bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "", + bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : ""); + bus->intr_status &=3D bus->intr_ctrl; if (bus->intr_status) { bus->controller->intr_status |=3D 1 << bus->id; @@ -170,41 +178,57 @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwa= ddr offset, { AspeedI2CBus *bus =3D opaque; AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(bus->controller); + uint64_t value =3D -1; =20 switch (offset) { case I2CD_FUN_CTRL_REG: - return bus->ctrl; + value =3D bus->ctrl; + break; case I2CD_AC_TIMING_REG1: - return bus->timing[0]; + value =3D bus->timing[0]; + break; case I2CD_AC_TIMING_REG2: - return bus->timing[1]; + value =3D bus->timing[1]; + break; case I2CD_INTR_CTRL_REG: - return bus->intr_ctrl; + value =3D bus->intr_ctrl; + break; case I2CD_INTR_STS_REG: - return bus->intr_status; + value =3D bus->intr_status; + break; case I2CD_POOL_CTRL_REG: - return bus->pool_ctrl; + value =3D bus->pool_ctrl; + break; case I2CD_BYTE_BUF_REG: - return bus->buf; + value =3D bus->buf; + break; case I2CD_CMD_REG: - return bus->cmd | (i2c_bus_busy(bus->bus) << 16); + value =3D bus->cmd | (i2c_bus_busy(bus->bus) << 16); + break; case I2CD_DMA_ADDR: if (!aic->has_dma) { qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func= __); - return -1; + break; } - return bus->dma_addr; + value =3D bus->dma_addr; + break; case I2CD_DMA_LEN: if (!aic->has_dma) { qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func= __); - return -1; + break; } - return bus->dma_len; + value =3D bus->dma_len; + break; + default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, off= set); - return -1; + value =3D -1; + break; } + + trace_aspeed_i2c_bus_read(bus->id, offset, size, value); + return value; } =20 static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state) @@ -246,6 +270,9 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8= _t pool_start) for (i =3D pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++= ) { uint8_t *pool_base =3D aic->bus_pool_base(bus); =20 + trace_aspeed_i2c_bus_send("BUF", i + 1, + I2CD_POOL_TX_COUNT(bus->pool_ctrl), + pool_base[i]); ret =3D i2c_send(bus->bus, pool_base[i]); if (ret) { break; @@ -256,6 +283,7 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8= _t pool_start) while (bus->dma_len) { uint8_t data; aspeed_i2c_dma_read(bus, &data); + trace_aspeed_i2c_bus_send("DMA", bus->dma_len, bus->dma_len, d= ata); ret =3D i2c_send(bus->bus, data); if (ret) { break; @@ -263,6 +291,7 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8= _t pool_start) } bus->cmd &=3D ~I2CD_TX_DMA_ENABLE; } else { + trace_aspeed_i2c_bus_send("BYTE", pool_start, 1, bus->buf); ret =3D i2c_send(bus->bus, bus->buf); } =20 @@ -281,6 +310,9 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus) =20 for (i =3D 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) { pool_base[i] =3D i2c_recv(bus->bus); + trace_aspeed_i2c_bus_recv("BUF", i + 1, + I2CD_POOL_RX_SIZE(bus->pool_ctrl), + pool_base[i]); } =20 /* Update RX count */ @@ -294,6 +326,7 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus) MemTxResult result; =20 data =3D i2c_recv(bus->bus); + trace_aspeed_i2c_bus_recv("DMA", bus->dma_len, bus->dma_len, d= ata); result =3D address_space_write(&s->dram_as, bus->dma_addr, MEMTXATTRS_UNSPECIFIED, &data, 1); if (result !=3D MEMTX_OK) { @@ -307,6 +340,7 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus) bus->cmd &=3D ~I2CD_RX_DMA_ENABLE; } else { data =3D i2c_recv(bus->bus); + trace_aspeed_i2c_bus_recv("BYTE", 1, 1, bus->buf); bus->buf =3D (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SH= IFT; } } @@ -364,6 +398,33 @@ static bool aspeed_i2c_check_sram(AspeedI2CBus *bus) return true; } =20 +static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus) +{ + g_autofree char *cmd_flags; + uint32_t count; + + if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) { + count =3D I2CD_POOL_TX_COUNT(bus->pool_ctrl); + } else if (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_RX_DMA_ENABLE)) { + count =3D bus->dma_len; + } else { /* BYTE mode */ + count =3D 1; + } + + cmd_flags =3D g_strdup_printf("%s%s%s%s%s%s%s%s%s", + bus->cmd & I2CD_M_START_CMD ? "start|" : "= ", + bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" := "", + bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" := "", + bus->cmd & I2CD_RX_BUFF_ENABLE ? "rxbuf|" = : "", + bus->cmd & I2CD_TX_BUFF_ENABLE ? "txbuf|" = : "", + bus->cmd & I2CD_M_TX_CMD ? "tx|" : "", + bus->cmd & I2CD_M_RX_CMD ? "rx|" : "", + bus->cmd & I2CD_M_S_RX_CMD_LAST ? "last|" = : "", + bus->cmd & I2CD_M_STOP_CMD ? "stop" : ""); + + trace_aspeed_i2c_bus_cmd(bus->cmd, cmd_flags, count, bus->intr_status); +} + /* * The state machine needs some refinement. It is only used to track * invalid STOP commands for the moment. @@ -379,6 +440,10 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bu= s, uint64_t value) return; } =20 + if (trace_event_get_state_backends(TRACE_ASPEED_I2C_BUS_CMD)) { + aspeed_i2c_bus_cmd_dump(bus); + } + if (bus->cmd & I2CD_M_START_CMD) { uint8_t state =3D aspeed_i2c_get_state(bus) & I2CD_MACTIVE ? I2CD_MSTARTR : I2CD_MSTART; @@ -465,6 +530,8 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr o= ffset, AspeedI2CClass *aic =3D ASPEED_I2C_GET_CLASS(bus->controller); bool handle_rx; =20 + trace_aspeed_i2c_bus_write(bus->id, offset, size, value); + switch (offset) { case I2CD_FUN_CTRL_REG: if (value & I2CD_SLAVE_EN) { diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events index e1c810d5bd08..08db8fa68924 100644 --- a/hw/i2c/trace-events +++ b/hw/i2c/trace-events @@ -5,3 +5,12 @@ i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)" i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x" i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x" + +# aspeed_i2c.c + +aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, ui= nt32_t intr_status) "handling cmd=3D0x%x %s count=3D%d intr=3D0x%x" +aspeed_i2c_bus_raise_interrupt(uint32_t intr_status, const char *str1, con= st char *str2, const char *str3, const char *str4, const char *str5) "handl= ed intr=3D0x%x %s%s%s%s%s" +aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64= _t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64 +aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint6= 4_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64 +aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s = send %d/%d 0x%02x" +aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s = recv %d/%d 0x%02x" --=20 2.21.0