Lines Matching +full:iommu +full:- +full:map

1 // SPDX-License-Identifier: GPL-2.0-only
3 * RISC-V IOMMU as a platform device
5 * Copyright © 2023 FORTH-ICS/CARV
6 * Copyright © 2023-2024 Rivos Inc.
19 #include "iommu-bits.h"
20 #include "iommu.h"
25 struct riscv_iommu_device *iommu = dev_get_drvdata(dev); in riscv_iommu_write_msi_msg() local
26 u16 idx = desc->msi_index; in riscv_iommu_write_msi_msg()
29 addr = ((u64)msg->address_hi << 32) | msg->address_lo; in riscv_iommu_write_msi_msg()
33 "uh oh, the IOMMU can't send MSIs to 0x%llx, sending to 0x%llx instead\n", in riscv_iommu_write_msi_msg()
39 riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(idx), addr); in riscv_iommu_write_msi_msg()
40 riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_DATA(idx), msg->data); in riscv_iommu_write_msi_msg()
41 riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_CTRL(idx), 0); in riscv_iommu_write_msi_msg()
47 struct device *dev = &pdev->dev; in riscv_iommu_platform_probe()
48 struct riscv_iommu_device *iommu = NULL; in riscv_iommu_platform_probe() local
52 iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL); in riscv_iommu_platform_probe()
53 if (!iommu) in riscv_iommu_platform_probe()
54 return -ENOMEM; in riscv_iommu_platform_probe()
56 iommu->dev = dev; in riscv_iommu_platform_probe()
57 iommu->reg = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in riscv_iommu_platform_probe()
58 if (IS_ERR(iommu->reg)) in riscv_iommu_platform_probe()
59 return dev_err_probe(dev, PTR_ERR(iommu->reg), in riscv_iommu_platform_probe()
60 "could not map register region\n"); in riscv_iommu_platform_probe()
62 dev_set_drvdata(dev, iommu); in riscv_iommu_platform_probe()
65 iommu->caps = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_CAPABILITIES); in riscv_iommu_platform_probe()
66 iommu->fctl = riscv_iommu_readl(iommu, RISCV_IOMMU_REG_FCTL); in riscv_iommu_platform_probe()
68 iommu->irqs_count = platform_irq_count(pdev); in riscv_iommu_platform_probe()
69 if (iommu->irqs_count <= 0) in riscv_iommu_platform_probe()
70 return dev_err_probe(dev, -ENODEV, in riscv_iommu_platform_probe()
72 if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT) in riscv_iommu_platform_probe()
73 iommu->irqs_count = RISCV_IOMMU_INTR_COUNT; in riscv_iommu_platform_probe()
75 igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps); in riscv_iommu_platform_probe()
79 if (is_of_node(dev->fwnode)) in riscv_iommu_platform_probe()
80 of_msi_configure(dev, to_of_node(dev->fwnode)); in riscv_iommu_platform_probe()
87 ret = platform_device_msi_init_and_alloc_irqs(dev, iommu->irqs_count, in riscv_iommu_platform_probe()
94 for (vec = 0; vec < iommu->irqs_count; vec++) in riscv_iommu_platform_probe()
95 iommu->irqs[vec] = msi_get_virq(dev, vec); in riscv_iommu_platform_probe()
97 /* Enable message-signaled interrupts, fctl.WSI */ in riscv_iommu_platform_probe()
98 if (iommu->fctl & RISCV_IOMMU_FCTL_WSI) { in riscv_iommu_platform_probe()
99 iommu->fctl ^= RISCV_IOMMU_FCTL_WSI; in riscv_iommu_platform_probe()
100 riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl); in riscv_iommu_platform_probe()
108 return dev_err_probe(dev, -ENODEV, in riscv_iommu_platform_probe()
109 "unable to use wire-signaled interrupts\n"); in riscv_iommu_platform_probe()
115 for (vec = 0; vec < iommu->irqs_count; vec++) in riscv_iommu_platform_probe()
116 iommu->irqs[vec] = platform_get_irq(pdev, vec); in riscv_iommu_platform_probe()
118 /* Enable wire-signaled interrupts, fctl.WSI */ in riscv_iommu_platform_probe()
119 if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) { in riscv_iommu_platform_probe()
120 iommu->fctl |= RISCV_IOMMU_FCTL_WSI; in riscv_iommu_platform_probe()
121 riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl); in riscv_iommu_platform_probe()
123 dev_info(dev, "using wire-signaled interrupts\n"); in riscv_iommu_platform_probe()
126 return dev_err_probe(dev, -ENODEV, "invalid IGS\n"); in riscv_iommu_platform_probe()
129 return riscv_iommu_init(iommu); in riscv_iommu_platform_probe()
134 struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev); in riscv_iommu_platform_remove() local
135 bool msi = !(iommu->fctl & RISCV_IOMMU_FCTL_WSI); in riscv_iommu_platform_remove()
137 riscv_iommu_remove(iommu); in riscv_iommu_platform_remove()
140 platform_device_msi_free_irqs_all(&pdev->dev); in riscv_iommu_platform_remove()
145 riscv_iommu_disable(dev_get_drvdata(&pdev->dev)); in riscv_iommu_platform_shutdown()
149 {.compatible = "riscv,iommu",},
158 .name = "riscv,iommu",