Lines Matching +full:fixed +full:- +full:rate
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Clock driver for Loongson-1 SoC
5 * Copyright (C) 2012-2023 Keguang Zhang <keguang.zhang@gmail.com>
9 #include <linux/clk-provider.h>
17 #include <dt-bindings/clock/loongson,ls1x-clk.h>
26 u32 fixed; member
64 const struct ls1x_clk_pll_data *d = ls1x_clk->data; in ls1x_pll_recalc_rate()
65 u32 val, rate; in ls1x_pll_recalc_rate() local
67 val = readl(ls1x_clk->reg); in ls1x_pll_recalc_rate()
68 rate = d->fixed; in ls1x_pll_recalc_rate()
69 rate += ls1x_pll_rate_part(val, d->int_shift, d->int_width); in ls1x_pll_recalc_rate()
70 if (d->frac_width) in ls1x_pll_recalc_rate()
71 rate += ls1x_pll_rate_part(val, d->frac_shift, d->frac_width); in ls1x_pll_recalc_rate()
72 rate *= parent_rate; in ls1x_pll_recalc_rate()
73 rate >>= d->shift; in ls1x_pll_recalc_rate()
75 return rate; in ls1x_pll_recalc_rate()
86 const struct ls1x_clk_div_data *d = ls1x_clk->data; in ls1x_divider_recalc_rate()
89 val = readl(ls1x_clk->reg) >> d->shift; in ls1x_divider_recalc_rate()
90 val &= clk_div_mask(d->width); in ls1x_divider_recalc_rate()
92 return divider_recalc_rate(hw, parent_rate, val, d->table, in ls1x_divider_recalc_rate()
93 d->flags, d->width); in ls1x_divider_recalc_rate()
96 static long ls1x_divider_round_rate(struct clk_hw *hw, unsigned long rate, in ls1x_divider_round_rate() argument
100 const struct ls1x_clk_div_data *d = ls1x_clk->data; in ls1x_divider_round_rate()
102 return divider_round_rate(hw, rate, prate, d->table, in ls1x_divider_round_rate()
103 d->width, d->flags); in ls1x_divider_round_rate()
106 static int ls1x_divider_set_rate(struct clk_hw *hw, unsigned long rate, in ls1x_divider_set_rate() argument
110 const struct ls1x_clk_div_data *d = ls1x_clk->data; in ls1x_divider_set_rate()
114 div_val = divider_get_val(rate, parent_rate, d->table, in ls1x_divider_set_rate()
115 d->width, d->flags); in ls1x_divider_set_rate()
119 spin_lock_irqsave(d->lock, flags); in ls1x_divider_set_rate()
122 val = readl(ls1x_clk->reg); in ls1x_divider_set_rate()
123 if (d->bypass_inv) in ls1x_divider_set_rate()
124 val &= ~BIT(d->bypass_shift); in ls1x_divider_set_rate()
126 val |= BIT(d->bypass_shift); in ls1x_divider_set_rate()
127 writel(val, ls1x_clk->reg); in ls1x_divider_set_rate()
129 val = readl(ls1x_clk->reg); in ls1x_divider_set_rate()
130 val &= ~(clk_div_mask(d->width) << d->shift); in ls1x_divider_set_rate()
131 val |= (u32)div_val << d->shift; in ls1x_divider_set_rate()
132 writel(val, ls1x_clk->reg); in ls1x_divider_set_rate()
135 val = readl(ls1x_clk->reg); in ls1x_divider_set_rate()
136 if (d->bypass_inv) in ls1x_divider_set_rate()
137 val |= BIT(d->bypass_shift); in ls1x_divider_set_rate()
139 val &= ~BIT(d->bypass_shift); in ls1x_divider_set_rate()
140 writel(val, ls1x_clk->reg); in ls1x_divider_set_rate()
142 spin_unlock_irqrestore(d->lock, flags); in ls1x_divider_set_rate()
158 .fixed = (_fixed), \
171 .index = -1, \
264 for (i = 0; i < hw_data->num; i++) { in ls1x_clk_init()
266 if (!hw_data->hws[i]) in ls1x_clk_init()
270 ls1x_clk = to_ls1x_clk(hw_data->hws[i]); in ls1x_clk_init()
271 ls1x_clk->reg = reg + ls1x_clk->offset; in ls1x_clk_init()
274 ret = of_clk_hw_register(np, hw_data->hws[i]); in ls1x_clk_init()
286 while (--i >= 0) in ls1x_clk_init()
287 clk_hw_unregister(hw_data->hws[i]); in ls1x_clk_init()
302 CLK_OF_DECLARE(ls1b_clk, "loongson,ls1b-clk", ls1b_clk_init);
303 CLK_OF_DECLARE(ls1c_clk, "loongson,ls1c-clk", ls1c_clk_init);