1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (c) 2012-2020, NVIDIA CORPORATION. All rights reserved.
4 */
5
6#ifndef __LINUX_CLK_TEGRA_H_
7#define __LINUX_CLK_TEGRA_H_
8
9#include <linux/types.h>
10#include <linux/bug.h>
11
12/*
13 * Tegra CPU clock and reset control ops
14 *
15 * wait_for_reset:
16 * keep waiting until the CPU in reset state
17 * put_in_reset:
18 * put the CPU in reset state
19 * out_of_reset:
20 * release the CPU from reset state
21 * enable_clock:
22 * CPU clock un-gate
23 * disable_clock:
24 * CPU clock gate
25 * rail_off_ready:
26 * CPU is ready for rail off
27 * suspend:
28 * save the clock settings when CPU go into low-power state
29 * resume:
30 * restore the clock settings when CPU exit low-power state
31 */
32struct tegra_cpu_car_ops {
33 void (*wait_for_reset)(u32 cpu);
34 void (*put_in_reset)(u32 cpu);
35 void (*out_of_reset)(u32 cpu);
36 void (*enable_clock)(u32 cpu);
37 void (*disable_clock)(u32 cpu);
38#ifdef CONFIG_PM_SLEEP
39 bool (*rail_off_ready)(void);
40 void (*suspend)(void);
41 void (*resume)(void);
42#endif
43};
44
45#ifdef CONFIG_ARCH_TEGRA
46extern struct tegra_cpu_car_ops *tegra_cpu_car_ops;
47
48static inline void tegra_wait_cpu_in_reset(u32 cpu)
49{
50 if (WARN_ON(!tegra_cpu_car_ops->wait_for_reset))
51 return;
52
53 tegra_cpu_car_ops->wait_for_reset(cpu);
54}
55
56static inline void tegra_put_cpu_in_reset(u32 cpu)
57{
58 if (WARN_ON(!tegra_cpu_car_ops->put_in_reset))
59 return;
60
61 tegra_cpu_car_ops->put_in_reset(cpu);
62}
63
64static inline void tegra_cpu_out_of_reset(u32 cpu)
65{
66 if (WARN_ON(!tegra_cpu_car_ops->out_of_reset))
67 return;
68
69 tegra_cpu_car_ops->out_of_reset(cpu);
70}
71
72static inline void tegra_enable_cpu_clock(u32 cpu)
73{
74 if (WARN_ON(!tegra_cpu_car_ops->enable_clock))
75 return;
76
77 tegra_cpu_car_ops->enable_clock(cpu);
78}
79
80static inline void tegra_disable_cpu_clock(u32 cpu)
81{
82 if (WARN_ON(!tegra_cpu_car_ops->disable_clock))
83 return;
84
85 tegra_cpu_car_ops->disable_clock(cpu);
86}
87#else
88static inline void tegra_wait_cpu_in_reset(u32 cpu)
89{
90}
91
92static inline void tegra_put_cpu_in_reset(u32 cpu)
93{
94}
95
96static inline void tegra_cpu_out_of_reset(u32 cpu)
97{
98}
99
100static inline void tegra_enable_cpu_clock(u32 cpu)
101{
102}
103
104static inline void tegra_disable_cpu_clock(u32 cpu)
105{
106}
107#endif
108
109#if defined(CONFIG_ARCH_TEGRA) && defined(CONFIG_PM_SLEEP)
110static inline bool tegra_cpu_rail_off_ready(void)
111{
112 if (WARN_ON(!tegra_cpu_car_ops->rail_off_ready))
113 return false;
114
115 return tegra_cpu_car_ops->rail_off_ready();
116}
117
118static inline void tegra_cpu_clock_suspend(void)
119{
120 if (WARN_ON(!tegra_cpu_car_ops->suspend))
121 return;
122
123 tegra_cpu_car_ops->suspend();
124}
125
126static inline void tegra_cpu_clock_resume(void)
127{
128 if (WARN_ON(!tegra_cpu_car_ops->resume))
129 return;
130
131 tegra_cpu_car_ops->resume();
132}
133#else
134static inline bool tegra_cpu_rail_off_ready(void)
135{
136 return false;
137}
138
139static inline void tegra_cpu_clock_suspend(void)
140{
141}
142
143static inline void tegra_cpu_clock_resume(void)
144{
145}
146#endif
147
148struct clk;
149struct tegra_emc;
150
151typedef long (tegra20_clk_emc_round_cb)(unsigned long rate,
152 unsigned long min_rate,
153 unsigned long max_rate,
154 void *arg);
155typedef int (tegra124_emc_prepare_timing_change_cb)(struct tegra_emc *emc,
156 unsigned long rate);
157typedef void (tegra124_emc_complete_timing_change_cb)(struct tegra_emc *emc,
158 unsigned long rate);
159
160struct tegra210_clk_emc_config {
161 unsigned long rate;
162 bool same_freq;
163 u32 value;
164
165 unsigned long parent_rate;
166 u8 parent;
167};
168
169struct tegra210_clk_emc_provider {
170 struct module *owner;
171 struct device *dev;
172
173 struct tegra210_clk_emc_config *configs;
174 unsigned int num_configs;
175
176 int (*set_rate)(struct device *dev,
177 const struct tegra210_clk_emc_config *config);
178};
179
180#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
181void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
182 void *cb_arg);
183int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same);
184#else
185static inline void
186tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
187 void *cb_arg)
188{
189}
190
191static inline int
192tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same)
193{
194 return 0;
195}
196#endif
197
198#ifdef CONFIG_TEGRA124_CLK_EMC
199void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb,
200 tegra124_emc_complete_timing_change_cb *complete_cb);
201#else
202static inline void
203tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb,
204 tegra124_emc_complete_timing_change_cb *complete_cb)
205{
206}
207#endif
208
209#ifdef CONFIG_ARCH_TEGRA_210_SOC
210int tegra210_plle_hw_sequence_start(void);
211bool tegra210_plle_hw_sequence_is_enabled(void);
212void tegra210_xusb_pll_hw_control_enable(void);
213void tegra210_xusb_pll_hw_sequence_start(void);
214void tegra210_sata_pll_hw_control_enable(void);
215void tegra210_sata_pll_hw_sequence_start(void);
216void tegra210_set_sata_pll_seq_sw(bool state);
217void tegra210_put_utmipll_in_iddq(void);
218void tegra210_put_utmipll_out_iddq(void);
219int tegra210_clk_handle_mbist_war(unsigned int id);
220void tegra210_clk_emc_dll_enable(bool flag);
221void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value);
222void tegra210_clk_emc_update_setting(u32 emc_src_value);
223
224int tegra210_clk_emc_attach(struct clk *clk,
225 struct tegra210_clk_emc_provider *provider);
226void tegra210_clk_emc_detach(struct clk *clk);
227#else
228static inline int tegra210_plle_hw_sequence_start(void)
229{
230 return 0;
231}
232
233static inline bool tegra210_plle_hw_sequence_is_enabled(void)
234{
235 return false;
236}
237
238static inline int tegra210_clk_handle_mbist_war(unsigned int id)
239{
240 return 0;
241}
242
243static inline int
244tegra210_clk_emc_attach(struct clk *clk,
245 struct tegra210_clk_emc_provider *provider)
246{
247 return 0;
248}
249
250static inline void tegra210_xusb_pll_hw_control_enable(void) {}
251static inline void tegra210_xusb_pll_hw_sequence_start(void) {}
252static inline void tegra210_sata_pll_hw_control_enable(void) {}
253static inline void tegra210_sata_pll_hw_sequence_start(void) {}
254static inline void tegra210_set_sata_pll_seq_sw(bool state) {}
255static inline void tegra210_put_utmipll_in_iddq(void) {}
256static inline void tegra210_put_utmipll_out_iddq(void) {}
257static inline void tegra210_clk_emc_dll_enable(bool flag) {}
258static inline void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value) {}
259static inline void tegra210_clk_emc_update_setting(u32 emc_src_value) {}
260static inline void tegra210_clk_emc_detach(struct clk *clk) {}
261#endif
262
263#endif /* __LINUX_CLK_TEGRA_H_ */
264

source code of linux/include/linux/clk/tegra.h