1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2019 DENX Software Engineering
4  * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
5  */
6 
7 #include <common.h>
8 #include <asm/io.h>
9 #include <div64.h>
10 #include <malloc.h>
11 #include <clk-uclass.h>
12 #include <dm/device.h>
13 #include <dm/devres.h>
14 #include <dm/uclass.h>
15 #include <clk.h>
16 #include "clk.h"
17 #include <linux/err.h>
18 
19 #define UBOOT_DM_CLK_IMX_PLLV3_GENERIC	"imx_clk_pllv3_generic"
20 #define UBOOT_DM_CLK_IMX_PLLV3_SYS	"imx_clk_pllv3_sys"
21 #define UBOOT_DM_CLK_IMX_PLLV3_USB	"imx_clk_pllv3_usb"
22 #define UBOOT_DM_CLK_IMX_PLLV3_AV	"imx_clk_pllv3_av"
23 #define UBOOT_DM_CLK_IMX_PLLV3_ENET     "imx_clk_pllv3_enet"
24 #define UBOOT_DM_CLK_IMX_PLLV3_GENV2	"imx_clk_pllv3_genericv2"
25 
26 #define PLL_NUM_OFFSET		0x10
27 #define PLL_DENOM_OFFSET	0x20
28 
29 #define BM_PLL_POWER		(0x1 << 12)
30 #define BM_PLL_POWER_V2		(0x1 << 21)
31 #define BM_PLL_ENABLE		(0x1 << 13)
32 #define BM_PLL_LOCK		(0x1 << 31)
33 #define BM_PLL_LOCK_V2		(0x1 << 29)
34 
35 struct clk_pllv3 {
36 	struct clk	clk;
37 	void __iomem	*base;
38 	u32		power_bit;
39 	bool		powerup_set;
40 	u32		lock_bit;
41 	u32		enable_bit;
42 	u32		div_mask;
43 	u32		div_shift;
44 	unsigned long   ref_clock;
45 };
46 
47 #define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
48 
clk_pllv3_genericv2_get_rate(struct clk * clk)49 static ulong clk_pllv3_genericv2_get_rate(struct clk *clk)
50 {
51 	struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
52 	unsigned long parent_rate = clk_get_parent_rate(clk);
53 
54 	u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
55 
56 	return (div == 0) ? parent_rate * 22 : parent_rate * 20;
57 }
58 
clk_pllv3_genericv2_set_rate(struct clk * clk,ulong rate)59 static ulong clk_pllv3_genericv2_set_rate(struct clk *clk, ulong rate)
60 {
61 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
62 	unsigned long parent_rate = clk_get_parent_rate(clk);
63 
64 	u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
65 	u32 val = (div == 0) ? parent_rate * 22 : parent_rate * 20;
66 
67 	if (rate == val)
68 		return 0;
69 
70 	return -EINVAL;
71 }
72 
clk_pllv3_generic_get_rate(struct clk * clk)73 static ulong clk_pllv3_generic_get_rate(struct clk *clk)
74 {
75 	struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
76 	unsigned long parent_rate = clk_get_parent_rate(clk);
77 
78 	u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
79 
80 	return (div == 1) ? parent_rate * 22 : parent_rate * 20;
81 }
82 
clk_pllv3_generic_set_rate(struct clk * clk,ulong rate)83 static ulong clk_pllv3_generic_set_rate(struct clk *clk, ulong rate)
84 {
85 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
86 	unsigned long parent_rate = clk_get_parent_rate(clk);
87 	u32 val, div;
88 
89 	if (rate == parent_rate * 22)
90 		div = 1;
91 	else if (rate == parent_rate * 20)
92 		div = 0;
93 	else
94 		return -EINVAL;
95 
96 	val = readl(pll->base);
97 	val &= ~(pll->div_mask << pll->div_shift);
98 	val |= (div << pll->div_shift);
99 	writel(val, pll->base);
100 
101 	/* Wait for PLL to lock */
102 	while (!(readl(pll->base) & pll->lock_bit))
103 		;
104 
105 	return 0;
106 }
107 
clk_pllv3_generic_enable(struct clk * clk)108 static int clk_pllv3_generic_enable(struct clk *clk)
109 {
110 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
111 	u32 val;
112 
113 	val = readl(pll->base);
114 	if (pll->powerup_set)
115 		val |= pll->power_bit;
116 	else
117 		val &= ~pll->power_bit;
118 
119 	val |= pll->enable_bit;
120 
121 	writel(val, pll->base);
122 
123 	return 0;
124 }
125 
clk_pllv3_generic_disable(struct clk * clk)126 static int clk_pllv3_generic_disable(struct clk *clk)
127 {
128 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
129 	u32 val;
130 
131 	val = readl(pll->base);
132 	if (pll->powerup_set)
133 		val &= ~pll->power_bit;
134 	else
135 		val |= pll->power_bit;
136 
137 	val &= ~pll->enable_bit;
138 
139 	writel(val, pll->base);
140 
141 	return 0;
142 }
143 
144 static const struct clk_ops clk_pllv3_generic_ops = {
145 	.get_rate	= clk_pllv3_generic_get_rate,
146 	.enable		= clk_pllv3_generic_enable,
147 	.disable	= clk_pllv3_generic_disable,
148 	.set_rate	= clk_pllv3_generic_set_rate,
149 };
150 
151 static const struct clk_ops clk_pllv3_genericv2_ops = {
152 	.get_rate	= clk_pllv3_genericv2_get_rate,
153 	.enable		= clk_pllv3_generic_enable,
154 	.disable	= clk_pllv3_generic_disable,
155 	.set_rate	= clk_pllv3_genericv2_set_rate,
156 };
157 
clk_pllv3_sys_get_rate(struct clk * clk)158 static ulong clk_pllv3_sys_get_rate(struct clk *clk)
159 {
160 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
161 	unsigned long parent_rate = clk_get_parent_rate(clk);
162 	u32 div = readl(pll->base) & pll->div_mask;
163 
164 	return parent_rate * div / 2;
165 }
166 
clk_pllv3_sys_set_rate(struct clk * clk,ulong rate)167 static ulong clk_pllv3_sys_set_rate(struct clk *clk, ulong rate)
168 {
169 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
170 	unsigned long parent_rate = clk_get_parent_rate(clk);
171 	unsigned long min_rate;
172 	unsigned long max_rate;
173 	u32 val, div;
174 
175 	if (parent_rate == 0)
176 		return -EINVAL;
177 
178 	min_rate = parent_rate * 54 / 2;
179 	max_rate = parent_rate * 108 / 2;
180 
181 	if (rate < min_rate || rate > max_rate)
182 		return -EINVAL;
183 
184 	div = rate * 2 / parent_rate;
185 	val = readl(pll->base);
186 	val &= ~pll->div_mask;
187 	val |= div;
188 	writel(val, pll->base);
189 
190 	/* Wait for PLL to lock */
191 	while (!(readl(pll->base) & pll->lock_bit))
192 		;
193 
194 	return 0;
195 }
196 
197 static const struct clk_ops clk_pllv3_sys_ops = {
198 	.enable		= clk_pllv3_generic_enable,
199 	.disable	= clk_pllv3_generic_disable,
200 	.get_rate	= clk_pllv3_sys_get_rate,
201 	.set_rate	= clk_pllv3_sys_set_rate,
202 };
203 
clk_pllv3_av_get_rate(struct clk * clk)204 static ulong clk_pllv3_av_get_rate(struct clk *clk)
205 {
206 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
207 	unsigned long parent_rate = clk_get_parent_rate(clk);
208 	u32 mfn = readl(pll->base + PLL_NUM_OFFSET);
209 	u32 mfd = readl(pll->base + PLL_DENOM_OFFSET);
210 	u32 div = readl(pll->base) & pll->div_mask;
211 	u64 temp64 = (u64)parent_rate;
212 
213 	if (mfd == 0)
214 		return -EIO;
215 
216 	temp64 *= mfn;
217 	do_div(temp64, mfd);
218 
219 	return parent_rate * div + (unsigned long)temp64;
220 }
221 
clk_pllv3_av_set_rate(struct clk * clk,ulong rate)222 static ulong clk_pllv3_av_set_rate(struct clk *clk, ulong rate)
223 {
224 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
225 	unsigned long parent_rate = clk_get_parent_rate(clk);
226 	unsigned long min_rate;
227 	unsigned long max_rate;
228 	u32 val, div;
229 	u32 mfn, mfd = 1000000;
230 	u32 max_mfd = 0x3FFFFFFF;
231 	u64 temp64;
232 
233 	if (parent_rate == 0)
234 		return -EINVAL;
235 
236 	min_rate = parent_rate * 27;
237 	max_rate = parent_rate * 54;
238 
239 	if (rate < min_rate || rate > max_rate)
240 		return -EINVAL;
241 
242 	if (parent_rate <= max_mfd)
243 		mfd = parent_rate;
244 
245 	div = rate / parent_rate;
246 	temp64 = (u64)(rate - div * parent_rate);
247 	temp64 *= mfd;
248 	do_div(temp64, parent_rate);
249 	mfn = temp64;
250 
251 	val = readl(pll->base);
252 	val &= ~pll->div_mask;
253 	val |= div;
254 	writel(val, pll->base);
255 	writel(mfn, pll->base + PLL_NUM_OFFSET);
256 	writel(mfd, pll->base + PLL_DENOM_OFFSET);
257 
258 	/* Wait for PLL to lock */
259 	while (!(readl(pll->base) & pll->lock_bit))
260 		;
261 
262 	return 0;
263 }
264 
265 static const struct clk_ops clk_pllv3_av_ops = {
266 	.enable		= clk_pllv3_generic_enable,
267 	.disable	= clk_pllv3_generic_disable,
268 	.get_rate	= clk_pllv3_av_get_rate,
269 	.set_rate	= clk_pllv3_av_set_rate,
270 };
271 
clk_pllv3_enet_get_rate(struct clk * clk)272 static ulong clk_pllv3_enet_get_rate(struct clk *clk)
273 {
274 	struct clk_pllv3 *pll = to_clk_pllv3(clk);
275 
276 	return pll->ref_clock;
277 }
278 
279 static const struct clk_ops clk_pllv3_enet_ops = {
280 	.enable	= clk_pllv3_generic_enable,
281 	.disable	= clk_pllv3_generic_disable,
282 	.get_rate	= clk_pllv3_enet_get_rate,
283 };
284 
imx_clk_pllv3(enum imx_pllv3_type type,const char * name,const char * parent_name,void __iomem * base,u32 div_mask)285 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
286 			  const char *parent_name, void __iomem *base,
287 			  u32 div_mask)
288 {
289 	struct clk_pllv3 *pll;
290 	struct clk *clk;
291 	char *drv_name;
292 	int ret;
293 
294 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
295 	if (!pll)
296 		return ERR_PTR(-ENOMEM);
297 
298 	pll->power_bit = BM_PLL_POWER;
299 	pll->enable_bit = BM_PLL_ENABLE;
300 	pll->lock_bit = BM_PLL_LOCK;
301 
302 	switch (type) {
303 	case IMX_PLLV3_GENERIC:
304 		drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENERIC;
305 		pll->div_shift = 0;
306 		pll->powerup_set = false;
307 		break;
308 	case IMX_PLLV3_GENERICV2:
309 		pll->power_bit = BM_PLL_POWER_V2;
310 		pll->lock_bit = BM_PLL_LOCK_V2;
311 		drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENV2;
312 		pll->div_shift = 0;
313 		pll->powerup_set = false;
314 		break;
315 	case IMX_PLLV3_SYS:
316 		drv_name = UBOOT_DM_CLK_IMX_PLLV3_SYS;
317 		pll->div_shift = 0;
318 		pll->powerup_set = false;
319 		break;
320 	case IMX_PLLV3_USB:
321 		drv_name = UBOOT_DM_CLK_IMX_PLLV3_USB;
322 		pll->div_shift = 1;
323 		pll->powerup_set = true;
324 		break;
325 	case IMX_PLLV3_AV:
326 		drv_name = UBOOT_DM_CLK_IMX_PLLV3_AV;
327 		pll->div_shift = 0;
328 		pll->powerup_set = false;
329 		break;
330 	case IMX_PLLV3_ENET:
331 		drv_name = UBOOT_DM_CLK_IMX_PLLV3_ENET;
332 		pll->ref_clock = 500000000;
333 		break;
334 	default:
335 		kfree(pll);
336 		return ERR_PTR(-EINVAL);
337 	}
338 
339 	pll->base = base;
340 	pll->div_mask = div_mask;
341 	clk = &pll->clk;
342 
343 	ret = clk_register(clk, drv_name, name, parent_name);
344 	if (ret) {
345 		kfree(pll);
346 		return ERR_PTR(ret);
347 	}
348 
349 	return clk;
350 }
351 
352 U_BOOT_DRIVER(clk_pllv3_generic) = {
353 	.name	= UBOOT_DM_CLK_IMX_PLLV3_GENERIC,
354 	.id	= UCLASS_CLK,
355 	.ops	= &clk_pllv3_generic_ops,
356 	.flags = DM_FLAG_PRE_RELOC,
357 };
358 
359 U_BOOT_DRIVER(clk_pllv3_genericv2) = {
360 	.name	= UBOOT_DM_CLK_IMX_PLLV3_GENV2,
361 	.id	= UCLASS_CLK,
362 	.ops	= &clk_pllv3_genericv2_ops,
363 	.flags = DM_FLAG_PRE_RELOC,
364 };
365 
366 U_BOOT_DRIVER(clk_pllv3_sys) = {
367 	.name	= UBOOT_DM_CLK_IMX_PLLV3_SYS,
368 	.id	= UCLASS_CLK,
369 	.ops	= &clk_pllv3_sys_ops,
370 	.flags = DM_FLAG_PRE_RELOC,
371 };
372 
373 U_BOOT_DRIVER(clk_pllv3_usb) = {
374 	.name	= UBOOT_DM_CLK_IMX_PLLV3_USB,
375 	.id	= UCLASS_CLK,
376 	.ops	= &clk_pllv3_generic_ops,
377 	.flags = DM_FLAG_PRE_RELOC,
378 };
379 
380 U_BOOT_DRIVER(clk_pllv3_av) = {
381 	.name	= UBOOT_DM_CLK_IMX_PLLV3_AV,
382 	.id	= UCLASS_CLK,
383 	.ops	= &clk_pllv3_av_ops,
384 	.flags = DM_FLAG_PRE_RELOC,
385 };
386 
387 U_BOOT_DRIVER(clk_pllv3_enet) = {
388 	.name	= UBOOT_DM_CLK_IMX_PLLV3_ENET,
389 	.id	= UCLASS_CLK,
390 	.ops	= &clk_pllv3_enet_ops,
391 };
392