baf4b5cb4b8a0a5b4ddd3ae84bfa42f201b2b17d
[platform/kernel/linux-starfive.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) [_idx] = {                    \
33         .name = _name,                                                          \
34         .flags = CLK_SET_RATE_PARENT | (_flags),                                \
35         .max = JH71X0_CLK_ENABLE,                                               \
36         .parents = { [0] = _parent },                                           \
37 }
38
39 #define JH71X0__DIV(_idx, _name, _max, _parent) [_idx] = {                      \
40         .name = _name,                                                          \
41         .flags = 0,                                                             \
42         .max = _max,                                                            \
43         .parents = { [0] = _parent },                                           \
44 }
45
46 #define JH71X0_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = {              \
47         .name = _name,                                                          \
48         .flags = _flags,                                                        \
49         .max = JH71X0_CLK_ENABLE | (_max),                                      \
50         .parents = { [0] = _parent },                                           \
51 }
52
53 #define JH71X0_FDIV(_idx, _name, _parent) [_idx] = {                            \
54         .name = _name,                                                          \
55         .flags = 0,                                                             \
56         .max = JH71X0_CLK_FRAC_MAX,                                             \
57         .parents = { [0] = _parent },                                           \
58 }
59
60 #define JH71X0__MUX(_idx, _name, _nparents, ...) [_idx] = {                     \
61         .name = _name,                                                          \
62         .flags = 0,                                                             \
63         .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT,                       \
64         .parents = { __VA_ARGS__ },                                             \
65 }
66
67 #define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = {             \
68         .name = _name,                                                          \
69         .flags = _flags,                                                        \
70         .max = JH71X0_CLK_ENABLE |                                              \
71                 (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT),                    \
72         .parents = { __VA_ARGS__ },                                             \
73 }
74
75 #define JH71X0_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = {               \
76         .name = _name,                                                          \
77         .flags = 0,                                                             \
78         .max = (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max),            \
79         .parents = { __VA_ARGS__ },                                             \
80 }
81
82 #define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = {       \
83         .name = _name,                                                          \
84         .flags = _flags,                                                        \
85         .max = JH71X0_CLK_ENABLE |                                              \
86                 (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max),           \
87         .parents = { __VA_ARGS__ },                                             \
88 }
89
90 #define JH71X0__INV(_idx, _name, _parent) [_idx] = {                            \
91         .name = _name,                                                          \
92         .flags = CLK_SET_RATE_PARENT,                                           \
93         .max = JH71X0_CLK_INVERT,                                               \
94         .parents = { [0] = _parent },                                           \
95 }
96
97 struct jh71x0_clk {
98         struct clk_hw hw;
99         unsigned int idx;
100         unsigned int max_div;
101 };
102
103 struct jh71x0_clk_priv {
104         /* protect clk enable and set rate/parent from happening at the same time */
105         spinlock_t rmw_lock;
106         struct device *dev;
107         void __iomem *base;
108         struct clk_hw *pll[3];
109         struct jh71x0_clk reg[];
110 };
111
112 const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
113
114 #endif