The x3130 upstream port is stuck at the 2.5GT/s x1 default. Following
the CXL upstream port pattern, introduce an XIO3130Upstream struct
wrapping PCIEPort with speed and width fields to be able to set them.

Default to 16GT/s x32 for new machine types and add compat entries
for <= 11.1 to preserve the old 2.5GT/s x1 behavior.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/4409
Signed-off-by: Cédric Le Goater <[email protected]>
---
 hw/core/machine.c                |  2 ++
 hw/pci-bridge/xio3130_upstream.c | 28 +++++++++++++++++++++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 
b702a61f7335a30841164279e73432bc238ee5e5..3c98d62860d5ce058c4fbfdb86d2661f20e22b8f
 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -45,6 +45,8 @@ GlobalProperty hw_compat_11_1[] = {
     { "pci-ehci-usb", "x-migrate-fetch-addr-64bit", "off" },
     { "xio3130-downstream", "x-speed", "2_5" },
     { "xio3130-downstream", "x-width", "1" },
+    { "x3130-upstream", "x-speed", "2_5" },
+    { "x3130-upstream", "x-width", "1" },
 };
 const size_t hw_compat_11_1_len = G_N_ELEMENTS(hw_compat_11_1);
 
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index 
40057b749bfd01bbd548b025607ef041b9feccc5..247994772c30373b7f3c6f9e72237dbed529ed98
 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -24,9 +24,24 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/pcie.h"
 #include "hw/pci/pcie_port.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qemu/module.h"
 
+#define TYPE_XIO3130_UPSTREAM "x3130-upstream"
+
+OBJECT_DECLARE_SIMPLE_TYPE(XIO3130Upstream, XIO3130_UPSTREAM)
+
+struct XIO3130Upstream {
+    /*< private >*/
+    PCIEPort parent_obj;
+
+    /*< public >*/
+    PCIExpLinkSpeed speed;
+    PCIExpLinkWidth width;
+};
+
 #define PCI_DEVICE_ID_TI_XIO3130U       0x8232  /* upstream port */
 #define XIO3130_REVISION                0x2
 #define XIO3130_MSI_OFFSET              0x70
@@ -49,9 +64,11 @@ static void xio3130_upstream_write_config(PCIDevice *d, 
uint32_t address,
 static void xio3130_upstream_reset(DeviceState *qdev)
 {
     PCIDevice *d = PCI_DEVICE(qdev);
+    XIO3130Upstream *u = XIO3130_UPSTREAM(qdev);
 
     pci_bridge_reset(qdev);
     pcie_cap_deverr_reset(d);
+    pcie_cap_fill_link_ep_usp(d, u->width, u->speed, false);
 }
 
 static void xio3130_upstream_realize(PCIDevice *d, Error **errp)
@@ -110,6 +127,13 @@ static void xio3130_upstream_exitfn(PCIDevice *d)
     pci_bridge_exitfn(d);
 }
 
+static const Property xio3130_upstream_props[] = {
+    DEFINE_PROP_PCIE_LINK_SPEED("x-speed", XIO3130Upstream,
+                                speed, PCIE_LINK_SPEED_16),
+    DEFINE_PROP_PCIE_LINK_WIDTH("x-width", XIO3130Upstream,
+                                width, PCIE_LINK_WIDTH_32),
+};
+
 static const VMStateDescription vmstate_xio3130_upstream = {
     .name = "xio3130-express-upstream-port",
     .priority = MIG_PRI_PCI_BUS,
@@ -138,11 +162,13 @@ static void xio3130_upstream_class_init(ObjectClass 
*klass, const void *data)
     dc->desc = "TI X3130 Upstream Port of PCI Express Switch";
     device_class_set_legacy_reset(dc, xio3130_upstream_reset);
     dc->vmsd = &vmstate_xio3130_upstream;
+    device_class_set_props(dc, xio3130_upstream_props);
 }
 
 static const TypeInfo xio3130_upstream_info = {
-    .name          = "x3130-upstream",
+    .name          = TYPE_XIO3130_UPSTREAM,
     .parent        = TYPE_PCIE_PORT,
+    .instance_size = sizeof(XIO3130Upstream),
     .class_init    = xio3130_upstream_class_init,
     .interfaces = (const InterfaceInfo[]) {
         { INTERFACE_PCIE_DEVICE },
-- 
2.55.0


Reply via email to