[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v1 2/3] pci/rcar: implement OSID configuration for Renesas RCar Gen4 PCIe host


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Mykyta Poturai <Mykyta_Poturai@xxxxxxxx>
  • Date: Mon, 7 Jul 2025 09:20:40 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MTENjK7DePGFpBf+qOVwkXl+er7/iccfAIg/6eqNWo4=; b=MTlq5XEd6N5sjioC11YR8C1NeQOqXu98DxVN5II36D848FDv/oyKUBjAhvlLOGY1Bv+IaJuD2V9q/8CvHWUR2BQehPXfV7SbhdZR1sOyqCp00kNDW5Gw7RPX5kY5YmwaSlEBNHRrj7HuD3cVBjeZkYEKnFuveSz+hY0GK3CQIIJ5R8V9zfYnbJRL0P49dKDsLhFyoTmPGWkJxxYCtYPdnxgHsVKtO2n9ojky8fVO8oNJIUaSsVK7CceSJGWo0DucWFfwi9DvvE+UG4X+GkZ5g133HS7EbufiJp3rmlDGctAgiaOrRMlCyPbm8z5ifnOKUM5aDBpxQOzOZllXNVQ/OQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=SYPxnTFCnbMQhG6dXjPynwMnVa0dl0kPvIfEf0apgNUvOZbFS6DJ1vcxYiaVWT/jJBEpq4VSbLL0lGOm9cmis24BfVJ5SxaXVrnHjEEcPjbow5iRxLrfMuTOrXHkER1fm5rIYbVReMDU/Dp0UYPRd7jbk6L1aElLVCc9jZFoHi/iZzyomDxbsA6YB/iqs9n8KE5fhB+Ht6p69b7tHGDkY5VLUf9EWTsrxOe1jA1b1EMPihHaQDIItxrLGrEFdONN4zDlIbcp7ajTdZRn2zQcWfm7m7hqmx35Im6nYgIYc3Y6oUTl5kjwKjolK4zCW5AK0GxSkIVFTj0LTjZs/6Kumg==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: Mykyta Poturai <Mykyta_Poturai@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Mon, 07 Jul 2025 09:20:59 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHb7yBoXFwmP3nV1kCE0zaBoehFqA==
  • Thread-topic: [PATCH v1 2/3] pci/rcar: implement OSID configuration for Renesas RCar Gen4 PCIe host

For IPMMU to be able to associate a specific PCI device with it's TLB
the BDF to OSID mapping needs to be set up in the host bridge. The
configured OSID is then emmited as a sideband data on the AXI bus during
PCI DMA transactions. OSID configuration registers are located in the
"app" region of the host bridge.

Map the "app" region on init and implement methods for setting up
BDF->OSID mappings

Signed-off-by: Mykyta Poturai <mykyta_poturai@xxxxxxxx>
---
 xen/arch/arm/pci/pci-host-rcar4.c | 148 ++++++++++++++++++++++++++++++
 xen/arch/arm/pci/pci-host-rcar4.h |  18 ++++
 2 files changed, 166 insertions(+)
 create mode 100644 xen/arch/arm/pci/pci-host-rcar4.h

diff --git a/xen/arch/arm/pci/pci-host-rcar4.c 
b/xen/arch/arm/pci/pci-host-rcar4.c
index 62d2130a63..9290c6cac5 100644
--- a/xen/arch/arm/pci/pci-host-rcar4.c
+++ b/xen/arch/arm/pci/pci-host-rcar4.c
@@ -16,6 +16,32 @@
 
 #define RCAR4_DWC_VERSION       0x520A
 
+/* PCIE BDF-OSID assignment */
+#define CNVID(n)             (0x700 + ((n) * 4))
+#define CNVID_CNV_EN         (1U << 31)
+#define CNVID_OSID_MASK      (0x0F << 16)
+#define CNVID_OSID_SHIFT     16
+#define CNVID_BDF_MASK       (0xFFFF << 0)
+#define CNVID_BDF_SHIFT      0
+
+#define CNVIDMSK(n)                (0x780 + ((n) * 4))
+#define CNVIDMSK_BDF_MSK_MASK      (0xFFFF << 0)
+#define CNVIDMSK_BDF_MSK_SHIFT     0
+
+#define CNVOSIDCTRL                0x800
+#define CNVOSIDCTRL_OSID_MASK      (0x0F << 16)
+#define CNVOSIDCTRL_OSID_SHIFT     16
+
+#define DEFAULT_OSID    0
+
+#define NUM_OSID_REGS    16
+
+struct rcar4_pcie_priv {
+    bool init_done;
+    void __iomem *app_base;
+    DECLARE_BITMAP(osid_regs, NUM_OSID_REGS);
+};
+
 /*
  * PCI host bridges often have different ways to access the root and child
  * bus config spaces:
@@ -65,17 +91,139 @@ static const struct dt_device_match __initconstrel 
rcar4_pcie_dt_match[] = {
     {},
 };
 
+static void rcar4_pcie_writel_app(struct rcar4_pcie_priv *pci, uint32_t reg,
+                                  uint32_t val)
+{
+    writel(val, pci->app_base + reg);
+}
+
+static uint32_t rcar4_pcie_readl_app(struct rcar4_pcie_priv *pci, uint32_t reg)
+{
+    return readl(pci->app_base + reg);
+}
+
+int rcar4_pcie_osid_regs_init(struct pci_host_bridge *bridge)
+{
+    struct rcar4_pcie_priv *priv = dw_pcie_get_priv(bridge);
+    uint32_t val = rcar4_pcie_readl_app(priv, CNVOSIDCTRL);
+
+    if ( priv->init_done )
+        return 0;
+    priv->init_done = true;
+
+    val = (val & ~CNVOSIDCTRL_OSID_MASK) |
+          (DEFAULT_OSID << CNVOSIDCTRL_OSID_SHIFT);
+    rcar4_pcie_writel_app(priv, CNVOSIDCTRL, val);
+    bitmap_zero(priv->osid_regs, NUM_OSID_REGS);
+
+    printk("%s: Initialized OSID regs (default OSID %u)\n",
+           bridge->dt_node->full_name, DEFAULT_OSID);
+
+    return 0;
+}
+
+int rcar4_pcie_osid_reg_alloc(struct pci_host_bridge *bridge)
+{
+    struct rcar4_pcie_priv *priv = dw_pcie_get_priv(bridge);
+    int ret;
+
+    ret = find_first_zero_bit(priv->osid_regs, NUM_OSID_REGS);
+    if ( ret != NUM_OSID_REGS )
+        set_bit(ret, priv->osid_regs);
+    else
+        ret = -EBUSY;
+
+    return ret;
+}
+
+void rcar4_pcie_osid_reg_free(struct pci_host_bridge *bridge,
+                              unsigned int reg_id)
+{
+    struct rcar4_pcie_priv *priv = dw_pcie_get_priv(bridge);
+
+    clear_bit(reg_id, priv->osid_regs);
+}
+
+void rcar4_pcie_osid_bdf_set(struct pci_host_bridge *bridge,
+                             unsigned int reg_id, uint32_t osid, uint32_t bdf)
+{
+    struct rcar4_pcie_priv *priv = dw_pcie_get_priv(bridge);
+    uint32_t data = rcar4_pcie_readl_app(priv, CNVID(reg_id));
+
+    data &= ~(CNVID_OSID_MASK | CNVID_BDF_MASK);
+    data |= CNVID_CNV_EN | (osid << CNVID_OSID_SHIFT) |
+            (bdf << CNVID_BDF_SHIFT);
+    rcar4_pcie_writel_app(priv, CNVID(reg_id), data);
+}
+
+void rcar4_pcie_osid_bdf_clear(struct pci_host_bridge *bridge,
+                               unsigned int reg_id)
+{
+    struct rcar4_pcie_priv *priv = dw_pcie_get_priv(bridge);
+    uint32_t data = rcar4_pcie_readl_app(priv, CNVID(reg_id));
+
+    data &= ~CNVID_CNV_EN;
+    rcar4_pcie_writel_app(priv, CNVID(reg_id), data);
+}
+
+void rcar4_pcie_bdf_msk_set(struct pci_host_bridge *bridge, unsigned int 
reg_id,
+                            uint32_t data)
+{
+    struct rcar4_pcie_priv *priv = dw_pcie_get_priv(bridge);
+
+    uint32_t val = rcar4_pcie_readl_app(priv, CNVIDMSK(reg_id));
+
+    val = (val & ~CNVIDMSK_BDF_MSK_MASK) | (data << CNVIDMSK_BDF_MSK_SHIFT);
+
+    rcar4_pcie_writel_app(priv, CNVIDMSK(reg_id), val);
+}
+
 static int __init pci_host_rcar4_probe(struct dt_device_node *dev,
                                        const void *data)
 {
     struct pci_host_bridge *bridge;
+    paddr_t app_phys_addr;
+    paddr_t app_size;
+    int app_idx, ret;
+
+    struct rcar4_pcie_priv *priv = xzalloc(struct rcar4_pcie_priv);
+    if ( !priv )
+        return -ENOMEM;
 
     bridge = dw_pcie_host_probe(dev, data, &rcar4_pcie_ops,
                                 &rcar4_pcie_child_ops);
 
+    app_idx = dt_property_match_string(dev, "reg-names", "app");
+    if ( app_idx < 0 )
+    {
+        printk(XENLOG_ERR "Cannot find \"app\" range index in device tree\n");
+        ret = app_idx;
+        goto err;
+    }
+    ret = dt_device_get_address(dev, app_idx, &app_phys_addr, &app_size);
+    if ( ret )
+    {
+        printk(XENLOG_ERR "Cannot find \"app\" range in device tree\n");
+        goto err;
+    }
+
+    priv->app_base = ioremap_nocache(app_phys_addr, app_size);
+    if ( !priv->app_base )
+    {
+        printk(XENLOG_ERR "APP ioremap failed\n");
+        ret = -ENXIO;
+        goto err;
+    }
+    printk("APP at [mem 0x%" PRIpaddr "-0x%" PRIpaddr "]\n", app_phys_addr,
+           app_phys_addr + app_size - 1);
+
+    dw_pcie_set_priv(bridge, priv);
     dw_pcie_set_version(bridge, RCAR4_DWC_VERSION);
 
     return 0;
+err:
+    xfree(priv);
+    return ret;
 }
 
 DT_DEVICE_START(pci_gen, "PCI HOST R-CAR GEN4", DEVICE_PCI_HOSTBRIDGE)
diff --git a/xen/arch/arm/pci/pci-host-rcar4.h 
b/xen/arch/arm/pci/pci-host-rcar4.h
new file mode 100644
index 0000000000..8ac6626a22
--- /dev/null
+++ b/xen/arch/arm/pci/pci-host-rcar4.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <asm/pci.h>
+
+#ifndef __PCI_HOST_RCAR4_H__
+#define __PCI_HOST_RCAR4_H__
+
+void rcar4_pcie_osid_bdf_set(struct pci_host_bridge *bridge,
+                             unsigned int reg_id, uint32_t osid, uint32_t bdf);
+void rcar4_pcie_osid_bdf_clear(struct pci_host_bridge *bridge,
+                               unsigned int reg_id);
+void rcar4_pcie_bdf_msk_set(struct pci_host_bridge *bridge, unsigned int 
reg_id,
+                            uint32_t data);
+int rcar4_pcie_osid_reg_alloc(struct pci_host_bridge *bridge);
+void rcar4_pcie_osid_reg_free(struct pci_host_bridge *bridge,
+                              unsigned int reg_id);
+int rcar4_pcie_osid_regs_init(struct pci_host_bridge *bridge);
+
+#endif /* __PCI_HOST_RCAR4_H__ */
-- 
2.34.1



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.