[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250307032942.10447-3-guangjie.song@mediatek.com>
Date: Fri, 7 Mar 2025 11:26:58 +0800
From: Guangjie Song <guangjie.song@...iatek.com>
To: Michael Turquette <mturquette@...libre.com>, Stephen Boyd
<sboyd@...nel.org>, Rob Herring <robh@...nel.org>, Krzysztof Kozlowski
<krzk+dt@...nel.org>, Conor Dooley <conor+dt@...nel.org>, Matthias Brugger
<matthias.bgg@...il.com>, AngeloGioacchino Del Regno
<angelogioacchino.delregno@...labora.com>, Richard Cochran
<richardcochran@...il.com>
CC: <linux-clk@...r.kernel.org>, <devicetree@...r.kernel.org>,
<linux-kernel@...r.kernel.org>, <linux-arm-kernel@...ts.infradead.org>,
<linux-mediatek@...ts.infradead.org>, <netdev@...r.kernel.org>, Guangjie Song
<guangjie.song@...iatek.com>,
<Project_Global_Chrome_Upstream_Group@...iatek.com>
Subject: [PATCH 02/26] clk: mediatek: Support voting for pll
Add data fields and ops to support voting for pll.
Signed-off-by: Guangjie Song <guangjie.song@...iatek.com>
---
drivers/clk/mediatek/clk-pll.c | 51 +++++++++++++++++++++++++++++++++-
drivers/clk/mediatek/clk-pll.h | 5 ++++
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index ce453e1718e5..fdaa4ee74608 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -13,6 +13,7 @@
#include <linux/of_address.h>
#include <linux/slab.h>
+#include "clk-mtk.h"
#include "clk-pll.h"
#define MHZ (1000 * 1000)
@@ -37,6 +38,13 @@ int mtk_pll_is_prepared(struct clk_hw *hw)
return (readl(pll->en_addr) & BIT(pll->data->pll_en_bit)) != 0;
}
+static int mtk_pll_fenc_is_prepared(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+
+ return (((readl(pll->fenc_addr) & pll->fenc_mask) != 0) || (pll->onoff_cnt != 0));
+}
+
static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
u32 pcw, int postdiv)
{
@@ -274,6 +282,30 @@ void mtk_pll_unprepare(struct clk_hw *hw)
writel(r, pll->pwr_addr);
}
+static int mtk_pll_fenc_prepare(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+
+ if (pll->onoff_cnt == 1) {
+ pr_err("%s: %s is already prepared\n", __func__, clk_hw_get_name(hw));
+ return -EPERM;
+ }
+
+ pll->onoff_cnt = 1;
+
+ return 0;
+}
+
+static void mtk_pll_fenc_unprepare(struct clk_hw *hw)
+{
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+
+ if (pll->onoff_cnt == 0)
+ pr_err("%s: %s is not prepared\n", __func__, clk_hw_get_name(hw));
+ else
+ pll->onoff_cnt = 0;
+}
+
const struct clk_ops mtk_pll_ops = {
.is_prepared = mtk_pll_is_prepared,
.prepare = mtk_pll_prepare,
@@ -283,6 +315,15 @@ const struct clk_ops mtk_pll_ops = {
.set_rate = mtk_pll_set_rate,
};
+static const struct clk_ops mtk_pll_fenc_ops = {
+ .is_prepared = mtk_pll_fenc_is_prepared,
+ .prepare = mtk_pll_fenc_prepare,
+ .unprepare = mtk_pll_fenc_unprepare,
+ .recalc_rate = mtk_pll_recalc_rate,
+ .round_rate = mtk_pll_round_rate,
+ .set_rate = mtk_pll_set_rate,
+};
+
struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
const struct mtk_pll_data *data,
void __iomem *base,
@@ -313,6 +354,11 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
init.name = data->name;
init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0;
+ if (data->flags & CLK_FENC_ENABLE) {
+ pll->fenc_addr = base + data->fenc_sta_ofs;
+ pll->fenc_mask = BIT(data->fenc_sta_bit);
+ }
+
init.ops = pll_ops;
if (data->parent_name)
init.parent_names = &data->parent_name;
@@ -338,7 +384,10 @@ struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data,
if (!pll)
return ERR_PTR(-ENOMEM);
- hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_ops);
+ if (data->flags & CLK_FENC_ENABLE)
+ hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_fenc_ops);
+ else
+ hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_ops);
if (IS_ERR(hw))
kfree(pll);
diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
index 285c8db958b3..3a1e48006e34 100644
--- a/drivers/clk/mediatek/clk-pll.h
+++ b/drivers/clk/mediatek/clk-pll.h
@@ -29,6 +29,7 @@ struct mtk_pll_data {
u32 reg;
u32 pwr_reg;
u32 en_mask;
+ u32 fenc_sta_ofs;
u32 pd_reg;
u32 tuner_reg;
u32 tuner_en_reg;
@@ -49,6 +50,7 @@ struct mtk_pll_data {
u32 en_reg;
u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
u8 pcw_chg_bit;
+ u8 fenc_sta_bit;
};
/*
@@ -69,6 +71,9 @@ struct mtk_clk_pll {
void __iomem *pcw_chg_addr;
void __iomem *en_addr;
const struct mtk_pll_data *data;
+ void __iomem *fenc_addr;
+ u32 fenc_mask;
+ u32 onoff_cnt;
};
int mtk_clk_register_plls(struct device_node *node,
--
2.45.2
Powered by blists - more mailing lists