1 // SPDX-License-Identifier: GPL-2.0+
3 * Based on drivers/clk/tegra/clk-emc.c
4 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
6 * Author: Dmitry Osipenko <digetx@gmail.com>
7 * Copyright (C) 2019 GRATE-DRIVER project
10 #define pr_fmt(fmt) "tegra-emc-clk: " fmt
12 #include <linux/bits.h>
13 #include <linux/clk-provider.h>
14 #include <linux/clk/tegra.h>
15 #include <linux/err.h>
16 #include <linux/export.h>
18 #include <linux/kernel.h>
19 #include <linux/slab.h>
23 #define CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK GENMASK(7, 0)
24 #define CLK_SOURCE_EMC_2X_CLK_SRC_MASK GENMASK(31, 30)
25 #define CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT 30
27 #define MC_EMC_SAME_FREQ BIT(16)
28 #define USE_PLLM_UD BIT(29)
30 #define EMC_SRC_PLL_M 0
31 #define EMC_SRC_PLL_C 1
32 #define EMC_SRC_PLL_P 2
33 #define EMC_SRC_CLK_M 3
35 static const char * const emc_parent_clk_names
[] = {
36 "pll_m", "pll_c", "pll_p", "clk_m",
39 struct tegra_clk_emc
{
45 tegra20_clk_emc_round_cb
*round_cb
;
49 static inline struct tegra_clk_emc
*to_tegra_clk_emc(struct clk_hw
*hw
)
51 return container_of(hw
, struct tegra_clk_emc
, hw
);
54 static unsigned long emc_recalc_rate(struct clk_hw
*hw
,
55 unsigned long parent_rate
)
57 struct tegra_clk_emc
*emc
= to_tegra_clk_emc(hw
);
60 val
= readl_relaxed(emc
->reg
);
61 div
= val
& CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK
;
63 return DIV_ROUND_UP(parent_rate
* 2, div
+ 2);
66 static u8
emc_get_parent(struct clk_hw
*hw
)
68 struct tegra_clk_emc
*emc
= to_tegra_clk_emc(hw
);
70 return readl_relaxed(emc
->reg
) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT
;
73 static int emc_set_parent(struct clk_hw
*hw
, u8 index
)
75 struct tegra_clk_emc
*emc
= to_tegra_clk_emc(hw
);
78 val
= readl_relaxed(emc
->reg
);
79 val
&= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK
;
80 val
|= index
<< CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT
;
82 div
= val
& CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK
;
84 if (index
== EMC_SRC_PLL_M
&& div
== 0 && emc
->want_low_jitter
)
89 if (emc
->mc_same_freq
)
90 val
|= MC_EMC_SAME_FREQ
;
92 val
&= ~MC_EMC_SAME_FREQ
;
94 writel_relaxed(val
, emc
->reg
);
96 fence_udelay(1, emc
->reg
);
101 static int emc_set_rate(struct clk_hw
*hw
, unsigned long rate
,
102 unsigned long parent_rate
)
104 struct tegra_clk_emc
*emc
= to_tegra_clk_emc(hw
);
108 div
= div_frac_get(rate
, parent_rate
, 8, 1, 0);
110 val
= readl_relaxed(emc
->reg
);
111 val
&= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK
;
114 index
= val
>> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT
;
116 if (index
== EMC_SRC_PLL_M
&& div
== 0 && emc
->want_low_jitter
)
121 if (emc
->mc_same_freq
)
122 val
|= MC_EMC_SAME_FREQ
;
124 val
&= ~MC_EMC_SAME_FREQ
;
126 writel_relaxed(val
, emc
->reg
);
128 fence_udelay(1, emc
->reg
);
133 static int emc_set_rate_and_parent(struct clk_hw
*hw
,
135 unsigned long parent_rate
,
138 struct tegra_clk_emc
*emc
= to_tegra_clk_emc(hw
);
141 div
= div_frac_get(rate
, parent_rate
, 8, 1, 0);
143 val
= readl_relaxed(emc
->reg
);
145 val
&= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK
;
146 val
|= index
<< CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT
;
148 val
&= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK
;
151 if (index
== EMC_SRC_PLL_M
&& div
== 0 && emc
->want_low_jitter
)
156 if (emc
->mc_same_freq
)
157 val
|= MC_EMC_SAME_FREQ
;
159 val
&= ~MC_EMC_SAME_FREQ
;
161 writel_relaxed(val
, emc
->reg
);
163 fence_udelay(1, emc
->reg
);
168 static int emc_determine_rate(struct clk_hw
*hw
, struct clk_rate_request
*req
)
170 struct tegra_clk_emc
*emc
= to_tegra_clk_emc(hw
);
171 struct clk_hw
*parent_hw
;
172 unsigned long divided_rate
;
173 unsigned long parent_rate
;
178 emc_rate
= emc
->round_cb(req
->rate
, req
->min_rate
, req
->max_rate
,
183 for (i
= 0; i
< ARRAY_SIZE(emc_parent_clk_names
); i
++) {
184 parent_hw
= clk_hw_get_parent_by_index(hw
, i
);
186 if (req
->best_parent_hw
== parent_hw
)
187 parent_rate
= req
->best_parent_rate
;
189 parent_rate
= clk_hw_get_rate(parent_hw
);
191 if (emc_rate
> parent_rate
)
194 div
= div_frac_get(emc_rate
, parent_rate
, 8, 1, 0);
195 divided_rate
= DIV_ROUND_UP(parent_rate
* 2, div
+ 2);
197 if (divided_rate
!= emc_rate
)
200 req
->best_parent_rate
= parent_rate
;
201 req
->best_parent_hw
= parent_hw
;
202 req
->rate
= emc_rate
;
206 if (i
== ARRAY_SIZE(emc_parent_clk_names
)) {
207 pr_err_once("can't find parent for rate %lu emc_rate %lu\n",
208 req
->rate
, emc_rate
);
215 static const struct clk_ops tegra_clk_emc_ops
= {
216 .recalc_rate
= emc_recalc_rate
,
217 .get_parent
= emc_get_parent
,
218 .set_parent
= emc_set_parent
,
219 .set_rate
= emc_set_rate
,
220 .set_rate_and_parent
= emc_set_rate_and_parent
,
221 .determine_rate
= emc_determine_rate
,
224 void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb
*round_cb
,
227 struct clk
*clk
= __clk_lookup("emc");
228 struct tegra_clk_emc
*emc
;
232 hw
= __clk_get_hw(clk
);
233 emc
= to_tegra_clk_emc(hw
);
235 emc
->round_cb
= round_cb
;
236 emc
->cb_arg
= cb_arg
;
239 EXPORT_SYMBOL_GPL(tegra20_clk_set_emc_round_callback
);
241 bool tegra20_clk_emc_driver_available(struct clk_hw
*emc_hw
)
243 return to_tegra_clk_emc(emc_hw
)->round_cb
!= NULL
;
246 struct clk
*tegra20_clk_register_emc(void __iomem
*ioaddr
, bool low_jitter
)
248 struct tegra_clk_emc
*emc
;
249 struct clk_init_data init
;
252 emc
= kzalloc(sizeof(*emc
), GFP_KERNEL
);
257 * EMC stands for External Memory Controller.
259 * We don't want EMC clock to be disabled ever by gating its
260 * parent and whatnot because system is busted immediately in that
261 * case, hence the clock is marked as critical.
264 init
.ops
= &tegra_clk_emc_ops
;
265 init
.flags
= CLK_IS_CRITICAL
;
266 init
.parent_names
= emc_parent_clk_names
;
267 init
.num_parents
= ARRAY_SIZE(emc_parent_clk_names
);
270 emc
->hw
.init
= &init
;
271 emc
->want_low_jitter
= low_jitter
;
273 clk
= clk_register(NULL
, &emc
->hw
);
282 int tegra20_clk_prepare_emc_mc_same_freq(struct clk
*emc_clk
, bool same
)
284 struct tegra_clk_emc
*emc
;
290 hw
= __clk_get_hw(emc_clk
);
291 emc
= to_tegra_clk_emc(hw
);
292 emc
->mc_same_freq
= same
;
296 EXPORT_SYMBOL_GPL(tegra20_clk_prepare_emc_mc_same_freq
);