1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Zynq PLL driver
4 *
5 * Copyright (C) 2013 Xilinx
6 *
7 * Sören Brinkmann <soren.brinkmann@xilinx.com>
8 */
9 #include <linux/clk/zynq.h>
10 #include <linux/clk-provider.h>
11 #include <linux/slab.h>
12 #include <linux/io.h>
13
14 /**
15 * struct zynq_pll - pll clock
16 * @hw: Handle between common and hardware-specific interfaces
17 * @pll_ctrl: PLL control register
18 * @pll_status: PLL status register
19 * @lock: Register lock
20 * @lockbit: Indicates the associated PLL_LOCKED bit in the PLL status
21 * register.
22 */
23 struct zynq_pll {
24 struct clk_hw hw;
25 void __iomem *pll_ctrl;
26 void __iomem *pll_status;
27 spinlock_t *lock;
28 u8 lockbit;
29 };
30 #define to_zynq_pll(_hw) container_of(_hw, struct zynq_pll, hw)
31
32 /* Register bitfield defines */
33 #define PLLCTRL_FBDIV_MASK 0x7f000
34 #define PLLCTRL_FBDIV_SHIFT 12
35 #define PLLCTRL_BPQUAL_MASK (1 << 3)
36 #define PLLCTRL_PWRDWN_MASK 2
37 #define PLLCTRL_PWRDWN_SHIFT 1
38 #define PLLCTRL_RESET_MASK 1
39 #define PLLCTRL_RESET_SHIFT 0
40
41 #define PLL_FBDIV_MIN 13
42 #define PLL_FBDIV_MAX 66
43
44 /**
45 * zynq_pll_round_rate() - Round a clock frequency
46 * @hw: Handle between common and hardware-specific interfaces
47 * @rate: Desired clock frequency
48 * @prate: Clock frequency of parent clock
49 * Return: frequency closest to @rate the hardware can generate.
50 */
zynq_pll_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)51 static int zynq_pll_determine_rate(struct clk_hw *hw,
52 struct clk_rate_request *req)
53 {
54 u32 fbdiv;
55
56 fbdiv = DIV_ROUND_CLOSEST(req->rate, req->best_parent_rate);
57 if (fbdiv < PLL_FBDIV_MIN)
58 fbdiv = PLL_FBDIV_MIN;
59 else if (fbdiv > PLL_FBDIV_MAX)
60 fbdiv = PLL_FBDIV_MAX;
61
62 req->rate = req->best_parent_rate * fbdiv;
63
64 return 0;
65 }
66
67 /**
68 * zynq_pll_recalc_rate() - Recalculate clock frequency
69 * @hw: Handle between common and hardware-specific interfaces
70 * @parent_rate: Clock frequency of parent clock
71 * Return: current clock frequency.
72 */
zynq_pll_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)73 static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
75 {
76 struct zynq_pll *clk = to_zynq_pll(hw);
77 u32 fbdiv;
78
79 /*
80 * makes probably sense to redundantly save fbdiv in the struct
81 * zynq_pll to save the IO access.
82 */
83 fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
84 PLLCTRL_FBDIV_SHIFT;
85
86 return parent_rate * fbdiv;
87 }
88
89 /**
90 * zynq_pll_is_enabled - Check if a clock is enabled
91 * @hw: Handle between common and hardware-specific interfaces
92 * Return: 1 if the clock is enabled, 0 otherwise.
93 *
94 * Not sure this is a good idea, but since disabled means bypassed for
95 * this clock implementation we say we are always enabled.
96 */
zynq_pll_is_enabled(struct clk_hw * hw)97 static int zynq_pll_is_enabled(struct clk_hw *hw)
98 {
99 unsigned long flags = 0;
100 u32 reg;
101 struct zynq_pll *clk = to_zynq_pll(hw);
102
103 spin_lock_irqsave(clk->lock, flags);
104
105 reg = readl(clk->pll_ctrl);
106
107 spin_unlock_irqrestore(clk->lock, flags);
108
109 return !(reg & (PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK));
110 }
111
112 /**
113 * zynq_pll_enable - Enable clock
114 * @hw: Handle between common and hardware-specific interfaces
115 * Return: 0 on success
116 */
zynq_pll_enable(struct clk_hw * hw)117 static int zynq_pll_enable(struct clk_hw *hw)
118 {
119 unsigned long flags = 0;
120 u32 reg;
121 struct zynq_pll *clk = to_zynq_pll(hw);
122
123 if (zynq_pll_is_enabled(hw))
124 return 0;
125
126 pr_info("PLL: enable\n");
127
128 /* Power up PLL and wait for lock */
129 spin_lock_irqsave(clk->lock, flags);
130
131 reg = readl(clk->pll_ctrl);
132 reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
133 writel(reg, clk->pll_ctrl);
134 while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
135 ;
136
137 spin_unlock_irqrestore(clk->lock, flags);
138
139 return 0;
140 }
141
142 /**
143 * zynq_pll_disable - Disable clock
144 * @hw: Handle between common and hardware-specific interfaces
145 * Returns 0 on success
146 */
zynq_pll_disable(struct clk_hw * hw)147 static void zynq_pll_disable(struct clk_hw *hw)
148 {
149 unsigned long flags = 0;
150 u32 reg;
151 struct zynq_pll *clk = to_zynq_pll(hw);
152
153 if (!zynq_pll_is_enabled(hw))
154 return;
155
156 pr_info("PLL: shutdown\n");
157
158 /* shut down PLL */
159 spin_lock_irqsave(clk->lock, flags);
160
161 reg = readl(clk->pll_ctrl);
162 reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK;
163 writel(reg, clk->pll_ctrl);
164
165 spin_unlock_irqrestore(clk->lock, flags);
166 }
167
168 static const struct clk_ops zynq_pll_ops = {
169 .enable = zynq_pll_enable,
170 .disable = zynq_pll_disable,
171 .is_enabled = zynq_pll_is_enabled,
172 .determine_rate = zynq_pll_determine_rate,
173 .recalc_rate = zynq_pll_recalc_rate
174 };
175
176 /**
177 * clk_register_zynq_pll() - Register PLL with the clock framework
178 * @name: PLL name
179 * @parent: Parent clock name
180 * @pll_ctrl: Pointer to PLL control register
181 * @pll_status: Pointer to PLL status register
182 * @lock_index: Bit index to this PLL's lock status bit in @pll_status
183 * @lock: Register lock
184 * Return: handle to the registered clock.
185 */
clk_register_zynq_pll(const char * name,const char * parent,void __iomem * pll_ctrl,void __iomem * pll_status,u8 lock_index,spinlock_t * lock)186 struct clk *clk_register_zynq_pll(const char *name, const char *parent,
187 void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
188 spinlock_t *lock)
189 {
190 struct zynq_pll *pll;
191 struct clk *clk;
192 u32 reg;
193 const char *parent_arr[1] = {parent};
194 unsigned long flags = 0;
195 struct clk_init_data initd = {
196 .name = name,
197 .parent_names = parent_arr,
198 .ops = &zynq_pll_ops,
199 .num_parents = 1,
200 .flags = 0
201 };
202
203 pll = kmalloc(sizeof(*pll), GFP_KERNEL);
204 if (!pll)
205 return ERR_PTR(-ENOMEM);
206
207 /* Populate the struct */
208 pll->hw.init = &initd;
209 pll->pll_ctrl = pll_ctrl;
210 pll->pll_status = pll_status;
211 pll->lockbit = lock_index;
212 pll->lock = lock;
213
214 spin_lock_irqsave(pll->lock, flags);
215
216 reg = readl(pll->pll_ctrl);
217 reg &= ~PLLCTRL_BPQUAL_MASK;
218 writel(reg, pll->pll_ctrl);
219
220 spin_unlock_irqrestore(pll->lock, flags);
221
222 clk = clk_register(NULL, &pll->hw);
223 if (WARN_ON(IS_ERR(clk)))
224 goto free_pll;
225
226 return clk;
227
228 free_pll:
229 kfree(pll);
230
231 return clk;
232 }
233