Lines Matching +full:set +full:- +full:rate +full:- +full:parent

1 // SPDX-License-Identifier: GPL-2.0-only
7 * Copyright (C) 2012-2015 Linus Walleij
17 #include <linux/clk-provider.h>
23 #include "clk-icst.h"
37 * struct clk_icst - ICST VCO clock wrapper
43 * @rate: current rate
52 unsigned long rate; member
59 * vco_get() - get ICST VCO settings from a certain ICST
68 ret = regmap_read(icst->map, icst->vcoreg_off, &val); in vco_get()
77 * "Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and in vco_get()
78 * CM1136JF-S User Guide" ARM DUI 0138E, page 3-13 thru 3-14. in vco_get()
80 if (icst->ctype == ICST_INTEGRATOR_AP_CM) { in vco_get()
81 vco->v = val & INTEGRATOR_AP_CM_BITS; in vco_get()
82 vco->r = 22; in vco_get()
83 vco->s = 1; in vco_get()
93 * page 3-16. in vco_get()
95 if (icst->ctype == ICST_INTEGRATOR_AP_SYS) { in vco_get()
96 vco->v = val & INTEGRATOR_AP_SYS_BITS; in vco_get()
97 vco->r = 46; in vco_get()
98 vco->s = 3; in vco_get()
110 if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { in vco_get()
113 vco->v = divxy ? 17 : 14; in vco_get()
114 vco->r = divxy ? 22 : 14; in vco_get()
115 vco->s = 1; in vco_get()
125 * ARM DUI 0157A, page 3-20 thru 3-23 and 4-10. in vco_get()
127 if (icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) { in vco_get()
128 vco->v = val & 0xFF; in vco_get()
129 vco->r = 22; in vco_get()
130 vco->s = (val >> 8) & 7; in vco_get()
134 if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) { in vco_get()
135 vco->v = (val >> 12) & 0xFF; in vco_get()
136 vco->r = 22; in vco_get()
137 vco->s = (val >> 20) & 7; in vco_get()
141 vco->v = val & 0x1ff; in vco_get()
142 vco->r = (val >> 9) & 0x7f; in vco_get()
143 vco->s = (val >> 16) & 03; in vco_get()
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
159 switch (icst->ctype) { in vco_set()
164 pr_err("ICST error: tried to set bit 8 of VDW\n"); in vco_set()
174 pr_err("ICST error: tried to set bit 8 of VDW\n"); in vco_set()
184 pr_err("ICST error: tried to set bit 8 of VDW\n"); in vco_set()
192 pr_err("ICST error: tried to set bit 8 of VDW\n"); in vco_set()
206 ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL); in vco_set()
209 ret = regmap_update_bits(icst->map, icst->vcoreg_off, mask, val); in vco_set()
213 ret = regmap_write(icst->map, icst->lockreg_off, 0); in vco_set()
227 icst->params->ref = parent_rate; in icst_recalc_rate()
233 icst->rate = icst_hz(icst->params, vco); in icst_recalc_rate()
234 return icst->rate; in icst_recalc_rate()
243 if (icst->ctype == ICST_INTEGRATOR_AP_CM || in icst_determine_rate()
244 icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) { in icst_determine_rate()
245 if (req->rate <= 12000000) in icst_determine_rate()
246 req->rate = 12000000; in icst_determine_rate()
247 else if (req->rate >= 160000000) in icst_determine_rate()
248 req->rate = 160000000; in icst_determine_rate()
251 req->rate = DIV_ROUND_CLOSEST(req->rate, 1000000) * 1000000; in icst_determine_rate()
257 if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) { in icst_determine_rate()
258 if (req->rate <= 6000000) in icst_determine_rate()
259 req->rate = 6000000; in icst_determine_rate()
260 else if (req->rate >= 66000000) in icst_determine_rate()
261 req->rate = 66000000; in icst_determine_rate()
264 req->rate = DIV_ROUND_CLOSEST(req->rate, 500000) * 500000; in icst_determine_rate()
270 if (icst->ctype == ICST_INTEGRATOR_AP_SYS) { in icst_determine_rate()
272 if (req->rate <= 3000000) in icst_determine_rate()
273 req->rate = 3000000; in icst_determine_rate()
274 else if (req->rate >= 50000000) in icst_determine_rate()
275 req->rate = 5000000; in icst_determine_rate()
278 req->rate = DIV_ROUND_CLOSEST(req->rate, 250000) * 250000; in icst_determine_rate()
284 if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { in icst_determine_rate()
289 if (req->rate <= 25000000 || req->rate < 29000000) in icst_determine_rate()
290 req->rate = 25000000; in icst_determine_rate()
293 req->rate = 33000000; in icst_determine_rate()
299 vco = icst_hz_to_vco(icst->params, req->rate); in icst_determine_rate()
300 req->rate = icst_hz(icst->params, vco); in icst_determine_rate()
305 static int icst_set_rate(struct clk_hw *hw, unsigned long rate, in icst_set_rate() argument
311 if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { in icst_set_rate()
316 if (rate == 25000000) { in icst_set_rate()
318 } else if (rate == 33000000) { in icst_set_rate()
321 pr_err("ICST: cannot set PCI frequency %lu\n", in icst_set_rate()
322 rate); in icst_set_rate()
323 return -EINVAL; in icst_set_rate()
325 ret = regmap_write(icst->map, icst->lockreg_off, in icst_set_rate()
329 ret = regmap_update_bits(icst->map, icst->vcoreg_off, in icst_set_rate()
335 ret = regmap_write(icst->map, icst->lockreg_off, 0); in icst_set_rate()
342 icst->params->ref = parent_rate; in icst_set_rate()
343 vco = icst_hz_to_vco(icst->params, rate); in icst_set_rate()
344 icst->rate = icst_hz(icst->params, vco); in icst_set_rate()
368 return ERR_PTR(-ENOMEM); in icst_clk_setup()
370 pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL); in icst_clk_setup()
373 return ERR_PTR(-ENOMEM); in icst_clk_setup()
381 icst->map = map; in icst_clk_setup()
382 icst->hw.init = &init; in icst_clk_setup()
383 icst->params = pclone; in icst_clk_setup()
384 icst->vcoreg_off = desc->vco_offset; in icst_clk_setup()
385 icst->lockreg_off = desc->lock_offset; in icst_clk_setup()
386 icst->ctype = ctype; in icst_clk_setup()
388 clk = clk_register(dev, &icst->hw); in icst_clk_setup()
423 * In a device tree, an memory-mapped ICST clock appear as a child
461 * CM926EJ-S, CM1026EJ-S and CM1136JF-S can actually
502 struct device_node *parent; in of_syscon_icst_setup() local
511 parent = of_get_parent(np); in of_syscon_icst_setup()
512 if (!parent) { in of_syscon_icst_setup()
513 pr_err("no parent node for syscon ICST clock\n"); in of_syscon_icst_setup()
516 map = syscon_node_to_regmap(parent); in of_syscon_icst_setup()
518 pr_err("no regmap for syscon ICST clock parent\n"); in of_syscon_icst_setup()
523 of_property_read_u32(np, "vco-offset", &icst_desc.vco_offset)) { in of_syscon_icst_setup()
527 if (of_property_read_u32(np, "lock-offset", &icst_desc.lock_offset)) { in of_syscon_icst_setup()
532 if (of_device_is_compatible(np, "arm,syscon-icst525")) { in of_syscon_icst_setup()
535 } else if (of_device_is_compatible(np, "arm,syscon-icst307")) { in of_syscon_icst_setup()
538 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-cm")) { in of_syscon_icst_setup()
541 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-sys")) { in of_syscon_icst_setup()
544 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-pci")) { in of_syscon_icst_setup()
547 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-core")) { in of_syscon_icst_setup()
550 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-mem")) { in of_syscon_icst_setup()
558 /* Parent clock name is not the same as node parent */ in of_syscon_icst_setup()
573 "arm,syscon-icst525", of_syscon_icst_setup);
575 "arm,syscon-icst307", of_syscon_icst_setup);
577 "arm,syscon-icst525-integratorap-cm", of_syscon_icst_setup);
579 "arm,syscon-icst525-integratorap-sys", of_syscon_icst_setup);
581 "arm,syscon-icst525-integratorap-pci", of_syscon_icst_setup);
583 "arm,syscon-icst525-integratorcp-cm-core", of_syscon_icst_setup);
585 "arm,syscon-icst525-integratorcp-cm-mem", of_syscon_icst_setup);