summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.c203
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.h83
-rw-r--r--firmware/target/arm/imx233/emi-imx233.c28
-rw-r--r--firmware/target/arm/imx233/system-imx233.c2
4 files changed, 98 insertions, 218 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 {
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.h b/firmware/target/arm/imx233/clkctrl-imx233.h
index 30c1c54545..a15adb367e 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.h
+++ b/firmware/target/arm/imx233/clkctrl-imx233.h
@@ -25,92 +25,15 @@
25#include "system.h" 25#include "system.h"
26#include "cpu.h" 26#include "cpu.h"
27 27
28#define HW_CLKCTRL_BASE 0x80040000 28#include "regs/regs-clkctrl.h"
29
30#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
31#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
32#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
33#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BP 20
34#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BM (3 << 20)
35
36#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
37#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31)
38
39#define HW_CLKCTRL_CPU (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
40#define HW_CLKCTRL_CPU__DIV_CPU_BP 0
41#define HW_CLKCTRL_CPU__DIV_CPU_BM 0x3f
42#define HW_CLKCTRL_CPU__INTERRUPT_WAIT (1 << 12)
43#define HW_CLKCTRL_CPU__DIV_XTAL_BP 16
44#define HW_CLKCTRL_CPU__DIV_XTAL_BM (0x3ff << 16)
45#define HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN (1 << 26)
46#define HW_CLKCTRL_CPU__BUSY_REF_CPU (1 << 28)
47
48#define HW_CLKCTRL_HBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
49#define HW_CLKCTRL_HBUS__DIV_BP 0
50#define HW_CLKCTRL_HBUS__DIV_BM 0x1f
51#define HW_CLKCTRL_HBUS__DIV_FRAC_EN (1 << 5)
52#define HW_CLKCTRL_HBUS__SLOW_DIV_BP 16
53#define HW_CLKCTRL_HBUS__SLOW_DIV_BM (0x7 << 16)
54#define HW_CLKCTRL_HBUS__AUTO_SLOW_MODE (1 << 20)
55
56/* warning: this register doesn't have a CLR/SET variant ! */
57#define HW_CLKCTRL_XBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
58#define HW_CLKCTRL_XBUS__DIV_BP 0
59#define HW_CLKCTRL_XBUS__DIV_BM 0x3ff
60#define HW_CLKCTRL_XBUS__BUSY (1 << 31)
61
62#define HW_CLKCTRL_XTAL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x50))
63#define HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE (1 << 26)
64#define HW_CLKCTRL_XTAL__DRI_CLK24M_GATE (1 << 28)
65#define HW_CLKCTRL_XTAL__FILT_CLK24M_GATE (1 << 30)
66
67/* warning: this register doesn't have a CLR/SET variant ! */
68#define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60))
69#define HW_CLKCTRL_PIX__DIV_BP 0
70#define HW_CLKCTRL_PIX__DIV_BM 0xfff
71
72/* warning: this register doesn't have a CLR/SET variant ! */
73#define HW_CLKCTRL_SSP (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
74#define HW_CLKCTRL_SSP__DIV_BP 0
75#define HW_CLKCTRL_SSP__DIV_BM 0x1ff
76
77/* warning: this register doesn't have a CLR/SET variant ! */
78#define HW_CLKCTRL_EMI (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xa0))
79#define HW_CLKCTRL_EMI__DIV_EMI_BP 0
80#define HW_CLKCTRL_EMI__DIV_EMI_BM 0x3f
81#define HW_CLKCTRL_EMI__DIV_XTAL_BP 8
82#define HW_CLKCTRL_EMI__DIV_XTAL_BM (0xf << 8)
83#define HW_CLKCTRL_EMI__BUSY_REF_EMI (1 << 28)
84#define HW_CLKCTRL_EMI__BUSY_REF_XTAL (1 << 29)
85#define HW_CLKCTRL_EMI__SYNC_MODE_EN (1 << 30)
86#define HW_CLKCTRL_EMI__CLKGATE (1 << 31)
87
88#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110))
89#define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1)
90#define HW_CLKCTRL_CLKSEQ__BYPASS_SSP (1 << 5)
91#define HW_CLKCTRL_CLKSEQ__BYPASS_EMI (1 << 6)
92#define HW_CLKCTRL_CLKSEQ__BYPASS_CPU (1 << 7)
93
94#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0))
95#define HW_CLKCTRL_FRAC_CPU (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf0))
96#define HW_CLKCTRL_FRAC_EMI (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf1))
97#define HW_CLKCTRL_FRAC_PIX (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf2))
98#define HW_CLKCTRL_FRAC_IO (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf3))
99#define HW_CLKCTRL_FRAC_XX__XXDIV_BM 0x3f
100#define HW_CLKCTRL_FRAC_XX__XX_STABLE (1 << 6)
101#define HW_CLKCTRL_FRAC_XX__CLKGATEXX (1 << 7)
102
103/* warning: this register doesn't have a CLR/SET variant ! */
104#define HW_CLKCTRL_RESET (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120))
105#define HW_CLKCTRL_RESET_CHIP 0x2
106#define HW_CLKCTRL_RESET_DIG 0x1
107 29
108static inline void core_sleep(void) 30static inline void core_sleep(void)
109{ 31{
110 __REG_SET(HW_CLKCTRL_CPU) = HW_CLKCTRL_CPU__INTERRUPT_WAIT; 32 BF_WR(CLKCTRL_CPU, INTERRUPT_WAIT, 1);
111 asm volatile ( 33 asm volatile (
112 "mcr p15, 0, %0, c7, c0, 4 \n" /* Wait for interrupt */ 34 "mcr p15, 0, %0, c7, c0, 4 \n" /* Wait for interrupt */
113 "nop\n" /* Datasheet unclear: "The lr sent to handler points here after RTI"*/ 35 "nop\n" /* Datasheet unclear: "The lr sent to handler points here after RTI"*/
36 "nop\n"
114 : : "r"(0) 37 : : "r"(0)
115 ); 38 );
116 enable_irq(); 39 enable_irq();
diff --git a/firmware/target/arm/imx233/emi-imx233.c b/firmware/target/arm/imx233/emi-imx233.c
index b10d08134d..57a929e65a 100644
--- a/firmware/target/arm/imx233/emi-imx233.c
+++ b/firmware/target/arm/imx233/emi-imx233.c
@@ -91,33 +91,37 @@ static void set_frequency(unsigned long freq) ICODE_ATTR;
91 91
92static void set_frequency(unsigned long freq) 92static void set_frequency(unsigned long freq)
93{ 93{
94 /* Set divider and clear clkgate. Do byte access to register to avoid bothering 94 /** WARNING all restriction of imx233_emi_set_frequency apply here !! */
95 * with other PFDs */ 95 /* Set divider and clear clkgate. */
96 unsigned fracdiv;
97 unsigned div;
96 switch(freq) 98 switch(freq)
97 { 99 {
98 case IMX233_EMIFREQ_151_MHz: 100 case IMX233_EMIFREQ_151_MHz:
99 /* clk_emi@ref_emi/3*18/19 */ 101 /* clk_emi@ref_emi/3*18/19 */
100 HW_CLKCTRL_FRAC_EMI = 19; 102 fracdiv = 19;
101 __FIELD_SET(HW_CLKCTRL_EMI, DIV_EMI, 3); 103 div = 3;
102 /* ref_emi@480 MHz 104 /* ref_emi@480 MHz
103 * clk_emi@151.58 MHz */ 105 * clk_emi@151.58 MHz */
104 break; 106 break;
105 case IMX233_EMIFREQ_130_MHz: 107 case IMX233_EMIFREQ_130_MHz:
106 /* clk_emi@ref_emi/2*18/33 */ 108 /* clk_emi@ref_emi/2*18/33 */
107 HW_CLKCTRL_FRAC_EMI = 33; 109 fracdiv = 33;
108 __FIELD_SET(HW_CLKCTRL_EMI, DIV_EMI, 2); 110 div = 2;
109 /* ref_emi@480 MHz 111 /* ref_emi@480 MHz
110 * clk_emi@130.91 MHz */ 112 * clk_emi@130.91 MHz */
111 break; 113 break;
112 case IMX233_EMIFREQ_64_MHz: 114 case IMX233_EMIFREQ_64_MHz:
113 default: 115 default:
114 /* clk_emi@ref_emi/5*18/27 */ 116 /* clk_emi@ref_emi/5*18/27 */
115 HW_CLKCTRL_FRAC_EMI = 27; 117 fracdiv = 27;
116 __FIELD_SET(HW_CLKCTRL_EMI, DIV_EMI, 5); 118 div = 5;
117 /* ref_emi@480 MHz 119 /* ref_emi@480 MHz
118 * clk_emi@64 MHz */ 120 * clk_emi@64 MHz */
119 break; 121 break;
120 } 122 }
123 BF_WR(CLKCTRL_FRAC, EMIFRAC, fracdiv);
124 BF_WR(CLKCTRL_EMI, DIV_EMI, div);
121} 125}
122 126
123void imx233_emi_set_frequency(unsigned long freq) ICODE_ATTR; 127void imx233_emi_set_frequency(unsigned long freq) ICODE_ATTR;
@@ -162,17 +166,17 @@ void imx233_emi_set_frequency(unsigned long freq)
162 HW_DRAM_CTLxx(regs->index) = regs->value; 166 HW_DRAM_CTLxx(regs->index) = regs->value;
163 while((regs++)->index != 40); 167 while((regs++)->index != 40);
164 /* switch emi to xtal */ 168 /* switch emi to xtal */
165 __REG_SET(HW_CLKCTRL_CLKSEQ) = HW_CLKCTRL_CLKSEQ__BYPASS_EMI; 169 BF_SET(CLKCTRL_CLKSEQ, BYPASS_EMI);
166 /* wait for transition */ 170 /* wait for transition */
167 while(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__BUSY_REF_XTAL); 171 while(BF_RD(CLKCTRL_EMI, BUSY_REF_XTAL));
168 /* put emi dll into reset mode */ 172 /* put emi dll into reset mode */
169 __REG_SET(HW_EMI_CTRL) = HW_EMI_CTRL__DLL_RESET | HW_EMI_CTRL__DLL_SHIFT_RESET; 173 __REG_SET(HW_EMI_CTRL) = HW_EMI_CTRL__DLL_RESET | HW_EMI_CTRL__DLL_SHIFT_RESET;
170 /* load the new frequency dividers */ 174 /* load the new frequency dividers */
171 set_frequency(freq); 175 set_frequency(freq);
172 /* switch emi back to pll */ 176 /* switch emi back to pll */
173 __REG_CLR(HW_CLKCTRL_CLKSEQ) = HW_CLKCTRL_CLKSEQ__BYPASS_EMI; 177 BF_CLR(CLKCTRL_CLKSEQ, BYPASS_EMI);
174 /* wait for transition */ 178 /* wait for transition */
175 while(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__BUSY_REF_EMI); 179 while(BF_RD(CLKCTRL_EMI, BUSY_REF_EMI));
176 /* allow emi dll to lock again */ 180 /* allow emi dll to lock again */
177 __REG_CLR(HW_EMI_CTRL) = HW_EMI_CTRL__DLL_RESET | HW_EMI_CTRL__DLL_SHIFT_RESET; 181 __REG_CLR(HW_EMI_CTRL) = HW_EMI_CTRL__DLL_RESET | HW_EMI_CTRL__DLL_SHIFT_RESET;
178 /* wait for lock */ 182 /* wait for lock */
diff --git a/firmware/target/arm/imx233/system-imx233.c b/firmware/target/arm/imx233/system-imx233.c
index 64309b6720..3bf6ebb0f7 100644
--- a/firmware/target/arm/imx233/system-imx233.c
+++ b/firmware/target/arm/imx233/system-imx233.c
@@ -44,7 +44,7 @@
44 44
45void imx233_chip_reset(void) 45void imx233_chip_reset(void)
46{ 46{
47 HW_CLKCTRL_RESET = HW_CLKCTRL_RESET_CHIP; 47 HW_CLKCTRL_RESET = BM_CLKCTRL_RESET_CHIP;
48} 48}
49 49
50void system_reboot(void) 50void system_reboot(void)