1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __LINUX_CLK_TEGRA_H_
18#define __LINUX_CLK_TEGRA_H_
19
20#include <linux/clk.h>
21
22/*
23 * Tegra CPU clock and reset control ops
24 *
25 * wait_for_reset:
26 *	keep waiting until the CPU in reset state
27 * put_in_reset:
28 *	put the CPU in reset state
29 * out_of_reset:
30 *	release the CPU from reset state
31 * enable_clock:
32 *	CPU clock un-gate
33 * disable_clock:
34 *	CPU clock gate
35 * rail_off_ready:
36 *	CPU is ready for rail off
37 * suspend:
38 *	save the clock settings when CPU go into low-power state
39 * resume:
40 *	restore the clock settings when CPU exit low-power state
41 */
42struct tegra_cpu_car_ops {
43	void (*wait_for_reset)(u32 cpu);
44	void (*put_in_reset)(u32 cpu);
45	void (*out_of_reset)(u32 cpu);
46	void (*enable_clock)(u32 cpu);
47	void (*disable_clock)(u32 cpu);
48#ifdef CONFIG_PM_SLEEP
49	bool (*rail_off_ready)(void);
50	void (*suspend)(void);
51	void (*resume)(void);
52#endif
53};
54
55extern struct tegra_cpu_car_ops *tegra_cpu_car_ops;
56
57static inline void tegra_wait_cpu_in_reset(u32 cpu)
58{
59	if (WARN_ON(!tegra_cpu_car_ops->wait_for_reset))
60		return;
61
62	tegra_cpu_car_ops->wait_for_reset(cpu);
63}
64
65static inline void tegra_put_cpu_in_reset(u32 cpu)
66{
67	if (WARN_ON(!tegra_cpu_car_ops->put_in_reset))
68		return;
69
70	tegra_cpu_car_ops->put_in_reset(cpu);
71}
72
73static inline void tegra_cpu_out_of_reset(u32 cpu)
74{
75	if (WARN_ON(!tegra_cpu_car_ops->out_of_reset))
76		return;
77
78	tegra_cpu_car_ops->out_of_reset(cpu);
79}
80
81static inline void tegra_enable_cpu_clock(u32 cpu)
82{
83	if (WARN_ON(!tegra_cpu_car_ops->enable_clock))
84		return;
85
86	tegra_cpu_car_ops->enable_clock(cpu);
87}
88
89static inline void tegra_disable_cpu_clock(u32 cpu)
90{
91	if (WARN_ON(!tegra_cpu_car_ops->disable_clock))
92		return;
93
94	tegra_cpu_car_ops->disable_clock(cpu);
95}
96
97#ifdef CONFIG_PM_SLEEP
98static inline bool tegra_cpu_rail_off_ready(void)
99{
100	if (WARN_ON(!tegra_cpu_car_ops->rail_off_ready))
101		return false;
102
103	return tegra_cpu_car_ops->rail_off_ready();
104}
105
106static inline void tegra_cpu_clock_suspend(void)
107{
108	if (WARN_ON(!tegra_cpu_car_ops->suspend))
109		return;
110
111	tegra_cpu_car_ops->suspend();
112}
113
114static inline void tegra_cpu_clock_resume(void)
115{
116	if (WARN_ON(!tegra_cpu_car_ops->resume))
117		return;
118
119	tegra_cpu_car_ops->resume();
120}
121#endif
122
123#endif /* __LINUX_CLK_TEGRA_H_ */
124