• Home
  • Raw
  • Download

Lines Matching +full:ti +full:- +full:sci

2  * SCI Clock driver for keystone based devices
4 * Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/
5 * Tero Kristo <t-kristo@ti.com>
16 #include <linux/clk-provider.h>
24 #include <linux/soc/ti/ti_sci_protocol.h>
33 * struct sci_clk_provider - TI SCI clock provider representation
34 * @sci: Handle to the System Control Interface protocol handler
35 * @ops: Pointer to the SCI ops to be used by the clocks
41 const struct ti_sci_handle *sci; member
49 * struct sci_clk - TI SCI clock representation
75 * sci_clk_prepare - Prepare (enable) a TI SCI clock
78 * Prepares a clock to be actively used. Returns the SCI protocol status.
83 bool enable_ssc = clk->flags & SCI_CLK_SSC_ENABLE; in sci_clk_prepare()
84 bool allow_freq_change = clk->flags & SCI_CLK_ALLOW_FREQ_CHANGE; in sci_clk_prepare()
85 bool input_termination = clk->flags & SCI_CLK_INPUT_TERMINATION; in sci_clk_prepare()
87 return clk->provider->ops->get_clock(clk->provider->sci, clk->dev_id, in sci_clk_prepare()
88 clk->clk_id, enable_ssc, in sci_clk_prepare()
94 * sci_clk_unprepare - Un-prepares (disables) a TI SCI clock
97 * Un-prepares a clock from active state.
104 ret = clk->provider->ops->put_clock(clk->provider->sci, clk->dev_id, in sci_clk_unprepare()
105 clk->clk_id); in sci_clk_unprepare()
107 dev_err(clk->provider->dev, in sci_clk_unprepare()
109 clk->dev_id, clk->clk_id, ret); in sci_clk_unprepare()
113 * sci_clk_is_prepared - Check if a TI SCI clock is prepared or not
116 * Checks if a clock is prepared (enabled) in hardware. Returns non-zero
125 ret = clk->provider->ops->is_on(clk->provider->sci, clk->dev_id, in sci_clk_is_prepared()
126 clk->clk_id, &req_state, in sci_clk_is_prepared()
129 dev_err(clk->provider->dev, in sci_clk_is_prepared()
131 clk->dev_id, clk->clk_id, ret); in sci_clk_is_prepared()
139 * sci_clk_recalc_rate - Get clock rate for a TI SCI clock
143 * Gets the current clock rate of a TI SCI clock. Returns the current
153 ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id, in sci_clk_recalc_rate()
154 clk->clk_id, &freq); in sci_clk_recalc_rate()
156 dev_err(clk->provider->dev, in sci_clk_recalc_rate()
157 "recalc-rate failed for dev=%d, clk=%d, ret=%d\n", in sci_clk_recalc_rate()
158 clk->dev_id, clk->clk_id, ret); in sci_clk_recalc_rate()
166 * sci_clk_determine_rate - Determines a clock rate a clock can be set to
170 * Determines a suitable clock rate and parent for a TI SCI clock.
171 * The parent handling is un-used, as generally the parent clock rates
182 if (clk->cached_req && clk->cached_req == req->rate) { in sci_clk_determine_rate()
183 req->rate = clk->cached_res; in sci_clk_determine_rate()
187 ret = clk->provider->ops->get_best_match_freq(clk->provider->sci, in sci_clk_determine_rate()
188 clk->dev_id, in sci_clk_determine_rate()
189 clk->clk_id, in sci_clk_determine_rate()
190 req->min_rate, in sci_clk_determine_rate()
191 req->rate, in sci_clk_determine_rate()
192 req->max_rate, in sci_clk_determine_rate()
195 dev_err(clk->provider->dev, in sci_clk_determine_rate()
196 "determine-rate failed for dev=%d, clk=%d, ret=%d\n", in sci_clk_determine_rate()
197 clk->dev_id, clk->clk_id, ret); in sci_clk_determine_rate()
201 clk->cached_req = req->rate; in sci_clk_determine_rate()
202 clk->cached_res = new_rate; in sci_clk_determine_rate()
204 req->rate = new_rate; in sci_clk_determine_rate()
210 * sci_clk_set_rate - Set rate for a TI SCI clock
213 * @parent_rate: rate of the clock parent, not used for TI SCI clocks
215 * Sets a clock frequency for a TI SCI clock. Returns the TI SCI
223 return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id, in sci_clk_set_rate()
224 clk->clk_id, rate / 10 * 9, rate, in sci_clk_set_rate()
229 * sci_clk_get_parent - Get the current parent of a TI SCI clock
232 * Returns the index of the currently selected parent for a TI SCI clock.
240 ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id, in sci_clk_get_parent()
241 clk->clk_id, (void *)&parent_id); in sci_clk_get_parent()
243 dev_err(clk->provider->dev, in sci_clk_get_parent()
244 "get-parent failed for dev=%d, clk=%d, ret=%d\n", in sci_clk_get_parent()
245 clk->dev_id, clk->clk_id, ret); in sci_clk_get_parent()
249 parent_id = parent_id - clk->clk_id - 1; in sci_clk_get_parent()
255 * sci_clk_set_parent - Set the parent of a TI SCI clock
259 * Sets the parent of a TI SCI clock. Return TI SCI protocol status.
265 clk->cached_req = 0; in sci_clk_set_parent()
267 return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id, in sci_clk_set_parent()
268 clk->clk_id, in sci_clk_set_parent()
269 index + 1 + clk->clk_id); in sci_clk_set_parent()
284 * _sci_clk_get - Gets a handle for an SCI clock
285 * @provider: Handle to SCI clock provider
286 * @sci_clk: Handle to the SCI clock to populate
288 * Gets a handle to an existing TI SCI hw clock, or builds a new clock
303 name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id, in _sci_clk_build()
304 sci_clk->clk_id); in _sci_clk_build()
306 return -ENOMEM; in _sci_clk_build()
316 if (sci_clk->num_parents < 2) in _sci_clk_build()
317 sci_clk->num_parents = 0; in _sci_clk_build()
319 if (sci_clk->num_parents) { in _sci_clk_build()
320 parent_names = kcalloc(sci_clk->num_parents, sizeof(char *), in _sci_clk_build()
324 ret = -ENOMEM; in _sci_clk_build()
328 for (i = 0; i < sci_clk->num_parents; i++) { in _sci_clk_build()
332 sci_clk->dev_id, in _sci_clk_build()
333 sci_clk->clk_id + 1 + i); in _sci_clk_build()
335 ret = -ENOMEM; in _sci_clk_build()
344 init.num_parents = sci_clk->num_parents; in _sci_clk_build()
345 sci_clk->hw.init = &init; in _sci_clk_build()
347 ret = devm_clk_hw_register(provider->dev, &sci_clk->hw); in _sci_clk_build()
349 dev_err(provider->dev, "failed clk register with %d\n", ret); in _sci_clk_build()
353 for (i = 0; i < sci_clk->num_parents; i++) in _sci_clk_build()
369 if (ca->dev_id == cb->dev_id && ca->clk_id == cb->clk_id) in _cmp_sci_clk()
371 if (ca->dev_id > cb->dev_id || in _cmp_sci_clk()
372 (ca->dev_id == cb->dev_id && ca->clk_id > cb->clk_id)) in _cmp_sci_clk()
374 return -1; in _cmp_sci_clk()
378 * sci_clk_get - Xlate function for getting clock handles
382 * Xlate function for retrieving clock TI SCI hw clock handles based on
385 * to the TI SCI hw clock struct, or ERR_PTR value in failure.
393 if (clkspec->args_count != 2) in sci_clk_get()
394 return ERR_PTR(-EINVAL); in sci_clk_get()
396 key.dev_id = clkspec->args[0]; in sci_clk_get()
397 key.clk_id = clkspec->args[1]; in sci_clk_get()
399 clk = bsearch(&key, provider->clocks, provider->num_clocks, in sci_clk_get()
403 return ERR_PTR(-ENODEV); in sci_clk_get()
405 return &(*clk)->hw; in sci_clk_get()
413 for (i = 0; i < p->num_clocks; i++) { in ti_sci_init_clocks()
414 ret = _sci_clk_build(p, p->clocks[i]); in ti_sci_init_clocks()
423 { .compatible = "ti,k2g-sci-clk" },
441 struct device *dev = provider->dev; in ti_sci_scan_clocks_from_fw()
444 ret = provider->ops->get_num_parents(provider->sci, dev_id, in ti_sci_scan_clocks_from_fw()
480 return -ENOMEM; in ti_sci_scan_clocks_from_fw()
481 sci_clk->dev_id = dev_id; in ti_sci_scan_clocks_from_fw()
482 sci_clk->clk_id = clk_id; in ti_sci_scan_clocks_from_fw()
483 sci_clk->provider = provider; in ti_sci_scan_clocks_from_fw()
484 sci_clk->num_parents = num_parents; in ti_sci_scan_clocks_from_fw()
492 provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk), in ti_sci_scan_clocks_from_fw()
494 if (!provider->clocks) in ti_sci_scan_clocks_from_fw()
495 return -ENOMEM; in ti_sci_scan_clocks_from_fw()
497 memcpy(provider->clocks, clks, num_clks * sizeof(sci_clk)); in ti_sci_scan_clocks_from_fw()
499 provider->num_clocks = num_clks; in ti_sci_scan_clocks_from_fw()
519 struct device *dev = provider->dev; in ti_sci_scan_clocks_from_dt()
530 "clocks", "assigned-clocks", "assigned-clock-parents", NULL in ti_sci_scan_clocks_from_dt()
552 "#clock-cells", index, in ti_sci_scan_clocks_from_dt()
557 if (args.args_count == 2 && args.np == dev->of_node) { in ti_sci_scan_clocks_from_dt()
561 return -ENOMEM; in ti_sci_scan_clocks_from_dt()
563 sci_clk->dev_id = args.args[0]; in ti_sci_scan_clocks_from_dt()
564 sci_clk->clk_id = args.args[1]; in ti_sci_scan_clocks_from_dt()
565 sci_clk->provider = provider; in ti_sci_scan_clocks_from_dt()
566 provider->ops->get_num_parents(provider->sci, in ti_sci_scan_clocks_from_dt()
567 sci_clk->dev_id, in ti_sci_scan_clocks_from_dt()
568 sci_clk->clk_id, in ti_sci_scan_clocks_from_dt()
569 (void *)&sci_clk->num_parents); in ti_sci_scan_clocks_from_dt()
570 list_add_tail(&sci_clk->node, &clks); in ti_sci_scan_clocks_from_dt()
574 num_parents = sci_clk->num_parents; in ti_sci_scan_clocks_from_dt()
582 * any mux clock from sci-clk driver in ti_sci_scan_clocks_from_dt()
590 sci_clk->dev_id, in ti_sci_scan_clocks_from_dt()
591 sci_clk->clk_id, num_parents); in ti_sci_scan_clocks_from_dt()
597 while (num_parents--) { in ti_sci_scan_clocks_from_dt()
602 return -ENOMEM; in ti_sci_scan_clocks_from_dt()
603 sci_clk->dev_id = args.args[0]; in ti_sci_scan_clocks_from_dt()
604 sci_clk->clk_id = clk_id++; in ti_sci_scan_clocks_from_dt()
605 sci_clk->provider = provider; in ti_sci_scan_clocks_from_dt()
606 list_add_tail(&sci_clk->node, &clks); in ti_sci_scan_clocks_from_dt()
618 provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk), in ti_sci_scan_clocks_from_dt()
620 if (!provider->clocks) in ti_sci_scan_clocks_from_dt()
621 return -ENOMEM; in ti_sci_scan_clocks_from_dt()
627 if (prev && prev->dev_id == sci_clk->dev_id && in ti_sci_scan_clocks_from_dt()
628 prev->clk_id == sci_clk->clk_id) in ti_sci_scan_clocks_from_dt()
631 provider->clocks[num_clks++] = sci_clk; in ti_sci_scan_clocks_from_dt()
635 provider->num_clocks = num_clks; in ti_sci_scan_clocks_from_dt()
642 * ti_sci_clk_probe - Probe function for the TI SCI clock driver
645 * Probes the TI SCI clock device. Allocates a new clock provider
653 struct device *dev = &pdev->dev; in ti_sci_clk_probe()
654 struct device_node *np = dev->of_node; in ti_sci_clk_probe()
665 return -ENOMEM; in ti_sci_clk_probe()
667 provider->sci = handle; in ti_sci_clk_probe()
668 provider->ops = &handle->ops.clk_ops; in ti_sci_clk_probe()
669 provider->dev = dev; in ti_sci_clk_probe()
687 pr_err("ti-sci-init-clocks failed.\n"); in ti_sci_clk_probe()
695 * ti_sci_clk_remove - Remove TI SCI clock device
698 * Removes the TI SCI device. Unregisters the clock provider registered
704 of_clk_del_provider(pdev->dev.of_node); in ti_sci_clk_remove()
713 .name = "ti-sci-clk",
720 MODULE_DESCRIPTION("TI System Control Interface(SCI) Clock driver");
722 MODULE_ALIAS("platform:ti-sci-clk");