b27ba4c5daeb3524e8de9e74baa2e4382a62b896
[platform/kernel/linux-starfive.git] / drivers / clk / starfive / clk-starfive-jh7110.h
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * StarFive JH7110 Clock Generator Driver
4  *
5  * Copyright (C) 2022 Xingyu Wu <xingyu.wu@starfivetech.com>
6  */
7
8 #ifndef _CLK_STARFIVE_JH7110_H_
9 #define _CLK_STARFIVE_JH7110_H_
10
11 #include <linux/bits.h>
12 #include <linux/clk-provider.h>
13 #include <linux/debugfs.h>
14 #include <dt-bindings/clock/starfive-jh7110-clkgen.h>
15 #include <dt-bindings/clock/starfive-jh7110-vout.h>
16
17 /* register flags */
18 #define JH7110_CLK_SYS_FLAG     1
19 #define JH7110_CLK_STG_FLAG     2
20 #define JH7110_CLK_AON_FLAG     3
21 #define JH7110_CLK_VOUT_FLAG    4
22 #define JH7110_CLK_ISP_FLAG     5
23
24 /* register fields */
25 #define JH7110_CLK_ENABLE       BIT(31)
26 #define JH7110_CLK_INVERT       BIT(30)
27 #define JH7110_CLK_MUX_MASK     GENMASK(29, 24)
28 #define JH7110_CLK_MUX_SHIFT    24
29 #define JH7110_CLK_DIV_MASK     GENMASK(23, 0)
30
31 /* clkgen PLL CLOCK offset */
32 #define PLL_OF(x)       (x - JH7110_CLK_REG_END)
33 /* vout PLL CLOCK offset */
34 #define PLL_OFV(x)      (x - JH7110_CLK_VOUT_REG_END)
35
36 /* clock data */
37 struct jh7110_clk_data {
38         const char *name;
39         unsigned long flags;
40         u32 max;
41         u16 parents[4];
42 };
43
44 struct jh7110_clk {
45         struct clk_hw hw;
46         unsigned int idx;
47         unsigned int max_div;
48         unsigned int reg_flags;
49 };
50
51 struct jh7110_clk_priv {
52         /* protect clk enable and set rate/parent from happening at the same time */
53         spinlock_t rmw_lock;
54         struct device *dev;
55         void __iomem *sys_base;
56         void __iomem *stg_base;
57         void __iomem *aon_base;
58         void __iomem *vout_base;
59         void __iomem *isp_base;
60         struct clk_hw *pll[PLL_OF(JH7110_CLK_END)];
61         struct jh7110_clk reg[];
62 };
63
64 #define JH7110_GATE(_idx, _name, _flags, _parent) [_idx] = {                    \
65         .name = _name,                                                          \
66         .flags = CLK_SET_RATE_PARENT | (_flags),                                \
67         .max = JH7110_CLK_ENABLE,                                               \
68         .parents = { [0] = _parent },                                           \
69 }
70
71 #define JH7110__DIV(_idx, _name, _max, _parent) [_idx] = {                      \
72         .name = _name,                                                          \
73         .flags = 0,                                                             \
74         .max = _max,                                                            \
75         .parents = { [0] = _parent },                                           \
76 }
77
78 #define JH7110_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = {              \
79         .name = _name,                                                          \
80         .flags = _flags,                                                        \
81         .max = JH7110_CLK_ENABLE | (_max),                                      \
82         .parents = { [0] = _parent },                                           \
83 }
84
85 #define JH7110__MUX(_idx, _name, _nparents, ...) [_idx] = {                     \
86         .name = _name,                                                          \
87         .flags = 0,                                                             \
88         .max = ((_nparents) - 1) << JH7110_CLK_MUX_SHIFT,                       \
89         .parents = { __VA_ARGS__ },                                             \
90 }
91
92 #define JH7110_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = {             \
93         .name = _name,                                                          \
94         .flags = _flags,                                                        \
95         .max = JH7110_CLK_ENABLE |                                              \
96                 (((_nparents) - 1) << JH7110_CLK_MUX_SHIFT),                    \
97         .parents = { __VA_ARGS__ },                                             \
98 }
99
100 #define JH7110_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = {               \
101         .name = _name,                                                          \
102         .flags = 0,                                                             \
103         .max = (((_nparents) - 1) << JH7110_CLK_MUX_SHIFT) | (_max),            \
104         .parents = { __VA_ARGS__ },                                             \
105 }
106
107 #define JH7110__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = {       \
108         .name = _name,                                                          \
109         .flags = _flags,                                                        \
110         .max = JH7110_CLK_ENABLE |                                              \
111                 (((_nparents) - 1) << JH7110_CLK_MUX_SHIFT) | (_max),           \
112         .parents = { __VA_ARGS__ },                                             \
113 }
114
115 #define JH7110__INV(_idx, _name, _parent) [_idx] = {                            \
116         .name = _name,                                                          \
117         .flags = CLK_SET_RATE_PARENT,                                           \
118         .max = JH7110_CLK_INVERT,                                               \
119         .parents = { [0] = _parent },                                           \
120 }
121
122 void __iomem *jh7110_clk_reg_addr_get(struct jh7110_clk *clk);
123 const struct clk_ops *starfive_jh7110_clk_ops(u32 max);
124
125 int __init clk_starfive_jh7110_sys_init(struct platform_device *pdev, \
126                                         struct jh7110_clk_priv *priv);
127 int __init clk_starfive_jh7110_stg_init(struct platform_device *pdev, \
128                                         struct jh7110_clk_priv *priv);
129 int __init clk_starfive_jh7110_aon_init(struct platform_device *pdev, \
130                                         struct jh7110_clk_priv *priv);
131
132 #endif