Lines Matching +full:platform +full:- +full:pll +full:- +full:div2

1 // SPDX-License-Identifier: GPL-2.0
3 * Sophgo SG2044 PLL clock controller driver
13 #include <linux/clk-provider.h>
22 #include <dt-bindings/clock/sophgo,sg2044-pll.h>
57 for (_var = (_limit)->min; _var <= (_limit)->max; _var++)
85 struct sg2044_pll_internal pll; member
90 struct sg2044_clk_common * const *pll; member
107 return value >= limit->min && value <= limit->max; in sg2044_clk_fit_limit()
142 struct sg2044_pll *pll = hw_to_sg2044_pll(hw); in sg2044_pll_recalc_rate() local
146 ret = regmap_read(pll->common.regmap, in sg2044_pll_recalc_rate()
147 pll->syscon_offset + pll->pll.ctrl_offset + PLL_HIGH_CTRL_OFFSET, in sg2044_pll_recalc_rate()
173 unsigned int div1, div2; in sg2042_pll_compute_postdiv() local
177 for_each_pll_limit_range(div2, &limits[PLL_LIMIT_POSTDIV2]) { in sg2042_pll_compute_postdiv()
181 div1, div2); in sg2042_pll_compute_postdiv()
188 best_div2 = div2; in sg2042_pll_compute_postdiv()
204 return -EINVAL; in sg2042_pll_compute_postdiv()
257 return -EINVAL; in sg2044_compute_pll_setting()
263 struct sg2044_pll *pll = hw_to_sg2044_pll(hw); in sg2044_pll_determine_rate() local
268 target = clamp(req->rate, pll->pll.limits[PLL_LIMIT_FOUT].min, in sg2044_pll_determine_rate()
269 pll->pll.limits[PLL_LIMIT_FOUT].max); in sg2044_pll_determine_rate()
271 ret = sg2044_compute_pll_setting(pll->pll.limits, target, in sg2044_pll_determine_rate()
272 req->best_parent_rate, &value); in sg2044_pll_determine_rate()
276 req->rate = sg2044_pll_calc_rate(req->best_parent_rate, in sg2044_pll_determine_rate()
285 static int sg2044_pll_poll_update(struct sg2044_pll *pll) in sg2044_pll_poll_update() argument
290 ret = regmap_read_poll_timeout_atomic(pll->common.regmap, in sg2044_pll_poll_update()
291 pll->syscon_offset + pll->pll.status_offset, in sg2044_pll_poll_update()
293 (value & BIT(pll->pll.status_lock_bit)), in sg2044_pll_poll_update()
298 return regmap_read_poll_timeout_atomic(pll->common.regmap, in sg2044_pll_poll_update()
299 pll->syscon_offset + pll->pll.status_offset, in sg2044_pll_poll_update()
301 (!(value & BIT(pll->pll.status_updating_bit))), in sg2044_pll_poll_update()
305 static int sg2044_pll_enable(struct sg2044_pll *pll, bool en) in sg2044_pll_enable() argument
308 if (sg2044_pll_poll_update(pll) < 0) in sg2044_pll_enable()
309 pr_warn("%s: fail to lock pll\n", clk_hw_get_name(&pll->common.hw)); in sg2044_pll_enable()
311 return regmap_set_bits(pll->common.regmap, in sg2044_pll_enable()
312 pll->syscon_offset + pll->pll.enable_offset, in sg2044_pll_enable()
313 BIT(pll->pll.enable_bit)); in sg2044_pll_enable()
316 return regmap_clear_bits(pll->common.regmap, in sg2044_pll_enable()
317 pll->syscon_offset + pll->pll.enable_offset, in sg2044_pll_enable()
318 BIT(pll->pll.enable_bit)); in sg2044_pll_enable()
321 static int sg2044_pll_update_vcosel(struct sg2044_pll *pll, u64 rate) in sg2044_pll_update_vcosel() argument
330 return regmap_write_bits(pll->common.regmap, in sg2044_pll_update_vcosel()
331 pll->syscon_offset + pll->pll.ctrl_offset, in sg2044_pll_update_vcosel()
339 struct sg2044_pll *pll = hw_to_sg2044_pll(hw); in sg2044_pll_set_rate() local
344 ret = sg2044_compute_pll_setting(pll->pll.limits, rate, in sg2044_pll_set_rate()
357 guard(spinlock_irqsave)(pll->common.lock); in sg2044_pll_set_rate()
359 ret = sg2044_pll_enable(pll, false); in sg2044_pll_set_rate()
363 sg2044_pll_update_vcosel(pll, vco); in sg2044_pll_set_rate()
365 regmap_write_bits(pll->common.regmap, in sg2044_pll_set_rate()
366 pll->syscon_offset + pll->pll.ctrl_offset + in sg2044_pll_set_rate()
370 sg2044_pll_enable(pll, true); in sg2044_pll_set_rate()
402 .pll = { \
423 .pll = { \
559 spin_lock_init(&ctrl->lock); in sg2044_pll_init_ctrl()
561 for (i = 0; i < desc->num_pll; i++) { in sg2044_pll_init_ctrl()
562 struct sg2044_clk_common *common = desc->pll[i]; in sg2044_pll_init_ctrl()
563 struct sg2044_pll *pll = hw_to_sg2044_pll(&common->hw); in sg2044_pll_init_ctrl() local
565 common->lock = &ctrl->lock; in sg2044_pll_init_ctrl()
566 common->regmap = regmap; in sg2044_pll_init_ctrl()
567 pll->syscon_offset = SG2044_SYSCON_PLL_OFFSET; in sg2044_pll_init_ctrl()
569 ret = devm_clk_hw_register(dev, &common->hw); in sg2044_pll_init_ctrl()
573 ctrl->data.hws[common->id] = &common->hw; in sg2044_pll_init_ctrl()
577 &ctrl->data); in sg2044_pll_init_ctrl()
582 struct device *dev = &pdev->dev; in sg2044_pll_probe()
587 regmap = device_node_to_regmap(pdev->dev.parent->of_node); in sg2044_pll_probe()
590 "fail to get the regmap for PLL\n"); in sg2044_pll_probe()
592 desc = (const struct sg2044_pll_desc_data *)platform_get_device_id(pdev)->driver_data; in sg2044_pll_probe()
594 return dev_err_probe(dev, -EINVAL, "no match data for platform\n"); in sg2044_pll_probe()
596 ctrl = devm_kzalloc(dev, struct_size(ctrl, data.hws, desc->num_pll), GFP_KERNEL); in sg2044_pll_probe()
598 return -ENOMEM; in sg2044_pll_probe()
600 ctrl->data.num = desc->num_pll; in sg2044_pll_probe()
606 .pll = sg2044_pll_commons,
611 { .name = "sg2044-pll",
615 MODULE_DEVICE_TABLE(platform, sg2044_pll_match);
620 .name = "sg2044-pll",
627 MODULE_DESCRIPTION("Sophgo SG2044 pll clock driver");