1178172Simp// SPDX-License-Identifier: GPL-2.0
2178172Simp/*
3178172Simp * Copyright (c) 2015-2020, NVIDIA CORPORATION.  All rights reserved.
4178172Simp */
5178172Simp
6178172Simp#include <linux/bitfield.h>
7178172Simp#include <linux/clk.h>
8178172Simp#include <linux/clk-provider.h>
9178172Simp#include <linux/clk/tegra.h>
10178172Simp#include <linux/device.h>
11178172Simp#include <linux/module.h>
12178172Simp#include <linux/io.h>
13178172Simp#include <linux/slab.h>
14178172Simp
15178172Simp#include "clk.h"
16178172Simp
17178172Simp#define CLK_SOURCE_EMC 0x19c
18178172Simp#define  CLK_SOURCE_EMC_2X_CLK_SRC GENMASK(31, 29)
19178172Simp#define  CLK_SOURCE_EMC_MC_EMC_SAME_FREQ BIT(16)
20178172Simp#define  CLK_SOURCE_EMC_2X_CLK_DIVISOR GENMASK(7, 0)
21178172Simp
22178172Simp#define CLK_SRC_PLLM 0
23178172Simp#define CLK_SRC_PLLC 1
24178172Simp#define CLK_SRC_PLLP 2
25178172Simp#define CLK_SRC_CLK_M 3
26178172Simp#define CLK_SRC_PLLM_UD 4
27178172Simp#define CLK_SRC_PLLMB_UD 5
28178172Simp#define CLK_SRC_PLLMB 6
29178172Simp#define CLK_SRC_PLLP_UD 7
30178172Simp
31178172Simpstruct tegra210_clk_emc {
32178172Simp	struct clk_hw hw;
33178172Simp	void __iomem *regs;
34178172Simp
35178172Simp	struct tegra210_clk_emc_provider *provider;
36178172Simp
37178172Simp	struct clk *parents[8];
38178172Simp};
39178172Simp
40178172Simpstatic inline struct tegra210_clk_emc *
41178172Simpto_tegra210_clk_emc(struct clk_hw *hw)
42202046Simp{
43178172Simp	return container_of(hw, struct tegra210_clk_emc, hw);
44178172Simp}
45178172Simp
46178172Simpstatic const char *tegra210_clk_emc_parents[] = {
47178172Simp	"pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb_ud",
48178172Simp	"pll_mb", "pll_p_ud",
49178172Simp};
50178172Simp
51178172Simpstatic u8 tegra210_clk_emc_get_parent(struct clk_hw *hw)
52178172Simp{
53209613Sjhb	struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
54178172Simp	u32 value;
55178172Simp	u8 src;
56178172Simp
57178172Simp	value = readl_relaxed(emc->regs + CLK_SOURCE_EMC);
58178172Simp	src = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, value);
59178172Simp
60178172Simp	return src;
61178172Simp}
62178172Simp
63178172Simpstatic unsigned long tegra210_clk_emc_recalc_rate(struct clk_hw *hw,
64178172Simp						  unsigned long parent_rate)
65178172Simp{
66178172Simp	struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
67178172Simp	u32 value, div;
68178172Simp
69178172Simp	/*
70178172Simp	 * CCF assumes that neither the parent nor its rate will change during
71178172Simp	 * ->set_rate(), so the parent rate passed in here was cached from the
72178172Simp	 * parent before the ->set_rate() call.
73178172Simp	 *
74178172Simp	 * This can lead to wrong results being reported for the EMC clock if
75178172Simp	 * the parent and/or parent rate have changed as part of the EMC rate
76178172Simp	 * change sequence. Fix this by overriding the parent clock with what
77178172Simp	 * we know to be the correct value after the rate change.
78178172Simp	 */
79178172Simp	parent_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
80178172Simp
81178172Simp	value = readl_relaxed(emc->regs + CLK_SOURCE_EMC);
82178172Simp
83178172Simp	div = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_DIVISOR, value);
84178172Simp	div += 2;
85178172Simp
86178172Simp	return DIV_ROUND_UP(parent_rate * 2, div);
87178172Simp}
88178172Simp
89178172Simpstatic long tegra210_clk_emc_round_rate(struct clk_hw *hw, unsigned long rate,
90178172Simp					unsigned long *prate)
91178172Simp{
92178172Simp	struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
93178172Simp	struct tegra210_clk_emc_provider *provider = emc->provider;
94178172Simp	unsigned int i;
95178172Simp
96178172Simp	if (!provider || !provider->configs || provider->num_configs == 0)
97178172Simp		return clk_hw_get_rate(hw);
98178172Simp
99178172Simp	for (i = 0; i < provider->num_configs; i++) {
100178172Simp		if (provider->configs[i].rate >= rate)
101178172Simp			return provider->configs[i].rate;
102178172Simp	}
103178172Simp
104178172Simp	return provider->configs[i - 1].rate;
105178172Simp}
106178172Simp
107178172Simpstatic struct clk *tegra210_clk_emc_find_parent(struct tegra210_clk_emc *emc,
108178172Simp						u8 index)
109178172Simp{
110178172Simp	struct clk_hw *parent = clk_hw_get_parent_by_index(&emc->hw, index);
111178172Simp	const char *name = clk_hw_get_name(parent);
112232585Sjmallett
113178172Simp	/* XXX implement cache? */
114178172Simp
115178172Simp	return __clk_lookup(name);
116178172Simp}
117178172Simp
118178172Simpstatic int tegra210_clk_emc_set_rate(struct clk_hw *hw, unsigned long rate,
119178172Simp				     unsigned long parent_rate)
120178172Simp{
121178172Simp	struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
122178172Simp	struct tegra210_clk_emc_provider *provider = emc->provider;
123178172Simp	struct tegra210_clk_emc_config *config;
124178172Simp	struct device *dev = provider->dev;
125178172Simp	struct clk_hw *old, *new, *parent;
126178172Simp	u8 old_idx, new_idx, index;
127178172Simp	struct clk *clk;
128178172Simp	unsigned int i;
129294930Sjhb	int err;
130178172Simp
131178172Simp	if (!provider->configs || provider->num_configs == 0)
132178172Simp		return -EINVAL;
133178172Simp
134178172Simp	for (i = 0; i < provider->num_configs; i++) {
135178172Simp		if (provider->configs[i].rate >= rate) {
136178172Simp			config = &provider->configs[i];
137178172Simp			break;
138209500Sjchandra		}
139178172Simp	}
140178172Simp
141209500Sjchandra	if (i == provider->num_configs)
142178172Simp		config = &provider->configs[i - 1];
143178172Simp
144178172Simp	old_idx = tegra210_clk_emc_get_parent(hw);
145178172Simp	new_idx = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, config->value);
146178172Simp
147209500Sjchandra	old = clk_hw_get_parent_by_index(hw, old_idx);
148178172Simp	new = clk_hw_get_parent_by_index(hw, new_idx);
149178172Simp
150178172Simp	/* if the rate has changed... */
151178172Simp	if (config->parent_rate != clk_hw_get_rate(old)) {
152178172Simp		/* ... but the clock source remains the same ... */
153178172Simp		if (new_idx == old_idx) {
154178172Simp			/* ... switch to the alternative clock source. */
155178172Simp			switch (new_idx) {
156178172Simp			case CLK_SRC_PLLM:
157178172Simp				new_idx = CLK_SRC_PLLMB;
158178172Simp				break;
159178172Simp
160178172Simp			case CLK_SRC_PLLM_UD:
161178172Simp				new_idx = CLK_SRC_PLLMB_UD;
162178172Simp				break;
163178172Simp
164178172Simp			case CLK_SRC_PLLMB_UD:
165178172Simp				new_idx = CLK_SRC_PLLM_UD;
166178172Simp				break;
167178172Simp
168178172Simp			case CLK_SRC_PLLMB:
169178172Simp				new_idx = CLK_SRC_PLLM;
170209500Sjchandra				break;
171209500Sjchandra			}
172209500Sjchandra
173178172Simp			/*
174178172Simp			 * This should never happen because we can't deal with
175178172Simp			 * it.
176209500Sjchandra			 */
177178172Simp			if (WARN_ON(new_idx == old_idx))
178178172Simp				return -EINVAL;
179178172Simp
180178172Simp			new = clk_hw_get_parent_by_index(hw, new_idx);
181178172Simp		}
182178172Simp
183178172Simp		index = new_idx;
184178172Simp		parent = new;
185178172Simp	} else {
186178172Simp		index = old_idx;
187178172Simp		parent = old;
188178172Simp	}
189225617Skmacy
190178172Simp	clk = tegra210_clk_emc_find_parent(emc, index);
191178172Simp	if (IS_ERR(clk)) {
192178172Simp		err = PTR_ERR(clk);
193178172Simp		dev_err(dev, "failed to get parent clock for index %u: %d\n",
194178172Simp			index, err);
195178172Simp		return err;
196178172Simp	}
197178172Simp
198232586Sjmallett	/* set the new parent clock to the required rate */
199232586Sjmallett	if (clk_get_rate(clk) != config->parent_rate) {
200232586Sjmallett		err = clk_set_rate(clk, config->parent_rate);
201178172Simp		if (err < 0) {
202232586Sjmallett			dev_err(dev, "failed to set rate %lu Hz for %pC: %d\n",
203178172Simp				config->parent_rate, clk, err);
204232586Sjmallett			return err;
205178172Simp		}
206178172Simp	}
207178172Simp
208178172Simp	/* enable the new parent clock */
209178172Simp	if (parent != old) {
210178172Simp		err = clk_prepare_enable(clk);
211178172Simp		if (err < 0) {
212178172Simp			dev_err(dev, "failed to enable parent clock %pC: %d\n",
213178172Simp				clk, err);
214178172Simp			return err;
215178172Simp		}
216178172Simp	}
217178172Simp
218291961Smarkj	/* update the EMC source configuration to reflect the new parent */
219291961Smarkj	config->value &= ~CLK_SOURCE_EMC_2X_CLK_SRC;
220291961Smarkj	config->value |= FIELD_PREP(CLK_SOURCE_EMC_2X_CLK_SRC, index);
221178172Simp
222178172Simp	/*
223178172Simp	 * Finally, switch the EMC programming with both old and new parent
224178172Simp	 * clocks enabled.
225178172Simp	 */
226178172Simp	err = provider->set_rate(dev, config);
227291961Smarkj	if (err < 0) {
228291961Smarkj		dev_err(dev, "failed to set EMC rate to %lu Hz: %d\n", rate,
229291961Smarkj			err);
230178172Simp
231178172Simp		/*
232178172Simp		 * If we're unable to switch to the new EMC frequency, we no
233178172Simp		 * longer need the new parent to be enabled.
234178172Simp		 */
235178172Simp		if (parent != old)
236178172Simp			clk_disable_unprepare(clk);
237178172Simp
238210038Simp		return err;
239178172Simp	}
240178172Simp
241178172Simp	/* reparent to new parent clock and disable the old parent clock */
242178172Simp	if (parent != old) {
243178172Simp		clk = tegra210_clk_emc_find_parent(emc, old_idx);
244178172Simp		if (IS_ERR(clk)) {
245178172Simp			err = PTR_ERR(clk);
246178172Simp			dev_err(dev,
247178172Simp				"failed to get parent clock for index %u: %d\n",
248178172Simp				old_idx, err);
249178172Simp			return err;
250178172Simp		}
251178172Simp
252202046Simp		clk_hw_reparent(hw, parent);
253178172Simp		clk_disable_unprepare(clk);
254178172Simp	}
255178172Simp
256178172Simp	return err;
257178172Simp}
258178172Simp
259178172Simpstatic const struct clk_ops tegra210_clk_emc_ops = {
260178172Simp	.get_parent = tegra210_clk_emc_get_parent,
261178172Simp	.recalc_rate = tegra210_clk_emc_recalc_rate,
262178172Simp	.round_rate = tegra210_clk_emc_round_rate,
263178172Simp	.set_rate = tegra210_clk_emc_set_rate,
264178172Simp};
265178172Simp
266178172Simpstruct clk *tegra210_clk_register_emc(struct device_node *np,
267178172Simp				      void __iomem *regs)
268178172Simp{
269178172Simp	struct tegra210_clk_emc *emc;
270178172Simp	struct clk_init_data init;
271178172Simp	struct clk *clk;
272178172Simp
273178172Simp	emc = kzalloc(sizeof(*emc), GFP_KERNEL);
274178172Simp	if (!emc)
275178172Simp		return ERR_PTR(-ENOMEM);
276178172Simp
277178172Simp	emc->regs = regs;
278178172Simp
279178172Simp	init.name = "emc";
280178172Simp	init.ops = &tegra210_clk_emc_ops;
281178172Simp	init.flags = CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE;
282178172Simp	init.parent_names = tegra210_clk_emc_parents;
283178172Simp	init.num_parents = ARRAY_SIZE(tegra210_clk_emc_parents);
284178172Simp	emc->hw.init = &init;
285178172Simp
286178172Simp	clk = clk_register(NULL, &emc->hw);
287178172Simp	if (IS_ERR(clk)) {
288178172Simp		kfree(emc);
289178172Simp		return clk;
290178172Simp	}
291178172Simp
292178172Simp	return clk;
293178172Simp}
294178172Simp
295178172Simpint tegra210_clk_emc_attach(struct clk *clk,
296178172Simp			    struct tegra210_clk_emc_provider *provider)
297178172Simp{
298178172Simp	struct clk_hw *hw = __clk_get_hw(clk);
299178172Simp	struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
300178172Simp	struct device *dev = provider->dev;
301178172Simp	unsigned int i;
302178172Simp	int err;
303178172Simp
304178172Simp	if (!try_module_get(provider->owner))
305178172Simp		return -ENODEV;
306178172Simp
307178172Simp	for (i = 0; i < provider->num_configs; i++) {
308178172Simp		struct tegra210_clk_emc_config *config = &provider->configs[i];
309178172Simp		struct clk_hw *parent;
310178172Simp		bool same_freq;
311178172Simp		u8 div, src;
312178172Simp
313178172Simp		div = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_DIVISOR, config->value);
314178172Simp		src = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, config->value);
315178172Simp
316178172Simp		/* do basic sanity checking on the EMC timings */
317178172Simp		if (div & 0x1) {
318178172Simp			dev_err(dev, "invalid odd divider %u for rate %lu Hz\n",
319178172Simp				div, config->rate);
320178172Simp			err = -EINVAL;
321178172Simp			goto put;
322178172Simp		}
323178172Simp
324178172Simp		same_freq = config->value & CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
325178172Simp
326178172Simp		if (same_freq != config->same_freq) {
327178172Simp			dev_err(dev,
328178172Simp				"ambiguous EMC to MC ratio for rate %lu Hz\n",
329178172Simp				config->rate);
330178172Simp			err = -EINVAL;
331178172Simp			goto put;
332178172Simp		}
333178172Simp
334178172Simp		parent = clk_hw_get_parent_by_index(hw, src);
335178172Simp		config->parent = src;
336178172Simp
337178172Simp		if (src == CLK_SRC_PLLM || src == CLK_SRC_PLLM_UD) {
338202046Simp			config->parent_rate = config->rate * (1 + div / 2);
339202046Simp		} else {
340202046Simp			unsigned long rate = config->rate * (1 + div / 2);
341202046Simp
342202046Simp			config->parent_rate = clk_hw_get_rate(parent);
343202046Simp
344178172Simp			if (config->parent_rate != rate) {
345178172Simp				dev_err(dev,
346178172Simp					"rate %lu Hz does not match input\n",
347202046Simp					config->rate);
348178172Simp				err = -EINVAL;
349178172Simp				goto put;
350178172Simp			}
351178172Simp		}
352278001Skib	}
353178172Simp
354178172Simp	emc->provider = provider;
355178172Simp
356178172Simp	return 0;
357178172Simp
358178172Simpput:
359178172Simp	module_put(provider->owner);
360178172Simp	return err;
361178172Simp}
362178172SimpEXPORT_SYMBOL_GPL(tegra210_clk_emc_attach);
363178172Simp
364178172Simpvoid tegra210_clk_emc_detach(struct clk *clk)
365178172Simp{
366178172Simp	struct tegra210_clk_emc *emc = to_tegra210_clk_emc(__clk_get_hw(clk));
367178172Simp
368202046Simp	module_put(emc->provider->owner);
369264625Srwatson	emc->provider = NULL;
370178172Simp}
371178172SimpEXPORT_SYMBOL_GPL(tegra210_clk_emc_detach);
372178172Simp