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 */
25struct 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
106struct jh71x0_clk {
107 struct clk_hw hw;
108 unsigned int idx;
109 unsigned int max_div;
110};
111
112struct 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
121const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
122
123#endif
124

source code of linux/drivers/clk/starfive/clk-starfive-jh71x0.h