Lines Matching +full:clk +full:- +full:div
1 // SPDX-License-Identifier: GPL-2.0+
3 * Based on drivers/clk/tegra/clk-emc.c
7 * Copyright (C) 2019 GRATE-DRIVER project
10 #define pr_fmt(fmt) "tegra-emc-clk: " fmt
13 #include <linux/clk-provider.h>
14 #include <linux/clk/tegra.h>
20 #include "clk.h"
57 u32 val, div; in emc_recalc_rate() local
59 val = readl_relaxed(emc->reg); in emc_recalc_rate()
60 div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; in emc_recalc_rate()
62 return DIV_ROUND_UP(parent_rate * 2, div + 2); in emc_recalc_rate()
69 return readl_relaxed(emc->reg) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; in emc_get_parent()
75 u32 val, div; in emc_set_parent() local
77 val = readl_relaxed(emc->reg); in emc_set_parent()
81 div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; in emc_set_parent()
83 if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) in emc_set_parent()
88 if (emc->mc_same_freq) in emc_set_parent()
93 writel_relaxed(val, emc->reg); in emc_set_parent()
95 fence_udelay(1, emc->reg); in emc_set_parent()
105 u32 val, div; in emc_set_rate() local
107 div = div_frac_get(rate, parent_rate, 8, 1, 0); in emc_set_rate()
109 val = readl_relaxed(emc->reg); in emc_set_rate()
111 val |= div; in emc_set_rate()
115 if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) in emc_set_rate()
120 if (emc->mc_same_freq) in emc_set_rate()
125 writel_relaxed(val, emc->reg); in emc_set_rate()
127 fence_udelay(1, emc->reg); in emc_set_rate()
138 u32 val, div; in emc_set_rate_and_parent() local
140 div = div_frac_get(rate, parent_rate, 8, 1, 0); in emc_set_rate_and_parent()
142 val = readl_relaxed(emc->reg); in emc_set_rate_and_parent()
148 val |= div; in emc_set_rate_and_parent()
150 if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) in emc_set_rate_and_parent()
155 if (emc->mc_same_freq) in emc_set_rate_and_parent()
160 writel_relaxed(val, emc->reg); in emc_set_rate_and_parent()
162 fence_udelay(1, emc->reg); in emc_set_rate_and_parent()
175 int div; in emc_determine_rate() local
177 emc_rate = emc->round_cb(req->rate, req->min_rate, req->max_rate, in emc_determine_rate()
178 emc->cb_arg); in emc_determine_rate()
185 if (req->best_parent_hw == parent_hw) in emc_determine_rate()
186 parent_rate = req->best_parent_rate; in emc_determine_rate()
193 div = div_frac_get(emc_rate, parent_rate, 8, 1, 0); in emc_determine_rate()
194 divided_rate = DIV_ROUND_UP(parent_rate * 2, div + 2); in emc_determine_rate()
199 req->best_parent_rate = parent_rate; in emc_determine_rate()
200 req->best_parent_hw = parent_hw; in emc_determine_rate()
201 req->rate = emc_rate; in emc_determine_rate()
207 req->rate, emc_rate); in emc_determine_rate()
208 return -EINVAL; in emc_determine_rate()
226 struct clk *clk = __clk_lookup("emc"); in tegra20_clk_set_emc_round_callback() local
230 if (clk) { in tegra20_clk_set_emc_round_callback()
231 hw = __clk_get_hw(clk); in tegra20_clk_set_emc_round_callback()
234 emc->round_cb = round_cb; in tegra20_clk_set_emc_round_callback()
235 emc->cb_arg = cb_arg; in tegra20_clk_set_emc_round_callback()
241 return to_tegra_clk_emc(emc_hw)->round_cb != NULL; in tegra20_clk_emc_driver_available()
244 struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter) in tegra20_clk_register_emc()
248 struct clk *clk; in tegra20_clk_register_emc() local
267 emc->reg = ioaddr; in tegra20_clk_register_emc()
268 emc->hw.init = &init; in tegra20_clk_register_emc()
269 emc->want_low_jitter = low_jitter; in tegra20_clk_register_emc()
271 clk = clk_register(NULL, &emc->hw); in tegra20_clk_register_emc()
272 if (IS_ERR(clk)) { in tegra20_clk_register_emc()
277 return clk; in tegra20_clk_register_emc()
280 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same) in tegra20_clk_prepare_emc_mc_same_freq()
286 return -EINVAL; in tegra20_clk_prepare_emc_mc_same_freq()
290 emc->mc_same_freq = same; in tegra20_clk_prepare_emc_mc_same_freq()