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