blob: 122925dbe54755b12ba4caacd906261dda42c9e4 [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,
Yong Wue6dec922017-08-21 19:00:16 +080042 M4U_MT8173,
Yong Wu907ba6a2019-08-24 11:02:02 +080043 M4U_MT8183,
Yong Wue6dec922017-08-21 19:00:16 +080044};
45
Yong Wucecdce92019-08-24 11:01:47 +080046struct mtk_iommu_plat_data {
47 enum mtk_iommu_plat m4u_plat;
Chao Hao6b717792020-07-03 12:41:20 +080048 u32 flags;
Chao Haob053bc72020-07-03 12:41:22 +080049 u32 inv_sel_reg;
Chao Hao37276e02020-07-03 12:41:23 +080050 unsigned char larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
Yong Wucecdce92019-08-24 11:01:47 +080051};
52
Honghui Zhang9ca340c2016-06-08 17:50:58 +080053struct mtk_iommu_domain;
54
55struct mtk_iommu_data {
56 void __iomem *base;
57 int irq;
58 struct device *dev;
59 struct clk *bclk;
60 phys_addr_t protect_base; /* protect memory base */
61 struct mtk_iommu_suspend_reg reg;
62 struct mtk_iommu_domain *m4u_dom;
63 struct iommu_group *m4u_group;
Honghui Zhang9ca340c2016-06-08 17:50:58 +080064 bool enable_4GB;
Yong Wuda3cc912019-11-04 15:01:03 +080065 spinlock_t tlb_lock; /* lock for tlb range flush */
Joerg Roedelb16c0172017-02-03 12:57:32 +010066
67 struct iommu_device iommu;
Yong Wucecdce92019-08-24 11:01:47 +080068 const struct mtk_iommu_plat_data *plat_data;
Yong Wu7c3a2ec2017-08-21 19:00:17 +080069
Joerg Roedel58960172020-06-25 15:08:31 +020070 struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */
71
Yong Wu7c3a2ec2017-08-21 19:00:17 +080072 struct list_head list;
Yong Wu1ee9feb2019-08-24 11:02:08 +080073 struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
Honghui Zhang9ca340c2016-06-08 17:50:58 +080074};
75
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020076static inline int compare_of(struct device *dev, void *data)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080077{
78 return dev->of_node == data;
79}
80
Russell King00c7c812016-10-19 11:30:34 +010081static inline void release_of(struct device *dev, void *data)
82{
83 of_node_put(data);
84}
85
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020086static inline int mtk_iommu_bind(struct device *dev)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080087{
88 struct mtk_iommu_data *data = dev_get_drvdata(dev);
89
Yong Wu1ee9feb2019-08-24 11:02:08 +080090 return component_bind_all(dev, &data->larb_imu);
Honghui Zhang9ca340c2016-06-08 17:50:58 +080091}
92
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020093static inline void mtk_iommu_unbind(struct device *dev)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080094{
95 struct mtk_iommu_data *data = dev_get_drvdata(dev);
96
Yong Wu1ee9feb2019-08-24 11:02:08 +080097 component_unbind_all(dev, &data->larb_imu);
Honghui Zhang9ca340c2016-06-08 17:50:58 +080098}
99
100#endif