#ifndef _RISCV_IOMMU_H_
#define _RISCV_IOMMU_H_
#include <linux/iommu.h>
#include <linux/types.h>
#include <linux/iopoll.h>
#include "iommu-bits.h"
struct riscv_iommu_device;
struct riscv_iommu_queue {
atomic_t prod;
atomic_t head;
atomic_t tail;
unsigned int mask;
unsigned int irq;
struct riscv_iommu_device *iommu;
void *base;
dma_addr_t phys;
u16 qbr;
u16 qcr;
u8 qid;
};
struct riscv_iommu_device {
struct iommu_device iommu;
struct device *dev;
void __iomem *reg;
u64 caps;
u32 fctl;
unsigned int irqs[RISCV_IOMMU_INTR_COUNT];
unsigned int irqs_count;
unsigned int icvec;
struct riscv_iommu_queue cmdq;
struct riscv_iommu_queue fltq;
unsigned int ddt_mode;
dma_addr_t ddt_phys;
u64 *ddt_root;
};
int riscv_iommu_init(struct riscv_iommu_device *iommu);
void riscv_iommu_remove(struct riscv_iommu_device *iommu);
void riscv_iommu_disable(struct riscv_iommu_device *iommu);
#define riscv_iommu_readl(iommu, addr) \
readl_relaxed((iommu)->reg + (addr))
#define riscv_iommu_readq(iommu, addr) \
readq_relaxed((iommu)->reg + (addr))
#define riscv_iommu_writel(iommu, addr, val) \
writel_relaxed((val), (iommu)->reg + (addr))
#define riscv_iommu_writeq(iommu, addr, val) \
writeq_relaxed((val), (iommu)->reg + (addr))
#define riscv_iommu_readq_timeout(iommu, addr, val, cond, delay_us, timeout_us) \
readx_poll_timeout(readq_relaxed, (iommu)->reg + (addr), val, cond, \
delay_us, timeout_us)
#define riscv_iommu_readl_timeout(iommu, addr, val, cond, delay_us, timeout_us) \
readx_poll_timeout(readl_relaxed, (iommu)->reg + (addr), val, cond, \
delay_us, timeout_us)
#endif