From: Kane Chen via <qemu-devel@nongnu.org>
To: "Cédric Le Goater" <clg@kaod.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Steven Lee" <steven_lee@aspeedtech.com>,
"Troy Lee" <leetroy@gmail.com>,
"Jamin Lin" <jamin_lin@aspeedtech.com>,
"Andrew Jeffery" <andrew@codeconstruct.com.au>,
"Joel Stanley" <joel@jms.id.au>,
"open list:ASPEED BMCs" <qemu-arm@nongnu.org>,
"open list:All patches CC here" <qemu-devel@nongnu.org>
Cc: <troy_lee@aspeedtech.com>, Kane-Chen-AS <kane_chen@aspeedtech.com>
Subject: [PATCH v3 01/18] hw/misc: Add LTPI controller
Date: Mon, 8 Dec 2025 15:44:13 +0800 [thread overview]
Message-ID: <20251208074436.1871180-2-kane_chen@aspeedtech.com> (raw)
In-Reply-To: <20251208074436.1871180-1-kane_chen@aspeedtech.com>
From: Kane-Chen-AS <kane_chen@aspeedtech.com>
LTPI (LVDS Tunneling Protocol & Interface) is defined in the OCP DC-SCM
2.0 specification:
https://www.opencompute.org/documents/ocp-dc-scm-2-0-ltpi-ver-1-0-pdf
LTPI is a protocol and physical interface for tunneling various low-speed
signals between the HPM and SCM. As shown in Figure 2, the AST27x0 (left)
integrates two LTPI controllers, allowing it to connect to up to two
extended boards.
This commit introduces a simple device model for the ASPEED LTPI
controller in QEMU.
The model includes basic MMIO read/write operations and sets default
register values during reset to emulate a link-up state.
Implements register space with read/write callbacks.
Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
---
include/hw/misc/aspeed_ltpi.h | 32 ++++++
hw/misc/aspeed_ltpi.c | 194 ++++++++++++++++++++++++++++++++++
hw/misc/meson.build | 1 +
3 files changed, 227 insertions(+)
create mode 100644 include/hw/misc/aspeed_ltpi.h
create mode 100644 hw/misc/aspeed_ltpi.c
diff --git a/include/hw/misc/aspeed_ltpi.h b/include/hw/misc/aspeed_ltpi.h
new file mode 100644
index 0000000000..cb1a9f4bd8
--- /dev/null
+++ b/include/hw/misc/aspeed_ltpi.h
@@ -0,0 +1,32 @@
+/*
+ * ASPEED LTPI Controller
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef ASPEED_LTPI_H
+#define ASPEED_LTPI_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ASPEED_LTPI "aspeed.ltpi-ctrl"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedLTPIState, ASPEED_LTPI)
+
+#define ASPEED_LTPI_CTRL_SIZE 0x200
+#define ASPEED_LTPI_PHY_SIZE 0x100
+#define ASPEED_LTPI_TOP_SIZE 0x100
+
+struct AspeedLTPIState {
+ SysBusDevice parent;
+ MemoryRegion mmio;
+ MemoryRegion mmio_ctrl;
+ MemoryRegion mmio_phy;
+ MemoryRegion mmio_top;
+
+ uint32_t ctrl_regs[ASPEED_LTPI_CTRL_SIZE >> 2];
+ uint32_t phy_regs[ASPEED_LTPI_PHY_SIZE >> 2];
+ uint32_t top_regs[ASPEED_LTPI_TOP_SIZE >> 2];
+};
+
+#endif /* ASPEED_LTPI_H */
diff --git a/hw/misc/aspeed_ltpi.c b/hw/misc/aspeed_ltpi.c
new file mode 100644
index 0000000000..a94ed804a3
--- /dev/null
+++ b/hw/misc/aspeed_ltpi.c
@@ -0,0 +1,194 @@
+/*
+ * ASPEED LTPI Controller
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/misc/aspeed_ltpi.h"
+
+#define ASPEED_LTPI_TOTAL_SIZE 0x900
+#define ASPEED_LTPI_CTRL_BASE 0x000
+#define ASPEED_LTPI_PHY_BASE 0x200
+#define ASPEED_LTPI_TOP_BASE 0x800
+
+#define LTPI_CTRL_LINK_MNG 0x42
+#define LTPI_PHY_MODE 0x0
+
+static uint64_t aspeed_ltpi_top_read(void *opaque, hwaddr offset, unsigned size)
+{
+ AspeedLTPIState *s = opaque;
+ uint32_t idx = offset >> 2;
+
+ return s->top_regs[idx];
+}
+
+static void aspeed_ltpi_top_write(void *opaque, hwaddr offset,
+ uint64_t val, unsigned size)
+{
+ AspeedLTPIState *s = opaque;
+ uint32_t idx = offset >> 2;
+
+ switch (offset) {
+ default:
+ s->top_regs[idx] = (uint32_t)val;
+ break;
+ }
+}
+
+static const MemoryRegionOps aspeed_ltpi_top_ops = {
+ .read = aspeed_ltpi_top_read,
+ .write = aspeed_ltpi_top_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
+};
+
+static uint64_t aspeed_ltpi_phy_read(void *opaque, hwaddr offset, unsigned size)
+{
+ AspeedLTPIState *s = opaque;
+ uint32_t idx = offset >> 2;
+
+ return s->phy_regs[idx];
+}
+
+static void aspeed_ltpi_phy_write(void *opaque, hwaddr offset,
+ uint64_t val, unsigned size)
+{
+ AspeedLTPIState *s = opaque;
+ uint32_t idx = offset >> 2;
+
+ switch (offset) {
+ default:
+ s->phy_regs[idx] = (uint32_t)val;
+ break;
+ }
+}
+
+static const MemoryRegionOps aspeed_ltpi_phy_ops = {
+ .read = aspeed_ltpi_phy_read,
+ .write = aspeed_ltpi_phy_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
+};
+
+static uint64_t aspeed_ltpi_ctrl_read(void *opaque,
+ hwaddr offset, unsigned size)
+{
+ AspeedLTPIState *s = opaque;
+ uint32_t idx = offset >> 2;
+
+ return s->ctrl_regs[idx];
+}
+
+static void aspeed_ltpi_ctrl_write(void *opaque, hwaddr offset,
+ uint64_t val, unsigned size)
+{
+ AspeedLTPIState *s = opaque;
+ uint32_t idx = offset >> 2;
+
+ switch (offset) {
+ default:
+ s->ctrl_regs[idx] = (uint32_t)val;
+ break;
+ }
+}
+
+static const MemoryRegionOps aspeed_ltpi_ctrl_ops = {
+ .read = aspeed_ltpi_ctrl_read,
+ .write = aspeed_ltpi_ctrl_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
+};
+
+static void aspeed_ltpi_reset(DeviceState *dev)
+{
+ AspeedLTPIState *s = ASPEED_LTPI(dev);
+
+ memset(s->ctrl_regs, 0, sizeof(s->ctrl_regs));
+ memset(s->phy_regs, 0, sizeof(s->phy_regs));
+ memset(s->top_regs, 0, sizeof(s->top_regs));
+ /* set default values */
+ s->ctrl_regs[LTPI_CTRL_LINK_MNG] = 0x11900007;
+ s->phy_regs[LTPI_PHY_MODE] = 0x2;
+}
+
+
+static const VMStateDescription vmstate_aspeed_ltpi = {
+ .name = TYPE_ASPEED_LTPI,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(ctrl_regs, AspeedLTPIState,
+ ASPEED_LTPI_CTRL_SIZE >> 2),
+ VMSTATE_UINT32_ARRAY(phy_regs, AspeedLTPIState,
+ ASPEED_LTPI_PHY_SIZE >> 2),
+ VMSTATE_UINT32_ARRAY(top_regs, AspeedLTPIState,
+ ASPEED_LTPI_TOP_SIZE >> 2),
+
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void aspeed_ltpi_realize(DeviceState *dev, Error **errp)
+{
+ AspeedLTPIState *s = ASPEED_LTPI(dev);
+
+ memory_region_init(&s->mmio, OBJECT(s), TYPE_ASPEED_LTPI,
+ ASPEED_LTPI_TOTAL_SIZE);
+
+ memory_region_init_io(&s->mmio_ctrl, OBJECT(s),
+ &aspeed_ltpi_ctrl_ops, s,
+ "aspeed-ltpi-ctrl", ASPEED_LTPI_CTRL_SIZE);
+
+ memory_region_init_io(&s->mmio_phy, OBJECT(s),
+ &aspeed_ltpi_phy_ops, s,
+ "aspeed-ltpi-phy", ASPEED_LTPI_PHY_SIZE);
+
+ memory_region_init_io(&s->mmio_top, OBJECT(s),
+ &aspeed_ltpi_top_ops, s,
+ "aspeed-ltpi-top", ASPEED_LTPI_TOP_SIZE);
+
+ memory_region_add_subregion(&s->mmio,
+ ASPEED_LTPI_CTRL_BASE, &s->mmio_ctrl);
+ memory_region_add_subregion(&s->mmio,
+ ASPEED_LTPI_PHY_BASE, &s->mmio_phy);
+ memory_region_add_subregion(&s->mmio,
+ ASPEED_LTPI_TOP_BASE, &s->mmio_top);
+
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio);
+}
+
+static void aspeed_ltpi_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->realize = aspeed_ltpi_realize;
+ dc->vmsd = &vmstate_aspeed_ltpi;
+ device_class_set_legacy_reset(dc, aspeed_ltpi_reset);
+}
+
+static const TypeInfo aspeed_ltpi_info = {
+ .name = TYPE_ASPEED_LTPI,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(AspeedLTPIState),
+ .class_init = aspeed_ltpi_class_init,
+};
+
+static void aspeed_ltpi_register_types(void)
+{
+ type_register_static(&aspeed_ltpi_info);
+}
+
+type_init(aspeed_ltpi_register_types);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index b1d8d8e5d2..45b16e7797 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -136,6 +136,7 @@ system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
'aspeed_hace.c',
'aspeed_i3c.c',
'aspeed_lpc.c',
+ 'aspeed_ltpi.c',
'aspeed_scu.c',
'aspeed_sbc.c',
'aspeed_sdmc.c',
--
2.43.0
next prev parent reply other threads:[~2025-12-08 7:46 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-08 7:44 [PATCH v3 00/18] hw/arm/aspeed: AST1700 LTPI support and device hookups Kane Chen via
2025-12-08 7:44 ` Kane Chen via [this message]
2025-12-10 23:00 ` [PATCH v3 01/18] hw/misc: Add LTPI controller Nabih Estefan
2025-12-08 7:44 ` [PATCH v3 02/18] hw/arm/aspeed: Attach LTPI controller to AST27X0 platform Kane Chen via
2025-12-10 23:00 ` Nabih Estefan
2025-12-08 7:44 ` [PATCH v3 03/18] hw/misc: Add basic Aspeed PWM model Kane Chen via
2025-12-10 23:00 ` Nabih Estefan
2025-12-08 7:44 ` [PATCH v3 04/18] hw/arm/aspeed: Add AST1700 LTPI expander device model Kane Chen via
2025-12-08 7:44 ` [PATCH v3 05/18] hw/arm/aspeed: Integrate AST1700 device into AST27X0 Kane Chen via
2025-12-08 7:44 ` [PATCH v3 06/18] hw/arm/aspeed: Integrate interrupt controller for AST1700 Kane Chen via
2025-12-08 21:03 ` Nabih Estefan
2025-12-09 2:08 ` Kane Chen
2025-12-09 8:47 ` Cédric Le Goater
2025-12-08 7:44 ` [PATCH v3 07/18] hw/arm/aspeed: Attach LTPI controller to AST1700 model Kane Chen via
2025-12-08 7:44 ` [PATCH v3 08/18] hw/arm/aspeed: Attach UART device " Kane Chen via
2025-12-08 7:44 ` [PATCH v3 09/18] hw/arm/aspeed: Attach SRAM " Kane Chen via
2025-12-08 7:44 ` [PATCH v3 10/18] hw/arm/aspeed: Attach SPI " Kane Chen via
2025-12-08 7:44 ` [PATCH v3 11/18] hw/arm/aspeed: Attach ADC " Kane Chen via
2025-12-08 7:44 ` [PATCH v3 12/18] hw/arm/aspeed: Attach SCU " Kane Chen via
2025-12-08 7:44 ` [PATCH v3 13/18] hw/arm/aspeed: Attach GPIO " Kane Chen via
2025-12-08 7:44 ` [PATCH v3 14/18] hw/arm/aspeed: attach I2C " Kane Chen via
2025-12-10 23:01 ` Nabih Estefan
2025-12-08 7:44 ` [PATCH v3 15/18] hw/arm/aspeed: Attach WDT " Kane Chen via
2025-12-08 7:44 ` [PATCH v3 16/18] hw/arm/aspeed: Attach PWM " Kane Chen via
2025-12-08 7:44 ` [PATCH v3 17/18] hw/arm/aspeed: Attach SGPIOM " Kane Chen via
2025-12-08 18:21 ` Nabih Estefan
2025-12-09 8:49 ` Cédric Le Goater
2025-12-09 10:17 ` Kane Chen
2025-12-10 2:41 ` Jamin Lin
2025-12-08 7:44 ` [PATCH v3 18/18] hw/arm/aspeed: Model AST1700 I3C block as unimplemented device Kane Chen via
2025-12-08 18:23 ` Nabih Estefan
2025-12-09 8:51 ` Cédric Le Goater
2025-12-10 23:01 ` [PATCH v3 00/18] hw/arm/aspeed: AST1700 LTPI support and device hookups Nabih Estefan
2025-12-11 6:42 ` Kane Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251208074436.1871180-2-kane_chen@aspeedtech.com \
--to=qemu-devel@nongnu.org \
--cc=andrew@codeconstruct.com.au \
--cc=clg@kaod.org \
--cc=jamin_lin@aspeedtech.com \
--cc=joel@jms.id.au \
--cc=kane_chen@aspeedtech.com \
--cc=leetroy@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=steven_lee@aspeedtech.com \
--cc=troy_lee@aspeedtech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).