]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
hw/pci-host/aspeed: Add AST2700 PCIe PHY
authorJamin Lin <jamin_lin@aspeedtech.com>
Fri, 19 Sep 2025 09:30:08 +0000 (17:30 +0800)
committerCédric Le Goater <clg@redhat.com>
Mon, 29 Sep 2025 16:00:20 +0000 (18:00 +0200)
Introduce a PCIe Host Controller PHY model for AST2700. This adds an
AST2700 specific PHY type (TYPE_ASPEED_2700_PCIE_PHY) with a 0x800 byte
register space and link-status bits compatible with the firmware’s
expectations.

AST2700 provides three PCIe RCs; PCIe0 and PCIe1 are GEN4, PCIe2 is
GEN2. The PHY exposes:
PEHR_2700_LINK_GEN2 at 0x344, bit 18 indicates GEN2 link up
PEHR_2700_LINK_GEN4 at 0x358, bit 8 indicates GEN4 link up

In real hardware these GEN2/GEN4 link bits are mutually exclusive.
QEMU does not model GEN2 vs GEN4 signaling differences, so the reset
handler sets both bits to 1. This keeps the model simple and lets
firmware see the link as up; firmware will read the appropriate
register per RC port to infer the intended mode.

The header gains TYPE_ASPEED_2700_PCIE_PHY; the new class derives from
TYPE_ASPEED_PCIE_PHY, sets nr_regs to 0x800 >> 2, and installs an
AST2700 reset routine that programs the class code (0x06040011) and the
GEN2/GEN4 status bits.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20250919093017.338309-10-jamin_lin@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
hw/pci-host/aspeed_pcie.c
include/hw/pci-host/aspeed_pcie.h

index 8be55b962fc7d56bcb0cee945fd514c77ad69ff1..788160d5325cf6b89392a4c968f2ac54c8bdc432 100644 (file)
@@ -696,6 +696,12 @@ REG32(PEHR_PROTECT,     0x7C)
 REG32(PEHR_LINK,        0xC0)
     FIELD(PEHR_LINK, STS, 5, 1)
 
+/* AST2700 */
+REG32(PEHR_2700_LINK_GEN2,  0x344)
+    FIELD(PEHR_2700_LINK_GEN2, STS, 18, 1)
+REG32(PEHR_2700_LINK_GEN4,  0x358)
+    FIELD(PEHR_2700_LINK_GEN4, STS, 8, 1)
+
 #define ASPEED_PCIE_PHY_UNLOCK  0xA8
 
 static uint64_t aspeed_pcie_phy_read(void *opaque, hwaddr addr,
@@ -803,6 +809,38 @@ static const TypeInfo aspeed_pcie_phy_info = {
     .class_size = sizeof(AspeedPCIEPhyClass),
 };
 
+static void aspeed_2700_pcie_phy_reset(DeviceState *dev)
+{
+    AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);
+    AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s);
+
+    memset(s->regs, 0, apc->nr_regs << 2);
+
+    s->regs[R_PEHR_ID] =
+        (0x1150 << R_PEHR_ID_DEV_SHIFT) | PCI_VENDOR_ID_ASPEED;
+    s->regs[R_PEHR_CLASS_CODE] = 0x06040011;
+    s->regs[R_PEHR_2700_LINK_GEN2] = R_PEHR_2700_LINK_GEN2_STS_MASK;
+    s->regs[R_PEHR_2700_LINK_GEN4] = R_PEHR_2700_LINK_GEN4_STS_MASK;
+}
+
+static void aspeed_2700_pcie_phy_class_init(ObjectClass *klass,
+                                            const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_CLASS(klass);
+
+    dc->desc = "ASPEED AST2700 PCIe Phy";
+    device_class_set_legacy_reset(dc, aspeed_2700_pcie_phy_reset);
+
+    apc->nr_regs = 0x800 >> 2;
+}
+
+static const TypeInfo aspeed_2700_pcie_phy_info = {
+    .name       = TYPE_ASPEED_2700_PCIE_PHY,
+    .parent     = TYPE_ASPEED_PCIE_PHY,
+    .class_init = aspeed_2700_pcie_phy_class_init,
+};
+
 static void aspeed_pcie_register_types(void)
 {
     type_register_static(&aspeed_pcie_rc_info);
@@ -810,6 +848,7 @@ static void aspeed_pcie_register_types(void)
     type_register_static(&aspeed_pcie_root_port_info);
     type_register_static(&aspeed_pcie_cfg_info);
     type_register_static(&aspeed_pcie_phy_info);
+    type_register_static(&aspeed_2700_pcie_phy_info);
 }
 
 type_init(aspeed_pcie_register_types);
index 5e60cba07b66bc31d1de976abee018802cdbb3f1..5806505f30efe8f351fd3e60e920b6528725caa4 100644 (file)
@@ -114,6 +114,7 @@ struct AspeedPCIECfgClass {
 };
 
 #define TYPE_ASPEED_PCIE_PHY "aspeed.pcie-phy"
+#define TYPE_ASPEED_2700_PCIE_PHY TYPE_ASPEED_PCIE_PHY "-ast2700"
 OBJECT_DECLARE_TYPE(AspeedPCIEPhyState, AspeedPCIEPhyClass, ASPEED_PCIE_PHY);
 
 struct AspeedPCIEPhyState {