[RFC PATCH v4 14/14] coco: host: arm64: Add NCOH_SYS stream support for RC endpoints

Aneesh Kumar K.V (Arm)
2026-04-27T06:52:53Z

Teach the host CCA pdev setup to handle PCI_EXP_TYPE_RC_END devices.

Classify RC integrated endpoints as RMI_PDEV_FLAGS_CATEGORY_ON_CHIP_EP when
building the RMM pdev parameters, and only advertise SPDM support when a
DOE mailbox is present.

Also add the stream setup path for these devices by creating an
RMI_PDEV_STREAM_NCOH_SYS stream using the endpoint pdev and its bridge
address windows. This allows RC endpoints to participate in the TDISP flow
without requiring a separate root-port pdev.

Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/virt/coco/arm-cca-host/arm-cca.c | 28 ++++++++++++++++++++++++
drivers/virt/coco/arm-cca-host/rmi-da.c | 10 +++++++++
2 files changed, 38 insertions(+)

diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/arm-cca-host/arm-cca.c
index 265aa0cb612a..8b1182620872 100644
--- a/drivers/virt/coco/arm-cca-host/arm-cca.c
+++ b/drivers/virt/coco/arm-cca-host/arm-cca.c
@@ -277,11 +277,39 @@ static int cca_pdev_create_ncoh_stream(struct pci_dev *pdev, unsigned long strea
return ret;
}

+static int cca_pdev_create_ncoh_sys_stream(struct pci_dev *pdev)
+{
+ int ret;
+ long stream_handle;
+ struct rmi_pdev_stream_params *params;
+ struct cca_host_pf0_ep_dsc *pf0_ep_dsc = to_cca_pf0_ep_dsc(pdev);
+
+ params = (struct rmi_pdev_stream_params *)get_zeroed_page(GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
+
+ params->flags = 0;
+ params->type = RMI_PDEV_STREAM_NCOH_SYS;
+ params->pdev_1 = virt_to_phys(pf0_ep_dsc->pdev.rmm_pdev);
+ params->pdev_2 = 0; /* ignored */
+ params->ide_sid = 0; /* ignored */
+ params->num_addr_range = pci_dev_addr_range(pdev, params->addr_range);
+
+ ret = cca_pdev_stream_connect(pdev, NULL, params, &stream_handle);
+ if (!ret)
+ pf0_ep_dsc->stream_handle = stream_handle;
+
+ free_page((unsigned long)params);
+ return ret;
+}
+
static int cca_pdev_create_streams(struct pci_dev *pdev, unsigned long stream_id)
{
switch (pci_pcie_type(pdev)) {
case PCI_EXP_TYPE_ENDPOINT:
return cca_pdev_create_ncoh_stream(pdev, stream_id);
+ case PCI_EXP_TYPE_RC_END:
+ return cca_pdev_create_ncoh_sys_stream(pdev);
default:
return -EINVAL;
}
diff --git a/drivers/virt/coco/arm-cca-host/rmi-da.c b/drivers/virt/coco/arm-cca-host/rmi-da.c
index a10ac6ff03d1..33a2551fd09f 100644
--- a/drivers/virt/coco/arm-cca-host/rmi-da.c
+++ b/drivers/virt/coco/arm-cca-host/rmi-da.c
@@ -66,6 +66,16 @@ static int init_pdev_params(struct pci_dev *pdev, struct rmi_pdev_params *params
category = RMI_PDEV_FLAGS_CATEGORY_ROOT_PORT;
break;
}
+ case PCI_EXP_TYPE_RC_END: {
+ struct cca_host_pf0_ep_dsc *pf0_ep_dsc = to_cca_pf0_ep_dsc(pdev);
+
+ /* Use SPDM if present */
+ if (pf0_ep_dsc->pci.doe_mb)
+ params->flags = RMI_PDEV_FLAGS_SPDM;
+
+ category = RMI_PDEV_FLAGS_CATEGORY_ON_CHIP_EP;
+ break;
+ }
default:
return -EINVAL;
}
--
2.43.0