Lines Matching +full:pci +full:- +full:iommu
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright © 2022-2024 Rivos Inc.
5 * Copyright © 2023 FORTH-ICS/CARV
7 * RISCV IOMMU as a PCIe device
16 #include <linux/iommu.h>
18 #include <linux/pci.h>
20 #include "iommu-bits.h"
21 #include "iommu.h"
23 /* QEMU RISC-V IOMMU implementation */
26 /* Rivos Inc. assigned PCI Vendor and Device IDs */
35 struct device *dev = &pdev->dev; in riscv_iommu_pci_probe()
36 struct riscv_iommu_device *iommu; in riscv_iommu_pci_probe() local
44 return -ENODEV; in riscv_iommu_pci_probe()
47 return -ENODEV; in riscv_iommu_pci_probe()
53 iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL); in riscv_iommu_pci_probe()
54 if (!iommu) in riscv_iommu_pci_probe()
55 return -ENOMEM; in riscv_iommu_pci_probe()
57 iommu->dev = dev; in riscv_iommu_pci_probe()
58 iommu->reg = pcim_iomap_table(pdev)[0]; in riscv_iommu_pci_probe()
61 dev_set_drvdata(dev, iommu); in riscv_iommu_pci_probe()
64 iommu->caps = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_CAPABILITIES); in riscv_iommu_pci_probe()
65 iommu->fctl = riscv_iommu_readl(iommu, RISCV_IOMMU_REG_FCTL); in riscv_iommu_pci_probe()
67 /* The PCI driver only uses MSIs, make sure the IOMMU supports this */ in riscv_iommu_pci_probe()
68 switch (FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps)) { in riscv_iommu_pci_probe()
73 return dev_err_probe(dev, -ENODEV, in riscv_iommu_pci_probe()
74 "unable to use message-signaled interrupts\n"); in riscv_iommu_pci_probe()
81 return dev_err_probe(dev, -ENODEV, in riscv_iommu_pci_probe()
84 iommu->irqs_count = rc; in riscv_iommu_pci_probe()
85 for (vec = 0; vec < iommu->irqs_count; vec++) in riscv_iommu_pci_probe()
86 iommu->irqs[vec] = msi_get_virq(dev, vec); in riscv_iommu_pci_probe()
88 /* Enable message-signaled interrupts, fctl.WSI */ in riscv_iommu_pci_probe()
89 if (iommu->fctl & RISCV_IOMMU_FCTL_WSI) { in riscv_iommu_pci_probe()
90 iommu->fctl ^= RISCV_IOMMU_FCTL_WSI; in riscv_iommu_pci_probe()
91 riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl); in riscv_iommu_pci_probe()
94 return riscv_iommu_init(iommu); in riscv_iommu_pci_probe()
99 struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev); in riscv_iommu_pci_remove() local
101 riscv_iommu_remove(iommu); in riscv_iommu_pci_remove()
106 struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev); in riscv_iommu_pci_shutdown() local
108 riscv_iommu_disable(iommu); in riscv_iommu_pci_shutdown()