Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad...
[linux-2.6-microblaze.git] / drivers / clk / sifive / sifive-prci.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2018-2019 SiFive, Inc.
4  * Wesley Terpstra
5  * Paul Walmsley
6  * Zong Li
7  */
8
9 #ifndef __SIFIVE_CLK_SIFIVE_PRCI_H
10 #define __SIFIVE_CLK_SIFIVE_PRCI_H
11
12 #include <linux/clk/analogbits-wrpll-cln28hpc.h>
13 #include <linux/clk-provider.h>
14 #include <linux/reset/reset-simple.h>
15 #include <linux/platform_device.h>
16
17 /*
18  * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
19  *     hfclk and rtcclk
20  */
21 #define EXPECTED_CLK_PARENT_COUNT 2
22
23 /*
24  * Register offsets and bitmasks
25  */
26
27 /* COREPLLCFG0 */
28 #define PRCI_COREPLLCFG0_OFFSET         0x4
29 #define PRCI_COREPLLCFG0_DIVR_SHIFT     0
30 #define PRCI_COREPLLCFG0_DIVR_MASK      (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
31 #define PRCI_COREPLLCFG0_DIVF_SHIFT     6
32 #define PRCI_COREPLLCFG0_DIVF_MASK      (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
33 #define PRCI_COREPLLCFG0_DIVQ_SHIFT     15
34 #define PRCI_COREPLLCFG0_DIVQ_MASK      (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
35 #define PRCI_COREPLLCFG0_RANGE_SHIFT    18
36 #define PRCI_COREPLLCFG0_RANGE_MASK     (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
37 #define PRCI_COREPLLCFG0_BYPASS_SHIFT   24
38 #define PRCI_COREPLLCFG0_BYPASS_MASK    (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
39 #define PRCI_COREPLLCFG0_FSE_SHIFT      25
40 #define PRCI_COREPLLCFG0_FSE_MASK       (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
41 #define PRCI_COREPLLCFG0_LOCK_SHIFT     31
42 #define PRCI_COREPLLCFG0_LOCK_MASK      (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
43
44 /* COREPLLCFG1 */
45 #define PRCI_COREPLLCFG1_OFFSET         0x8
46 #define PRCI_COREPLLCFG1_CKE_SHIFT      31
47 #define PRCI_COREPLLCFG1_CKE_MASK       (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
48
49 /* DDRPLLCFG0 */
50 #define PRCI_DDRPLLCFG0_OFFSET          0xc
51 #define PRCI_DDRPLLCFG0_DIVR_SHIFT      0
52 #define PRCI_DDRPLLCFG0_DIVR_MASK       (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
53 #define PRCI_DDRPLLCFG0_DIVF_SHIFT      6
54 #define PRCI_DDRPLLCFG0_DIVF_MASK       (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
55 #define PRCI_DDRPLLCFG0_DIVQ_SHIFT      15
56 #define PRCI_DDRPLLCFG0_DIVQ_MASK       (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
57 #define PRCI_DDRPLLCFG0_RANGE_SHIFT     18
58 #define PRCI_DDRPLLCFG0_RANGE_MASK      (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
59 #define PRCI_DDRPLLCFG0_BYPASS_SHIFT    24
60 #define PRCI_DDRPLLCFG0_BYPASS_MASK     (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
61 #define PRCI_DDRPLLCFG0_FSE_SHIFT       25
62 #define PRCI_DDRPLLCFG0_FSE_MASK        (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
63 #define PRCI_DDRPLLCFG0_LOCK_SHIFT      31
64 #define PRCI_DDRPLLCFG0_LOCK_MASK       (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
65
66 /* DDRPLLCFG1 */
67 #define PRCI_DDRPLLCFG1_OFFSET          0x10
68 #define PRCI_DDRPLLCFG1_CKE_SHIFT       31
69 #define PRCI_DDRPLLCFG1_CKE_MASK        (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
70
71 /* PCIEAUX */
72 #define PRCI_PCIE_AUX_OFFSET            0x14
73 #define PRCI_PCIE_AUX_EN_SHIFT          0
74 #define PRCI_PCIE_AUX_EN_MASK           (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
75
76 /* GEMGXLPLLCFG0 */
77 #define PRCI_GEMGXLPLLCFG0_OFFSET       0x1c
78 #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT   0
79 #define PRCI_GEMGXLPLLCFG0_DIVR_MASK    (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
80 #define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT   6
81 #define PRCI_GEMGXLPLLCFG0_DIVF_MASK    (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
82 #define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT   15
83 #define PRCI_GEMGXLPLLCFG0_DIVQ_MASK    (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
84 #define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT  18
85 #define PRCI_GEMGXLPLLCFG0_RANGE_MASK   (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
86 #define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24
87 #define PRCI_GEMGXLPLLCFG0_BYPASS_MASK  (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
88 #define PRCI_GEMGXLPLLCFG0_FSE_SHIFT    25
89 #define PRCI_GEMGXLPLLCFG0_FSE_MASK     (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
90 #define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT   31
91 #define PRCI_GEMGXLPLLCFG0_LOCK_MASK    (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
92
93 /* GEMGXLPLLCFG1 */
94 #define PRCI_GEMGXLPLLCFG1_OFFSET       0x20
95 #define PRCI_GEMGXLPLLCFG1_CKE_SHIFT    31
96 #define PRCI_GEMGXLPLLCFG1_CKE_MASK     (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
97
98 /* CORECLKSEL */
99 #define PRCI_CORECLKSEL_OFFSET                  0x24
100 #define PRCI_CORECLKSEL_CORECLKSEL_SHIFT        0
101 #define PRCI_CORECLKSEL_CORECLKSEL_MASK                                 \
102                 (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
103
104 /* DEVICESRESETREG */
105 #define PRCI_DEVICESRESETREG_OFFSET                             0x28
106 #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT               0
107 #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK                        \
108                 (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
109 #define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT                1
110 #define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK                         \
111                 (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
112 #define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT                2
113 #define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK                         \
114                 (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
115 #define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT                3
116 #define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK                         \
117                 (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
118 #define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT                 5
119 #define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK                          \
120                 (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
121 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT               6
122 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK                        \
123                 (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
124
125 #define PRCI_RST_NR                                             7
126
127 /* CLKMUXSTATUSREG */
128 #define PRCI_CLKMUXSTATUSREG_OFFSET                             0x2c
129 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT              1
130 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK                       \
131                 (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
132
133 /* CLTXPLLCFG0 */
134 #define PRCI_CLTXPLLCFG0_OFFSET         0x30
135 #define PRCI_CLTXPLLCFG0_DIVR_SHIFT     0
136 #define PRCI_CLTXPLLCFG0_DIVR_MASK      (0x3f << PRCI_CLTXPLLCFG0_DIVR_SHIFT)
137 #define PRCI_CLTXPLLCFG0_DIVF_SHIFT     6
138 #define PRCI_CLTXPLLCFG0_DIVF_MASK      (0x1ff << PRCI_CLTXPLLCFG0_DIVF_SHIFT)
139 #define PRCI_CLTXPLLCFG0_DIVQ_SHIFT     15
140 #define PRCI_CLTXPLLCFG0_DIVQ_MASK      (0x7 << PRCI_CLTXPLLCFG0_DIVQ_SHIFT)
141 #define PRCI_CLTXPLLCFG0_RANGE_SHIFT    18
142 #define PRCI_CLTXPLLCFG0_RANGE_MASK     (0x7 << PRCI_CLTXPLLCFG0_RANGE_SHIFT)
143 #define PRCI_CLTXPLLCFG0_BYPASS_SHIFT   24
144 #define PRCI_CLTXPLLCFG0_BYPASS_MASK    (0x1 << PRCI_CLTXPLLCFG0_BYPASS_SHIFT)
145 #define PRCI_CLTXPLLCFG0_FSE_SHIFT      25
146 #define PRCI_CLTXPLLCFG0_FSE_MASK       (0x1 << PRCI_CLTXPLLCFG0_FSE_SHIFT)
147 #define PRCI_CLTXPLLCFG0_LOCK_SHIFT     31
148 #define PRCI_CLTXPLLCFG0_LOCK_MASK      (0x1 << PRCI_CLTXPLLCFG0_LOCK_SHIFT)
149
150 /* CLTXPLLCFG1 */
151 #define PRCI_CLTXPLLCFG1_OFFSET         0x34
152 #define PRCI_CLTXPLLCFG1_CKE_SHIFT      31
153 #define PRCI_CLTXPLLCFG1_CKE_MASK       (0x1 << PRCI_CLTXPLLCFG1_CKE_SHIFT)
154
155 /* DVFSCOREPLLCFG0 */
156 #define PRCI_DVFSCOREPLLCFG0_OFFSET     0x38
157
158 /* DVFSCOREPLLCFG1 */
159 #define PRCI_DVFSCOREPLLCFG1_OFFSET     0x3c
160 #define PRCI_DVFSCOREPLLCFG1_CKE_SHIFT  31
161 #define PRCI_DVFSCOREPLLCFG1_CKE_MASK   (0x1 << PRCI_DVFSCOREPLLCFG1_CKE_SHIFT)
162
163 /* COREPLLSEL */
164 #define PRCI_COREPLLSEL_OFFSET                  0x40
165 #define PRCI_COREPLLSEL_COREPLLSEL_SHIFT        0
166 #define PRCI_COREPLLSEL_COREPLLSEL_MASK                                 \
167                 (0x1 << PRCI_COREPLLSEL_COREPLLSEL_SHIFT)
168
169 /* HFPCLKPLLCFG0 */
170 #define PRCI_HFPCLKPLLCFG0_OFFSET               0x50
171 #define PRCI_HFPCLKPLL_CFG0_DIVR_SHIFT          0
172 #define PRCI_HFPCLKPLL_CFG0_DIVR_MASK                                   \
173                 (0x3f << PRCI_HFPCLKPLLCFG0_DIVR_SHIFT)
174 #define PRCI_HFPCLKPLL_CFG0_DIVF_SHIFT          6
175 #define PRCI_HFPCLKPLL_CFG0_DIVF_MASK                                   \
176                 (0x1ff << PRCI_HFPCLKPLLCFG0_DIVF_SHIFT)
177 #define PRCI_HFPCLKPLL_CFG0_DIVQ_SHIFT          15
178 #define PRCI_HFPCLKPLL_CFG0_DIVQ_MASK                                   \
179                 (0x7 << PRCI_HFPCLKPLLCFG0_DIVQ_SHIFT)
180 #define PRCI_HFPCLKPLL_CFG0_RANGE_SHIFT         18
181 #define PRCI_HFPCLKPLL_CFG0_RANGE_MASK                                  \
182                 (0x7 << PRCI_HFPCLKPLLCFG0_RANGE_SHIFT)
183 #define PRCI_HFPCLKPLL_CFG0_BYPASS_SHIFT        24
184 #define PRCI_HFPCLKPLL_CFG0_BYPASS_MASK                                 \
185                 (0x1 << PRCI_HFPCLKPLLCFG0_BYPASS_SHIFT)
186 #define PRCI_HFPCLKPLL_CFG0_FSE_SHIFT           25
187 #define PRCI_HFPCLKPLL_CFG0_FSE_MASK                                    \
188                 (0x1 << PRCI_HFPCLKPLLCFG0_FSE_SHIFT)
189 #define PRCI_HFPCLKPLL_CFG0_LOCK_SHIFT          31
190 #define PRCI_HFPCLKPLL_CFG0_LOCK_MASK                                   \
191                 (0x1 << PRCI_HFPCLKPLLCFG0_LOCK_SHIFT)
192
193 /* HFPCLKPLLCFG1 */
194 #define PRCI_HFPCLKPLLCFG1_OFFSET               0x54
195 #define PRCI_HFPCLKPLLCFG1_CKE_SHIFT            31
196 #define PRCI_HFPCLKPLLCFG1_CKE_MASK                                     \
197                 (0x1 << PRCI_HFPCLKPLLCFG1_CKE_SHIFT)
198
199 /* HFPCLKPLLSEL */
200 #define PRCI_HFPCLKPLLSEL_OFFSET                0x58
201 #define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT    0
202 #define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK                             \
203                 (0x1 << PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT)
204
205 /* HFPCLKPLLDIV */
206 #define PRCI_HFPCLKPLLDIV_OFFSET                0x5c
207
208 /* PRCIPLL */
209 #define PRCI_PRCIPLL_OFFSET                     0xe0
210
211 /* PROCMONCFG */
212 #define PRCI_PROCMONCFG_OFFSET                  0xf0
213
214 /*
215  * Private structures
216  */
217
218 /**
219  * struct __prci_data - per-device-instance data
220  * @va: base virtual address of the PRCI IP block
221  * @hw_clks: encapsulates struct clk_hw records
222  *
223  * PRCI per-device instance data
224  */
225 struct __prci_data {
226         void __iomem *va;
227         struct reset_simple_data reset;
228         struct clk_hw_onecell_data hw_clks;
229 };
230
231 /**
232  * struct __prci_wrpll_data - WRPLL configuration and integration data
233  * @c: WRPLL current configuration record
234  * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
235  * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
236  * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
237  * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address
238  *
239  * @enable_bypass and @disable_bypass are used for WRPLL instances
240  * that contain a separate external glitchless clock mux downstream
241  * from the PLL.  The WRPLL internal bypass mux is not glitchless.
242  */
243 struct __prci_wrpll_data {
244         struct wrpll_cfg c;
245         void (*enable_bypass)(struct __prci_data *pd);
246         void (*disable_bypass)(struct __prci_data *pd);
247         u8 cfg0_offs;
248         u8 cfg1_offs;
249 };
250
251 /**
252  * struct __prci_clock - describes a clock device managed by PRCI
253  * @name: user-readable clock name string - should match the manual
254  * @parent_name: parent name for this clock
255  * @ops: struct clk_ops for the Linux clock framework to use for control
256  * @hw: Linux-private clock data
257  * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
258  * @pd: PRCI-specific data associated with this clock (if not NULL)
259  *
260  * PRCI clock data.  Used by the PRCI driver to register PRCI-provided
261  * clocks to the Linux clock infrastructure.
262  */
263 struct __prci_clock {
264         const char *name;
265         const char *parent_name;
266         const struct clk_ops *ops;
267         struct clk_hw hw;
268         struct __prci_wrpll_data *pwd;
269         struct __prci_data *pd;
270 };
271
272 #define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
273
274 /*
275  * struct prci_clk_desc - describes the information of clocks of each SoCs
276  * @clks: point to a array of __prci_clock
277  * @num_clks: the number of element of clks
278  */
279 struct prci_clk_desc {
280         struct __prci_clock *clks;
281         size_t num_clks;
282 };
283
284 /* Core clock mux control */
285 void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd);
286 void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd);
287 void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd);
288 void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd);
289 void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd);
290 void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd);
291 void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd);
292
293 /* Linux clock framework integration */
294 long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
295                                   unsigned long *parent_rate);
296 int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
297                                unsigned long parent_rate);
298 int sifive_clk_is_enabled(struct clk_hw *hw);
299 int sifive_prci_clock_enable(struct clk_hw *hw);
300 void sifive_prci_clock_disable(struct clk_hw *hw);
301 unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
302                                             unsigned long parent_rate);
303 unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
304                                                unsigned long parent_rate);
305 unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
306                                                    unsigned long parent_rate);
307
308 int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
309 int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
310 void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
311
312 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */