Re: [PATCH v1 2/2] iommu: add Unisoc iommu basic driver
On Fri, 22 Jan 2021 at 05:46, Robin Murphy wrote: > > On 2021-01-21 11:23, Chunyan Zhang wrote: > > From: Chunyan Zhang > > > > This patch only adds display iommu support, the driver was tested with sprd > > dpu and image codec processor. > > > > The iommu support for others would be added once finished tests with those > > devices, such as a few signal processors, including VSP(video), > > GSP(graphic), ISP(image), and camera CPP, etc. > > > > Signed-off-by: Chunyan Zhang > > --- > > drivers/iommu/Kconfig | 12 + > > drivers/iommu/Makefile | 1 + > > drivers/iommu/sprd-iommu.c | 566 + > > 3 files changed, 579 insertions(+) > > create mode 100644 drivers/iommu/sprd-iommu.c > > > > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig > > index 192ef8f61310..79af62c519ae 100644 > > --- a/drivers/iommu/Kconfig > > +++ b/drivers/iommu/Kconfig > > @@ -408,4 +408,16 @@ config VIRTIO_IOMMU > > > > Say Y here if you intend to run this kernel as a guest. > > > > +config SPRD_IOMMU > > + tristate "Unisoc IOMMU Support" > > + depends on ARCH_SPRD || COMPILE_TEST > > + select IOMMU_API > > + help > > + Support for IOMMU on Unisoc's SoCs on which multi-media subsystems > > + need IOMMU, such as DPU, Image codec(jpeg) processor, and a few > > + signal processors, including VSP(video), GSP(graphic), ISP(image), > > and > > + CPP, etc. > > + > > + Say Y here if you want multi-media functions. > > + > > endif # IOMMU_SUPPORT > > diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile > > index 61bd30cd8369..5925b6af2123 100644 > > --- a/drivers/iommu/Makefile > > +++ b/drivers/iommu/Makefile > > @@ -28,3 +28,4 @@ obj-$(CONFIG_S390_IOMMU) += s390-iommu.o > > obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o > > obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o > > obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o > > +obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o > > diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c > > new file mode 100644 > > index ..44cde44017fa > > --- /dev/null > > +++ b/drivers/iommu/sprd-iommu.c > > @@ -0,0 +1,566 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Unisoc IOMMU driver > > + * > > + * Copyright (C) 2020 Unisoc, Inc. > > + * Author: Chunyan Zhang > > + */ > > + > > +#include > > +#include > > +#include > > You need since you're using the DMA API. > > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* SPRD IOMMU page is 4K size alignment */ > > +#define SPRD_IOMMU_PAGE_SHIFT12 > > +#define SPRD_IOMMU_PAGE_SIZE SZ_4K > > + > > +#define SPRD_EX_CFG 0x0 > > +#define SPRD_IOMMU_VAOR_BYPASS BIT(4) > > +#define SPRD_IOMMU_GATE_EN BIT(1) > > +#define SPRD_IOMMU_ENBIT(0) > > +#define SPRD_EX_UPDATE 0x4 > > +#define SPRD_EX_FIRST_VPN0x8 > > +#define SPRD_EX_VPN_RANGE0xc > > +#define SPRD_EX_FIRST_PPN0x10 > > +#define SPRD_EX_DEFAULT_PPN 0x14 > > + > > +#define SPRD_IOMMU_VERSION 0x0 > > +#define SPRD_VERSION_MASKGENMASK(15, 8) > > +#define SPRD_VERSION_SHIFT 0x8 > > +#define SPRD_VAU_CFG 0x4 > > +#define SPRD_VAU_UPDATE 0x8 > > +#define SPRD_VAU_AUTH_CFG0xc > > +#define SPRD_VAU_FIRST_PPN 0x10 > > +#define SPRD_VAU_DEFAULT_PPN_RD 0x14 > > +#define SPRD_VAU_DEFAULT_PPN_WR 0x18 > > +#define SPRD_VAU_FIRST_VPN 0x1c > > +#define SPRD_VAU_VPN_RANGE 0x20 > > + > > +enum sprd_iommu_version { > > + SPRD_IOMMU_EX, > > + SPRD_IOMMU_VAU, > > +}; > > + > > +struct sprd_iommu_match_data { > > + unsigned long reg_offset; > > +}; > > + > > +/* > > + * struct sprd_iommu_device - high-level sprd iommu device representation, > > + * including hardware information and configuration, also driver data, etc > > + * > > + * @mdata: hardware configuration and information > > + * @ver: sprd iommu device version > > + * @prot_page: protect page base address, data would be written to > > here > > + * while translation fault > > + * @base:mapped base address for accessing registers > > + * @dev: pointer to basic device structure > > + * @iommu: IOMMU core representation > > + * @group: IOMMU group > > + */ > > +struct sprd_iommu_device { > > + const struct sprd_iommu_match_data *mdata; > > + enum sprd_iommu_version ver; > > + u32 *prot_page_va; > > + dma_addr_t prot_page_pa; > > + void __iomem*base; > > + struct device *dev; > > + struct iommu_device iommu; > > + struct iommu_group *group; > > +}; > > + > > +struct sprd_iommu_domain { > > + spinlock_t pgtlock; /* lock for page table */ > > + struct iommu_domain domain; > > + u32 *pgt_va; /* page table virtual address base */ > > + dma_addr_t pgt_pa; /* page
Re: [PATCH v1 2/2] iommu: add Unisoc iommu basic driver
On 2021-01-21 11:23, Chunyan Zhang wrote: From: Chunyan Zhang This patch only adds display iommu support, the driver was tested with sprd dpu and image codec processor. The iommu support for others would be added once finished tests with those devices, such as a few signal processors, including VSP(video), GSP(graphic), ISP(image), and camera CPP, etc. Signed-off-by: Chunyan Zhang --- drivers/iommu/Kconfig | 12 + drivers/iommu/Makefile | 1 + drivers/iommu/sprd-iommu.c | 566 + 3 files changed, 579 insertions(+) create mode 100644 drivers/iommu/sprd-iommu.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 192ef8f61310..79af62c519ae 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -408,4 +408,16 @@ config VIRTIO_IOMMU Say Y here if you intend to run this kernel as a guest. +config SPRD_IOMMU + tristate "Unisoc IOMMU Support" + depends on ARCH_SPRD || COMPILE_TEST + select IOMMU_API + help + Support for IOMMU on Unisoc's SoCs on which multi-media subsystems + need IOMMU, such as DPU, Image codec(jpeg) processor, and a few + signal processors, including VSP(video), GSP(graphic), ISP(image), and + CPP, etc. + + Say Y here if you want multi-media functions. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 61bd30cd8369..5925b6af2123 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -28,3 +28,4 @@ obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o +obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c new file mode 100644 index ..44cde44017fa --- /dev/null +++ b/drivers/iommu/sprd-iommu.c @@ -0,0 +1,566 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Unisoc IOMMU driver + * + * Copyright (C) 2020 Unisoc, Inc. + * Author: Chunyan Zhang + */ + +#include +#include +#include You need since you're using the DMA API. +#include +#include +#include +#include +#include + +/* SPRD IOMMU page is 4K size alignment */ +#define SPRD_IOMMU_PAGE_SHIFT 12 +#define SPRD_IOMMU_PAGE_SIZE SZ_4K + +#define SPRD_EX_CFG0x0 +#define SPRD_IOMMU_VAOR_BYPASS BIT(4) +#define SPRD_IOMMU_GATE_EN BIT(1) +#define SPRD_IOMMU_EN BIT(0) +#define SPRD_EX_UPDATE 0x4 +#define SPRD_EX_FIRST_VPN 0x8 +#define SPRD_EX_VPN_RANGE 0xc +#define SPRD_EX_FIRST_PPN 0x10 +#define SPRD_EX_DEFAULT_PPN0x14 + +#define SPRD_IOMMU_VERSION 0x0 +#define SPRD_VERSION_MASK GENMASK(15, 8) +#define SPRD_VERSION_SHIFT 0x8 +#define SPRD_VAU_CFG 0x4 +#define SPRD_VAU_UPDATE0x8 +#define SPRD_VAU_AUTH_CFG 0xc +#define SPRD_VAU_FIRST_PPN 0x10 +#define SPRD_VAU_DEFAULT_PPN_RD0x14 +#define SPRD_VAU_DEFAULT_PPN_WR0x18 +#define SPRD_VAU_FIRST_VPN 0x1c +#define SPRD_VAU_VPN_RANGE 0x20 + +enum sprd_iommu_version { + SPRD_IOMMU_EX, + SPRD_IOMMU_VAU, +}; + +struct sprd_iommu_match_data { + unsigned long reg_offset; +}; + +/* + * struct sprd_iommu_device - high-level sprd iommu device representation, + * including hardware information and configuration, also driver data, etc + * + * @mdata: hardware configuration and information + * @ver: sprd iommu device version + * @prot_page: protect page base address, data would be written to here + * while translation fault + * @base: mapped base address for accessing registers + * @dev: pointer to basic device structure + * @iommu: IOMMU core representation + * @group: IOMMU group + */ +struct sprd_iommu_device { + const struct sprd_iommu_match_data *mdata; + enum sprd_iommu_version ver; + u32 *prot_page_va; + dma_addr_t prot_page_pa; + void __iomem*base; + struct device *dev; + struct iommu_device iommu; + struct iommu_group *group; +}; + +struct sprd_iommu_domain { + spinlock_t pgtlock; /* lock for page table */ + struct iommu_domain domain; + u32 *pgt_va; /* page table virtual address base */ + dma_addr_t pgt_pa; /* page table physical address base */ + struct sprd_iommu_device*sdev; +}; + +static const struct iommu_ops sprd_iommu_ops; + +static struct sprd_iommu_domain *to_sprd_domain(struct iommu_domain *dom) +{ + return container_of(dom, struct sprd_iommu_domain, domain); +} + +static inline void +sprd_iommu_writel(struct sprd_iommu_device *sdev, unsigned int reg, u32 val) +{ + writel_relaxed(val, sdev->base + sdev->mdata->reg_offset + reg); +} + +static inline u32 +sprd_iommu_readl(struct sprd_iommu_device
Re: [PATCH v1 2/2] iommu: add Unisoc iommu basic driver
Hi Chunyan, I love your patch! Yet something to improve: [auto build test ERROR on robh/for-next] [also build test ERROR on v5.11-rc4 next-20210121] [cannot apply to iommu/next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Chunyan-Zhang/Add-Unisoc-iommu-basic-driver/20210121-194023 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next config: arc-allyesconfig (attached as .config) compiler: arceb-elf-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/891db11d7229149235a02e5bc31a61188243a5d7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Chunyan-Zhang/Add-Unisoc-iommu-basic-driver/20210121-194023 git checkout 891db11d7229149235a02e5bc31a61188243a5d7 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arc If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): drivers/iommu/sprd-iommu.c: In function 'sprd_iommu_attach_device': >> drivers/iommu/sprd-iommu.c:248:16: error: implicit declaration of function >> 'dma_alloc_coherent' [-Werror=implicit-function-declaration] 248 | dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, &dom->pgt_pa, GFP_KERNEL); |^~ drivers/iommu/sprd-iommu.c:248:14: warning: assignment to 'u32 *' {aka 'unsigned int *'} from 'int' makes pointer from integer without a cast [-Wint-conversion] 248 | dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, &dom->pgt_pa, GFP_KERNEL); | ^ drivers/iommu/sprd-iommu.c: In function 'sprd_iommu_detach_device': >> drivers/iommu/sprd-iommu.c:270:2: error: implicit declaration of function >> 'dma_free_coherent' [-Werror=implicit-function-declaration] 270 | dma_free_coherent(sdev->dev, pgt_size, dom->pgt_va, dom->pgt_pa); | ^ In file included from include/linux/device.h:15, from drivers/iommu/sprd-iommu.c:10: drivers/iommu/sprd-iommu.c: In function 'sprd_iommu_map': drivers/iommu/sprd-iommu.c:296:27: warning: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'size_t' {aka 'unsigned int'} [-Wformat=] 296 | dev_err(dom->sdev->dev, "(iova(0x%lx) + sixe(0x%lx)) are not in the range!\n", | ^ include/linux/dev_printk.h:19:22: note: in definition of macro 'dev_fmt' 19 | #define dev_fmt(fmt) fmt | ^~~ drivers/iommu/sprd-iommu.c:296:3: note: in expansion of macro 'dev_err' 296 | dev_err(dom->sdev->dev, "(iova(0x%lx) + sixe(0x%lx)) are not in the range!\n", | ^~~ drivers/iommu/sprd-iommu.c:296:52: note: format string is defined here 296 | dev_err(dom->sdev->dev, "(iova(0x%lx) + sixe(0x%lx)) are not in the range!\n", | ~~^ || |long unsigned int | %x drivers/iommu/sprd-iommu.c:279:38: warning: variable 'mdata' set but not used [-Wunused-but-set-variable] 279 | const struct sprd_iommu_match_data *mdata; | ^ drivers/iommu/sprd-iommu.c: In function 'sprd_iommu_probe': drivers/iommu/sprd-iommu.c:483:21: warning: assignment to 'u32 *' {aka 'unsigned int *'} from 'int' makes pointer from integer without a cast [-Wint-conversion] 483 | sdev->prot_page_va = dma_alloc_coherent(dev, SPRD_IOMMU_PAGE_SIZE, | ^ cc1: some warnings being treated as errors vim +/dma_alloc_coherent +248 drivers/iommu/sprd-iommu.c 240 241 static int sprd_iommu_attach_device(struct iommu_domain *domain, 242 struct device *dev) 243 { 244 struct sprd_iommu_device *sdev = dev_iommu_priv_get(dev); 245 struct sprd_iommu_domain *dom = to_sprd_domain(domain); 246 size_t pgt_size = sprd_iommu_pgt_size(domain); 247 > 248 dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, > &dom->pgt_pa, GFP_KERNEL); 249 if (!dom->pgt_va) 250 return -ENOMEM; 251 252 dom->sdev = sdev; 253 254 sprd_iommu_first_ppn(dom); 255
Re: [PATCH v1 2/2] iommu: add Unisoc iommu basic driver
Hi Chunyan, I love your patch! Perhaps something to improve: [auto build test WARNING on robh/for-next] [also build test WARNING on v5.11-rc4 next-20210121] [cannot apply to iommu/next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Chunyan-Zhang/Add-Unisoc-iommu-basic-driver/20210121-194023 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next config: arc-allyesconfig (attached as .config) compiler: arceb-elf-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/891db11d7229149235a02e5bc31a61188243a5d7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Chunyan-Zhang/Add-Unisoc-iommu-basic-driver/20210121-194023 git checkout 891db11d7229149235a02e5bc31a61188243a5d7 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arc If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/iommu/sprd-iommu.c: In function 'sprd_iommu_attach_device': drivers/iommu/sprd-iommu.c:248:16: error: implicit declaration of function 'dma_alloc_coherent' [-Werror=implicit-function-declaration] 248 | dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, &dom->pgt_pa, GFP_KERNEL); |^~ >> drivers/iommu/sprd-iommu.c:248:14: warning: assignment to 'u32 *' {aka >> 'unsigned int *'} from 'int' makes pointer from integer without a cast >> [-Wint-conversion] 248 | dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, &dom->pgt_pa, GFP_KERNEL); | ^ drivers/iommu/sprd-iommu.c: In function 'sprd_iommu_detach_device': drivers/iommu/sprd-iommu.c:270:2: error: implicit declaration of function 'dma_free_coherent' [-Werror=implicit-function-declaration] 270 | dma_free_coherent(sdev->dev, pgt_size, dom->pgt_va, dom->pgt_pa); | ^ In file included from include/linux/device.h:15, from drivers/iommu/sprd-iommu.c:10: drivers/iommu/sprd-iommu.c: In function 'sprd_iommu_map': >> drivers/iommu/sprd-iommu.c:296:27: warning: format '%lx' expects argument of >> type 'long unsigned int', but argument 4 has type 'size_t' {aka 'unsigned >> int'} [-Wformat=] 296 | dev_err(dom->sdev->dev, "(iova(0x%lx) + sixe(0x%lx)) are not in the range!\n", | ^ include/linux/dev_printk.h:19:22: note: in definition of macro 'dev_fmt' 19 | #define dev_fmt(fmt) fmt | ^~~ drivers/iommu/sprd-iommu.c:296:3: note: in expansion of macro 'dev_err' 296 | dev_err(dom->sdev->dev, "(iova(0x%lx) + sixe(0x%lx)) are not in the range!\n", | ^~~ drivers/iommu/sprd-iommu.c:296:52: note: format string is defined here 296 | dev_err(dom->sdev->dev, "(iova(0x%lx) + sixe(0x%lx)) are not in the range!\n", | ~~^ || |long unsigned int | %x >> drivers/iommu/sprd-iommu.c:279:38: warning: variable 'mdata' set but not >> used [-Wunused-but-set-variable] 279 | const struct sprd_iommu_match_data *mdata; | ^ drivers/iommu/sprd-iommu.c: In function 'sprd_iommu_probe': drivers/iommu/sprd-iommu.c:483:21: warning: assignment to 'u32 *' {aka 'unsigned int *'} from 'int' makes pointer from integer without a cast [-Wint-conversion] 483 | sdev->prot_page_va = dma_alloc_coherent(dev, SPRD_IOMMU_PAGE_SIZE, | ^ cc1: some warnings being treated as errors vim +248 drivers/iommu/sprd-iommu.c 240 241 static int sprd_iommu_attach_device(struct iommu_domain *domain, 242 struct device *dev) 243 { 244 struct sprd_iommu_device *sdev = dev_iommu_priv_get(dev); 245 struct sprd_iommu_domain *dom = to_sprd_domain(domain); 246 size_t pgt_size = sprd_iommu_pgt_size(domain); 247 > 248 dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, > &dom->pgt_pa, GFP_KERNEL); 249 if (!dom->pgt_va) 250 return -ENOMEM; 251 252 dom->sdev = sdev; 253 254 sprd_iommu_first_ppn(dom); 255 s
[PATCH v1 2/2] iommu: add Unisoc iommu basic driver
From: Chunyan Zhang This patch only adds display iommu support, the driver was tested with sprd dpu and image codec processor. The iommu support for others would be added once finished tests with those devices, such as a few signal processors, including VSP(video), GSP(graphic), ISP(image), and camera CPP, etc. Signed-off-by: Chunyan Zhang --- drivers/iommu/Kconfig | 12 + drivers/iommu/Makefile | 1 + drivers/iommu/sprd-iommu.c | 566 + 3 files changed, 579 insertions(+) create mode 100644 drivers/iommu/sprd-iommu.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 192ef8f61310..79af62c519ae 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -408,4 +408,16 @@ config VIRTIO_IOMMU Say Y here if you intend to run this kernel as a guest. +config SPRD_IOMMU + tristate "Unisoc IOMMU Support" + depends on ARCH_SPRD || COMPILE_TEST + select IOMMU_API + help + Support for IOMMU on Unisoc's SoCs on which multi-media subsystems + need IOMMU, such as DPU, Image codec(jpeg) processor, and a few + signal processors, including VSP(video), GSP(graphic), ISP(image), and + CPP, etc. + + Say Y here if you want multi-media functions. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 61bd30cd8369..5925b6af2123 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -28,3 +28,4 @@ obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o +obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c new file mode 100644 index ..44cde44017fa --- /dev/null +++ b/drivers/iommu/sprd-iommu.c @@ -0,0 +1,566 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Unisoc IOMMU driver + * + * Copyright (C) 2020 Unisoc, Inc. + * Author: Chunyan Zhang + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* SPRD IOMMU page is 4K size alignment */ +#define SPRD_IOMMU_PAGE_SHIFT 12 +#define SPRD_IOMMU_PAGE_SIZE SZ_4K + +#define SPRD_EX_CFG0x0 +#define SPRD_IOMMU_VAOR_BYPASS BIT(4) +#define SPRD_IOMMU_GATE_EN BIT(1) +#define SPRD_IOMMU_EN BIT(0) +#define SPRD_EX_UPDATE 0x4 +#define SPRD_EX_FIRST_VPN 0x8 +#define SPRD_EX_VPN_RANGE 0xc +#define SPRD_EX_FIRST_PPN 0x10 +#define SPRD_EX_DEFAULT_PPN0x14 + +#define SPRD_IOMMU_VERSION 0x0 +#define SPRD_VERSION_MASK GENMASK(15, 8) +#define SPRD_VERSION_SHIFT 0x8 +#define SPRD_VAU_CFG 0x4 +#define SPRD_VAU_UPDATE0x8 +#define SPRD_VAU_AUTH_CFG 0xc +#define SPRD_VAU_FIRST_PPN 0x10 +#define SPRD_VAU_DEFAULT_PPN_RD0x14 +#define SPRD_VAU_DEFAULT_PPN_WR0x18 +#define SPRD_VAU_FIRST_VPN 0x1c +#define SPRD_VAU_VPN_RANGE 0x20 + +enum sprd_iommu_version { + SPRD_IOMMU_EX, + SPRD_IOMMU_VAU, +}; + +struct sprd_iommu_match_data { + unsigned long reg_offset; +}; + +/* + * struct sprd_iommu_device - high-level sprd iommu device representation, + * including hardware information and configuration, also driver data, etc + * + * @mdata: hardware configuration and information + * @ver: sprd iommu device version + * @prot_page: protect page base address, data would be written to here + * while translation fault + * @base: mapped base address for accessing registers + * @dev: pointer to basic device structure + * @iommu: IOMMU core representation + * @group: IOMMU group + */ +struct sprd_iommu_device { + const struct sprd_iommu_match_data *mdata; + enum sprd_iommu_version ver; + u32 *prot_page_va; + dma_addr_t prot_page_pa; + void __iomem*base; + struct device *dev; + struct iommu_device iommu; + struct iommu_group *group; +}; + +struct sprd_iommu_domain { + spinlock_t pgtlock; /* lock for page table */ + struct iommu_domain domain; + u32 *pgt_va; /* page table virtual address base */ + dma_addr_t pgt_pa; /* page table physical address base */ + struct sprd_iommu_device*sdev; +}; + +static const struct iommu_ops sprd_iommu_ops; + +static struct sprd_iommu_domain *to_sprd_domain(struct iommu_domain *dom) +{ + return container_of(dom, struct sprd_iommu_domain, domain); +} + +static inline void +sprd_iommu_writel(struct sprd_iommu_device *sdev, unsigned int reg, u32 val) +{ + writel_relaxed(val, sdev->base + sdev->mdata->reg_offset + reg); +} + +static inline u32 +sprd_iommu_readl(struct sprd_iommu_device *sdev, unsigned int reg) +{ + return readl_relaxed(sdev->base + sdev->mdata->reg_offset +