1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (C) 2018-2019 SiFive, Inc.
9 #ifndef __SIFIVE_CLK_SIFIVE_PRCI_H
10 #define __SIFIVE_CLK_SIFIVE_PRCI_H
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>
18 * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
21 #define EXPECTED_CLK_PARENT_COUNT 2
24 * Register offsets and bitmasks
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)
45 #define PRCI_COREPLLCFG1_OFFSET 0x8
46 #define PRCI_COREPLLCFG1_CKE_SHIFT 31
47 #define PRCI_COREPLLCFG1_CKE_MASK (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
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)
67 #define PRCI_DDRPLLCFG1_OFFSET 0x10
68 #define PRCI_DDRPLLCFG1_CKE_SHIFT 31
69 #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
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)
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)
94 #define PRCI_GEMGXLPLLCFG1_OFFSET 0x20
95 #define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 31
96 #define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
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)
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)
125 #define PRCI_RST_NR 7
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)
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)
151 #define PRCI_CLTXPLLCFG1_OFFSET 0x34
152 #define PRCI_CLTXPLLCFG1_CKE_SHIFT 31
153 #define PRCI_CLTXPLLCFG1_CKE_MASK (0x1 << PRCI_CLTXPLLCFG1_CKE_SHIFT)
155 /* DVFSCOREPLLCFG0 */
156 #define PRCI_DVFSCOREPLLCFG0_OFFSET 0x38
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)
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)
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)
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)
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)
206 #define PRCI_HFPCLKPLLDIV_OFFSET 0x5c
209 #define PRCI_PRCIPLL_OFFSET 0xe0
212 #define PRCI_PROCMONCFG_OFFSET 0xf0
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
223 * PRCI per-device instance data
227 struct reset_simple_data reset
;
228 struct clk_hw_onecell_data hw_clks
;
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
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.
243 struct __prci_wrpll_data
{
245 void (*enable_bypass
)(struct __prci_data
*pd
);
246 void (*disable_bypass
)(struct __prci_data
*pd
);
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)
260 * PRCI clock data. Used by the PRCI driver to register PRCI-provided
261 * clocks to the Linux clock infrastructure.
263 struct __prci_clock
{
265 const char *parent_name
;
266 const struct clk_ops
*ops
;
268 struct __prci_wrpll_data
*pwd
;
269 struct __prci_data
*pd
;
272 #define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
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
279 struct prci_clk_desc
{
280 struct __prci_clock
*clks
;
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
);
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
);
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
);
312 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */