GNU Linux-libre 5.10.217-gnu1
[releases.git] / drivers / clk / tegra / clk-tegra20-emc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Based on drivers/clk/tegra/clk-emc.c
4  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * Author: Dmitry Osipenko <digetx@gmail.com>
7  * Copyright (C) 2019 GRATE-DRIVER project
8  */
9
10 #define pr_fmt(fmt)     "tegra-emc-clk: " fmt
11
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/io.h>
17 #include <linux/kernel.h>
18 #include <linux/slab.h>
19
20 #include "clk.h"
21
22 #define CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK      GENMASK(7, 0)
23 #define CLK_SOURCE_EMC_2X_CLK_SRC_MASK          GENMASK(31, 30)
24 #define CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT         30
25
26 #define MC_EMC_SAME_FREQ        BIT(16)
27 #define USE_PLLM_UD             BIT(29)
28
29 #define EMC_SRC_PLL_M           0
30 #define EMC_SRC_PLL_C           1
31 #define EMC_SRC_PLL_P           2
32 #define EMC_SRC_CLK_M           3
33
34 static const char * const emc_parent_clk_names[] = {
35         "pll_m", "pll_c", "pll_p", "clk_m",
36 };
37
38 struct tegra_clk_emc {
39         struct clk_hw hw;
40         void __iomem *reg;
41         bool mc_same_freq;
42         bool want_low_jitter;
43
44         tegra20_clk_emc_round_cb *round_cb;
45         void *cb_arg;
46 };
47
48 static inline struct tegra_clk_emc *to_tegra_clk_emc(struct clk_hw *hw)
49 {
50         return container_of(hw, struct tegra_clk_emc, hw);
51 }
52
53 static unsigned long emc_recalc_rate(struct clk_hw *hw,
54                                      unsigned long parent_rate)
55 {
56         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
57         u32 val, div;
58
59         val = readl_relaxed(emc->reg);
60         div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
61
62         return DIV_ROUND_UP(parent_rate * 2, div + 2);
63 }
64
65 static u8 emc_get_parent(struct clk_hw *hw)
66 {
67         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
68
69         return readl_relaxed(emc->reg) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;
70 }
71
72 static int emc_set_parent(struct clk_hw *hw, u8 index)
73 {
74         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
75         u32 val, div;
76
77         val = readl_relaxed(emc->reg);
78         val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK;
79         val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;
80
81         div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
82
83         if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
84                 val |= USE_PLLM_UD;
85         else
86                 val &= ~USE_PLLM_UD;
87
88         if (emc->mc_same_freq)
89                 val |= MC_EMC_SAME_FREQ;
90         else
91                 val &= ~MC_EMC_SAME_FREQ;
92
93         writel_relaxed(val, emc->reg);
94
95         fence_udelay(1, emc->reg);
96
97         return 0;
98 }
99
100 static int emc_set_rate(struct clk_hw *hw, unsigned long rate,
101                         unsigned long parent_rate)
102 {
103         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
104         unsigned int index;
105         u32 val, div;
106
107         div = div_frac_get(rate, parent_rate, 8, 1, 0);
108
109         val = readl_relaxed(emc->reg);
110         val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
111         val |= div;
112
113         index = val >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;
114
115         if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
116                 val |= USE_PLLM_UD;
117         else
118                 val &= ~USE_PLLM_UD;
119
120         if (emc->mc_same_freq)
121                 val |= MC_EMC_SAME_FREQ;
122         else
123                 val &= ~MC_EMC_SAME_FREQ;
124
125         writel_relaxed(val, emc->reg);
126
127         fence_udelay(1, emc->reg);
128
129         return 0;
130 }
131
132 static int emc_set_rate_and_parent(struct clk_hw *hw,
133                                    unsigned long rate,
134                                    unsigned long parent_rate,
135                                    u8 index)
136 {
137         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
138         u32 val, div;
139
140         div = div_frac_get(rate, parent_rate, 8, 1, 0);
141
142         val = readl_relaxed(emc->reg);
143
144         val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK;
145         val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;
146
147         val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
148         val |= div;
149
150         if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
151                 val |= USE_PLLM_UD;
152         else
153                 val &= ~USE_PLLM_UD;
154
155         if (emc->mc_same_freq)
156                 val |= MC_EMC_SAME_FREQ;
157         else
158                 val &= ~MC_EMC_SAME_FREQ;
159
160         writel_relaxed(val, emc->reg);
161
162         fence_udelay(1, emc->reg);
163
164         return 0;
165 }
166
167 static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
168 {
169         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
170         struct clk_hw *parent_hw;
171         unsigned long divided_rate;
172         unsigned long parent_rate;
173         unsigned int i;
174         long emc_rate;
175         int div;
176
177         emc_rate = emc->round_cb(req->rate, req->min_rate, req->max_rate,
178                                  emc->cb_arg);
179         if (emc_rate < 0)
180                 return emc_rate;
181
182         for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) {
183                 parent_hw = clk_hw_get_parent_by_index(hw, i);
184
185                 if (req->best_parent_hw == parent_hw)
186                         parent_rate = req->best_parent_rate;
187                 else
188                         parent_rate = clk_hw_get_rate(parent_hw);
189
190                 if (emc_rate > parent_rate)
191                         continue;
192
193                 div = div_frac_get(emc_rate, parent_rate, 8, 1, 0);
194                 divided_rate = DIV_ROUND_UP(parent_rate * 2, div + 2);
195
196                 if (divided_rate != emc_rate)
197                         continue;
198
199                 req->best_parent_rate = parent_rate;
200                 req->best_parent_hw = parent_hw;
201                 req->rate = emc_rate;
202                 break;
203         }
204
205         if (i == ARRAY_SIZE(emc_parent_clk_names)) {
206                 pr_err_once("can't find parent for rate %lu emc_rate %lu\n",
207                             req->rate, emc_rate);
208                 return -EINVAL;
209         }
210
211         return 0;
212 }
213
214 static const struct clk_ops tegra_clk_emc_ops = {
215         .recalc_rate = emc_recalc_rate,
216         .get_parent = emc_get_parent,
217         .set_parent = emc_set_parent,
218         .set_rate = emc_set_rate,
219         .set_rate_and_parent = emc_set_rate_and_parent,
220         .determine_rate = emc_determine_rate,
221 };
222
223 void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
224                                         void *cb_arg)
225 {
226         struct clk *clk = __clk_lookup("emc");
227         struct tegra_clk_emc *emc;
228         struct clk_hw *hw;
229
230         if (clk) {
231                 hw = __clk_get_hw(clk);
232                 emc = to_tegra_clk_emc(hw);
233
234                 emc->round_cb = round_cb;
235                 emc->cb_arg = cb_arg;
236         }
237 }
238
239 bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw)
240 {
241         return to_tegra_clk_emc(emc_hw)->round_cb != NULL;
242 }
243
244 struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter)
245 {
246         struct tegra_clk_emc *emc;
247         struct clk_init_data init;
248         struct clk *clk;
249
250         emc = kzalloc(sizeof(*emc), GFP_KERNEL);
251         if (!emc)
252                 return NULL;
253
254         /*
255          * EMC stands for External Memory Controller.
256          *
257          * We don't want EMC clock to be disabled ever by gating its
258          * parent and whatnot because system is busted immediately in that
259          * case, hence the clock is marked as critical.
260          */
261         init.name = "emc";
262         init.ops = &tegra_clk_emc_ops;
263         init.flags = CLK_IS_CRITICAL;
264         init.parent_names = emc_parent_clk_names;
265         init.num_parents = ARRAY_SIZE(emc_parent_clk_names);
266
267         emc->reg = ioaddr;
268         emc->hw.init = &init;
269         emc->want_low_jitter = low_jitter;
270
271         clk = clk_register(NULL, &emc->hw);
272         if (IS_ERR(clk)) {
273                 kfree(emc);
274                 return NULL;
275         }
276
277         return clk;
278 }
279
280 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same)
281 {
282         struct tegra_clk_emc *emc;
283         struct clk_hw *hw;
284
285         if (!emc_clk)
286                 return -EINVAL;
287
288         hw = __clk_get_hw(emc_clk);
289         emc = to_tegra_clk_emc(hw);
290         emc->mc_same_freq = same;
291
292         return 0;
293 }