]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iommu/mediatek: Add REG_MMU_WR_LEN_CTRL register definition
authorChao Hao <chao.hao@mediatek.com>
Fri, 3 Jul 2020 04:41:24 +0000 (12:41 +0800)
committerJoerg Roedel <jroedel@suse.de>
Fri, 10 Jul 2020 14:13:11 +0000 (16:13 +0200)
Some platforms(ex: mt6779) need to improve performance by setting
REG_MMU_WR_LEN_CTRL register. And we can use WR_THROT_EN macro to control
whether we need to set the register. If the register uses default value,
iommu will send command to EMI without restriction, when the number of
commands become more and more, it will drop the EMI performance. So when
more than ten_commands(default value) don't be handled for EMI, iommu will
stop send command to EMI for keeping EMI's performace by enabling write
throttling mechanism(bit[5][21]=0) in MMU_WR_LEN_CTRL register.

Signed-off-by: Chao Hao <chao.hao@mediatek.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Link: https://lore.kernel.org/r/20200703044127.27438-8-chao.hao@mediatek.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/mtk_iommu.c
drivers/iommu/mtk_iommu.h

index 0d96dcd8612bb32815411c51cfa27764769c267c..5c8e141668fcfc02329ff46f160e906fc5420ec1 100644 (file)
@@ -46,6 +46,8 @@
 #define F_MMU_STANDARD_AXI_MODE_MASK           (BIT(3) | BIT(19))
 
 #define REG_MMU_DCM_DIS                                0x050
+#define REG_MMU_WR_LEN_CTRL                    0x054
+#define F_MMU_WR_THROT_DIS_MASK                        (BIT(5) | BIT(21))
 
 #define REG_MMU_CTRL_REG                       0x110
 #define F_MMU_TF_PROT_TO_PROGRAM_ADDR          (2 << 4)
 #define RESET_AXI                      BIT(3)
 #define OUT_ORDER_WR_EN                        BIT(4)
 #define HAS_SUB_COMM                   BIT(5)
+#define WR_THROT_EN                    BIT(6)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
                ((((pdata)->flags) & (_x)) == (_x))
@@ -593,6 +596,12 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
                writel_relaxed(regval, data->base + REG_MMU_VLD_PA_RNG);
        }
        writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
+       if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) {
+               /* write command throttling mode */
+               regval = readl_relaxed(data->base + REG_MMU_WR_LEN_CTRL);
+               regval &= ~F_MMU_WR_THROT_DIS_MASK;
+               writel_relaxed(regval, data->base + REG_MMU_WR_LEN_CTRL);
+       }
 
        if (MTK_IOMMU_HAS_FLAG(data->plat_data, RESET_AXI)) {
                /* The register is called STANDARD_AXI_MODE in this case */
@@ -747,6 +756,7 @@ static int __maybe_unused mtk_iommu_suspend(struct device *dev)
        struct mtk_iommu_suspend_reg *reg = &data->reg;
        void __iomem *base = data->base;
 
+       reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL);
        reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL);
        reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM_DIS);
        reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG);
@@ -771,6 +781,7 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
                dev_err(data->dev, "Failed to enable clk(%d) in resume\n", ret);
                return ret;
        }
+       writel_relaxed(reg->wr_len_ctrl, base + REG_MMU_WR_LEN_CTRL);
        writel_relaxed(reg->misc_ctrl, base + REG_MMU_MISC_CTRL);
        writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS);
        writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG);
index 46d0d47b22e10062249cc3089d456900c27404d4..31edd05e2eb146f2e49a5469063064904612704d 100644 (file)
@@ -31,6 +31,7 @@ struct mtk_iommu_suspend_reg {
        u32                             int_main_control;
        u32                             ivrp_paddr;
        u32                             vld_pa_rng;
+       u32                             wr_len_ctrl;
 };
 
 enum mtk_iommu_plat {