Each bank has some independent registers. thus backup/restore them for
each a bank when suspend and resume.

Signed-off-by: Yong Wu <yong...@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno 
<angelogioacchino.delre...@collabora.com>
---
 drivers/iommu/mtk_iommu.c | 46 ++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 400dea33aea1..d3e8773b4c47 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -173,11 +173,12 @@ struct mtk_iommu_suspend_reg {
        u32                     misc_ctrl;
        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                     int_control[MTK_IOMMU_BANK_MAX];
+       u32                     int_main_control[MTK_IOMMU_BANK_MAX];
+       u32                     ivrp_paddr[MTK_IOMMU_BANK_MAX];
 };
 
 struct mtk_iommu_plat_data {
@@ -1302,16 +1303,23 @@ static int __maybe_unused 
mtk_iommu_runtime_suspend(struct device *dev)
 {
        struct mtk_iommu_data *data = dev_get_drvdata(dev);
        struct mtk_iommu_suspend_reg *reg = &data->reg;
-       void __iomem *base = data->bank[0].base;
+       void __iomem *base;
+       int i = 0;
 
+       base = data->bank[i].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);
-       reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0);
-       reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
-       reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR);
        reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG);
+       do {
+               if (!data->plat_data->banks_enable[i])
+                       continue;
+               base = data->bank[i].base;
+               reg->int_control[i] = readl_relaxed(base + 
REG_MMU_INT_CONTROL0);
+               reg->int_main_control[i] = readl_relaxed(base + 
REG_MMU_INT_MAIN_CONTROL);
+               reg->ivrp_paddr[i] = readl_relaxed(base + REG_MMU_IVRP_PADDR);
+       } while (++i < data->plat_data->banks_num);
        clk_disable_unprepare(data->bclk);
        return 0;
 }
@@ -1320,9 +1328,9 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct 
device *dev)
 {
        struct mtk_iommu_data *data = dev_get_drvdata(dev);
        struct mtk_iommu_suspend_reg *reg = &data->reg;
-       struct mtk_iommu_domain *m4u_dom = data->bank[0].m4u_dom;
-       void __iomem *base = data->bank[0].base;
-       int ret;
+       struct mtk_iommu_domain *m4u_dom;
+       void __iomem *base;
+       int ret, i = 0;
 
        ret = clk_prepare_enable(data->bclk);
        if (ret) {
@@ -1334,18 +1342,26 @@ static int __maybe_unused 
mtk_iommu_runtime_resume(struct device *dev)
         * Uppon first resume, only enable the clk and return, since the values 
of the
         * registers are not yet set.
         */
-       if (!m4u_dom)
+       if (!reg->wr_len_ctrl)
                return 0;
 
+       base = data->bank[i].base;
        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);
-       writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
-       writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
-       writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
        writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG);
-       writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, base + 
REG_MMU_PT_BASE_ADDR);
+       do {
+               m4u_dom = data->bank[i].m4u_dom;
+               if (!data->plat_data->banks_enable[i] || !m4u_dom)
+                       continue;
+               base = data->bank[i].base;
+               writel_relaxed(reg->int_control[i], base + 
REG_MMU_INT_CONTROL0);
+               writel_relaxed(reg->int_main_control[i], base + 
REG_MMU_INT_MAIN_CONTROL);
+               writel_relaxed(reg->ivrp_paddr[i], base + REG_MMU_IVRP_PADDR);
+               writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
+                      base + REG_MMU_PT_BASE_ADDR);
+       } while (++i < data->plat_data->banks_num);
 
        /*
         * Users may allocate dma buffer before they call pm_runtime_get,
-- 
2.18.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to