1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (c) 2015-2016 MediaTek Inc.
4 * Author: Honghui Zhang <honghui.zhang@mediatek.com>
5 */
6
7#ifndef _MTK_IOMMU_H_
8#define _MTK_IOMMU_H_
9
10#include <linux/clk.h>
11#include <linux/component.h>
12#include <linux/device.h>
13#include <linux/io.h>
14#include <linux/io-pgtable.h>
15#include <linux/iommu.h>
16#include <linux/list.h>
17#include <linux/spinlock.h>
18#include <linux/dma-mapping.h>
19#include <soc/mediatek/smi.h>
20
21#define MTK_LARB_COM_MAX	8
22#define MTK_LARB_SUBCOM_MAX	4
23
24struct mtk_iommu_suspend_reg {
25	union {
26		u32			standard_axi_mode;/* v1 */
27		u32			misc_ctrl;/* v2 */
28	};
29	u32				dcm_dis;
30	u32				ctrl_reg;
31	u32				int_control0;
32	u32				int_main_control;
33	u32				ivrp_paddr;
34	u32				vld_pa_rng;
35	u32				wr_len_ctrl;
36};
37
38enum mtk_iommu_plat {
39	M4U_MT2701,
40	M4U_MT2712,
41	M4U_MT6779,
42	M4U_MT8167,
43	M4U_MT8173,
44	M4U_MT8183,
45};
46
47struct mtk_iommu_plat_data {
48	enum mtk_iommu_plat m4u_plat;
49	u32                 flags;
50	u32                 inv_sel_reg;
51	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
52};
53
54struct mtk_iommu_domain;
55
56struct mtk_iommu_data {
57	void __iomem			*base;
58	int				irq;
59	struct device			*dev;
60	struct clk			*bclk;
61	phys_addr_t			protect_base; /* protect memory base */
62	struct mtk_iommu_suspend_reg	reg;
63	struct mtk_iommu_domain		*m4u_dom;
64	struct iommu_group		*m4u_group;
65	bool                            enable_4GB;
66	spinlock_t			tlb_lock; /* lock for tlb range flush */
67
68	struct iommu_device		iommu;
69	const struct mtk_iommu_plat_data *plat_data;
70
71	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
72
73	struct list_head		list;
74	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
75};
76
77static inline int compare_of(struct device *dev, void *data)
78{
79	return dev->of_node == data;
80}
81
82static inline void release_of(struct device *dev, void *data)
83{
84	of_node_put(data);
85}
86
87static inline int mtk_iommu_bind(struct device *dev)
88{
89	struct mtk_iommu_data *data = dev_get_drvdata(dev);
90
91	return component_bind_all(dev, &data->larb_imu);
92}
93
94static inline void mtk_iommu_unbind(struct device *dev)
95{
96	struct mtk_iommu_data *data = dev_get_drvdata(dev);
97
98	component_unbind_all(dev, &data->larb_imu);
99}
100
101#endif
102