blob: f81fa8862ed04b22f997bf45700e58dd90fc068b [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>
Yong Wu66a28912021-01-11 19:18:49 +080020#include <dt-bindings/memory/mtk-memory-port.h>
Honghui Zhang9ca340c2016-06-08 17:50:58 +080021
Chao Hao37276e02020-07-03 12:41:23 +080022#define MTK_LARB_COM_MAX 8
23#define MTK_LARB_SUBCOM_MAX 4
24
Yong Wuc3045f32021-01-11 19:19:09 +080025#define MTK_IOMMU_GROUP_MAX 8
26
Honghui Zhang9ca340c2016-06-08 17:50:58 +080027struct mtk_iommu_suspend_reg {
Chao Hao75eed352020-07-03 12:41:19 +080028 union {
29 u32 standard_axi_mode;/* v1 */
30 u32 misc_ctrl;/* v2 */
31 };
Honghui Zhang9ca340c2016-06-08 17:50:58 +080032 u32 dcm_dis;
33 u32 ctrl_reg;
34 u32 int_control0;
35 u32 int_main_control;
Yong Wu70ca6082018-03-18 09:52:54 +080036 u32 ivrp_paddr;
Yong Wub9475b32019-08-24 11:02:06 +080037 u32 vld_pa_rng;
Chao Hao35c1b482020-07-03 12:41:24 +080038 u32 wr_len_ctrl;
Honghui Zhang9ca340c2016-06-08 17:50:58 +080039};
40
Yong Wue6dec922017-08-21 19:00:16 +080041enum mtk_iommu_plat {
42 M4U_MT2701,
43 M4U_MT2712,
Chao Hao068c86e2020-07-03 12:41:27 +080044 M4U_MT6779,
Fabien Parent3c213562020-09-07 12:16:49 +020045 M4U_MT8167,
Yong Wue6dec922017-08-21 19:00:16 +080046 M4U_MT8173,
Yong Wu907ba6a2019-08-24 11:02:02 +080047 M4U_MT8183,
Yong Wu9e3489e2021-01-11 19:19:13 +080048 M4U_MT8192,
Yong Wue6dec922017-08-21 19:00:16 +080049};
50
Yong Wu585e58f2021-01-11 19:19:07 +080051struct mtk_iommu_iova_region;
52
Yong Wucecdce92019-08-24 11:01:47 +080053struct mtk_iommu_plat_data {
54 enum mtk_iommu_plat m4u_plat;
Chao Hao6b717792020-07-03 12:41:20 +080055 u32 flags;
Chao Haob053bc72020-07-03 12:41:22 +080056 u32 inv_sel_reg;
Yong Wu585e58f2021-01-11 19:19:07 +080057
58 unsigned int iova_region_nr;
59 const struct mtk_iommu_iova_region *iova_region;
Chao Hao37276e02020-07-03 12:41:23 +080060 unsigned char larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
Yong Wucecdce92019-08-24 11:01:47 +080061};
62
Honghui Zhang9ca340c2016-06-08 17:50:58 +080063struct mtk_iommu_domain;
64
65struct mtk_iommu_data {
66 void __iomem *base;
67 int irq;
68 struct device *dev;
69 struct clk *bclk;
70 phys_addr_t protect_base; /* protect memory base */
71 struct mtk_iommu_suspend_reg reg;
72 struct mtk_iommu_domain *m4u_dom;
Yong Wuc3045f32021-01-11 19:19:09 +080073 struct iommu_group *m4u_group[MTK_IOMMU_GROUP_MAX];
Honghui Zhang9ca340c2016-06-08 17:50:58 +080074 bool enable_4GB;
Yong Wuda3cc912019-11-04 15:01:03 +080075 spinlock_t tlb_lock; /* lock for tlb range flush */
Joerg Roedelb16c0172017-02-03 12:57:32 +010076
77 struct iommu_device iommu;
Yong Wucecdce92019-08-24 11:01:47 +080078 const struct mtk_iommu_plat_data *plat_data;
Yong Wubaf94e62021-01-11 19:18:59 +080079 struct device *smicomm_dev;
Yong Wu7c3a2ec2017-08-21 19:00:17 +080080
Joerg Roedel58960172020-06-25 15:08:31 +020081 struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */
82
Yong Wu7c3a2ec2017-08-21 19:00:17 +080083 struct list_head list;
Yong Wu1ee9feb2019-08-24 11:02:08 +080084 struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
Honghui Zhang9ca340c2016-06-08 17:50:58 +080085};
86
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020087static inline int compare_of(struct device *dev, void *data)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080088{
89 return dev->of_node == data;
90}
91
Russell King00c7c812016-10-19 11:30:34 +010092static inline void release_of(struct device *dev, void *data)
93{
94 of_node_put(data);
95}
96
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020097static inline int mtk_iommu_bind(struct device *dev)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080098{
99 struct mtk_iommu_data *data = dev_get_drvdata(dev);
100
Yong Wu1ee9feb2019-08-24 11:02:08 +0800101 return component_bind_all(dev, &data->larb_imu);
Honghui Zhang9ca340c2016-06-08 17:50:58 +0800102}
103
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +0200104static inline void mtk_iommu_unbind(struct device *dev)
Honghui Zhang9ca340c2016-06-08 17:50:58 +0800105{
106 struct mtk_iommu_data *data = dev_get_drvdata(dev);
107
Yong Wu1ee9feb2019-08-24 11:02:08 +0800108 component_unbind_all(dev, &data->larb_imu);
Honghui Zhang9ca340c2016-06-08 17:50:58 +0800109}
110
111#endif