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