xref: /linux/drivers/clk/zynq/pll.c (revision 522ba450b56fff29f868b1552bdc2965f55de7ed)
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