summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/clkctrl-imx233.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233/clkctrl-imx233.c')
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.c203
1 files changed, 78 insertions, 125 deletions
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.c b/firmware/target/arm/imx233/clkctrl-imx233.c
index cfee4aea37..1553889543 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.c
+++ b/firmware/target/arm/imx233/clkctrl-imx233.c
@@ -26,9 +26,9 @@
26void imx233_clkctrl_enable_xtal(enum imx233_xtal_clk_t xtal_clk, bool enable) 26void imx233_clkctrl_enable_xtal(enum imx233_xtal_clk_t xtal_clk, bool enable)
27{ 27{
28 if(enable) 28 if(enable)
29 __REG_CLR(HW_CLKCTRL_XTAL) = xtal_clk; 29 HW_CLKCTRL_XTAL_CLR = xtal_clk;
30 else 30 else
31 __REG_SET(HW_CLKCTRL_XTAL) = xtal_clk; 31 HW_CLKCTRL_XTAL_SET = xtal_clk;
32} 32}
33 33
34bool imx233_clkctrl_is_xtal_enable(enum imx233_xtal_clk_t clk) 34bool imx233_clkctrl_is_xtal_enable(enum imx233_xtal_clk_t clk)
@@ -38,78 +38,49 @@ bool imx233_clkctrl_is_xtal_enable(enum imx233_xtal_clk_t clk)
38 38
39void imx233_clkctrl_enable_clock(enum imx233_clock_t clk, bool enable) 39void imx233_clkctrl_enable_clock(enum imx233_clock_t clk, bool enable)
40{ 40{
41 volatile uint32_t *REG; 41 bool gate = !enable;
42 switch(clk) 42 switch(clk)
43 { 43 {
44 case CLK_PIX: REG = &HW_CLKCTRL_PIX; break; 44 case CLK_PIX: BF_WR(CLKCTRL_PIX, CLKGATE, gate); break;
45 case CLK_SSP: REG = &HW_CLKCTRL_SSP; break; 45 case CLK_SSP: BF_WR(CLKCTRL_SSP, CLKGATE, gate); break;
46 case CLK_PLL: 46 case CLK_PLL:
47 { 47 /* pll is a special case */
48 if(enable) 48 if(enable)
49 { 49 {
50 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER; 50 BF_SET(CLKCTRL_PLLCTRL0, POWER);
51 while(!(HW_CLKCTRL_PLLCTRL1 & HW_CLKCTRL_PLLCTRL1__LOCK)); 51 while(!BF_RD(CLKCTRL_PLLCTRL1, LOCK));
52 } 52 }
53 else 53 else
54 __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER; 54 BF_CLR(CLKCTRL_PLLCTRL0, POWER);
55 return; 55 break;
56 } 56 default:
57 default: return; 57 break;
58 }
59
60 /* warning: some registers like HW_CLKCTRL_PIX don't have a CLR/SET variant ! */
61 if(enable)
62 {
63 *REG = (*REG) & ~__CLK_CLKGATE;
64 while((*REG) & __CLK_CLKGATE);
65 while((*REG) & __CLK_BUSY);
66 }
67 else
68 {
69 *REG |= __CLK_CLKGATE;
70 while(!((*REG) & __CLK_CLKGATE));
71 } 58 }
72} 59}
73 60
74bool imx233_clkctrl_is_clock_enabled(enum imx233_clock_t clk) 61bool imx233_clkctrl_is_clock_enabled(enum imx233_clock_t clk)
75{ 62{
76 volatile uint32_t *REG;
77 switch(clk) 63 switch(clk)
78 { 64 {
79 case CLK_PLL: return HW_CLKCTRL_PLLCTRL0 & HW_CLKCTRL_PLLCTRL0__POWER; 65 case CLK_PLL: return BF_RD(CLKCTRL_PLLCTRL0, POWER);
80 case CLK_PIX: REG = &HW_CLKCTRL_PIX; break; 66 case CLK_PIX: return !BF_RD(CLKCTRL_PIX, CLKGATE);
81 case CLK_SSP: REG = &HW_CLKCTRL_SSP; break; 67 case CLK_SSP: return !BF_RD(CLKCTRL_SSP, CLKGATE);
82 default: return true; 68 default: return true;
83 } 69 }
84
85 return !((*REG) & __CLK_CLKGATE);
86} 70}
87 71
88void imx233_clkctrl_set_clock_divisor(enum imx233_clock_t clk, int div) 72void imx233_clkctrl_set_clock_divisor(enum imx233_clock_t clk, int div)
89{ 73{
90 /* warning: some registers like HW_CLKCTRL_PIX don't have a CLR/SET variant ! */ 74 /* warning: some registers like HW_CLKCTRL_PIX don't have a CLR/SET variant !
75 * assume that we always derive emi and cpu from ref_XX */
91 switch(clk) 76 switch(clk)
92 { 77 {
93 case CLK_PIX: 78 case CLK_PIX: BF_WR(CLKCTRL_PIX, DIV, div); break;
94 __FIELD_SET(HW_CLKCTRL_PIX, DIV, div); 79 case CLK_CPU: BF_WR(CLKCTRL_CPU, DIV_CPU, div); break;
95 break; 80 case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV_EMI, div); break;
96 case CLK_SSP: 81 case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV, div); break;
97 __FIELD_SET(HW_CLKCTRL_SSP, DIV, div); 82 case CLK_HBUS: BF_WR(CLKCTRL_HBUS, DIV, div); break;
98 break; 83 case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV, div); break;
99 case CLK_CPU:
100 __FIELD_SET(HW_CLKCTRL_CPU, DIV_CPU, div);
101 break;
102 case CLK_EMI:
103 __FIELD_SET(HW_CLKCTRL_EMI, DIV_EMI, div);
104 break;
105 case CLK_HBUS:
106 /* disable frac enable at the same time */
107 HW_CLKCTRL_HBUS = div << HW_CLKCTRL_HBUS__DIV_BP |
108 (HW_CLKCTRL_HBUS & ~(HW_CLKCTRL_HBUS__DIV_FRAC_EN | HW_CLKCTRL_HBUS__DIV_BM));
109 break;
110 case CLK_XBUS:
111 __FIELD_SET(HW_CLKCTRL_XBUS, DIV, div);
112 break;
113 default: return; 84 default: return;
114 } 85 }
115} 86}
@@ -118,66 +89,54 @@ int imx233_clkctrl_get_clock_divisor(enum imx233_clock_t clk)
118{ 89{
119 switch(clk) 90 switch(clk)
120 { 91 {
121 case CLK_PIX: return __XTRACT(HW_CLKCTRL_PIX, DIV); 92 case CLK_PIX: return BF_RD(CLKCTRL_PIX, DIV);
122 case CLK_SSP: return __XTRACT(HW_CLKCTRL_SSP, DIV); 93 case CLK_CPU: return BF_RD(CLKCTRL_CPU, DIV_CPU);
123 case CLK_CPU: return __XTRACT(HW_CLKCTRL_CPU, DIV_CPU); 94 case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV_EMI);
124 case CLK_EMI: return __XTRACT(HW_CLKCTRL_EMI, DIV_EMI); 95 case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV);
125 case CLK_HBUS: 96 case CLK_HBUS: return BF_RD(CLKCTRL_HBUS, DIV);
126 if(HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__DIV_FRAC_EN) 97 case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV);
127 return 0;
128 else
129 return __XTRACT(HW_CLKCTRL_HBUS, DIV);
130 case CLK_XBUS: return __XTRACT(HW_CLKCTRL_XBUS, DIV);
131 default: return 0; 98 default: return 0;
132 } 99 }
133} 100}
134 101
135void imx233_clkctrl_set_fractional_divisor(enum imx233_clock_t clk, int fracdiv) 102void imx233_clkctrl_set_fractional_divisor(enum imx233_clock_t clk, int fracdiv)
136{ 103{
137 /* NOTE: HW_CLKCTRL_FRAC only support byte access ! */ 104#define handle_frac(dev) \
138 volatile uint8_t *REG; 105 case CLK_##dev: \
106 if(fracdiv == 0) \
107 BF_SET(CLKCTRL_FRAC, CLKGATE##dev); \
108 else { \
109 BF_WR(CLKCTRL_FRAC, dev##FRAC, fracdiv); \
110 BF_CLR(CLKCTRL_FRAC, CLKGATE##dev); } \
111 break;
139 switch(clk) 112 switch(clk)
140 { 113 {
141 case CLK_HBUS: 114 handle_frac(PIX)
142 /* set frac enable at the same time */ 115 handle_frac(IO)
143 HW_CLKCTRL_HBUS = fracdiv << HW_CLKCTRL_HBUS__DIV_BP | HW_CLKCTRL_HBUS__DIV_FRAC_EN | 116 handle_frac(CPU)
144 (HW_CLKCTRL_HBUS & ~HW_CLKCTRL_HBUS__DIV_BM); 117 handle_frac(EMI)
145 return; 118 default: break;
146 case CLK_PIX: REG = &HW_CLKCTRL_FRAC_PIX; break;
147 case CLK_IO: REG = &HW_CLKCTRL_FRAC_IO; break;
148 case CLK_CPU: REG = &HW_CLKCTRL_FRAC_CPU; break;
149 case CLK_EMI: REG = &HW_CLKCTRL_FRAC_EMI; break;
150 default: return;
151 } 119 }
152 120#undef handle_frac
153 if(fracdiv != 0)
154 *REG = fracdiv;
155 else
156 *REG = HW_CLKCTRL_FRAC_XX__CLKGATEXX;
157} 121}
158 122
159int imx233_clkctrl_get_fractional_divisor(enum imx233_clock_t clk) 123int imx233_clkctrl_get_fractional_divisor(enum imx233_clock_t clk)
160{ 124{
161 /* NOTE: HW_CLKCTRL_FRAC only support byte access ! */ 125#define handle_frac(dev) \
162 volatile uint8_t *REG; 126 case CLK_##dev:\
127 if(BF_RD(CLKCTRL_FRAC, CLKGATE##dev)) \
128 return 0; \
129 else \
130 return BF_RD(CLKCTRL_FRAC, dev##FRAC);
163 switch(clk) 131 switch(clk)
164 { 132 {
165 case CLK_HBUS: 133 handle_frac(PIX)
166 if(HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__DIV_FRAC_EN) 134 handle_frac(IO)
167 return __XTRACT(HW_CLKCTRL_HBUS, DIV); 135 handle_frac(CPU)
168 else 136 handle_frac(EMI)
169 return 0;
170 case CLK_PIX: REG = &HW_CLKCTRL_FRAC_PIX; break;
171 case CLK_IO: REG = &HW_CLKCTRL_FRAC_IO; break;
172 case CLK_CPU: REG = &HW_CLKCTRL_FRAC_CPU; break;
173 case CLK_EMI: REG = &HW_CLKCTRL_FRAC_EMI; break;
174 default: return 0; 137 default: return 0;
175 } 138 }
176 139#undef handle_frac
177 if((*REG) & HW_CLKCTRL_FRAC_XX__CLKGATEXX)
178 return 0;
179 else
180 return *REG & ~HW_CLKCTRL_FRAC_XX__XX_STABLE;
181} 140}
182 141
183void imx233_clkctrl_set_bypass_pll(enum imx233_clock_t clk, bool bypass) 142void imx233_clkctrl_set_bypass_pll(enum imx233_clock_t clk, bool bypass)
@@ -185,45 +144,42 @@ void imx233_clkctrl_set_bypass_pll(enum imx233_clock_t clk, bool bypass)
185 uint32_t msk; 144 uint32_t msk;
186 switch(clk) 145 switch(clk)
187 { 146 {
188 case CLK_PIX: msk = HW_CLKCTRL_CLKSEQ__BYPASS_PIX; break; 147 case CLK_PIX: msk = BM_CLKCTRL_CLKSEQ_BYPASS_PIX; break;
189 case CLK_SSP: msk = HW_CLKCTRL_CLKSEQ__BYPASS_SSP; break; 148 case CLK_SSP: msk = BM_CLKCTRL_CLKSEQ_BYPASS_SSP; break;
190 case CLK_CPU: msk = HW_CLKCTRL_CLKSEQ__BYPASS_CPU; break; 149 case CLK_CPU: msk = BM_CLKCTRL_CLKSEQ_BYPASS_CPU; break;
191 case CLK_EMI: msk = HW_CLKCTRL_CLKSEQ__BYPASS_EMI; break; 150 case CLK_EMI: msk = BM_CLKCTRL_CLKSEQ_BYPASS_EMI; break;
192 default: return; 151 default: return;
193 } 152 }
194 153
195 if(bypass) 154 if(bypass)
196 __REG_SET(HW_CLKCTRL_CLKSEQ) = msk; 155 HW_CLKCTRL_CLKSEQ_SET = msk;
197 else 156 else
198 __REG_CLR(HW_CLKCTRL_CLKSEQ) = msk; 157 HW_CLKCTRL_CLKSEQ_CLR = msk;
199} 158}
200 159
201bool imx233_clkctrl_get_bypass_pll(enum imx233_clock_t clk) 160bool imx233_clkctrl_get_bypass_pll(enum imx233_clock_t clk)
202{ 161{
203 uint32_t msk;
204 switch(clk) 162 switch(clk)
205 { 163 {
206 case CLK_PIX: msk = HW_CLKCTRL_CLKSEQ__BYPASS_PIX; break; 164 case CLK_PIX: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_PIX);
207 case CLK_SSP: msk = HW_CLKCTRL_CLKSEQ__BYPASS_SSP; break; 165 case CLK_SSP: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_SSP);
208 case CLK_CPU: msk = HW_CLKCTRL_CLKSEQ__BYPASS_CPU; break; 166 case CLK_CPU: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_CPU);
209 case CLK_EMI: msk = HW_CLKCTRL_CLKSEQ__BYPASS_EMI; break; 167 case CLK_EMI: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_EMI);
210 default: return false; 168 default: return false;
211 } 169 }
212
213 return HW_CLKCTRL_CLKSEQ & msk;
214} 170}
215 171
216void imx233_clkctrl_enable_usb_pll(bool enable) 172void imx233_clkctrl_enable_usb_pll(bool enable)
217{ 173{
218 if(enable) 174 if(enable)
219 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; 175 BF_SET(CLKCTRL_PLLCTRL0, EN_USB_CLKS);
220 else 176 else
221 __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; 177 BF_CLR(CLKCTRL_PLLCTRL0, EN_USB_CLKS);
222} 178}
223 179
224bool imx233_clkctrl_is_usb_pll_enabled(void) 180bool imx233_clkctrl_is_usb_pll_enabled(void)
225{ 181{
226 return HW_CLKCTRL_PLLCTRL0 & HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; 182 return BF_RD(CLKCTRL_PLLCTRL0, EN_USB_CLKS);
227} 183}
228 184
229void imx233_clkctrl_set_auto_slow_divisor(enum imx233_as_div_t div) 185void imx233_clkctrl_set_auto_slow_divisor(enum imx233_as_div_t div)
@@ -231,34 +187,31 @@ void imx233_clkctrl_set_auto_slow_divisor(enum imx233_as_div_t div)
231 /* the SLOW_DIV must only be set when auto-slow is disabled */ 187 /* the SLOW_DIV must only be set when auto-slow is disabled */
232 bool old_status = imx233_clkctrl_is_auto_slow_enabled(); 188 bool old_status = imx233_clkctrl_is_auto_slow_enabled();
233 imx233_clkctrl_enable_auto_slow(false); 189 imx233_clkctrl_enable_auto_slow(false);
234 __FIELD_SET(HW_CLKCTRL_HBUS, SLOW_DIV, div); 190 BF_WR(CLKCTRL_HBUS, SLOW_DIV, div);
235 imx233_clkctrl_enable_auto_slow(old_status); 191 imx233_clkctrl_enable_auto_slow(old_status);
236} 192}
237 193
238enum imx233_as_div_t imx233_clkctrl_get_auto_slow_divisor(void) 194enum imx233_as_div_t imx233_clkctrl_get_auto_slow_divisor(void)
239{ 195{
240 return __XTRACT(HW_CLKCTRL_HBUS, SLOW_DIV); 196 return BF_RD(CLKCTRL_HBUS, SLOW_DIV);
241} 197}
242 198
243void imx233_clkctrl_enable_auto_slow(bool enable) 199void imx233_clkctrl_enable_auto_slow(bool enable)
244{ 200{
245 if(enable) 201 BF_WR(CLKCTRL_HBUS, AUTO_SLOW_MODE, enable);
246 __REG_SET(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__AUTO_SLOW_MODE;
247 else
248 __REG_CLR(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__AUTO_SLOW_MODE;
249} 202}
250 203
251bool imx233_clkctrl_is_auto_slow_enabled(void) 204bool imx233_clkctrl_is_auto_slow_enabled(void)
252{ 205{
253 return HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__AUTO_SLOW_MODE; 206 return BF_RD(CLKCTRL_HBUS, AUTO_SLOW_MODE);
254} 207}
255 208
256void imx233_clkctrl_enable_auto_slow_monitor(enum imx233_as_monitor_t monitor, bool enable) 209void imx233_clkctrl_enable_auto_slow_monitor(enum imx233_as_monitor_t monitor, bool enable)
257{ 210{
258 if(enable) 211 if(enable)
259 __REG_SET(HW_CLKCTRL_HBUS) = monitor; 212 HW_CLKCTRL_HBUS_SET = monitor;
260 else 213 else
261 __REG_CLR(HW_CLKCTRL_HBUS) = monitor; 214 HW_CLKCTRL_HBUS_CLR = monitor;
262} 215}
263 216
264bool imx233_clkctrl_is_auto_slow_monitor_enabled(enum imx233_as_monitor_t monitor) 217bool imx233_clkctrl_is_auto_slow_monitor_enabled(enum imx233_as_monitor_t monitor)
@@ -268,7 +221,7 @@ bool imx233_clkctrl_is_auto_slow_monitor_enabled(enum imx233_as_monitor_t monito
268 221
269bool imx233_clkctrl_is_emi_sync_enabled(void) 222bool imx233_clkctrl_is_emi_sync_enabled(void)
270{ 223{
271 return !!(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__SYNC_MODE_EN); 224 return BF_RD(CLKCTRL_EMI, SYNC_MODE_EN);
272} 225}
273 226
274unsigned imx233_clkctrl_get_clock_freq(enum imx233_clock_t clk) 227unsigned imx233_clkctrl_get_clock_freq(enum imx233_clock_t clk)
@@ -289,9 +242,9 @@ unsigned imx233_clkctrl_get_clock_freq(enum imx233_clock_t clk)
289 { 242 {
290 ref = imx233_clkctrl_get_clock_freq(CLK_XTAL); 243 ref = imx233_clkctrl_get_clock_freq(CLK_XTAL);
291 /* Integer divide mode vs fractional divide mode */ 244 /* Integer divide mode vs fractional divide mode */
292 if(HW_CLKCTRL_CPU & HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN) 245 if(BF_RD(CLKCTRL_CPU, DIV_XTAL_FRAC_EN))
293 246
294 return (ref * __XTRACT(HW_CLKCTRL_CPU, DIV_XTAL)) / 32; 247 return (ref * BF_RD(CLKCTRL_CPU, DIV_XTAL)) / 32;
295 else 248 else
296 return ref / imx233_clkctrl_get_clock_divisor(CLK_CPU); 249 return ref / imx233_clkctrl_get_clock_divisor(CLK_CPU);
297 } 250 }
@@ -357,10 +310,10 @@ unsigned imx233_clkctrl_get_clock_freq(enum imx233_clock_t clk)
357 if(imx233_clkctrl_get_bypass_pll(CLK_EMI)) 310 if(imx233_clkctrl_get_bypass_pll(CLK_EMI))
358 { 311 {
359 ref = imx233_clkctrl_get_clock_freq(CLK_XTAL); 312 ref = imx233_clkctrl_get_clock_freq(CLK_XTAL);
360 if(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__CLKGATE) 313 if(BF_RD(CLKCTRL_EMI, CLKGATE))
361 return 0; 314 return 0;
362 else 315 else
363 return ref / __XTRACT(HW_CLKCTRL_EMI, DIV_XTAL); 316 return ref / BF_RD(CLKCTRL_EMI, DIV_XTAL);
364 } 317 }
365 else 318 else
366 { 319 {