Lines Matching +full:bt1 +full:- +full:ccu

1 // SPDX-License-Identifier: GPL-2.0-only
9 * Baikal-T1 CCU PLL interface driver
12 #define pr_fmt(fmt) "bt1-ccu-pll: " fmt
20 #include <linux/clk-provider.h>
29 #include "ccu-pll.h"
97 regmap_update_bits(pll->sys_regs, pll->reg_ctl, in ccu_pll_reset()
100 return regmap_read_poll_timeout_atomic(pll->sys_regs, pll->reg_ctl, val, in ccu_pll_reset()
114 return -EINVAL; in ccu_pll_enable()
117 regmap_read(pll->sys_regs, pll->reg_ctl, &val); in ccu_pll_enable()
121 spin_lock_irqsave(&pll->lock, flags); in ccu_pll_enable()
122 regmap_write(pll->sys_regs, pll->reg_ctl, val | CCU_PLL_CTL_EN); in ccu_pll_enable()
125 spin_unlock_irqrestore(&pll->lock, flags); in ccu_pll_enable()
137 spin_lock_irqsave(&pll->lock, flags); in ccu_pll_disable()
138 regmap_update_bits(pll->sys_regs, pll->reg_ctl, CCU_PLL_CTL_EN, 0); in ccu_pll_disable()
139 spin_unlock_irqrestore(&pll->lock, flags); in ccu_pll_disable()
147 regmap_read(pll->sys_regs, pll->reg_ctl, &val); in ccu_pll_is_enabled()
159 regmap_read(pll->sys_regs, pll->reg_ctl, &val); in ccu_pll_recalc_rate()
205 * Bypass the out-of-bound values, which can't be properly in ccu_pll_calc_factors()
221 err = abs((int64_t)freq - num); in ccu_pll_calc_factors()
242 * This method is used for PLLs, which support the on-the-fly dividers
258 val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) | in ccu_pll_set_rate_reset()
259 FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) | in ccu_pll_set_rate_reset()
260 FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1); in ccu_pll_set_rate_reset()
262 spin_lock_irqsave(&pll->lock, flags); in ccu_pll_set_rate_reset()
263 regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val); in ccu_pll_set_rate_reset()
265 spin_unlock_irqrestore(&pll->lock, flags); in ccu_pll_set_rate_reset()
273 * This method is used for PLLs, which don't support the on-the-fly dividers
292 val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) | in ccu_pll_set_rate_norst()
293 FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) | in ccu_pll_set_rate_norst()
294 FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1); in ccu_pll_set_rate_norst()
296 spin_lock_irqsave(&pll->lock, flags); in ccu_pll_set_rate_norst()
297 regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val); in ccu_pll_set_rate_norst()
298 spin_unlock_irqrestore(&pll->lock, flags); in ccu_pll_set_rate_norst()
372 struct ccu_pll *pll = bit->pll; in ccu_pll_dbgfs_bit_set()
375 spin_lock_irqsave(&pll->lock, flags); in ccu_pll_dbgfs_bit_set()
376 regmap_update_bits(pll->sys_regs, pll->reg_ctl + bit->reg, in ccu_pll_dbgfs_bit_set()
377 bit->mask, val ? bit->mask : 0); in ccu_pll_dbgfs_bit_set()
378 spin_unlock_irqrestore(&pll->lock, flags); in ccu_pll_dbgfs_bit_set()
386 struct ccu_pll *pll = fld->pll; in ccu_pll_dbgfs_fld_set()
390 val = clamp_t(u64, val, fld->min, fld->max); in ccu_pll_dbgfs_fld_set()
391 data = ((val - 1) << fld->lsb) & fld->mask; in ccu_pll_dbgfs_fld_set()
393 spin_lock_irqsave(&pll->lock, flags); in ccu_pll_dbgfs_fld_set()
394 regmap_update_bits(pll->sys_regs, pll->reg_ctl + fld->reg, fld->mask, in ccu_pll_dbgfs_fld_set()
396 spin_unlock_irqrestore(&pll->lock, flags); in ccu_pll_dbgfs_fld_set()
414 struct ccu_pll *pll = bit->pll; in ccu_pll_dbgfs_bit_get()
417 regmap_read(pll->sys_regs, pll->reg_ctl + bit->reg, &data); in ccu_pll_dbgfs_bit_get()
418 *val = !!(data & bit->mask); in ccu_pll_dbgfs_bit_get()
428 struct ccu_pll *pll = fld->pll; in ccu_pll_dbgfs_fld_get()
431 regmap_read(pll->sys_regs, pll->reg_ctl + fld->reg, &data); in ccu_pll_dbgfs_fld_get()
432 *val = ((data & fld->mask) >> fld->lsb) + 1; in ccu_pll_dbgfs_fld_get()
507 return ERR_PTR(-EINVAL); in ccu_pll_hw_register()
511 return ERR_PTR(-ENOMEM); in ccu_pll_hw_register()
514 * Note since Baikal-T1 System Controller registers are MMIO-backed in ccu_pll_hw_register()
518 pll->hw.init = &hw_init; in ccu_pll_hw_register()
519 pll->reg_ctl = pll_init->base + CCU_PLL_CTL; in ccu_pll_hw_register()
520 pll->reg_ctl1 = pll_init->base + CCU_PLL_CTL1; in ccu_pll_hw_register()
521 pll->sys_regs = pll_init->sys_regs; in ccu_pll_hw_register()
522 pll->id = pll_init->id; in ccu_pll_hw_register()
523 spin_lock_init(&pll->lock); in ccu_pll_hw_register()
525 hw_init.name = pll_init->name; in ccu_pll_hw_register()
526 hw_init.flags = pll_init->flags; in ccu_pll_hw_register()
533 if (!pll_init->parent_name) { in ccu_pll_hw_register()
534 ret = -EINVAL; in ccu_pll_hw_register()
537 parent_data.fw_name = pll_init->parent_name; in ccu_pll_hw_register()
541 ret = of_clk_hw_register(pll_init->np, &pll->hw); in ccu_pll_hw_register()
555 clk_hw_unregister(&pll->hw); in ccu_pll_hw_unregister()