xref: /openbmc/linux/drivers/clk/clk-cs2000-cp.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * CS2000  --  CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier
4   *
5   * Copyright (C) 2015 Renesas Electronics Corporation
6   * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7   */
8  #include <linux/clk-provider.h>
9  #include <linux/delay.h>
10  #include <linux/clk.h>
11  #include <linux/i2c.h>
12  #include <linux/of.h>
13  #include <linux/module.h>
14  #include <linux/regmap.h>
15  
16  #define CH_MAX 4
17  #define RATIO_REG_SIZE 4
18  
19  #define DEVICE_ID	0x1
20  #define DEVICE_CTRL	0x2
21  #define DEVICE_CFG1	0x3
22  #define DEVICE_CFG2	0x4
23  #define GLOBAL_CFG	0x5
24  #define Ratio_Add(x, nth)	(6 + (x * 4) + (nth))
25  #define Ratio_Val(x, nth)	((x >> (24 - (8 * nth))) & 0xFF)
26  #define Val_Ratio(x, nth)	((x & 0xFF) << (24 - (8 * nth)))
27  #define FUNC_CFG1	0x16
28  #define FUNC_CFG2	0x17
29  
30  /* DEVICE_ID */
31  #define REVISION_MASK	(0x7)
32  #define REVISION_B2_B3	(0x4)
33  #define REVISION_C1	(0x6)
34  
35  /* DEVICE_CTRL */
36  #define PLL_UNLOCK	(1 << 7)
37  #define AUXOUTDIS	(1 << 1)
38  #define CLKOUTDIS	(1 << 0)
39  
40  /* DEVICE_CFG1 */
41  #define RSEL(x)		(((x) & 0x3) << 3)
42  #define RSEL_MASK	RSEL(0x3)
43  #define AUXOUTSRC(x)	(((x) & 0x3) << 1)
44  #define AUXOUTSRC_MASK	AUXOUTSRC(0x3)
45  #define ENDEV1		(0x1)
46  
47  /* DEVICE_CFG2 */
48  #define AUTORMOD	(1 << 3)
49  #define LOCKCLK(x)	(((x) & 0x3) << 1)
50  #define LOCKCLK_MASK	LOCKCLK(0x3)
51  #define FRACNSRC_MASK	(1 << 0)
52  #define FRACNSRC_STATIC		(0 << 0)
53  #define FRACNSRC_DYNAMIC	(1 << 0)
54  
55  /* GLOBAL_CFG */
56  #define FREEZE		(1 << 7)
57  #define ENDEV2		(0x1)
58  
59  /* FUNC_CFG1 */
60  #define CLKSKIPEN	(1 << 7)
61  #define REFCLKDIV(x)	(((x) & 0x3) << 3)
62  #define REFCLKDIV_MASK	REFCLKDIV(0x3)
63  
64  /* FUNC_CFG2 */
65  #define LFRATIO_MASK	(1 << 3)
66  #define LFRATIO_20_12	(0 << 3)
67  #define LFRATIO_12_20	(1 << 3)
68  
69  #define CH_SIZE_ERR(ch)		((ch < 0) || (ch >= CH_MAX))
70  #define hw_to_priv(_hw)		container_of(_hw, struct cs2000_priv, hw)
71  #define priv_to_client(priv)	(priv->client)
72  #define priv_to_dev(priv)	(&(priv_to_client(priv)->dev))
73  
74  #define CLK_IN	0
75  #define REF_CLK	1
76  #define CLK_MAX 2
77  
cs2000_readable_reg(struct device * dev,unsigned int reg)78  static bool cs2000_readable_reg(struct device *dev, unsigned int reg)
79  {
80  	return reg > 0;
81  }
82  
cs2000_writeable_reg(struct device * dev,unsigned int reg)83  static bool cs2000_writeable_reg(struct device *dev, unsigned int reg)
84  {
85  	return reg != DEVICE_ID;
86  }
87  
cs2000_volatile_reg(struct device * dev,unsigned int reg)88  static bool cs2000_volatile_reg(struct device *dev, unsigned int reg)
89  {
90  	return reg == DEVICE_CTRL;
91  }
92  
93  static const struct regmap_config cs2000_regmap_config = {
94  	.reg_bits	= 8,
95  	.val_bits	= 8,
96  	.max_register	= FUNC_CFG2,
97  	.readable_reg	= cs2000_readable_reg,
98  	.writeable_reg	= cs2000_writeable_reg,
99  	.volatile_reg	= cs2000_volatile_reg,
100  };
101  
102  struct cs2000_priv {
103  	struct clk_hw hw;
104  	struct i2c_client *client;
105  	struct clk *clk_in;
106  	struct clk *ref_clk;
107  	struct regmap *regmap;
108  
109  	bool dynamic_mode;
110  	bool lf_ratio;
111  	bool clk_skip;
112  
113  	/* suspend/resume */
114  	unsigned long saved_rate;
115  	unsigned long saved_parent_rate;
116  };
117  
118  static const struct of_device_id cs2000_of_match[] = {
119  	{ .compatible = "cirrus,cs2000-cp", },
120  	{},
121  };
122  MODULE_DEVICE_TABLE(of, cs2000_of_match);
123  
124  static const struct i2c_device_id cs2000_id[] = {
125  	{ "cs2000-cp", },
126  	{}
127  };
128  MODULE_DEVICE_TABLE(i2c, cs2000_id);
129  
cs2000_enable_dev_config(struct cs2000_priv * priv,bool enable)130  static int cs2000_enable_dev_config(struct cs2000_priv *priv, bool enable)
131  {
132  	int ret;
133  
134  	ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, ENDEV1,
135  				 enable ? ENDEV1 : 0);
136  	if (ret < 0)
137  		return ret;
138  
139  	ret = regmap_update_bits(priv->regmap, GLOBAL_CFG,  ENDEV2,
140  				 enable ? ENDEV2 : 0);
141  	if (ret < 0)
142  		return ret;
143  
144  	ret = regmap_update_bits(priv->regmap, FUNC_CFG1, CLKSKIPEN,
145  				 (enable && priv->clk_skip) ? CLKSKIPEN : 0);
146  	if (ret < 0)
147  		return ret;
148  
149  	return 0;
150  }
151  
cs2000_ref_clk_bound_rate(struct cs2000_priv * priv,u32 rate_in)152  static int cs2000_ref_clk_bound_rate(struct cs2000_priv *priv,
153  				     u32 rate_in)
154  {
155  	u32 val;
156  
157  	if (rate_in >= 32000000 && rate_in < 56000000)
158  		val = 0x0;
159  	else if (rate_in >= 16000000 && rate_in < 28000000)
160  		val = 0x1;
161  	else if (rate_in >= 8000000 && rate_in < 14000000)
162  		val = 0x2;
163  	else
164  		return -EINVAL;
165  
166  	return regmap_update_bits(priv->regmap, FUNC_CFG1,
167  				  REFCLKDIV_MASK,
168  				  REFCLKDIV(val));
169  }
170  
cs2000_wait_pll_lock(struct cs2000_priv * priv)171  static int cs2000_wait_pll_lock(struct cs2000_priv *priv)
172  {
173  	struct device *dev = priv_to_dev(priv);
174  	unsigned int i, val;
175  	int ret;
176  
177  	for (i = 0; i < 256; i++) {
178  		ret = regmap_read(priv->regmap, DEVICE_CTRL, &val);
179  		if (ret < 0)
180  			return ret;
181  		if (!(val & PLL_UNLOCK))
182  			return 0;
183  		udelay(1);
184  	}
185  
186  	dev_err(dev, "pll lock failed\n");
187  
188  	return -ETIMEDOUT;
189  }
190  
cs2000_clk_out_enable(struct cs2000_priv * priv,bool enable)191  static int cs2000_clk_out_enable(struct cs2000_priv *priv, bool enable)
192  {
193  	/* enable both AUX_OUT, CLK_OUT */
194  	return regmap_update_bits(priv->regmap, DEVICE_CTRL,
195  				  (AUXOUTDIS | CLKOUTDIS),
196  				  enable ? 0 :
197  				  (AUXOUTDIS | CLKOUTDIS));
198  }
199  
cs2000_rate_to_ratio(u32 rate_in,u32 rate_out,bool lf_ratio)200  static u32 cs2000_rate_to_ratio(u32 rate_in, u32 rate_out, bool lf_ratio)
201  {
202  	u64 ratio;
203  	u32 multiplier = lf_ratio ? 12 : 20;
204  
205  	/*
206  	 * ratio = rate_out / rate_in * 2^multiplier
207  	 *
208  	 * To avoid over flow, rate_out is u64.
209  	 * The result should be u32.
210  	 */
211  	ratio = (u64)rate_out << multiplier;
212  	do_div(ratio, rate_in);
213  
214  	return ratio;
215  }
216  
cs2000_ratio_to_rate(u32 ratio,u32 rate_in,bool lf_ratio)217  static unsigned long cs2000_ratio_to_rate(u32 ratio, u32 rate_in, bool lf_ratio)
218  {
219  	u64 rate_out;
220  	u32 multiplier = lf_ratio ? 12 : 20;
221  
222  	/*
223  	 * ratio = rate_out / rate_in * 2^multiplier
224  	 *
225  	 * To avoid over flow, rate_out is u64.
226  	 * The result should be u32 or unsigned long.
227  	 */
228  
229  	rate_out = (u64)ratio * rate_in;
230  	return rate_out >> multiplier;
231  }
232  
cs2000_ratio_set(struct cs2000_priv * priv,int ch,u32 rate_in,u32 rate_out)233  static int cs2000_ratio_set(struct cs2000_priv *priv,
234  			    int ch, u32 rate_in, u32 rate_out)
235  {
236  	u32 val;
237  	unsigned int i;
238  	int ret;
239  
240  	if (CH_SIZE_ERR(ch))
241  		return -EINVAL;
242  
243  	val = cs2000_rate_to_ratio(rate_in, rate_out, priv->lf_ratio);
244  	for (i = 0; i < RATIO_REG_SIZE; i++) {
245  		ret = regmap_write(priv->regmap,
246  				   Ratio_Add(ch, i),
247  				   Ratio_Val(val, i));
248  		if (ret < 0)
249  			return ret;
250  	}
251  
252  	return 0;
253  }
254  
cs2000_ratio_get(struct cs2000_priv * priv,int ch)255  static u32 cs2000_ratio_get(struct cs2000_priv *priv, int ch)
256  {
257  	unsigned int tmp, i;
258  	u32 val;
259  	int ret;
260  
261  	val = 0;
262  	for (i = 0; i < RATIO_REG_SIZE; i++) {
263  		ret = regmap_read(priv->regmap, Ratio_Add(ch, i), &tmp);
264  		if (ret < 0)
265  			return 0;
266  
267  		val |= Val_Ratio(tmp, i);
268  	}
269  
270  	return val;
271  }
272  
cs2000_ratio_select(struct cs2000_priv * priv,int ch)273  static int cs2000_ratio_select(struct cs2000_priv *priv, int ch)
274  {
275  	int ret;
276  	u8 fracnsrc;
277  
278  	if (CH_SIZE_ERR(ch))
279  		return -EINVAL;
280  
281  	ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, RSEL_MASK, RSEL(ch));
282  	if (ret < 0)
283  		return ret;
284  
285  	fracnsrc = priv->dynamic_mode ? FRACNSRC_DYNAMIC : FRACNSRC_STATIC;
286  
287  	ret = regmap_update_bits(priv->regmap, DEVICE_CFG2,
288  				 AUTORMOD | LOCKCLK_MASK | FRACNSRC_MASK,
289  				 LOCKCLK(ch) | fracnsrc);
290  	if (ret < 0)
291  		return ret;
292  
293  	return 0;
294  }
295  
cs2000_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)296  static unsigned long cs2000_recalc_rate(struct clk_hw *hw,
297  					unsigned long parent_rate)
298  {
299  	struct cs2000_priv *priv = hw_to_priv(hw);
300  	int ch = 0; /* it uses ch0 only at this point */
301  	u32 ratio;
302  
303  	ratio = cs2000_ratio_get(priv, ch);
304  
305  	return cs2000_ratio_to_rate(ratio, parent_rate, priv->lf_ratio);
306  }
307  
cs2000_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * parent_rate)308  static long cs2000_round_rate(struct clk_hw *hw, unsigned long rate,
309  			      unsigned long *parent_rate)
310  {
311  	struct cs2000_priv *priv = hw_to_priv(hw);
312  	u32 ratio;
313  
314  	ratio = cs2000_rate_to_ratio(*parent_rate, rate, priv->lf_ratio);
315  
316  	return cs2000_ratio_to_rate(ratio, *parent_rate, priv->lf_ratio);
317  }
318  
cs2000_select_ratio_mode(struct cs2000_priv * priv,unsigned long rate,unsigned long parent_rate)319  static int cs2000_select_ratio_mode(struct cs2000_priv *priv,
320  				    unsigned long rate,
321  				    unsigned long parent_rate)
322  {
323  	/*
324  	 * From the datasheet:
325  	 *
326  	 * | It is recommended that the 12.20 High-Resolution format be
327  	 * | utilized whenever the desired ratio is less than 4096 since
328  	 * | the output frequency accuracy of the PLL is directly proportional
329  	 * | to the accuracy of the timing reference clock and the resolution
330  	 * | of the R_UD.
331  	 *
332  	 * This mode is only available in dynamic mode.
333  	 */
334  	priv->lf_ratio = priv->dynamic_mode && ((rate / parent_rate) > 4096);
335  
336  	return regmap_update_bits(priv->regmap, FUNC_CFG2, LFRATIO_MASK,
337  				  priv->lf_ratio ? LFRATIO_20_12 : LFRATIO_12_20);
338  }
339  
__cs2000_set_rate(struct cs2000_priv * priv,int ch,unsigned long rate,unsigned long parent_rate)340  static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
341  			     unsigned long rate, unsigned long parent_rate)
342  
343  {
344  	int ret;
345  
346  	ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, FREEZE, FREEZE);
347  	if (ret < 0)
348  		return ret;
349  
350  	ret = cs2000_select_ratio_mode(priv, rate, parent_rate);
351  	if (ret < 0)
352  		return ret;
353  
354  	ret = cs2000_ratio_set(priv, ch, parent_rate, rate);
355  	if (ret < 0)
356  		return ret;
357  
358  	ret = cs2000_ratio_select(priv, ch);
359  	if (ret < 0)
360  		return ret;
361  
362  	ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, FREEZE, 0);
363  	if (ret < 0)
364  		return ret;
365  
366  	priv->saved_rate	= rate;
367  	priv->saved_parent_rate	= parent_rate;
368  
369  	return 0;
370  }
371  
cs2000_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)372  static int cs2000_set_rate(struct clk_hw *hw,
373  			   unsigned long rate, unsigned long parent_rate)
374  {
375  	struct cs2000_priv *priv = hw_to_priv(hw);
376  	int ch = 0; /* it uses ch0 only at this point */
377  
378  	return __cs2000_set_rate(priv, ch, rate, parent_rate);
379  }
380  
cs2000_set_saved_rate(struct cs2000_priv * priv)381  static int cs2000_set_saved_rate(struct cs2000_priv *priv)
382  {
383  	int ch = 0; /* it uses ch0 only at this point */
384  
385  	return __cs2000_set_rate(priv, ch,
386  				 priv->saved_rate,
387  				 priv->saved_parent_rate);
388  }
389  
cs2000_enable(struct clk_hw * hw)390  static int cs2000_enable(struct clk_hw *hw)
391  {
392  	struct cs2000_priv *priv = hw_to_priv(hw);
393  	int ret;
394  
395  	ret = cs2000_enable_dev_config(priv, true);
396  	if (ret < 0)
397  		return ret;
398  
399  	ret = cs2000_clk_out_enable(priv, true);
400  	if (ret < 0)
401  		return ret;
402  
403  	ret = cs2000_wait_pll_lock(priv);
404  	if (ret < 0)
405  		return ret;
406  
407  	return ret;
408  }
409  
cs2000_disable(struct clk_hw * hw)410  static void cs2000_disable(struct clk_hw *hw)
411  {
412  	struct cs2000_priv *priv = hw_to_priv(hw);
413  
414  	cs2000_enable_dev_config(priv, false);
415  
416  	cs2000_clk_out_enable(priv, false);
417  }
418  
cs2000_get_parent(struct clk_hw * hw)419  static u8 cs2000_get_parent(struct clk_hw *hw)
420  {
421  	struct cs2000_priv *priv = hw_to_priv(hw);
422  
423  	/*
424  	 * In dynamic mode, output rates are derived from CLK_IN.
425  	 * In static mode, CLK_IN is ignored, so we return REF_CLK instead.
426  	 */
427  	return priv->dynamic_mode ? CLK_IN : REF_CLK;
428  }
429  
430  static const struct clk_ops cs2000_ops = {
431  	.get_parent	= cs2000_get_parent,
432  	.recalc_rate	= cs2000_recalc_rate,
433  	.round_rate	= cs2000_round_rate,
434  	.set_rate	= cs2000_set_rate,
435  	.prepare	= cs2000_enable,
436  	.unprepare	= cs2000_disable,
437  };
438  
cs2000_clk_get(struct cs2000_priv * priv)439  static int cs2000_clk_get(struct cs2000_priv *priv)
440  {
441  	struct device *dev = priv_to_dev(priv);
442  	struct clk *clk_in, *ref_clk;
443  
444  	clk_in = devm_clk_get(dev, "clk_in");
445  	/* not yet provided */
446  	if (IS_ERR(clk_in))
447  		return -EPROBE_DEFER;
448  
449  	ref_clk = devm_clk_get(dev, "ref_clk");
450  	/* not yet provided */
451  	if (IS_ERR(ref_clk))
452  		return -EPROBE_DEFER;
453  
454  	priv->clk_in	= clk_in;
455  	priv->ref_clk	= ref_clk;
456  
457  	return 0;
458  }
459  
cs2000_clk_register(struct cs2000_priv * priv)460  static int cs2000_clk_register(struct cs2000_priv *priv)
461  {
462  	struct device *dev = priv_to_dev(priv);
463  	struct device_node *np = dev->of_node;
464  	struct clk_init_data init;
465  	const char *name = np->name;
466  	static const char *parent_names[CLK_MAX];
467  	u32 aux_out = 0;
468  	int ref_clk_rate;
469  	int ch = 0; /* it uses ch0 only at this point */
470  	int ret;
471  
472  	of_property_read_string(np, "clock-output-names", &name);
473  
474  	priv->dynamic_mode = of_property_read_bool(np, "cirrus,dynamic-mode");
475  	dev_info(dev, "operating in %s mode\n",
476  		 priv->dynamic_mode ? "dynamic" : "static");
477  
478  	of_property_read_u32(np, "cirrus,aux-output-source", &aux_out);
479  	ret = regmap_update_bits(priv->regmap, DEVICE_CFG1,
480  				 AUXOUTSRC_MASK, AUXOUTSRC(aux_out));
481  	if (ret < 0)
482  		return ret;
483  
484  	priv->clk_skip = of_property_read_bool(np, "cirrus,clock-skip");
485  
486  	ref_clk_rate = clk_get_rate(priv->ref_clk);
487  	ret = cs2000_ref_clk_bound_rate(priv, ref_clk_rate);
488  	if (ret < 0)
489  		return ret;
490  
491  	if (priv->dynamic_mode) {
492  		/* Default to low-frequency mode to allow for large ratios */
493  		priv->lf_ratio = true;
494  	} else {
495  		/*
496  		 * set default rate as 1/1.
497  		 * otherwise .set_rate which setup ratio
498  		 * is never called if user requests 1/1 rate
499  		 */
500  		ret = __cs2000_set_rate(priv, ch, ref_clk_rate, ref_clk_rate);
501  		if (ret < 0)
502  			return ret;
503  	}
504  
505  	parent_names[CLK_IN]	= __clk_get_name(priv->clk_in);
506  	parent_names[REF_CLK]	= __clk_get_name(priv->ref_clk);
507  
508  	init.name		= name;
509  	init.ops		= &cs2000_ops;
510  	init.flags		= CLK_SET_RATE_GATE;
511  	init.parent_names	= parent_names;
512  	init.num_parents	= ARRAY_SIZE(parent_names);
513  
514  	priv->hw.init = &init;
515  
516  	ret = clk_hw_register(dev, &priv->hw);
517  	if (ret)
518  		return ret;
519  
520  	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
521  	if (ret < 0) {
522  		clk_hw_unregister(&priv->hw);
523  		return ret;
524  	}
525  
526  	return 0;
527  }
528  
cs2000_version_print(struct cs2000_priv * priv)529  static int cs2000_version_print(struct cs2000_priv *priv)
530  {
531  	struct device *dev = priv_to_dev(priv);
532  	const char *revision;
533  	unsigned int val;
534  	int ret;
535  
536  	ret = regmap_read(priv->regmap, DEVICE_ID, &val);
537  	if (ret < 0)
538  		return ret;
539  
540  	/* CS2000 should be 0x0 */
541  	if (val >> 3)
542  		return -EIO;
543  
544  	switch (val & REVISION_MASK) {
545  	case REVISION_B2_B3:
546  		revision = "B2 / B3";
547  		break;
548  	case REVISION_C1:
549  		revision = "C1";
550  		break;
551  	default:
552  		return -EIO;
553  	}
554  
555  	dev_info(dev, "revision - %s\n", revision);
556  
557  	return 0;
558  }
559  
cs2000_remove(struct i2c_client * client)560  static void cs2000_remove(struct i2c_client *client)
561  {
562  	struct cs2000_priv *priv = i2c_get_clientdata(client);
563  	struct device *dev = priv_to_dev(priv);
564  	struct device_node *np = dev->of_node;
565  
566  	of_clk_del_provider(np);
567  
568  	clk_hw_unregister(&priv->hw);
569  }
570  
cs2000_probe(struct i2c_client * client)571  static int cs2000_probe(struct i2c_client *client)
572  {
573  	struct cs2000_priv *priv;
574  	struct device *dev = &client->dev;
575  	int ret;
576  
577  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
578  	if (!priv)
579  		return -ENOMEM;
580  
581  	priv->client = client;
582  	i2c_set_clientdata(client, priv);
583  
584  	priv->regmap = devm_regmap_init_i2c(client, &cs2000_regmap_config);
585  	if (IS_ERR(priv->regmap))
586  		return PTR_ERR(priv->regmap);
587  
588  	ret = cs2000_clk_get(priv);
589  	if (ret < 0)
590  		return ret;
591  
592  	ret = cs2000_clk_register(priv);
593  	if (ret < 0)
594  		return ret;
595  
596  	ret = cs2000_version_print(priv);
597  	if (ret < 0)
598  		goto probe_err;
599  
600  	return 0;
601  
602  probe_err:
603  	cs2000_remove(client);
604  
605  	return ret;
606  }
607  
cs2000_resume(struct device * dev)608  static int __maybe_unused cs2000_resume(struct device *dev)
609  {
610  	struct cs2000_priv *priv = dev_get_drvdata(dev);
611  
612  	return cs2000_set_saved_rate(priv);
613  }
614  
615  static const struct dev_pm_ops cs2000_pm_ops = {
616  	SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, cs2000_resume)
617  };
618  
619  static struct i2c_driver cs2000_driver = {
620  	.driver = {
621  		.name = "cs2000-cp",
622  		.pm	= &cs2000_pm_ops,
623  		.of_match_table = cs2000_of_match,
624  	},
625  	.probe		= cs2000_probe,
626  	.remove		= cs2000_remove,
627  	.id_table	= cs2000_id,
628  };
629  
630  module_i2c_driver(cs2000_driver);
631  
632  MODULE_DESCRIPTION("CS2000-CP driver");
633  MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
634  MODULE_LICENSE("GPL v2");
635