xref: /openbmc/linux/drivers/clk/versatile/clk-icst.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Driver for the ICST307 VCO clock found in the ARM Reference designs.
4   * We wrap the custom interface from <asm/hardware/icst.h> into the generic
5   * clock framework.
6   *
7   * Copyright (C) 2012-2015 Linus Walleij
8   *
9   * TODO: when all ARM reference designs are migrated to generic clocks, the
10   * ICST clock code from the ARM tree should probably be merged into this
11   * file.
12   */
13  #include <linux/kernel.h>
14  #include <linux/slab.h>
15  #include <linux/export.h>
16  #include <linux/err.h>
17  #include <linux/clk-provider.h>
18  #include <linux/io.h>
19  #include <linux/regmap.h>
20  #include <linux/mfd/syscon.h>
21  
22  #include "icst.h"
23  #include "clk-icst.h"
24  
25  /* Magic unlocking token used on all Versatile boards */
26  #define VERSATILE_LOCK_VAL	0xA05F
27  
28  #define VERSATILE_AUX_OSC_BITS 0x7FFFF
29  #define INTEGRATOR_AP_CM_BITS 0xFF
30  #define INTEGRATOR_AP_SYS_BITS 0xFF
31  #define INTEGRATOR_CP_CM_CORE_BITS 0x7FF
32  #define INTEGRATOR_CP_CM_MEM_BITS 0x7FF000
33  
34  #define INTEGRATOR_AP_PCI_25_33_MHZ BIT(8)
35  
36  /**
37   * struct clk_icst - ICST VCO clock wrapper
38   * @hw: corresponding clock hardware entry
39   * @map: register map
40   * @vcoreg_off: VCO register address
41   * @lockreg_off: VCO lock register address
42   * @params: parameters for this ICST instance
43   * @rate: current rate
44   * @ctype: the type of control register for the ICST
45   */
46  struct clk_icst {
47  	struct clk_hw hw;
48  	struct regmap *map;
49  	u32 vcoreg_off;
50  	u32 lockreg_off;
51  	struct icst_params *params;
52  	unsigned long rate;
53  	enum icst_control_type ctype;
54  };
55  
56  #define to_icst(_hw) container_of(_hw, struct clk_icst, hw)
57  
58  /**
59   * vco_get() - get ICST VCO settings from a certain ICST
60   * @icst: the ICST clock to get
61   * @vco: the VCO struct to return the value in
62   */
vco_get(struct clk_icst * icst,struct icst_vco * vco)63  static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
64  {
65  	u32 val;
66  	int ret;
67  
68  	ret = regmap_read(icst->map, icst->vcoreg_off, &val);
69  	if (ret)
70  		return ret;
71  
72  	/*
73  	 * The Integrator/AP core clock can only access the low eight
74  	 * bits of the v PLL divider. Bit 8 is tied low and always zero,
75  	 * r is hardwired to 22 and output divider s is hardwired to 1
76  	 * (divide by 2) according to the document
77  	 * "Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and
78  	 * CM1136JF-S User Guide" ARM DUI 0138E, page 3-13 thru 3-14.
79  	 */
80  	if (icst->ctype == ICST_INTEGRATOR_AP_CM) {
81  		vco->v = val & INTEGRATOR_AP_CM_BITS;
82  		vco->r = 22;
83  		vco->s = 1;
84  		return 0;
85  	}
86  
87  	/*
88  	 * The Integrator/AP system clock on the base board can only
89  	 * access the low eight bits of the v PLL divider. Bit 8 is tied low
90  	 * and always zero, r is hardwired to 46, and the output divider is
91  	 * hardwired to 3 (divide by 4) according to the document
92  	 * "Integrator AP ASIC Development Motherboard" ARM DUI 0098B,
93  	 * page 3-16.
94  	 */
95  	if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
96  		vco->v = val & INTEGRATOR_AP_SYS_BITS;
97  		vco->r = 46;
98  		vco->s = 3;
99  		return 0;
100  	}
101  
102  	/*
103  	 * The Integrator/AP PCI clock is using an odd pattern to create
104  	 * the child clock, basically a single bit called DIVX/Y is used
105  	 * to select between two different hardwired values: setting the
106  	 * bit to 0 yields v = 17, r = 22 and OD = 1, whereas setting the
107  	 * bit to 1 yields v = 14, r = 14 and OD = 1 giving the frequencies
108  	 * 33 or 25 MHz respectively.
109  	 */
110  	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
111  		bool divxy = !!(val & INTEGRATOR_AP_PCI_25_33_MHZ);
112  
113  		vco->v = divxy ? 17 : 14;
114  		vco->r = divxy ? 22 : 14;
115  		vco->s = 1;
116  		return 0;
117  	}
118  
119  	/*
120  	 * The Integrator/CP core clock can access the low eight bits
121  	 * of the v PLL divider. Bit 8 is tied low and always zero,
122  	 * r is hardwired to 22 and the output divider s is accessible
123  	 * in bits 8 thru 10 according to the document
124  	 * "Integrator/CM940T, CM920T, CM740T, and CM720T User Guide"
125  	 * ARM DUI 0157A, page 3-20 thru 3-23 and 4-10.
126  	 */
127  	if (icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
128  		vco->v = val & 0xFF;
129  		vco->r = 22;
130  		vco->s = (val >> 8) & 7;
131  		return 0;
132  	}
133  
134  	if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
135  		vco->v = (val >> 12) & 0xFF;
136  		vco->r = 22;
137  		vco->s = (val >> 20) & 7;
138  		return 0;
139  	}
140  
141  	vco->v = val & 0x1ff;
142  	vco->r = (val >> 9) & 0x7f;
143  	vco->s = (val >> 16) & 03;
144  	return 0;
145  }
146  
147  /**
148   * vco_set() - commit changes to an ICST VCO
149   * @icst: the ICST clock to set
150   * @vco: the VCO struct to set the changes from
151   */
vco_set(struct clk_icst * icst,struct icst_vco vco)152  static int vco_set(struct clk_icst *icst, struct icst_vco vco)
153  {
154  	u32 mask;
155  	u32 val;
156  	int ret;
157  
158  	/* Mask the bits used by the VCO */
159  	switch (icst->ctype) {
160  	case ICST_INTEGRATOR_AP_CM:
161  		mask = INTEGRATOR_AP_CM_BITS;
162  		val = vco.v & 0xFF;
163  		if (vco.v & 0x100)
164  			pr_err("ICST error: tried to set bit 8 of VDW\n");
165  		if (vco.s != 1)
166  			pr_err("ICST error: tried to use VOD != 1\n");
167  		if (vco.r != 22)
168  			pr_err("ICST error: tried to use RDW != 22\n");
169  		break;
170  	case ICST_INTEGRATOR_AP_SYS:
171  		mask = INTEGRATOR_AP_SYS_BITS;
172  		val = vco.v & 0xFF;
173  		if (vco.v & 0x100)
174  			pr_err("ICST error: tried to set bit 8 of VDW\n");
175  		if (vco.s != 3)
176  			pr_err("ICST error: tried to use VOD != 1\n");
177  		if (vco.r != 46)
178  			pr_err("ICST error: tried to use RDW != 22\n");
179  		break;
180  	case ICST_INTEGRATOR_CP_CM_CORE:
181  		mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */
182  		val = (vco.v & 0xFF) | vco.s << 8;
183  		if (vco.v & 0x100)
184  			pr_err("ICST error: tried to set bit 8 of VDW\n");
185  		if (vco.r != 22)
186  			pr_err("ICST error: tried to use RDW != 22\n");
187  		break;
188  	case ICST_INTEGRATOR_CP_CM_MEM:
189  		mask = INTEGRATOR_CP_CM_MEM_BITS; /* Uses 12 bits */
190  		val = ((vco.v & 0xFF) << 12) | (vco.s << 20);
191  		if (vco.v & 0x100)
192  			pr_err("ICST error: tried to set bit 8 of VDW\n");
193  		if (vco.r != 22)
194  			pr_err("ICST error: tried to use RDW != 22\n");
195  		break;
196  	default:
197  		/* Regular auxilary oscillator */
198  		mask = VERSATILE_AUX_OSC_BITS;
199  		val = vco.v | (vco.r << 9) | (vco.s << 16);
200  		break;
201  	}
202  
203  	pr_debug("ICST: new val = 0x%08x\n", val);
204  
205  	/* This magic unlocks the VCO so it can be controlled */
206  	ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL);
207  	if (ret)
208  		return ret;
209  	ret = regmap_update_bits(icst->map, icst->vcoreg_off, mask, val);
210  	if (ret)
211  		return ret;
212  	/* This locks the VCO again */
213  	ret = regmap_write(icst->map, icst->lockreg_off, 0);
214  	if (ret)
215  		return ret;
216  	return 0;
217  }
218  
icst_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)219  static unsigned long icst_recalc_rate(struct clk_hw *hw,
220  				      unsigned long parent_rate)
221  {
222  	struct clk_icst *icst = to_icst(hw);
223  	struct icst_vco vco;
224  	int ret;
225  
226  	if (parent_rate)
227  		icst->params->ref = parent_rate;
228  	ret = vco_get(icst, &vco);
229  	if (ret) {
230  		pr_err("ICST: could not get VCO setting\n");
231  		return 0;
232  	}
233  	icst->rate = icst_hz(icst->params, vco);
234  	return icst->rate;
235  }
236  
icst_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)237  static long icst_round_rate(struct clk_hw *hw, unsigned long rate,
238  			    unsigned long *prate)
239  {
240  	struct clk_icst *icst = to_icst(hw);
241  	struct icst_vco vco;
242  
243  	if (icst->ctype == ICST_INTEGRATOR_AP_CM ||
244  	    icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
245  		if (rate <= 12000000)
246  			return 12000000;
247  		if (rate >= 160000000)
248  			return 160000000;
249  		/* Slam to closest megahertz */
250  		return DIV_ROUND_CLOSEST(rate, 1000000) * 1000000;
251  	}
252  
253  	if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
254  		if (rate <= 6000000)
255  			return 6000000;
256  		if (rate >= 66000000)
257  			return 66000000;
258  		/* Slam to closest 0.5 megahertz */
259  		return DIV_ROUND_CLOSEST(rate, 500000) * 500000;
260  	}
261  
262  	if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
263  		/* Divides between 3 and 50 MHz in steps of 0.25 MHz */
264  		if (rate <= 3000000)
265  			return 3000000;
266  		if (rate >= 50000000)
267  			return 5000000;
268  		/* Slam to closest 0.25 MHz */
269  		return DIV_ROUND_CLOSEST(rate, 250000) * 250000;
270  	}
271  
272  	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
273  		/*
274  		 * If we're below or less than halfway from 25 to 33 MHz
275  		 * select 25 MHz
276  		 */
277  		if (rate <= 25000000 || rate < 29000000)
278  			return 25000000;
279  		/* Else just return the default frequency */
280  		return 33000000;
281  	}
282  
283  	vco = icst_hz_to_vco(icst->params, rate);
284  	return icst_hz(icst->params, vco);
285  }
286  
icst_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)287  static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
288  			 unsigned long parent_rate)
289  {
290  	struct clk_icst *icst = to_icst(hw);
291  	struct icst_vco vco;
292  
293  	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
294  		/* This clock is especially primitive */
295  		unsigned int val;
296  		int ret;
297  
298  		if (rate == 25000000) {
299  			val = 0;
300  		} else if (rate == 33000000) {
301  			val = INTEGRATOR_AP_PCI_25_33_MHZ;
302  		} else {
303  			pr_err("ICST: cannot set PCI frequency %lu\n",
304  			       rate);
305  			return -EINVAL;
306  		}
307  		ret = regmap_write(icst->map, icst->lockreg_off,
308  				   VERSATILE_LOCK_VAL);
309  		if (ret)
310  			return ret;
311  		ret = regmap_update_bits(icst->map, icst->vcoreg_off,
312  					 INTEGRATOR_AP_PCI_25_33_MHZ,
313  					 val);
314  		if (ret)
315  			return ret;
316  		/* This locks the VCO again */
317  		ret = regmap_write(icst->map, icst->lockreg_off, 0);
318  		if (ret)
319  			return ret;
320  		return 0;
321  	}
322  
323  	if (parent_rate)
324  		icst->params->ref = parent_rate;
325  	vco = icst_hz_to_vco(icst->params, rate);
326  	icst->rate = icst_hz(icst->params, vco);
327  	return vco_set(icst, vco);
328  }
329  
330  static const struct clk_ops icst_ops = {
331  	.recalc_rate = icst_recalc_rate,
332  	.round_rate = icst_round_rate,
333  	.set_rate = icst_set_rate,
334  };
335  
icst_clk_setup(struct device * dev,const struct clk_icst_desc * desc,const char * name,const char * parent_name,struct regmap * map,enum icst_control_type ctype)336  struct clk *icst_clk_setup(struct device *dev,
337  			   const struct clk_icst_desc *desc,
338  			   const char *name,
339  			   const char *parent_name,
340  			   struct regmap *map,
341  			   enum icst_control_type ctype)
342  {
343  	struct clk *clk;
344  	struct clk_icst *icst;
345  	struct clk_init_data init;
346  	struct icst_params *pclone;
347  
348  	icst = kzalloc(sizeof(*icst), GFP_KERNEL);
349  	if (!icst)
350  		return ERR_PTR(-ENOMEM);
351  
352  	pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL);
353  	if (!pclone) {
354  		kfree(icst);
355  		return ERR_PTR(-ENOMEM);
356  	}
357  
358  	init.name = name;
359  	init.ops = &icst_ops;
360  	init.flags = 0;
361  	init.parent_names = (parent_name ? &parent_name : NULL);
362  	init.num_parents = (parent_name ? 1 : 0);
363  	icst->map = map;
364  	icst->hw.init = &init;
365  	icst->params = pclone;
366  	icst->vcoreg_off = desc->vco_offset;
367  	icst->lockreg_off = desc->lock_offset;
368  	icst->ctype = ctype;
369  
370  	clk = clk_register(dev, &icst->hw);
371  	if (IS_ERR(clk)) {
372  		kfree(pclone);
373  		kfree(icst);
374  	}
375  
376  	return clk;
377  }
378  EXPORT_SYMBOL_GPL(icst_clk_setup);
379  
icst_clk_register(struct device * dev,const struct clk_icst_desc * desc,const char * name,const char * parent_name,void __iomem * base)380  struct clk *icst_clk_register(struct device *dev,
381  			const struct clk_icst_desc *desc,
382  			const char *name,
383  			const char *parent_name,
384  			void __iomem *base)
385  {
386  	struct regmap_config icst_regmap_conf = {
387  		.reg_bits = 32,
388  		.val_bits = 32,
389  		.reg_stride = 4,
390  	};
391  	struct regmap *map;
392  
393  	map = regmap_init_mmio(dev, base, &icst_regmap_conf);
394  	if (IS_ERR(map)) {
395  		pr_err("could not initialize ICST regmap\n");
396  		return ERR_CAST(map);
397  	}
398  	return icst_clk_setup(dev, desc, name, parent_name, map,
399  			      ICST_VERSATILE);
400  }
401  EXPORT_SYMBOL_GPL(icst_clk_register);
402  
403  #ifdef CONFIG_OF
404  /*
405   * In a device tree, an memory-mapped ICST clock appear as a child
406   * of a syscon node. Assume this and probe it only as a child of a
407   * syscon.
408   */
409  
410  static const struct icst_params icst525_params = {
411  	.vco_max	= ICST525_VCO_MAX_5V,
412  	.vco_min	= ICST525_VCO_MIN,
413  	.vd_min		= 8,
414  	.vd_max		= 263,
415  	.rd_min		= 3,
416  	.rd_max		= 65,
417  	.s2div		= icst525_s2div,
418  	.idx2s		= icst525_idx2s,
419  };
420  
421  static const struct icst_params icst307_params = {
422  	.vco_max	= ICST307_VCO_MAX,
423  	.vco_min	= ICST307_VCO_MIN,
424  	.vd_min		= 4 + 8,
425  	.vd_max		= 511 + 8,
426  	.rd_min		= 1 + 2,
427  	.rd_max		= 127 + 2,
428  	.s2div		= icst307_s2div,
429  	.idx2s		= icst307_idx2s,
430  };
431  
432  /*
433   * The core modules on the Integrator/AP and Integrator/CP have
434   * especially crippled ICST525 control.
435   */
436  static const struct icst_params icst525_apcp_cm_params = {
437  	.vco_max	= ICST525_VCO_MAX_5V,
438  	.vco_min	= ICST525_VCO_MIN,
439  	/* Minimum 12 MHz, VDW = 4 */
440  	.vd_min		= 12,
441  	/*
442  	 * Maximum 160 MHz, VDW = 152 for all core modules, but
443  	 * CM926EJ-S, CM1026EJ-S and CM1136JF-S can actually
444  	 * go to 200 MHz (max VDW = 192).
445  	 */
446  	.vd_max		= 192,
447  	/* r is hardcoded to 22 and this is the actual divisor, +2 */
448  	.rd_min		= 24,
449  	.rd_max		= 24,
450  	.s2div		= icst525_s2div,
451  	.idx2s		= icst525_idx2s,
452  };
453  
454  static const struct icst_params icst525_ap_sys_params = {
455  	.vco_max	= ICST525_VCO_MAX_5V,
456  	.vco_min	= ICST525_VCO_MIN,
457  	/* Minimum 3 MHz, VDW = 4 */
458  	.vd_min		= 3,
459  	/* Maximum 50 MHz, VDW = 192 */
460  	.vd_max		= 50,
461  	/* r is hardcoded to 46 and this is the actual divisor, +2 */
462  	.rd_min		= 48,
463  	.rd_max		= 48,
464  	.s2div		= icst525_s2div,
465  	.idx2s		= icst525_idx2s,
466  };
467  
468  static const struct icst_params icst525_ap_pci_params = {
469  	.vco_max	= ICST525_VCO_MAX_5V,
470  	.vco_min	= ICST525_VCO_MIN,
471  	/* Minimum 25 MHz */
472  	.vd_min		= 25,
473  	/* Maximum 33 MHz */
474  	.vd_max		= 33,
475  	/* r is hardcoded to 14 or 22 and this is the actual divisors +2 */
476  	.rd_min		= 16,
477  	.rd_max		= 24,
478  	.s2div		= icst525_s2div,
479  	.idx2s		= icst525_idx2s,
480  };
481  
of_syscon_icst_setup(struct device_node * np)482  static void __init of_syscon_icst_setup(struct device_node *np)
483  {
484  	struct device_node *parent;
485  	struct regmap *map;
486  	struct clk_icst_desc icst_desc;
487  	const char *name;
488  	const char *parent_name;
489  	struct clk *regclk;
490  	enum icst_control_type ctype;
491  
492  	/* We do not release this reference, we are using it perpetually */
493  	parent = of_get_parent(np);
494  	if (!parent) {
495  		pr_err("no parent node for syscon ICST clock\n");
496  		return;
497  	}
498  	map = syscon_node_to_regmap(parent);
499  	if (IS_ERR(map)) {
500  		pr_err("no regmap for syscon ICST clock parent\n");
501  		return;
502  	}
503  
504  	if (of_property_read_u32(np, "reg", &icst_desc.vco_offset) &&
505  	    of_property_read_u32(np, "vco-offset", &icst_desc.vco_offset)) {
506  		pr_err("no VCO register offset for ICST clock\n");
507  		return;
508  	}
509  	if (of_property_read_u32(np, "lock-offset", &icst_desc.lock_offset)) {
510  		pr_err("no lock register offset for ICST clock\n");
511  		return;
512  	}
513  
514  	if (of_device_is_compatible(np, "arm,syscon-icst525")) {
515  		icst_desc.params = &icst525_params;
516  		ctype = ICST_VERSATILE;
517  	} else if (of_device_is_compatible(np, "arm,syscon-icst307")) {
518  		icst_desc.params = &icst307_params;
519  		ctype = ICST_VERSATILE;
520  	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-cm")) {
521  		icst_desc.params = &icst525_apcp_cm_params;
522  		ctype = ICST_INTEGRATOR_AP_CM;
523  	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-sys")) {
524  		icst_desc.params = &icst525_ap_sys_params;
525  		ctype = ICST_INTEGRATOR_AP_SYS;
526  	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-pci")) {
527  		icst_desc.params = &icst525_ap_pci_params;
528  		ctype = ICST_INTEGRATOR_AP_PCI;
529  	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-core")) {
530  		icst_desc.params = &icst525_apcp_cm_params;
531  		ctype = ICST_INTEGRATOR_CP_CM_CORE;
532  	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-mem")) {
533  		icst_desc.params = &icst525_apcp_cm_params;
534  		ctype = ICST_INTEGRATOR_CP_CM_MEM;
535  	} else {
536  		pr_err("unknown ICST clock %pOF\n", np);
537  		return;
538  	}
539  
540  	/* Parent clock name is not the same as node parent */
541  	parent_name = of_clk_get_parent_name(np, 0);
542  	name = kasprintf(GFP_KERNEL, "%pOFP", np);
543  
544  	regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype);
545  	if (IS_ERR(regclk)) {
546  		pr_err("error setting up syscon ICST clock %s\n", name);
547  		kfree(name);
548  		return;
549  	}
550  	of_clk_add_provider(np, of_clk_src_simple_get, regclk);
551  	pr_debug("registered syscon ICST clock %s\n", name);
552  }
553  
554  CLK_OF_DECLARE(arm_syscon_icst525_clk,
555  	       "arm,syscon-icst525", of_syscon_icst_setup);
556  CLK_OF_DECLARE(arm_syscon_icst307_clk,
557  	       "arm,syscon-icst307", of_syscon_icst_setup);
558  CLK_OF_DECLARE(arm_syscon_integratorap_cm_clk,
559  	       "arm,syscon-icst525-integratorap-cm", of_syscon_icst_setup);
560  CLK_OF_DECLARE(arm_syscon_integratorap_sys_clk,
561  	       "arm,syscon-icst525-integratorap-sys", of_syscon_icst_setup);
562  CLK_OF_DECLARE(arm_syscon_integratorap_pci_clk,
563  	       "arm,syscon-icst525-integratorap-pci", of_syscon_icst_setup);
564  CLK_OF_DECLARE(arm_syscon_integratorcp_cm_core_clk,
565  	       "arm,syscon-icst525-integratorcp-cm-core", of_syscon_icst_setup);
566  CLK_OF_DECLARE(arm_syscon_integratorcp_cm_mem_clk,
567  	       "arm,syscon-icst525-integratorcp-cm-mem", of_syscon_icst_setup);
568  #endif
569