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_...@aspeedtech.com> --- include/hw/pci-host/aspeed_pcie.h | 1 + hw/pci-host/aspeed_pcie.c | 39 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/hw/pci-host/aspeed_pcie.h b/include/hw/pci-host/aspeed_pcie.h index 6bc54659ee..908800614c 100644 --- a/include/hw/pci-host/aspeed_pcie.h +++ b/include/hw/pci-host/aspeed_pcie.h @@ -102,6 +102,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 { diff --git a/hw/pci-host/aspeed_pcie.c b/hw/pci-host/aspeed_pcie.c index 566feaebc7..edd4aedfaf 100644 --- a/hw/pci-host/aspeed_pcie.c +++ b/hw/pci-host/aspeed_pcie.c @@ -639,6 +639,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, @@ -746,12 +752,45 @@ 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_root_info); type_register_static(&aspeed_pcie_rc_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); -- 2.43.0