Merge tag 'ntb-5.11' of git://github.com/jonmason/ntb
[linux-block.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/export.h>
17 #include <linux/io.h>
18 #include <linux/kernel.h>
19 #include <linux/slab.h>
20
21 #include "clk.h"
22
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
26
27 #define MC_EMC_SAME_FREQ        BIT(16)
28 #define USE_PLLM_UD             BIT(29)
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
34
35 static const char * const emc_parent_clk_names[] = {
36         "pll_m", "pll_c", "pll_p", "clk_m",
37 };
38
39 struct tegra_clk_emc {
40         struct clk_hw hw;
41         void __iomem *reg;
42         bool mc_same_freq;
43         bool want_low_jitter;
44
45         tegra20_clk_emc_round_cb *round_cb;
46         void *cb_arg;
47 };
48
49 static inline struct tegra_clk_emc *to_tegra_clk_emc(struct clk_hw *hw)
50 {
51         return container_of(hw, struct tegra_clk_emc, hw);
52 }
53
54 static unsigned long emc_recalc_rate(struct clk_hw *hw,
55                                      unsigned long parent_rate)
56 {
57         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
58         u32 val, div;
59
60         val = readl_relaxed(emc->reg);
61         div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
62
63         return DIV_ROUND_UP(parent_rate * 2, div + 2);
64 }
65
66 static u8 emc_get_parent(struct clk_hw *hw)
67 {
68         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
69
70         return readl_relaxed(emc->reg) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;
71 }
72
73 static int emc_set_parent(struct clk_hw *hw, u8 index)
74 {
75         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
76         u32 val, div;
77
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;
81
82         div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
83
84         if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
85                 val |= USE_PLLM_UD;
86         else
87                 val &= ~USE_PLLM_UD;
88
89         if (emc->mc_same_freq)
90                 val |= MC_EMC_SAME_FREQ;
91         else
92                 val &= ~MC_EMC_SAME_FREQ;
93
94         writel_relaxed(val, emc->reg);
95
96         fence_udelay(1, emc->reg);
97
98         return 0;
99 }
100
101 static int emc_set_rate(struct clk_hw *hw, unsigned long rate,
102                         unsigned long parent_rate)
103 {
104         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
105         unsigned int index;
106         u32 val, div;
107
108         div = div_frac_get(rate, parent_rate, 8, 1, 0);
109
110         val = readl_relaxed(emc->reg);
111         val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
112         val |= div;
113
114         index = val >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;
115
116         if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
117                 val |= USE_PLLM_UD;
118         else
119                 val &= ~USE_PLLM_UD;
120
121         if (emc->mc_same_freq)
122                 val |= MC_EMC_SAME_FREQ;
123         else
124                 val &= ~MC_EMC_SAME_FREQ;
125
126         writel_relaxed(val, emc->reg);
127
128         fence_udelay(1, emc->reg);
129
130         return 0;
131 }
132
133 static int emc_set_rate_and_parent(struct clk_hw *hw,
134                                    unsigned long rate,
135                                    unsigned long parent_rate,
136                                    u8 index)
137 {
138         struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
139         u32 val, div;
140
141         div = div_frac_get(rate, parent_rate, 8, 1, 0);
142
143         val = readl_relaxed(emc->reg);
144
145         val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK;
146         val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;
147
148         val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
149         val |= div;
150
151         if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
152                 val |= USE_PLLM_UD;
153         else
154                 val &= ~USE_PLLM_UD;
155
156         if (emc->mc_same_freq)
157                 val |= MC_EMC_SAME_FREQ;
158         else
159                 val &= ~MC_EMC_SAME_FREQ;
160
161         writel_relaxed(val, emc->reg);
162
163         fence_udelay(1, emc->reg);
164
165         return 0;
166 }
167
168 static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
169 {
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;
174         unsigned int i;
175         long emc_rate;
176         int div;
177
178         emc_rate = emc->round_cb(req->rate, req->min_rate, req->max_rate,
179                                  emc->cb_arg);
180         if (emc_rate < 0)
181                 return emc_rate;
182
183         for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) {
184                 parent_hw = clk_hw_get_parent_by_index(hw, i);
185
186                 if (req->best_parent_hw == parent_hw)
187                         parent_rate = req->best_parent_rate;
188                 else
189                         parent_rate = clk_hw_get_rate(parent_hw);
190
191                 if (emc_rate > parent_rate)
192                         continue;
193
194                 div = div_frac_get(emc_rate, parent_rate, 8, 1, 0);
195                 divided_rate = DIV_ROUND_UP(parent_rate * 2, div + 2);
196
197                 if (divided_rate != emc_rate)
198                         continue;
199
200                 req->best_parent_rate = parent_rate;
201                 req->best_parent_hw = parent_hw;
202                 req->rate = emc_rate;
203                 break;
204         }
205
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);
209                 return -EINVAL;
210         }
211
212         return 0;
213 }
214
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,
222 };
223
224 void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
225                                         void *cb_arg)
226 {
227         struct clk *clk = __clk_lookup("emc");
228         struct tegra_clk_emc *emc;
229         struct clk_hw *hw;
230
231         if (clk) {
232                 hw = __clk_get_hw(clk);
233                 emc = to_tegra_clk_emc(hw);
234
235                 emc->round_cb = round_cb;
236                 emc->cb_arg = cb_arg;
237         }
238 }
239 EXPORT_SYMBOL_GPL(tegra20_clk_set_emc_round_callback);
240
241 bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw)
242 {
243         return to_tegra_clk_emc(emc_hw)->round_cb != NULL;
244 }
245
246 struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter)
247 {
248         struct tegra_clk_emc *emc;
249         struct clk_init_data init;
250         struct clk *clk;
251
252         emc = kzalloc(sizeof(*emc), GFP_KERNEL);
253         if (!emc)
254                 return NULL;
255
256         /*
257          * EMC stands for External Memory Controller.
258          *
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.
262          */
263         init.name = "emc";
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);
268
269         emc->reg = ioaddr;
270         emc->hw.init = &init;
271         emc->want_low_jitter = low_jitter;
272
273         clk = clk_register(NULL, &emc->hw);
274         if (IS_ERR(clk)) {
275                 kfree(emc);
276                 return NULL;
277         }
278
279         return clk;
280 }
281
282 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same)
283 {
284         struct tegra_clk_emc *emc;
285         struct clk_hw *hw;
286
287         if (!emc_clk)
288                 return -EINVAL;
289
290         hw = __clk_get_hw(emc_clk);
291         emc = to_tegra_clk_emc(hw);
292         emc->mc_same_freq = same;
293
294         return 0;
295 }
296 EXPORT_SYMBOL_GPL(tegra20_clk_prepare_emc_mc_same_freq);