blob: c64b428359a4c3f66c36aec0d127a3b38a522d2f [file] [log] [blame] [edit]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2016 MediaTek Inc.
* Author: Honghui Zhang <honghui.zhang@mediatek.com>
*/
#if (!IS_ENABLED(CONFIG_MTK_IOMMU_MT8XXX))
#ifndef _MTK_IOMMU_H_
#define _MTK_IOMMU_H_
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/io-pgtable.h>
#include <linux/iommu.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
#include <soc/mediatek/smi.h>
#include <dt-bindings/memory/mtk-memory-port.h>
#define MTK_LARB_COM_MAX 16
#define MTK_LARB_SUBCOM_MAX 4
#define MTK_IOMMU_GROUP_MAX MTK_M4U_DOM_NR_MAX
struct mtk_iommu_suspend_reg {
union {
u32 standard_axi_mode;/* v1 */
u32 misc_ctrl;/* v2 */
};
u32 dcm_dis;
u32 ctrl_reg;
u32 int_control0;
u32 int_main_control;
u32 ivrp_paddr;
u32 vld_pa_rng;
u32 wr_len_ctrl;
u32 tbw_id;
u32 mau_real_size;
u32 *mau;
};
enum mtk_iommu_plat {
M4U_MT2701,
M4U_MT2712,
M4U_MT6779,
M4U_MT6853,
M4U_MT6855,
M4U_MT6873,
M4U_MT6879,
M4U_MT6886,
M4U_MT6895,
M4U_MT6983,
M4U_MT6985,
M4U_MT8167,
M4U_MT6893,
M4U_MT8173,
M4U_MT8183,
M4U_MT8192,
};
enum mtk_iommu_type {
MM_IOMMU,
APU_IOMMU,
PERI_IOMMU,
TYPE_NUM
};
enum mm_iommu {
DISP_IOMMU,
MDP_IOMMU,
MM_IOMMU_NUM
};
enum apu_iommu {
APU_IOMMU0,
APU_IOMMU1,
APU_IOMMU_NUM
};
enum peri_iommu {
PERI_IOMMU_M4,
PERI_IOMMU_M6,
PERI_IOMMU_M7,
PERI_IOMMU_NUM
};
enum iommu_bank {
IOMMU_BK0, /* normal bank */
IOMMU_BK1, /* protected bank1 */
IOMMU_BK2, /* protected bank2 */
IOMMU_BK3, /* protected bank3 */
IOMMU_BK4, /* secure bank */
IOMMU_BK_NUM
};
enum iommu_tab_type {
NS_TAB,
PROT_TAB,
SEC_TAB,
TAB_TYPE_NUM
};
enum iommu_tab_id {
MM_TABLE,
APU_TABLE,
PERI_TABLE,
PGTBALE_NUM
};
struct mtk_iommu_iova_region;
struct mau_config_info {
unsigned int iommu_type;
unsigned int iommu_id;
unsigned int slave;
unsigned int mau;
unsigned int start;
unsigned int end;
unsigned int port_mask;
unsigned int larb_mask;
unsigned int wr; /* 0:read, 1:write for each MAU set */
unsigned int virt; /* 0: PA; 1: VA for each MAU set */
unsigned int io; /* 0:input, 1:output for each MAU set */
unsigned int start_bit32; /* bit34-32 of start address */
unsigned int end_bit32; /* bit34-32 of end address */
};
struct mtk_iommu_plat_data {
enum mtk_iommu_plat m4u_plat;
u32 flags;
u32 inv_sel_reg;
u32 tbw_reg_val;
u32 reg_val;
u32 normal_dom;
int iommu_id;
enum mtk_iommu_type iommu_type;
enum iommu_tab_id tab_id;
struct list_head *hw_list;
unsigned int iova_region_nr;
const struct mtk_iommu_iova_region *iova_region;
unsigned char larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
unsigned int mau_count;
};
struct mtk_iommu_domain;
struct mtk_iommu_data {
void __iomem *base;
int irq;
int bk_irq[IOMMU_BK_NUM];
struct device *dev;
struct device *bk_dev[IOMMU_BK_NUM];
struct clk *bclk;
phys_addr_t protect_base; /* protect memory base */
struct mtk_iommu_suspend_reg reg;
struct mtk_iommu_domain *m4u_dom;
struct iommu_group *m4u_group[MTK_IOMMU_GROUP_MAX];
bool enable_4GB;
spinlock_t tlb_lock; /* lock for tlb range flush */
struct iommu_device iommu;
const struct mtk_iommu_plat_data *plat_data;
struct device *smicomm_dev;
struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */
int isr_cnt;
unsigned long first_jiffies;
struct timer_list iommu_isr_pause_timer;
struct list_head *hw_list;
struct list_head hw_list_head;
struct list_head list;
struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
};
static inline int compare_of(struct device *dev, void *data)
{
return dev->of_node == data;
}
static inline void release_of(struct device *dev, void *data)
{
of_node_put(data);
}
static inline int mtk_iommu_bind(struct device *dev)
{
struct mtk_iommu_data *data = dev_get_drvdata(dev);
return component_bind_all(dev, &data->larb_imu);
}
static inline void mtk_iommu_unbind(struct device *dev)
{
struct mtk_iommu_data *data = dev_get_drvdata(dev);
component_unbind_all(dev, &data->larb_imu);
}
#if IS_ENABLED(CONFIG_DEVICE_MODULES_MTK_IOMMU)
int dev_is_normal_region(struct device *dev);
void mtk_iommu_dbg_hang_detect(enum mtk_iommu_type type, int id);
uint64_t mtee_iova_to_phys(unsigned long iova, u32 tab_id, u32 *sr_info,
u64 *pa, u32 *type, u32 *lvl);
#else
int dev_is_normal_region(struct device *dev)
{
return 0;
}
void mtk_iommu_dbg_hang_detect(enum mtk_iommu_type type, int id)
{
}
uint64_t mtee_iova_to_phys(unsigned long iova, u32 tab_id, u32 *sr_info,
u64 *pa, u32 *type, u32 *lvl)
{
return 0;
}
#endif
#endif /* _MTK_IOMMU_H_ */
#else /* CONFIG_MTK_IOMMU_MT8XXX */
#include "mtk_iommu_mt8xxx.h"
#ifndef _MTK_IOMMU_MT_H_
#define _MTK_IOMMU_MT_H_
/* fake defination */
enum mtk_iommu_type {
TYPE_NUM,
};
enum mm_iommu {
MM_IOMMU_NUM,
};
enum apu_iommu {
APU_IOMMU_NUM,
};
enum peri_iommu {
PERI_IOMMU_NUM,
};
#endif
#endif /* CONFIG_MTK_IOMMU_MT8XXX */