1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright © 2022-2024 Rivos Inc. 4 * Copyright © 2023 FORTH-ICS/CARV 5 * 6 * Authors 7 * Tomasz Jeznach <[email protected]> 8 * Nick Kossifidis <[email protected]> 9 */ 10 11 #ifndef _RISCV_IOMMU_H_ 12 #define _RISCV_IOMMU_H_ 13 14 #include <linux/iommu.h> 15 #include <linux/types.h> 16 #include <linux/iopoll.h> 17 18 #include "iommu-bits.h" 19 20 struct riscv_iommu_device; 21 22 struct riscv_iommu_queue { 23 atomic_t prod; /* unbounded producer allocation index */ 24 atomic_t head; /* unbounded shadow ring buffer consumer index */ 25 atomic_t tail; /* unbounded shadow ring buffer producer index */ 26 unsigned int mask; /* index mask, queue length - 1 */ 27 unsigned int irq; /* allocated interrupt number */ 28 struct riscv_iommu_device *iommu; /* iommu device handling the queue when active */ 29 void *base; /* ring buffer kernel pointer */ 30 dma_addr_t phys; /* ring buffer physical address */ 31 u16 qbr; /* base register offset, head and tail reference */ 32 u16 qcr; /* control and status register offset */ 33 u8 qid; /* queue identifier, same as RISCV_IOMMU_INTR_XX */ 34 }; 35 36 struct riscv_iommu_device { 37 /* iommu core interface */ 38 struct iommu_device iommu; 39 40 /* iommu hardware */ 41 struct device *dev; 42 43 /* hardware control register space */ 44 void __iomem *reg; 45 46 /* supported and enabled hardware capabilities */ 47 u64 caps; 48 u32 fctl; 49 50 /* available interrupt numbers, MSI or WSI */ 51 unsigned int irqs[RISCV_IOMMU_INTR_COUNT]; 52 unsigned int irqs_count; 53 unsigned int icvec; 54 55 /* hardware queues */ 56 struct riscv_iommu_queue cmdq; 57 struct riscv_iommu_queue fltq; 58 59 /* device directory */ 60 unsigned int ddt_mode; 61 dma_addr_t ddt_phys; 62 u64 *ddt_root; 63 }; 64 65 int riscv_iommu_init(struct riscv_iommu_device *iommu); 66 void riscv_iommu_remove(struct riscv_iommu_device *iommu); 67 void riscv_iommu_disable(struct riscv_iommu_device *iommu); 68 69 #define riscv_iommu_readl(iommu, addr) \ 70 readl_relaxed((iommu)->reg + (addr)) 71 72 #define riscv_iommu_readq(iommu, addr) \ 73 readq_relaxed((iommu)->reg + (addr)) 74 75 #define riscv_iommu_writel(iommu, addr, val) \ 76 writel_relaxed((val), (iommu)->reg + (addr)) 77 78 #define riscv_iommu_writeq(iommu, addr, val) \ 79 writeq_relaxed((val), (iommu)->reg + (addr)) 80 81 #define riscv_iommu_readq_timeout(iommu, addr, val, cond, delay_us, timeout_us) \ 82 readx_poll_timeout(readq_relaxed, (iommu)->reg + (addr), val, cond, \ 83 delay_us, timeout_us) 84 85 #define riscv_iommu_readl_timeout(iommu, addr, val, cond, delay_us, timeout_us) \ 86 readx_poll_timeout(readl_relaxed, (iommu)->reg + (addr), val, cond, \ 87 delay_us, timeout_us) 88 89 #endif 90