blob: 8cae22de766335fc0063ab47b54a0b68dc59b0cd [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>
18#include <soc/mediatek/smi.h>
19
Honghui Zhang9ca340c2016-06-08 17:50:58 +080020struct mtk_iommu_suspend_reg {
21 u32 standard_axi_mode;
22 u32 dcm_dis;
23 u32 ctrl_reg;
24 u32 int_control0;
25 u32 int_main_control;
Yong Wu70ca6082018-03-18 09:52:54 +080026 u32 ivrp_paddr;
Yong Wub9475b32019-08-24 11:02:06 +080027 u32 vld_pa_rng;
Honghui Zhang9ca340c2016-06-08 17:50:58 +080028};
29
Yong Wue6dec922017-08-21 19:00:16 +080030enum mtk_iommu_plat {
31 M4U_MT2701,
32 M4U_MT2712,
33 M4U_MT8173,
Yong Wu907ba6a2019-08-24 11:02:02 +080034 M4U_MT8183,
Yong Wue6dec922017-08-21 19:00:16 +080035};
36
Yong Wucecdce92019-08-24 11:01:47 +080037struct mtk_iommu_plat_data {
38 enum mtk_iommu_plat m4u_plat;
Yong Wub4dad402019-08-24 11:01:55 +080039 bool has_4gb_mode;
Yong Wu2aa4c252019-08-24 11:01:56 +080040
41 /* HW will use the EMI clock if there isn't the "bclk". */
42 bool has_bclk;
Yong Wu2b326d82019-08-24 11:02:00 +080043 bool has_vld_pa_rng;
Yong Wu50822b02019-08-24 11:01:59 +080044 bool reset_axi;
Yong Wub3e5eee72019-08-24 11:01:57 +080045 unsigned char larbid_remap[MTK_LARB_NR_MAX];
Yong Wucecdce92019-08-24 11:01:47 +080046};
47
Honghui Zhang9ca340c2016-06-08 17:50:58 +080048struct mtk_iommu_domain;
49
50struct mtk_iommu_data {
51 void __iomem *base;
52 int irq;
53 struct device *dev;
54 struct clk *bclk;
55 phys_addr_t protect_base; /* protect memory base */
56 struct mtk_iommu_suspend_reg reg;
57 struct mtk_iommu_domain *m4u_dom;
58 struct iommu_group *m4u_group;
Honghui Zhang9ca340c2016-06-08 17:50:58 +080059 bool enable_4GB;
Robin Murphy98a8f632017-07-06 17:55:30 +010060 bool tlb_flush_active;
Yong Wuda3cc912019-11-04 15:01:03 +080061 spinlock_t tlb_lock; /* lock for tlb range flush */
Joerg Roedelb16c0172017-02-03 12:57:32 +010062
63 struct iommu_device iommu;
Yong Wucecdce92019-08-24 11:01:47 +080064 const struct mtk_iommu_plat_data *plat_data;
Yong Wu7c3a2ec2017-08-21 19:00:17 +080065
66 struct list_head list;
Yong Wu1ee9feb2019-08-24 11:02:08 +080067 struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
Honghui Zhang9ca340c2016-06-08 17:50:58 +080068};
69
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020070static inline int compare_of(struct device *dev, void *data)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080071{
72 return dev->of_node == data;
73}
74
Russell King00c7c812016-10-19 11:30:34 +010075static inline void release_of(struct device *dev, void *data)
76{
77 of_node_put(data);
78}
79
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020080static inline int mtk_iommu_bind(struct device *dev)
Honghui Zhang9ca340c2016-06-08 17:50:58 +080081{
82 struct mtk_iommu_data *data = dev_get_drvdata(dev);
83
Yong Wu1ee9feb2019-08-24 11:02:08 +080084 return component_bind_all(dev, &data->larb_imu);
Honghui Zhang9ca340c2016-06-08 17:50:58 +080085}
86
Joerg Roedel9a8a5dc2016-08-09 15:46:46 +020087static inline void mtk_iommu_unbind(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 component_unbind_all(dev, &data->larb_imu);
Honghui Zhang9ca340c2016-06-08 17:50:58 +080092}
93
94#endif