clk: mediatek: add set_clr_upd mux type flow

Add new set_clr_upd mux type and related operation to
mtk common clock driver to support mt8512
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 6c6b500..450de98 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -67,12 +67,23 @@
 		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 @@
 		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 @@
 		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 dce9325..7ea0042 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 @@
 	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 @@
 		.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;