summaryrefslogtreecommitdiff
path: root/drivers/clk/mediatek/clk-pll.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/mediatek/clk-pll.h')
-rw-r--r--drivers/clk/mediatek/clk-pll.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
index fe3199715688..f17278ff15d7 100644
--- a/drivers/clk/mediatek/clk-pll.h
+++ b/drivers/clk/mediatek/clk-pll.h
@@ -7,6 +7,7 @@
#ifndef __DRV_CLK_MTK_PLL_H
#define __DRV_CLK_MTK_PLL_H
+#include <linux/clk-provider.h>
#include <linux/types.h>
struct clk_ops;
@@ -20,6 +21,7 @@ struct mtk_pll_div_table {
#define HAVE_RST_BAR BIT(0)
#define PLL_AO BIT(1)
+#define POSTDIV_MASK GENMASK(2, 0)
struct mtk_pll_data {
int id;
@@ -48,10 +50,63 @@ struct mtk_pll_data {
u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
};
+/*
+ * MediaTek PLLs are configured through their pcw value. The pcw value describes
+ * a divider in the PLL feedback loop which consists of 7 bits for the integer
+ * part and the remaining bits (if present) for the fractional part. Also they
+ * have a 3 bit power-of-two post divider.
+ */
+
+struct mtk_clk_pll {
+ struct clk_hw hw;
+ void __iomem *base_addr;
+ void __iomem *pd_addr;
+ void __iomem *pwr_addr;
+ void __iomem *tuner_addr;
+ void __iomem *tuner_en_addr;
+ void __iomem *pcw_addr;
+ void __iomem *pcw_chg_addr;
+ void __iomem *en_addr;
+ const struct mtk_pll_data *data;
+};
+
int mtk_clk_register_plls(struct device_node *node,
const struct mtk_pll_data *plls, int num_plls,
struct clk_hw_onecell_data *clk_data);
void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
struct clk_hw_onecell_data *clk_data);
+extern const struct clk_ops mtk_pll_ops;
+
+static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
+{
+ return container_of(hw, struct mtk_clk_pll, hw);
+}
+
+int mtk_pll_is_prepared(struct clk_hw *hw);
+
+int mtk_pll_prepare(struct clk_hw *hw);
+
+void mtk_pll_unprepare(struct clk_hw *hw);
+
+unsigned long mtk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate);
+
+void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
+ u32 freq, u32 fin);
+int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate);
+long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate);
+
+struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
+ const struct mtk_pll_data *data,
+ void __iomem *base,
+ const struct clk_ops *pll_ops);
+struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data,
+ void __iomem *base);
+void mtk_clk_unregister_pll(struct clk_hw *hw);
+
+__iomem void *mtk_clk_pll_get_base(struct clk_hw *hw,
+ const struct mtk_pll_data *data);
+
#endif /* __DRV_CLK_MTK_PLL_H */