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