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
10struct clk_hw;
11struct device;
12struct regmap;
13
14#define UNIPHIER_CLK_CPUGEAR_MAX_PARENTS	16
15#define UNIPHIER_CLK_MUX_MAX_PARENTS		8
16
17enum 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
25struct 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
32struct uniphier_clk_fixed_factor_data {
33	const char *parent_name;
34	unsigned int mult;
35	unsigned int div;
36};
37
38struct uniphier_clk_fixed_rate_data {
39	unsigned long fixed_rate;
40};
41
42struct uniphier_clk_gate_data {
43	const char *parent_name;
44	unsigned int reg;
45	unsigned int bit;
46};
47
48struct 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
56struct 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
126struct 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);
130struct clk_hw *uniphier_clk_register_fixed_factor(struct device *dev,
131						  const char *name,
132			const struct uniphier_clk_fixed_factor_data *data);
133struct clk_hw *uniphier_clk_register_fixed_rate(struct device *dev,
134						const char *name,
135			const struct uniphier_clk_fixed_rate_data *data);
136struct 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);
140struct 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
145extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[];
146extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[];
147extern const struct uniphier_clk_data uniphier_sld8_sys_clk_data[];
148extern const struct uniphier_clk_data uniphier_pro5_sys_clk_data[];
149extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[];
150extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[];
151extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[];
152extern const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[];
153extern const struct uniphier_clk_data uniphier_nx1_sys_clk_data[];
154extern const struct uniphier_clk_data uniphier_ld4_mio_clk_data[];
155extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[];
156extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[];
157extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[];
158extern const struct uniphier_clk_data uniphier_pro4_sg_clk_data[];
159
160#endif /* __CLK_UNIPHIER_H__ */
161