1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Hisilicon Hi3620 clock gate driver
4 *
5 * Copyright (c) 2012-2013 Hisilicon Limited.
6 * Copyright (c) 2012-2013 Linaro Limited.
7 *
8 * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
9 *	   Xin Li <li.xin@linaro.org>
10 */
11
12#ifndef	__HISI_CLK_H
13#define	__HISI_CLK_H
14
15#include <linux/clk-provider.h>
16#include <linux/io.h>
17#include <linux/spinlock.h>
18
19struct platform_device;
20
21struct hisi_clock_data {
22	struct clk_onecell_data	clk_data;
23	void __iomem		*base;
24};
25
26struct hisi_fixed_rate_clock {
27	unsigned int		id;
28	char			*name;
29	const char		*parent_name;
30	unsigned long		flags;
31	unsigned long		fixed_rate;
32};
33
34struct hisi_fixed_factor_clock {
35	unsigned int		id;
36	char			*name;
37	const char		*parent_name;
38	unsigned long		mult;
39	unsigned long		div;
40	unsigned long		flags;
41};
42
43struct hisi_mux_clock {
44	unsigned int		id;
45	const char		*name;
46	const char		*const *parent_names;
47	u8			num_parents;
48	unsigned long		flags;
49	unsigned long		offset;
50	u8			shift;
51	u8			width;
52	u8			mux_flags;
53	const u32		*table;
54	const char		*alias;
55};
56
57struct hisi_phase_clock {
58	unsigned int		id;
59	const char		*name;
60	const char		*parent_names;
61	unsigned long		flags;
62	unsigned long		offset;
63	u8			shift;
64	u8			width;
65	u32			*phase_degrees;
66	u32			*phase_regvals;
67	u8			phase_num;
68};
69
70struct hisi_divider_clock {
71	unsigned int		id;
72	const char		*name;
73	const char		*parent_name;
74	unsigned long		flags;
75	unsigned long		offset;
76	u8			shift;
77	u8			width;
78	u8			div_flags;
79	struct clk_div_table	*table;
80	const char		*alias;
81};
82
83struct hi6220_divider_clock {
84	unsigned int		id;
85	const char		*name;
86	const char		*parent_name;
87	unsigned long		flags;
88	unsigned long		offset;
89	u8			shift;
90	u8			width;
91	u32			mask_bit;
92	const char		*alias;
93};
94
95struct hisi_gate_clock {
96	unsigned int		id;
97	const char		*name;
98	const char		*parent_name;
99	unsigned long		flags;
100	unsigned long		offset;
101	u8			bit_idx;
102	u8			gate_flags;
103	const char		*alias;
104};
105
106struct clk *hisi_register_clkgate_sep(struct device *, const char *,
107				const char *, unsigned long,
108				void __iomem *, u8,
109				u8, spinlock_t *);
110struct clk *hi6220_register_clkdiv(struct device *dev, const char *name,
111	const char *parent_name, unsigned long flags, void __iomem *reg,
112	u8 shift, u8 width, u32 mask_bit, spinlock_t *lock);
113
114struct hisi_clock_data *hisi_clk_alloc(struct platform_device *, int);
115struct hisi_clock_data *hisi_clk_init(struct device_node *, int);
116int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *,
117				int, struct hisi_clock_data *);
118int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
119				int, struct hisi_clock_data *);
120int hisi_clk_register_mux(const struct hisi_mux_clock *, int,
121				struct hisi_clock_data *);
122struct clk *clk_register_hisi_phase(struct device *dev,
123				const struct hisi_phase_clock *clks,
124				void __iomem *base, spinlock_t *lock);
125int hisi_clk_register_phase(struct device *dev,
126				const struct hisi_phase_clock *clks,
127				int nums, struct hisi_clock_data *data);
128int hisi_clk_register_divider(const struct hisi_divider_clock *,
129				int, struct hisi_clock_data *);
130int hisi_clk_register_gate(const struct hisi_gate_clock *,
131				int, struct hisi_clock_data *);
132void hisi_clk_register_gate_sep(const struct hisi_gate_clock *,
133				int, struct hisi_clock_data *);
134void hi6220_clk_register_divider(const struct hi6220_divider_clock *,
135				int, struct hisi_clock_data *);
136
137#define hisi_clk_unregister(type) \
138static inline \
139void hisi_clk_unregister_##type(const struct hisi_##type##_clock *clks, \
140				int nums, struct hisi_clock_data *data) \
141{ \
142	struct clk **clocks = data->clk_data.clks; \
143	int i; \
144	for (i = 0; i < nums; i++) { \
145		int id = clks[i].id; \
146		if (clocks[id])  \
147			clk_unregister_##type(clocks[id]); \
148	} \
149}
150
151hisi_clk_unregister(fixed_rate)
152hisi_clk_unregister(fixed_factor)
153hisi_clk_unregister(mux)
154hisi_clk_unregister(divider)
155hisi_clk_unregister(gate)
156
157#endif	/* __HISI_CLK_H */
158