xref: /openbmc/linux/drivers/clk/mediatek/clk-pll.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1  /* SPDX-License-Identifier: GPL-2.0-only */
2  /*
3   * Copyright (c) 2014 MediaTek Inc.
4   * Author: James Liao <jamesjj.liao@mediatek.com>
5   */
6  
7  #ifndef __DRV_CLK_MTK_PLL_H
8  #define __DRV_CLK_MTK_PLL_H
9  
10  #include <linux/clk-provider.h>
11  #include <linux/types.h>
12  
13  struct clk_ops;
14  struct clk_hw_onecell_data;
15  struct device_node;
16  
17  struct mtk_pll_div_table {
18  	u32 div;
19  	unsigned long freq;
20  };
21  
22  #define HAVE_RST_BAR	BIT(0)
23  #define PLL_AO		BIT(1)
24  #define POSTDIV_MASK	GENMASK(2, 0)
25  
26  struct mtk_pll_data {
27  	int id;
28  	const char *name;
29  	u32 reg;
30  	u32 pwr_reg;
31  	u32 en_mask;
32  	u32 pd_reg;
33  	u32 tuner_reg;
34  	u32 tuner_en_reg;
35  	u8 tuner_en_bit;
36  	int pd_shift;
37  	unsigned int flags;
38  	const struct clk_ops *ops;
39  	u32 rst_bar_mask;
40  	unsigned long fmin;
41  	unsigned long fmax;
42  	int pcwbits;
43  	int pcwibits;
44  	u32 pcw_reg;
45  	int pcw_shift;
46  	u32 pcw_chg_reg;
47  	const struct mtk_pll_div_table *div_table;
48  	const char *parent_name;
49  	u32 en_reg;
50  	u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
51  };
52  
53  /*
54   * MediaTek PLLs are configured through their pcw value. The pcw value describes
55   * a divider in the PLL feedback loop which consists of 7 bits for the integer
56   * part and the remaining bits (if present) for the fractional part. Also they
57   * have a 3 bit power-of-two post divider.
58   */
59  
60  struct mtk_clk_pll {
61  	struct clk_hw	hw;
62  	void __iomem	*base_addr;
63  	void __iomem	*pd_addr;
64  	void __iomem	*pwr_addr;
65  	void __iomem	*tuner_addr;
66  	void __iomem	*tuner_en_addr;
67  	void __iomem	*pcw_addr;
68  	void __iomem	*pcw_chg_addr;
69  	void __iomem	*en_addr;
70  	const struct mtk_pll_data *data;
71  };
72  
73  int mtk_clk_register_plls(struct device_node *node,
74  			  const struct mtk_pll_data *plls, int num_plls,
75  			  struct clk_hw_onecell_data *clk_data);
76  void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
77  			     struct clk_hw_onecell_data *clk_data);
78  
79  extern const struct clk_ops mtk_pll_ops;
80  
to_mtk_clk_pll(struct clk_hw * hw)81  static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
82  {
83  	return container_of(hw, struct mtk_clk_pll, hw);
84  }
85  
86  int mtk_pll_is_prepared(struct clk_hw *hw);
87  
88  int mtk_pll_prepare(struct clk_hw *hw);
89  
90  void mtk_pll_unprepare(struct clk_hw *hw);
91  
92  unsigned long mtk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate);
93  
94  void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
95  			 u32 freq, u32 fin);
96  int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
97  		     unsigned long parent_rate);
98  long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
99  			unsigned long *prate);
100  
101  struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
102  					const struct mtk_pll_data *data,
103  					void __iomem *base,
104  					const struct clk_ops *pll_ops);
105  struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data,
106  				    void __iomem *base);
107  void mtk_clk_unregister_pll(struct clk_hw *hw);
108  
109  __iomem void *mtk_clk_pll_get_base(struct clk_hw *hw,
110  				   const struct mtk_pll_data *data);
111  
112  #endif /* __DRV_CLK_MTK_PLL_H */
113