]>
Commit | Line | Data |
---|---|---|
5fe225c1 RJ |
1 | /* |
2 | * Copyright (C) 2014 Broadcom Corporation | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License as | |
6 | * published by the Free Software Foundation version 2. | |
7 | * | |
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | |
9 | * kind, whether express or implied; without even the implied warranty | |
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | */ | |
13 | ||
14 | #ifndef _CLK_IPROC_H | |
15 | #define _CLK_IPROC_H | |
16 | ||
17 | #include <linux/kernel.h> | |
18 | #include <linux/list.h> | |
19 | #include <linux/spinlock.h> | |
20 | #include <linux/slab.h> | |
21 | #include <linux/device.h> | |
22 | #include <linux/of.h> | |
23 | #include <linux/clk-provider.h> | |
24 | ||
25 | #define IPROC_CLK_NAME_LEN 25 | |
26 | #define IPROC_CLK_INVALID_OFFSET 0xffffffff | |
27 | #define bit_mask(width) ((1 << (width)) - 1) | |
28 | ||
29 | /* clocks that should not be disabled at runtime */ | |
30 | #define IPROC_CLK_AON BIT(0) | |
31 | ||
32 | /* PLL that requires gating through ASIU */ | |
33 | #define IPROC_CLK_PLL_ASIU BIT(1) | |
34 | ||
35 | /* PLL that has fractional part of the NDIV */ | |
36 | #define IPROC_CLK_PLL_HAS_NDIV_FRAC BIT(2) | |
37 | ||
38 | /* | |
39 | * Some of the iProc PLL/clocks may have an ASIC bug that requires read back | |
40 | * of the same register following the write to flush the write transaction into | |
41 | * the intended register | |
42 | */ | |
43 | #define IPROC_CLK_NEEDS_READ_BACK BIT(3) | |
44 | ||
45 | /* | |
46 | * Some PLLs require the PLL SW override bit to be set before changes can be | |
47 | * applied to the PLL | |
48 | */ | |
49 | #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4) | |
50 | ||
01b6722f JM |
51 | /* |
52 | * Some PLLs use a different way to control clock power, via the PWRDWN bit in | |
53 | * the PLL control register | |
54 | */ | |
55 | #define IPROC_CLK_EMBED_PWRCTRL BIT(5) | |
56 | ||
5fe225c1 RJ |
57 | /* |
58 | * Parameters for VCO frequency configuration | |
59 | * | |
60 | * VCO frequency = | |
61 | * ((ndiv_int + ndiv_frac / 2^20) * (ref freqeuncy / pdiv) | |
62 | */ | |
63 | struct iproc_pll_vco_param { | |
64 | unsigned long rate; | |
65 | unsigned int ndiv_int; | |
66 | unsigned int ndiv_frac; | |
67 | unsigned int pdiv; | |
68 | }; | |
69 | ||
70 | struct iproc_clk_reg_op { | |
71 | unsigned int offset; | |
72 | unsigned int shift; | |
73 | unsigned int width; | |
74 | }; | |
75 | ||
76 | /* | |
77 | * Clock gating control at the top ASIU level | |
78 | */ | |
79 | struct iproc_asiu_gate { | |
80 | unsigned int offset; | |
81 | unsigned int en_shift; | |
82 | }; | |
83 | ||
84 | /* | |
85 | * Control of powering on/off of a PLL | |
86 | * | |
87 | * Before powering off a PLL, input isolation (ISO) needs to be enabled | |
88 | */ | |
89 | struct iproc_pll_aon_pwr_ctrl { | |
90 | unsigned int offset; | |
91 | unsigned int pwr_width; | |
92 | unsigned int pwr_shift; | |
93 | unsigned int iso_shift; | |
94 | }; | |
95 | ||
96 | /* | |
f713c6bf | 97 | * Control of the PLL reset |
5fe225c1 RJ |
98 | */ |
99 | struct iproc_pll_reset_ctrl { | |
100 | unsigned int offset; | |
101 | unsigned int reset_shift; | |
102 | unsigned int p_reset_shift; | |
f713c6bf JM |
103 | }; |
104 | ||
105 | /* | |
106 | * Control of the Ki, Kp, and Ka parameters | |
107 | */ | |
108 | struct iproc_pll_dig_filter_ctrl { | |
109 | unsigned int offset; | |
5fe225c1 RJ |
110 | unsigned int ki_shift; |
111 | unsigned int ki_width; | |
112 | unsigned int kp_shift; | |
113 | unsigned int kp_width; | |
114 | unsigned int ka_shift; | |
115 | unsigned int ka_width; | |
116 | }; | |
117 | ||
118 | /* | |
119 | * To enable SW control of the PLL | |
120 | */ | |
121 | struct iproc_pll_sw_ctrl { | |
122 | unsigned int offset; | |
123 | unsigned int shift; | |
124 | }; | |
125 | ||
126 | struct iproc_pll_vco_ctrl { | |
127 | unsigned int u_offset; | |
128 | unsigned int l_offset; | |
129 | }; | |
130 | ||
131 | /* | |
132 | * Main PLL control parameters | |
133 | */ | |
134 | struct iproc_pll_ctrl { | |
135 | unsigned long flags; | |
136 | struct iproc_pll_aon_pwr_ctrl aon; | |
137 | struct iproc_asiu_gate asiu; | |
138 | struct iproc_pll_reset_ctrl reset; | |
f713c6bf | 139 | struct iproc_pll_dig_filter_ctrl dig_filter; |
5fe225c1 RJ |
140 | struct iproc_pll_sw_ctrl sw_ctrl; |
141 | struct iproc_clk_reg_op ndiv_int; | |
142 | struct iproc_clk_reg_op ndiv_frac; | |
143 | struct iproc_clk_reg_op pdiv; | |
144 | struct iproc_pll_vco_ctrl vco_ctrl; | |
145 | struct iproc_clk_reg_op status; | |
146 | }; | |
147 | ||
148 | /* | |
149 | * Controls enabling/disabling a PLL derived clock | |
150 | */ | |
151 | struct iproc_clk_enable_ctrl { | |
152 | unsigned int offset; | |
153 | unsigned int enable_shift; | |
154 | unsigned int hold_shift; | |
155 | unsigned int bypass_shift; | |
156 | }; | |
157 | ||
158 | /* | |
159 | * Main clock control parameters for clocks derived from the PLLs | |
160 | */ | |
161 | struct iproc_clk_ctrl { | |
162 | unsigned int channel; | |
163 | unsigned long flags; | |
164 | struct iproc_clk_enable_ctrl enable; | |
165 | struct iproc_clk_reg_op mdiv; | |
166 | }; | |
167 | ||
168 | /* | |
169 | * Divisor of the ASIU clocks | |
170 | */ | |
171 | struct iproc_asiu_div { | |
172 | unsigned int offset; | |
173 | unsigned int en_shift; | |
174 | unsigned int high_shift; | |
175 | unsigned int high_width; | |
176 | unsigned int low_shift; | |
177 | unsigned int low_width; | |
178 | }; | |
179 | ||
180 | void __init iproc_armpll_setup(struct device_node *node); | |
181 | void __init iproc_pll_clk_setup(struct device_node *node, | |
182 | const struct iproc_pll_ctrl *pll_ctrl, | |
183 | const struct iproc_pll_vco_param *vco, | |
184 | unsigned int num_vco_entries, | |
185 | const struct iproc_clk_ctrl *clk_ctrl, | |
186 | unsigned int num_clks); | |
187 | void __init iproc_asiu_setup(struct device_node *node, | |
188 | const struct iproc_asiu_div *div, | |
189 | const struct iproc_asiu_gate *gate, | |
190 | unsigned int num_clks); | |
191 | ||
192 | #endif /* _CLK_IPROC_H */ |