GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / clk / starfive / clk-starfive-jh71x0.h
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, _flags, _nparents, ...)                        \
65 [_idx] = {                                                                      \
66         .name = _name,                                                          \
67         .flags = _flags,                                                        \
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_hw *pll[3];
118         struct jh71x0_clk reg[];
119 };
120
121 const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
122
123 #endif