Lines Matching +full:clk +full:- +full:div
1 // SPDX-License-Identifier: GPL-2.0
5 * based on clk-mux.c
9 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
13 #include <linux/clk-provider.h>
18 #include "clk.h"
50 val = readl_relaxed(sdmmc_mux->reg); in clk_sdmmc_mux_get_parent()
73 val = readl_relaxed(sdmmc_mux->reg); in clk_sdmmc_mux_set_parent()
82 writel(val, sdmmc_mux->reg); in clk_sdmmc_mux_set_parent()
92 int div; in clk_sdmmc_mux_recalc_rate() local
95 val = readl_relaxed(sdmmc_mux->reg); in clk_sdmmc_mux_recalc_rate()
96 div = get_div_field(val); in clk_sdmmc_mux_recalc_rate()
98 div += SDMMC_MUL; in clk_sdmmc_mux_recalc_rate()
101 rate += div - 1; in clk_sdmmc_mux_recalc_rate()
102 do_div(rate, div); in clk_sdmmc_mux_recalc_rate()
111 int div; in clk_sdmmc_mux_determine_rate() local
112 unsigned long output_rate = req->best_parent_rate; in clk_sdmmc_mux_determine_rate()
114 req->rate = max(req->rate, req->min_rate); in clk_sdmmc_mux_determine_rate()
115 req->rate = min(req->rate, req->max_rate); in clk_sdmmc_mux_determine_rate()
117 if (!req->rate) in clk_sdmmc_mux_determine_rate()
120 div = div_frac_get(req->rate, output_rate, 8, 1, sdmmc_mux->div_flags); in clk_sdmmc_mux_determine_rate()
121 if (div < 0) in clk_sdmmc_mux_determine_rate()
122 div = 0; in clk_sdmmc_mux_determine_rate()
124 if (sdmmc_mux->div_flags & TEGRA_DIVIDER_ROUND_UP) in clk_sdmmc_mux_determine_rate()
125 req->rate = DIV_ROUND_UP(output_rate * SDMMC_MUL, in clk_sdmmc_mux_determine_rate()
126 div + SDMMC_MUL); in clk_sdmmc_mux_determine_rate()
128 req->rate = output_rate * SDMMC_MUL / (div + SDMMC_MUL); in clk_sdmmc_mux_determine_rate()
137 int div; in clk_sdmmc_mux_set_rate() local
142 div = div_frac_get(rate, parent_rate, 8, 1, sdmmc_mux->div_flags); in clk_sdmmc_mux_set_rate()
143 if (div < 0) in clk_sdmmc_mux_set_rate()
144 return div; in clk_sdmmc_mux_set_rate()
146 if (sdmmc_mux->lock) in clk_sdmmc_mux_set_rate()
147 spin_lock_irqsave(sdmmc_mux->lock, flags); in clk_sdmmc_mux_set_rate()
150 if (div) in clk_sdmmc_mux_set_rate()
156 val |= div; in clk_sdmmc_mux_set_rate()
157 writel(val, sdmmc_mux->reg); in clk_sdmmc_mux_set_rate()
158 fence_udelay(2, sdmmc_mux->reg); in clk_sdmmc_mux_set_rate()
160 if (sdmmc_mux->lock) in clk_sdmmc_mux_set_rate()
161 spin_unlock_irqrestore(sdmmc_mux->lock, flags); in clk_sdmmc_mux_set_rate()
169 const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; in clk_sdmmc_mux_is_enabled()
170 struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; in clk_sdmmc_mux_is_enabled()
174 return gate_ops->is_enabled(gate_hw); in clk_sdmmc_mux_is_enabled()
180 const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; in clk_sdmmc_mux_enable()
181 struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; in clk_sdmmc_mux_enable()
185 return gate_ops->enable(gate_hw); in clk_sdmmc_mux_enable()
191 const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; in clk_sdmmc_mux_disable()
192 struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; in clk_sdmmc_mux_disable()
194 gate_ops->disable(gate_hw); in clk_sdmmc_mux_disable()
224 struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, in tegra_clk_register_sdmmc_mux_div()
228 struct clk *clk; in tegra_clk_register_sdmmc_mux_div() local
241 return ERR_PTR(-EINVAL); in tegra_clk_register_sdmmc_mux_div()
245 return ERR_PTR(-ENOMEM); in tegra_clk_register_sdmmc_mux_div()
248 sdmmc_mux->hw.init = &init; in tegra_clk_register_sdmmc_mux_div()
249 sdmmc_mux->reg = clk_base + offset; in tegra_clk_register_sdmmc_mux_div()
250 sdmmc_mux->lock = lock; in tegra_clk_register_sdmmc_mux_div()
251 sdmmc_mux->gate.clk_base = clk_base; in tegra_clk_register_sdmmc_mux_div()
252 sdmmc_mux->gate.regs = bank; in tegra_clk_register_sdmmc_mux_div()
253 sdmmc_mux->gate.enable_refcnt = periph_clk_enb_refcnt; in tegra_clk_register_sdmmc_mux_div()
254 sdmmc_mux->gate.clk_num = clk_num; in tegra_clk_register_sdmmc_mux_div()
255 sdmmc_mux->gate.flags = TEGRA_PERIPH_ON_APB; in tegra_clk_register_sdmmc_mux_div()
256 sdmmc_mux->div_flags = div_flags; in tegra_clk_register_sdmmc_mux_div()
257 sdmmc_mux->gate_ops = &tegra_clk_periph_gate_ops; in tegra_clk_register_sdmmc_mux_div()
259 clk = clk_register(NULL, &sdmmc_mux->hw); in tegra_clk_register_sdmmc_mux_div()
260 if (IS_ERR(clk)) { in tegra_clk_register_sdmmc_mux_div()
262 return clk; in tegra_clk_register_sdmmc_mux_div()
265 sdmmc_mux->gate.hw.clk = clk; in tegra_clk_register_sdmmc_mux_div()
267 return clk; in tegra_clk_register_sdmmc_mux_div()