1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (C) 2016 Socionext Inc.
4  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
5  */
6 
7 #ifndef __CLK_UNIPHIER_H__
8 #define __CLK_UNIPHIER_H__
9 
10 struct clk_hw;
11 struct device;
12 struct regmap;
13 
14 #define UNIPHIER_CLK_CPUGEAR_MAX_PARENTS	16
15 #define UNIPHIER_CLK_MUX_MAX_PARENTS		8
16 
17 enum uniphier_clk_type {
18 	UNIPHIER_CLK_TYPE_CPUGEAR,
19 	UNIPHIER_CLK_TYPE_FIXED_FACTOR,
20 	UNIPHIER_CLK_TYPE_FIXED_RATE,
21 	UNIPHIER_CLK_TYPE_GATE,
22 	UNIPHIER_CLK_TYPE_MUX,
23 };
24 
25 struct uniphier_clk_cpugear_data {
26 	const char *parent_names[UNIPHIER_CLK_CPUGEAR_MAX_PARENTS];
27 	unsigned int num_parents;
28 	unsigned int regbase;
29 	unsigned int mask;
30 };
31 
32 struct uniphier_clk_fixed_factor_data {
33 	const char *parent_name;
34 	unsigned int mult;
35 	unsigned int div;
36 };
37 
38 struct uniphier_clk_fixed_rate_data {
39 	unsigned long fixed_rate;
40 };
41 
42 struct uniphier_clk_gate_data {
43 	const char *parent_name;
44 	unsigned int reg;
45 	unsigned int bit;
46 };
47 
48 struct uniphier_clk_mux_data {
49 	const char *parent_names[UNIPHIER_CLK_MUX_MAX_PARENTS];
50 	unsigned int num_parents;
51 	unsigned int reg;
52 	unsigned int masks[UNIPHIER_CLK_MUX_MAX_PARENTS];
53 	unsigned int vals[UNIPHIER_CLK_MUX_MAX_PARENTS];
54 };
55 
56 struct uniphier_clk_data {
57 	const char *name;
58 	enum uniphier_clk_type type;
59 	int idx;
60 	union {
61 		struct uniphier_clk_cpugear_data cpugear;
62 		struct uniphier_clk_fixed_factor_data factor;
63 		struct uniphier_clk_fixed_rate_data rate;
64 		struct uniphier_clk_gate_data gate;
65 		struct uniphier_clk_mux_data mux;
66 	} data;
67 };
68 
69 #define UNIPHIER_CLK_CPUGEAR(_name, _idx, _regbase, _mask,	\
70 			     _num_parents, ...)			\
71 	{							\
72 		.name = (_name),				\
73 		.type = UNIPHIER_CLK_TYPE_CPUGEAR,		\
74 		.idx = (_idx),					\
75 		.data.cpugear = {				\
76 			.parent_names = { __VA_ARGS__ },	\
77 			.num_parents = (_num_parents),		\
78 			.regbase = (_regbase),			\
79 			.mask = (_mask)				\
80 		 },						\
81 	}
82 
83 #define UNIPHIER_CLK_FACTOR(_name, _idx, _parent, _mult, _div)	\
84 	{							\
85 		.name = (_name),				\
86 		.type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,		\
87 		.idx = (_idx),					\
88 		.data.factor = {				\
89 			.parent_name = (_parent),		\
90 			.mult = (_mult),			\
91 			.div = (_div),				\
92 		},						\
93 	}
94 
95 #define UNIPHIER_CLK_GATE(_name, _idx, _parent, _reg, _bit)	\
96 	{							\
97 		.name = (_name),				\
98 		.type = UNIPHIER_CLK_TYPE_GATE,			\
99 		.idx = (_idx),					\
100 		.data.gate = {					\
101 			.parent_name = (_parent),		\
102 			.reg = (_reg),				\
103 			.bit = (_bit),				\
104 		},						\
105 	}
106 
107 #define UNIPHIER_CLK_DIV(parent, div)				\
108 	UNIPHIER_CLK_FACTOR(parent "/" #div, -1, parent, 1, div)
109 
110 #define UNIPHIER_CLK_DIV2(parent, div0, div1)			\
111 	UNIPHIER_CLK_DIV(parent, div0),				\
112 	UNIPHIER_CLK_DIV(parent, div1)
113 
114 #define UNIPHIER_CLK_DIV3(parent, div0, div1, div2)		\
115 	UNIPHIER_CLK_DIV2(parent, div0, div1),			\
116 	UNIPHIER_CLK_DIV(parent, div2)
117 
118 #define UNIPHIER_CLK_DIV4(parent, div0, div1, div2, div3)	\
119 	UNIPHIER_CLK_DIV2(parent, div0, div1),			\
120 	UNIPHIER_CLK_DIV2(parent, div2, div3)
121 
122 #define UNIPHIER_CLK_DIV5(parent, div0, div1, div2, div3, div4)	\
123 	UNIPHIER_CLK_DIV4(parent, div0, div1, div2, div3),	\
124 	UNIPHIER_CLK_DIV(parent, div4)
125 
126 struct clk_hw *uniphier_clk_register_cpugear(struct device *dev,
127 					     struct regmap *regmap,
128 					     const char *name,
129 				const struct uniphier_clk_cpugear_data *data);
130 struct clk_hw *uniphier_clk_register_fixed_factor(struct device *dev,
131 						  const char *name,
132 			const struct uniphier_clk_fixed_factor_data *data);
133 struct clk_hw *uniphier_clk_register_fixed_rate(struct device *dev,
134 						const char *name,
135 			const struct uniphier_clk_fixed_rate_data *data);
136 struct clk_hw *uniphier_clk_register_gate(struct device *dev,
137 					  struct regmap *regmap,
138 					  const char *name,
139 				const struct uniphier_clk_gate_data *data);
140 struct clk_hw *uniphier_clk_register_mux(struct device *dev,
141 					 struct regmap *regmap,
142 					 const char *name,
143 				const struct uniphier_clk_mux_data *data);
144 
145 extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[];
146 extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[];
147 extern const struct uniphier_clk_data uniphier_sld8_sys_clk_data[];
148 extern const struct uniphier_clk_data uniphier_pro5_sys_clk_data[];
149 extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[];
150 extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[];
151 extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[];
152 extern const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[];
153 extern const struct uniphier_clk_data uniphier_nx1_sys_clk_data[];
154 extern const struct uniphier_clk_data uniphier_ld4_mio_clk_data[];
155 extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[];
156 extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[];
157 extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[];
158 
159 #endif /* __CLK_UNIPHIER_H__ */
160