Commit | Line | Data |
---|---|---|
9952f691 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
dab403ef | 2 | /* |
54443ef6 | 3 | * Copyright (c) 2012-2020, NVIDIA CORPORATION. All rights reserved. |
dab403ef JL |
4 | */ |
5 | ||
89572c77 PG |
6 | #ifndef __LINUX_CLK_TEGRA_H_ |
7 | #define __LINUX_CLK_TEGRA_H_ | |
dab403ef | 8 | |
584ac4e9 SB |
9 | #include <linux/types.h> |
10 | #include <linux/bug.h> | |
61fd290d | 11 | |
dab403ef JL |
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 | |
a6e293ee JL |
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 | |
dab403ef JL |
31 | */ |
32 | struct 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); | |
a6e293ee JL |
38 | #ifdef CONFIG_PM_SLEEP |
39 | bool (*rail_off_ready)(void); | |
40 | void (*suspend)(void); | |
41 | void (*resume)(void); | |
42 | #endif | |
dab403ef JL |
43 | }; |
44 | ||
4ad81f6e | 45 | #ifdef CONFIG_ARCH_TEGRA |
dab403ef JL |
46 | extern struct tegra_cpu_car_ops *tegra_cpu_car_ops; |
47 | ||
48 | static 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 | ||
56 | static 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 | ||
64 | static 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 | ||
72 | static 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 | ||
80 | static 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 | } | |
4ad81f6e TR |
87 | #else |
88 | static inline void tegra_wait_cpu_in_reset(u32 cpu) | |
89 | { | |
90 | } | |
dab403ef | 91 | |
4ad81f6e TR |
92 | static inline void tegra_put_cpu_in_reset(u32 cpu) |
93 | { | |
94 | } | |
95 | ||
96 | static inline void tegra_cpu_out_of_reset(u32 cpu) | |
97 | { | |
98 | } | |
99 | ||
100 | static inline void tegra_enable_cpu_clock(u32 cpu) | |
101 | { | |
102 | } | |
103 | ||
104 | static inline void tegra_disable_cpu_clock(u32 cpu) | |
105 | { | |
106 | } | |
107 | #endif | |
108 | ||
109 | #if defined(CONFIG_ARCH_TEGRA) && defined(CONFIG_PM_SLEEP) | |
a6e293ee JL |
110 | static 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 | ||
118 | static 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 | ||
126 | static 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 | } | |
5699d160 DO |
133 | #else |
134 | static inline bool tegra_cpu_rail_off_ready(void) | |
135 | { | |
136 | return false; | |
137 | } | |
138 | ||
139 | static inline void tegra_cpu_clock_suspend(void) | |
140 | { | |
141 | } | |
142 | ||
143 | static inline void tegra_cpu_clock_resume(void) | |
144 | { | |
145 | } | |
a6e293ee JL |
146 | #endif |
147 | ||
ed1a2459 | 148 | struct clk; |
281462e5 | 149 | struct tegra_emc; |
ed1a2459 DO |
150 | |
151 | typedef long (tegra20_clk_emc_round_cb)(unsigned long rate, | |
152 | unsigned long min_rate, | |
153 | unsigned long max_rate, | |
154 | void *arg); | |
281462e5 DO |
155 | typedef int (tegra124_emc_prepare_timing_change_cb)(struct tegra_emc *emc, |
156 | unsigned long rate); | |
157 | typedef void (tegra124_emc_complete_timing_change_cb)(struct tegra_emc *emc, | |
158 | unsigned long rate); | |
281462e5 | 159 | |
0ac65fc9 JL |
160 | struct 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 | ||
169 | struct 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 | ||
e848edae DO |
180 | #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC) |
181 | void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, | |
182 | void *cb_arg); | |
183 | int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same); | |
184 | #else | |
185 | static inline void | |
186 | tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, | |
187 | void *cb_arg) | |
188 | { | |
189 | } | |
190 | ||
191 | static inline int | |
192 | tegra20_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 | |
199 | void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb, | |
200 | tegra124_emc_complete_timing_change_cb *complete_cb); | |
201 | #else | |
202 | static inline void | |
203 | tegra124_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 | |
210 | int tegra210_plle_hw_sequence_start(void); | |
211 | bool tegra210_plle_hw_sequence_is_enabled(void); | |
212 | void tegra210_xusb_pll_hw_control_enable(void); | |
213 | void tegra210_xusb_pll_hw_sequence_start(void); | |
214 | void tegra210_sata_pll_hw_control_enable(void); | |
215 | void tegra210_sata_pll_hw_sequence_start(void); | |
216 | void tegra210_set_sata_pll_seq_sw(bool state); | |
217 | void tegra210_put_utmipll_in_iddq(void); | |
218 | void tegra210_put_utmipll_out_iddq(void); | |
219 | int tegra210_clk_handle_mbist_war(unsigned int id); | |
220 | void tegra210_clk_emc_dll_enable(bool flag); | |
221 | void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value); | |
222 | void tegra210_clk_emc_update_setting(u32 emc_src_value); | |
223 | ||
0ac65fc9 JL |
224 | int tegra210_clk_emc_attach(struct clk *clk, |
225 | struct tegra210_clk_emc_provider *provider); | |
226 | void tegra210_clk_emc_detach(struct clk *clk); | |
e848edae DO |
227 | #else |
228 | static inline int tegra210_plle_hw_sequence_start(void) | |
229 | { | |
230 | return 0; | |
231 | } | |
232 | ||
233 | static inline bool tegra210_plle_hw_sequence_is_enabled(void) | |
234 | { | |
235 | return false; | |
236 | } | |
237 | ||
238 | static inline int tegra210_clk_handle_mbist_war(unsigned int id) | |
239 | { | |
240 | return 0; | |
241 | } | |
242 | ||
243 | static inline int | |
244 | tegra210_clk_emc_attach(struct clk *clk, | |
245 | struct tegra210_clk_emc_provider *provider) | |
246 | { | |
247 | return 0; | |
248 | } | |
249 | ||
250 | static inline void tegra210_xusb_pll_hw_control_enable(void) {} | |
251 | static inline void tegra210_xusb_pll_hw_sequence_start(void) {} | |
252 | static inline void tegra210_sata_pll_hw_control_enable(void) {} | |
253 | static inline void tegra210_sata_pll_hw_sequence_start(void) {} | |
254 | static inline void tegra210_set_sata_pll_seq_sw(bool state) {} | |
255 | static inline void tegra210_put_utmipll_in_iddq(void) {} | |
256 | static inline void tegra210_put_utmipll_out_iddq(void) {} | |
257 | static inline void tegra210_clk_emc_dll_enable(bool flag) {} | |
258 | static inline void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value) {} | |
259 | static inline void tegra210_clk_emc_update_setting(u32 emc_src_value) {} | |
260 | static inline void tegra210_clk_emc_detach(struct clk *clk) {} | |
261 | #endif | |
0ac65fc9 | 262 | |
89572c77 | 263 | #endif /* __LINUX_CLK_TEGRA_H_ */ |