blob: df32b3e3408b79d32f71ea90dec7e172607bb160 [file] [log] [blame]
Thomas Gleixner1802d0b2019-05-27 08:55:21 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Honghui Zhang9ca340c2016-06-08 17:50:58 +08002/*
3 * Copyright (c) 2015-2016 MediaTek Inc.
4 * Author: Honghui Zhang <honghui.zhang@mediatek.com>
Honghui Zhang9ca340c2016-06-08 17:50:58 +08005 */
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>
Rob Herringb77cf112019-02-05 10:37:31 -060014#include <linux/io-pgtable.h>
Honghui Zhang9ca340c2016-06-08 17:50:58 +080015#include <linux/iommu.h>
16#include <linux/list.h>
17#include <linux/spinlock.h>
Joerg Roedel397e18b2020-07-13 12:16:48 +020018#include <linux/dma-mapping.h>
Honghui Zhang9ca340c2016-06-08 17:50:58 +080019#include <soc/mediatek/smi.h>
20
Chao Hao37276e02020-07-03 12:41:23 +080021#define MTK_LARB_COM_MAX 8
22#define MTK_LARB_SUBCOM_MAX 4
23
Honghui Zhang9ca340c2016-06-08 17:50:58 +080024struct mtk_iommu_suspend_reg {
Chao Hao75eed352020-07-03 12:41:19 +080025 union {
26 u32 standard_axi_mode;/* v1 */
27 u32 misc_ctrl;/* v2 */
28 };
Honghui Zhang9ca340c2016-06-08 17:50:58 +080029 u32 dcm_dis;
30 u32 ctrl_reg;
31 u32 int_control0;
32 u32 int_main_control;
Yong Wu70ca6082018-03-18 09:52:54 +080033 u32 ivrp_paddr;
Yong Wub9475b32019-08-24 11:02:06 +080034 u32 vld_pa_rng;
Chao Hao35c1b482020-07-03 12:41:24 +080035 u32 wr_len_ctrl;
Honghui Zhang9ca340c2016-06-08 17:50:58 +080036};
37
Yong Wue6dec922017-08-21 19:00:16 +080038enum mtk_iommu_plat {
39 M4U_MT2701,
40 M4U_MT2712,
Chao Hao068c86e2020-07-03 12:41:27 +080041 M4U_MT6779,
Fabien Parent3c213562020-09-07 12:16:49 +020042 M4U_MT8167,
Yong Wue6dec922017-08-21 19:00:16 +080043 M4U_MT8173,
Yong Wu907ba6a2019-08-24 11:02:02 +080044 M4U_MT8183,
Yong Wue6dec922017-08-21 19:00:16 +080045};
46
Yong Wucecdce92019-08-24 11:01:47 +080047struct mtk_iommu_plat_data {
48 enum mtk_iommu_plat m4u_plat;
Chao Hao6b717792020-07-03 12:41:20 +080049 u32 flags;
Chao Haob053bc72020-07-03 12:41:22 +080050 u32 inv_sel_reg;
Chao Hao37276e02020-07-03 12:41:23 +080051 unsigned char larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
Yong Wucecdce92019-08-24 11:01:47 +080052};
53
Honghui Zhang9ca340c2016-06-08 17:50:58 +080054struct 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;
Honghui Zhang9ca340c2016-06-08 17:50:58 +080065 bool enable_4GB;
Yong Wuda3cc912019-11-04 15:01:03 +080066 spinlock_t tlb_lock; /* lock for tlb range flush */
Joerg Roedelb16c0172017-02-03 12:57:32 +010067
68 struct iommu_device iommu;
Yong Wucecdce92019-08-24 11:01:47 +080069 const struct mtk_iommu_plat_data *plat_data;
Yong Wu7c3a2ec2017-08-21 19:00:17 +080070
Joerg Roedel58960172020-06-25 15:08:31 +020071 struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */
72
Yong Wu7c3a2ec2017-08-21 19:00:17 +080073 struct list_head list;
Yong Wu1ee9feb2019-08-24 11:02:08 +080074 struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
Honghui Zhang9ca340c2016-06-08 17:50:58 +080075};
76
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020077static inline int compare_of(struct device *dev, void *data)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080078{
79 return dev->of_node == data;
80}
81
Russell King00c7c812016-10-19 11:30:34 +010082static inline void release_of(struct device *dev, void *data)
83{
84 of_node_put(data);
85}
86
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020087static inline int mtk_iommu_bind(struct device *dev)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080088{
89 struct mtk_iommu_data *data = dev_get_drvdata(dev);
90
Yong Wu1ee9feb2019-08-24 11:02:08 +080091 return component_bind_all(dev, &data->larb_imu);
Honghui Zhang9ca340c2016-06-08 17:50:58 +080092}
93
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020094static inline void mtk_iommu_unbind(struct device *dev)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080095{
96 struct mtk_iommu_data *data = dev_get_drvdata(dev);
97
Yong Wu1ee9feb2019-08-24 11:02:08 +080098 component_unbind_all(dev, &data->larb_imu);
Honghui Zhang9ca340c2016-06-08 17:50:58 +080099}
100
101#endif