1e19aa786SEmil Renner Berthing /* SPDX-License-Identifier: GPL-2.0 */
2*147455edSEmil Renner Berthing #ifndef __CLK_STARFIVE_JH71X0_H
3*147455edSEmil Renner Berthing #define __CLK_STARFIVE_JH71X0_H
4e19aa786SEmil Renner Berthing 
5e19aa786SEmil Renner Berthing #include <linux/bits.h>
6e19aa786SEmil Renner Berthing #include <linux/clk-provider.h>
7e19aa786SEmil Renner Berthing #include <linux/device.h>
8e19aa786SEmil Renner Berthing #include <linux/spinlock.h>
9e19aa786SEmil Renner Berthing 
10e19aa786SEmil Renner Berthing /* register fields */
11*147455edSEmil Renner Berthing #define JH71X0_CLK_ENABLE	BIT(31)
12*147455edSEmil Renner Berthing #define JH71X0_CLK_INVERT	BIT(30)
13*147455edSEmil Renner Berthing #define JH71X0_CLK_MUX_MASK	GENMASK(27, 24)
14*147455edSEmil Renner Berthing #define JH71X0_CLK_MUX_SHIFT	24
15*147455edSEmil Renner Berthing #define JH71X0_CLK_DIV_MASK	GENMASK(23, 0)
16*147455edSEmil Renner Berthing #define JH71X0_CLK_FRAC_MASK	GENMASK(15, 8)
17*147455edSEmil Renner Berthing #define JH71X0_CLK_FRAC_SHIFT	8
18*147455edSEmil Renner Berthing #define JH71X0_CLK_INT_MASK	GENMASK(7, 0)
19e19aa786SEmil Renner Berthing 
20e19aa786SEmil Renner Berthing /* fractional divider min/max */
21*147455edSEmil Renner Berthing #define JH71X0_CLK_FRAC_MIN	100UL
22*147455edSEmil Renner Berthing #define JH71X0_CLK_FRAC_MAX	25599UL
23e19aa786SEmil Renner Berthing 
24e19aa786SEmil Renner Berthing /* clock data */
25*147455edSEmil Renner Berthing struct jh71x0_clk_data {
26e19aa786SEmil Renner Berthing 	const char *name;
27e19aa786SEmil Renner Berthing 	unsigned long flags;
28e19aa786SEmil Renner Berthing 	u32 max;
29e19aa786SEmil Renner Berthing 	u8 parents[4];
30e19aa786SEmil Renner Berthing };
31e19aa786SEmil Renner Berthing 
32*147455edSEmil Renner Berthing #define JH71X0_GATE(_idx, _name, _flags, _parent)				\
33*147455edSEmil Renner Berthing [_idx] = {									\
34e19aa786SEmil Renner Berthing 	.name = _name,								\
35e19aa786SEmil Renner Berthing 	.flags = CLK_SET_RATE_PARENT | (_flags),				\
36*147455edSEmil Renner Berthing 	.max = JH71X0_CLK_ENABLE,						\
37e19aa786SEmil Renner Berthing 	.parents = { [0] = _parent },						\
38e19aa786SEmil Renner Berthing }
39e19aa786SEmil Renner Berthing 
40*147455edSEmil Renner Berthing #define JH71X0__DIV(_idx, _name, _max, _parent)					\
41*147455edSEmil Renner Berthing [_idx] = {									\
42e19aa786SEmil Renner Berthing 	.name = _name,								\
43e19aa786SEmil Renner Berthing 	.flags = 0,								\
44e19aa786SEmil Renner Berthing 	.max = _max,								\
45e19aa786SEmil Renner Berthing 	.parents = { [0] = _parent },						\
46e19aa786SEmil Renner Berthing }
47e19aa786SEmil Renner Berthing 
48*147455edSEmil Renner Berthing #define JH71X0_GDIV(_idx, _name, _flags, _max, _parent)				\
49*147455edSEmil Renner Berthing [_idx] = {									\
50e19aa786SEmil Renner Berthing 	.name = _name,								\
51e19aa786SEmil Renner Berthing 	.flags = _flags,							\
52*147455edSEmil Renner Berthing 	.max = JH71X0_CLK_ENABLE | (_max),					\
53e19aa786SEmil Renner Berthing 	.parents = { [0] = _parent },						\
54e19aa786SEmil Renner Berthing }
55e19aa786SEmil Renner Berthing 
56*147455edSEmil Renner Berthing #define JH71X0_FDIV(_idx, _name, _parent)					\
57*147455edSEmil Renner Berthing [_idx] = {									\
58e19aa786SEmil Renner Berthing 	.name = _name,								\
59e19aa786SEmil Renner Berthing 	.flags = 0,								\
60*147455edSEmil Renner Berthing 	.max = JH71X0_CLK_FRAC_MAX,						\
61e19aa786SEmil Renner Berthing 	.parents = { [0] = _parent },						\
62e19aa786SEmil Renner Berthing }
63e19aa786SEmil Renner Berthing 
64*147455edSEmil Renner Berthing #define JH71X0__MUX(_idx, _name, _nparents, ...)				\
65*147455edSEmil Renner Berthing [_idx] = {									\
66e19aa786SEmil Renner Berthing 	.name = _name,								\
67e19aa786SEmil Renner Berthing 	.flags = 0,								\
68*147455edSEmil Renner Berthing 	.max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT,			\
69e19aa786SEmil Renner Berthing 	.parents = { __VA_ARGS__ },						\
70e19aa786SEmil Renner Berthing }
71e19aa786SEmil Renner Berthing 
72*147455edSEmil Renner Berthing #define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...)			\
73*147455edSEmil Renner Berthing [_idx] = {									\
74e19aa786SEmil Renner Berthing 	.name = _name,								\
75e19aa786SEmil Renner Berthing 	.flags = _flags,							\
76*147455edSEmil Renner Berthing 	.max = JH71X0_CLK_ENABLE |						\
77*147455edSEmil Renner Berthing 		(((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT),			\
78e19aa786SEmil Renner Berthing 	.parents = { __VA_ARGS__ },						\
79e19aa786SEmil Renner Berthing }
80e19aa786SEmil Renner Berthing 
81*147455edSEmil Renner Berthing #define JH71X0_MDIV(_idx, _name, _max, _nparents, ...)				\
82*147455edSEmil Renner Berthing [_idx] = {									\
83e19aa786SEmil Renner Berthing 	.name = _name,								\
84e19aa786SEmil Renner Berthing 	.flags = 0,								\
85*147455edSEmil Renner Berthing 	.max = (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max),		\
86e19aa786SEmil Renner Berthing 	.parents = { __VA_ARGS__ },						\
87e19aa786SEmil Renner Berthing }
88e19aa786SEmil Renner Berthing 
89*147455edSEmil Renner Berthing #define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...)			\
90*147455edSEmil Renner Berthing [_idx] = {									\
91e19aa786SEmil Renner Berthing 	.name = _name,								\
92e19aa786SEmil Renner Berthing 	.flags = _flags,							\
93*147455edSEmil Renner Berthing 	.max = JH71X0_CLK_ENABLE |						\
94*147455edSEmil Renner Berthing 		(((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max),		\
95e19aa786SEmil Renner Berthing 	.parents = { __VA_ARGS__ },						\
96e19aa786SEmil Renner Berthing }
97e19aa786SEmil Renner Berthing 
98*147455edSEmil Renner Berthing #define JH71X0__INV(_idx, _name, _parent)					\
99*147455edSEmil Renner Berthing [_idx] = {									\
100e19aa786SEmil Renner Berthing 	.name = _name,								\
101e19aa786SEmil Renner Berthing 	.flags = CLK_SET_RATE_PARENT,						\
102*147455edSEmil Renner Berthing 	.max = JH71X0_CLK_INVERT,						\
103e19aa786SEmil Renner Berthing 	.parents = { [0] = _parent },						\
104e19aa786SEmil Renner Berthing }
105e19aa786SEmil Renner Berthing 
106*147455edSEmil Renner Berthing struct jh71x0_clk {
107e19aa786SEmil Renner Berthing 	struct clk_hw hw;
108e19aa786SEmil Renner Berthing 	unsigned int idx;
109e19aa786SEmil Renner Berthing 	unsigned int max_div;
110e19aa786SEmil Renner Berthing };
111e19aa786SEmil Renner Berthing 
112*147455edSEmil Renner Berthing struct jh71x0_clk_priv {
113e19aa786SEmil Renner Berthing 	/* protect clk enable and set rate/parent from happening at the same time */
114e19aa786SEmil Renner Berthing 	spinlock_t rmw_lock;
115e19aa786SEmil Renner Berthing 	struct device *dev;
116e19aa786SEmil Renner Berthing 	void __iomem *base;
117e19aa786SEmil Renner Berthing 	struct clk_hw *pll[3];
118*147455edSEmil Renner Berthing 	struct jh71x0_clk reg[];
119e19aa786SEmil Renner Berthing };
120e19aa786SEmil Renner Berthing 
121*147455edSEmil Renner Berthing const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
122e19aa786SEmil Renner Berthing 
123e19aa786SEmil Renner Berthing #endif
124