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>
21 #include "clk.h"
58 u32 val, div; in emc_recalc_rate() local
60 val = readl_relaxed(emc->reg); in emc_recalc_rate()
61 div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; in emc_recalc_rate()
63 return DIV_ROUND_UP(parent_rate * 2, div + 2); in emc_recalc_rate()
70 return readl_relaxed(emc->reg) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; in emc_get_parent()
76 u32 val, div; in emc_set_parent() local
78 val = readl_relaxed(emc->reg); in emc_set_parent()
82 div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; in emc_set_parent()
84 if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) in emc_set_parent()
89 if (emc->mc_same_freq) in emc_set_parent()
94 writel_relaxed(val, emc->reg); in emc_set_parent()
96 fence_udelay(1, emc->reg); in emc_set_parent()
106 u32 val, div; in emc_set_rate() local
108 div = div_frac_get(rate, parent_rate, 8, 1, 0); in emc_set_rate()
110 val = readl_relaxed(emc->reg); in emc_set_rate()
112 val |= div; in emc_set_rate()
116 if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) in emc_set_rate()
121 if (emc->mc_same_freq) in emc_set_rate()
126 writel_relaxed(val, emc->reg); in emc_set_rate()
128 fence_udelay(1, emc->reg); in emc_set_rate()
139 u32 val, div; in emc_set_rate_and_parent() local
141 div = div_frac_get(rate, parent_rate, 8, 1, 0); in emc_set_rate_and_parent()
143 val = readl_relaxed(emc->reg); in emc_set_rate_and_parent()
149 val |= div; in emc_set_rate_and_parent()
151 if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) in emc_set_rate_and_parent()
156 if (emc->mc_same_freq) in emc_set_rate_and_parent()
161 writel_relaxed(val, emc->reg); in emc_set_rate_and_parent()
163 fence_udelay(1, emc->reg); in emc_set_rate_and_parent()
176 int div; in emc_determine_rate() local
178 emc_rate = emc->round_cb(req->rate, req->min_rate, req->max_rate, in emc_determine_rate()
179 emc->cb_arg); in emc_determine_rate()
186 if (req->best_parent_hw == parent_hw) in emc_determine_rate()
187 parent_rate = req->best_parent_rate; in emc_determine_rate()
194 div = div_frac_get(emc_rate, parent_rate, 8, 1, 0); in emc_determine_rate()
195 divided_rate = DIV_ROUND_UP(parent_rate * 2, div + 2); in emc_determine_rate()
200 req->best_parent_rate = parent_rate; in emc_determine_rate()
201 req->best_parent_hw = parent_hw; in emc_determine_rate()
202 req->rate = emc_rate; in emc_determine_rate()
208 req->rate, emc_rate); in emc_determine_rate()
209 return -EINVAL; in emc_determine_rate()
227 struct clk *clk = __clk_lookup("emc"); in tegra20_clk_set_emc_round_callback() local
231 if (clk) { in tegra20_clk_set_emc_round_callback()
232 hw = __clk_get_hw(clk); in tegra20_clk_set_emc_round_callback()
235 emc->round_cb = round_cb; in tegra20_clk_set_emc_round_callback()
236 emc->cb_arg = cb_arg; in tegra20_clk_set_emc_round_callback()
243 return to_tegra_clk_emc(emc_hw)->round_cb != NULL; in tegra20_clk_emc_driver_available()
246 struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter) in tegra20_clk_register_emc()
250 struct clk *clk; in tegra20_clk_register_emc() local
269 emc->reg = ioaddr; in tegra20_clk_register_emc()
270 emc->hw.init = &init; in tegra20_clk_register_emc()
271 emc->want_low_jitter = low_jitter; in tegra20_clk_register_emc()
273 clk = clk_register(NULL, &emc->hw); in tegra20_clk_register_emc()
274 if (IS_ERR(clk)) { in tegra20_clk_register_emc()
279 return clk; in tegra20_clk_register_emc()
282 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same) in tegra20_clk_prepare_emc_mc_same_freq()
288 return -EINVAL; in tegra20_clk_prepare_emc_mc_same_freq()
292 emc->mc_same_freq = same; in tegra20_clk_prepare_emc_mc_same_freq()