Add new set_clr_upd mux type and related operation to
mtk common clock driver to support mt8512
---
 drivers/clk/mediatek/clk-mtk.c | 43 +++++++++++++++++++++++++---------
 drivers/clk/mediatek/clk-mtk.h | 23 ++++++++++++++++++
 2 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 6c6b500d9b..450de981e9 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -67,12 +67,23 @@ static int mtk_clk_mux_set_parent(void __iomem *base, u32 
parent,
                if (++index == mux->num_parents)
                        return -EINVAL;
 
-       /* switch mux to a select parent */
-       val = readl(base + mux->mux_reg);
-       val &= ~(mux->mux_mask << mux->mux_shift);
+       if (mux->flags & CLK_MUX_SETCLR_UPD) {
+               val = (mux->mux_mask << mux->mux_shift);
+               writel(val, base + mux->mux_clr_reg);
 
-       val |= index << mux->mux_shift;
-       writel(val, base + mux->mux_reg);
+               val = (index << mux->mux_shift);
+               writel(val, base + mux->mux_set_reg);
+
+               if (mux->upd_shift >= 0)
+                       writel(BIT(mux->upd_shift), base + mux->upd_reg);
+       } else {
+               /* switch mux to a select parent */
+               val = readl(base + mux->mux_reg);
+               val &= ~(mux->mux_mask << mux->mux_shift);
+
+               val |= index << mux->mux_shift;
+               writel(val, base + mux->mux_reg);
+       }
 
        return 0;
 }
@@ -332,9 +343,14 @@ static int mtk_topckgen_enable(struct clk *clk)
                return 0;
 
        /* enable clock gate */
-       val = readl(priv->base + mux->gate_reg);
-       val &= ~BIT(mux->gate_shift);
-       writel(val, priv->base + mux->gate_reg);
+       if (mux->flags & CLK_MUX_SETCLR_UPD) {
+               val = BIT(mux->gate_shift);
+               writel(val, priv->base + mux->mux_clr_reg);
+       } else {
+               val = readl(priv->base + mux->gate_reg);
+               val &= ~BIT(mux->gate_shift);
+               writel(val, priv->base + mux->gate_reg);
+       }
 
        if (mux->flags & CLK_DOMAIN_SCPSYS) {
                /* enable scpsys clock off control */
@@ -360,9 +376,14 @@ static int mtk_topckgen_disable(struct clk *clk)
                return 0;
 
        /* disable clock gate */
-       val = readl(priv->base + mux->gate_reg);
-       val |= BIT(mux->gate_shift);
-       writel(val, priv->base + mux->gate_reg);
+       if (mux->flags & CLK_MUX_SETCLR_UPD) {
+               val = BIT(mux->gate_shift);
+               writel(val, priv->base + mux->mux_set_reg);
+       } else {
+               val = readl(priv->base + mux->gate_reg);
+               val |= BIT(mux->gate_shift);
+               writel(val, priv->base + mux->gate_reg);
+       }
 
        return 0;
 }
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index dce93253ad..7ea0042500 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -12,6 +12,7 @@
 
 #define HAVE_RST_BAR                   BIT(0)
 #define CLK_DOMAIN_SCPSYS              BIT(0)
+#define CLK_MUX_SETCLR_UPD             BIT(1)
 
 #define CLK_GATE_SETCLR                        BIT(0)
 #define CLK_GATE_SETCLR_INV            BIT(1)
@@ -102,9 +103,13 @@ struct mtk_composite {
        const int id;
        const int *parent;
        u32 mux_reg;
+       u32 mux_set_reg;
+       u32 mux_clr_reg;
+       u32 upd_reg;
        u32 gate_reg;
        u32 mux_mask;
        signed char mux_shift;
+       signed char upd_shift;
        signed char gate_shift;
        signed char num_parents;
        u16 flags;
@@ -137,6 +142,24 @@ struct mtk_composite {
                .flags = 0,                                             \
        }
 
+#define MUX_CLR_SET_UPD_FLAGS(_id, _parents, _mux_ofs, _mux_set_ofs,\
+                       _mux_clr_ofs, _shift, _width, _gate,            \
+                       _upd_ofs, _upd, _flags) {                       \
+               .id = _id,                                              \
+               .mux_reg = _mux_ofs,                                    \
+               .mux_set_reg = _mux_set_ofs,                    \
+               .mux_clr_reg = _mux_clr_ofs,                    \
+               .upd_reg = _upd_ofs,                                    \
+               .upd_shift = _upd,                                      \
+               .mux_shift = _shift,                                    \
+               .mux_mask = BIT(_width) - 1,                            \
+               .gate_reg = _mux_ofs,                                   \
+               .gate_shift = _gate,                                    \
+               .parent = _parents,                                     \
+               .num_parents = ARRAY_SIZE(_parents),                    \
+               .flags = _flags,                                        \
+       }
+
 struct mtk_gate_regs {
        u32 sta_ofs;
        u32 clr_ofs;
-- 
2.24.1

Reply via email to