On 9/19/25 05:24, Jamin Lin wrote:
> 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>
Thanks,
C.
> ---
>   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 5e60cba07b..5806505f30 100644
> --- a/include/hw/pci-host/aspeed_pcie.h
> +++ b/include/hw/pci-host/aspeed_pcie.h
> @@ -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 {
> diff --git a/hw/pci-host/aspeed_pcie.c b/hw/pci-host/aspeed_pcie.c
> index 8be55b962f..788160d532 100644
> --- a/hw/pci-host/aspeed_pcie.c
> +++ b/hw/pci-host/aspeed_pcie.c
> @@ -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);