3
3
* Copyright (c) 2015-2016 MediaTek Inc.
4
4
* Author: Yong Wu <[email protected] >
5
5
*/
6
+ #include <linux/arm-smccc.h>
6
7
#include <linux/bitfield.h>
7
8
#include <linux/bug.h>
8
9
#include <linux/clk.h>
27
28
#include <linux/slab.h>
28
29
#include <linux/spinlock.h>
29
30
#include <linux/soc/mediatek/infracfg.h>
31
+ #include <linux/soc/mediatek/mtk_sip_svc.h>
30
32
#include <asm/barrier.h>
31
33
#include <soc/mediatek/smi.h>
32
34
143
145
#define PGTABLE_PA_35_EN BIT(17)
144
146
#define TF_PORT_TO_ADDR_MT8173 BIT(18)
145
147
#define INT_ID_PORT_WIDTH_6 BIT(19)
148
+ #define CFG_IFA_MASTER_IN_ATF BIT(20)
146
149
147
150
#define MTK_IOMMU_HAS_FLAG_MASK (pdata , _x , mask ) \
148
151
((((pdata)->flags) & (mask)) == (_x))
@@ -580,6 +583,7 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
580
583
struct iommu_fwspec * fwspec = dev_iommu_fwspec_get (dev );
581
584
const struct mtk_iommu_iova_region * region ;
582
585
unsigned long portid_msk = 0 ;
586
+ struct arm_smccc_res res ;
583
587
int i , ret = 0 ;
584
588
585
589
for (i = 0 ; i < fwspec -> num_ids ; ++ i ) {
@@ -605,17 +609,24 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
605
609
else
606
610
larb_mmu -> mmu &= ~portid_msk ;
607
611
} else if (MTK_IOMMU_IS_TYPE (data -> plat_data , MTK_IOMMU_TYPE_INFRA )) {
608
- /* PCI dev has only one output id, enable the next writing bit for PCIe */
609
- if (dev_is_pci (dev )) {
610
- if (fwspec -> num_ids != 1 ) {
611
- dev_err (dev , "PCI dev can only have one port.\n" );
612
- return - ENODEV ;
612
+ if (MTK_IOMMU_HAS_FLAG (data -> plat_data , CFG_IFA_MASTER_IN_ATF )) {
613
+ arm_smccc_smc (MTK_SIP_KERNEL_IOMMU_CONTROL ,
614
+ IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU ,
615
+ portid_msk , enable , 0 , 0 , 0 , 0 , & res );
616
+ ret = res .a0 ;
617
+ } else {
618
+ /* PCI dev has only one output id, enable the next writing bit for PCIe */
619
+ if (dev_is_pci (dev )) {
620
+ if (fwspec -> num_ids != 1 ) {
621
+ dev_err (dev , "PCI dev can only have one port.\n" );
622
+ return - ENODEV ;
623
+ }
624
+ portid_msk |= BIT (portid + 1 );
613
625
}
614
- portid_msk |= BIT (portid + 1 );
615
- }
616
626
617
- ret = regmap_update_bits (data -> pericfg , PERICFG_IOMMU_1 ,
618
- (u32 )portid_msk , enable ? (u32 )portid_msk : 0 );
627
+ ret = regmap_update_bits (data -> pericfg , PERICFG_IOMMU_1 ,
628
+ (u32 )portid_msk , enable ? (u32 )portid_msk : 0 );
629
+ }
619
630
if (ret )
620
631
dev_err (dev , "%s iommu(%s) inframaster 0x%lx fail(%d).\n" ,
621
632
enable ? "enable" : "disable" ,
@@ -1330,7 +1341,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
1330
1341
dev_err_probe (dev , ret , "mm dts parse fail\n" );
1331
1342
goto out_runtime_disable ;
1332
1343
}
1333
- } else if (MTK_IOMMU_IS_TYPE (data -> plat_data , MTK_IOMMU_TYPE_INFRA )) {
1344
+ } else if (MTK_IOMMU_IS_TYPE (data -> plat_data , MTK_IOMMU_TYPE_INFRA ) &&
1345
+ !MTK_IOMMU_HAS_FLAG (data -> plat_data , CFG_IFA_MASTER_IN_ATF )) {
1334
1346
p = data -> plat_data -> pericfg_comp_str ;
1335
1347
data -> pericfg = syscon_regmap_lookup_by_compatible (p );
1336
1348
if (IS_ERR (data -> pericfg )) {
0 commit comments