summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-06-16 20:54:41 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-06-17 00:29:24 +0200
commit2d0d752bf8aed6bf91cdabd0d4571f336e7370eb (patch)
treee2e0cc39fe0e60f4096e1d4fe23e4e652bbe7f37 /firmware/target
parent023621d4018d2f08a8cebb805270cf9e945a645a (diff)
downloadrockbox-2d0d752bf8aed6bf91cdabd0d4571f336e7370eb.tar.gz
rockbox-2d0d752bf8aed6bf91cdabd0d4571f336e7370eb.zip
imx233: fix clkctrl for stmp3600 and stmp3700
Change-Id: I7596e41c0d0b7fdcc18f7d328a0927c2c78dc4cb
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.c58
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.h8
2 files changed, 61 insertions, 5 deletions
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.c b/firmware/target/arm/imx233/clkctrl-imx233.c
index 102ef4e432..a5ca61c1c7 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.c
+++ b/firmware/target/arm/imx233/clkctrl-imx233.c
@@ -19,6 +19,8 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "clkctrl-imx233.h" 21#include "clkctrl-imx233.h"
22#include "string.h"
23#include "debug.h"
22 24
23void imx233_clkctrl_enable(enum imx233_clock_t clk, bool enable) 25void imx233_clkctrl_enable(enum imx233_clock_t clk, bool enable)
24{ 26{
@@ -26,7 +28,9 @@ void imx233_clkctrl_enable(enum imx233_clock_t clk, bool enable)
26 bool gate = !enable; 28 bool gate = !enable;
27 switch(clk) 29 switch(clk)
28 { 30 {
31#if IMX233_SUBTARGET >= 3700
29 case CLK_PIX: BF_WR(CLKCTRL_PIX, CLKGATE, gate); break; 32 case CLK_PIX: BF_WR(CLKCTRL_PIX, CLKGATE, gate); break;
33#endif
30 case CLK_SSP: BF_WR(CLKCTRL_SSP, CLKGATE, gate); break; 34 case CLK_SSP: BF_WR(CLKCTRL_SSP, CLKGATE, gate); break;
31 case CLK_DRI: BF_WR(CLKCTRL_XTAL, DRI_CLK24M_GATE, gate); break; 35 case CLK_DRI: BF_WR(CLKCTRL_XTAL, DRI_CLK24M_GATE, gate); break;
32 case CLK_PWM: BF_WR(CLKCTRL_XTAL, PWM_CLK24M_GATE, gate); break; 36 case CLK_PWM: BF_WR(CLKCTRL_XTAL, PWM_CLK24M_GATE, gate); break;
@@ -46,6 +50,8 @@ void imx233_clkctrl_enable(enum imx233_clock_t clk, bool enable)
46 default: 50 default:
47 break; 51 break;
48 } 52 }
53#undef handle_std
54#undef handle_xtal
49} 55}
50 56
51bool imx233_clkctrl_is_enabled(enum imx233_clock_t clk) 57bool imx233_clkctrl_is_enabled(enum imx233_clock_t clk)
@@ -53,7 +59,9 @@ bool imx233_clkctrl_is_enabled(enum imx233_clock_t clk)
53 switch(clk) 59 switch(clk)
54 { 60 {
55 case CLK_PLL: return BF_RD(CLKCTRL_PLLCTRL0, POWER); 61 case CLK_PLL: return BF_RD(CLKCTRL_PLLCTRL0, POWER);
62#if IMX233_SUBTARGET >= 3700
56 case CLK_PIX: return !BF_RD(CLKCTRL_PIX, CLKGATE); 63 case CLK_PIX: return !BF_RD(CLKCTRL_PIX, CLKGATE);
64#endif
57 case CLK_SSP: return !BF_RD(CLKCTRL_SSP, CLKGATE); 65 case CLK_SSP: return !BF_RD(CLKCTRL_SSP, CLKGATE);
58 case CLK_DRI: return !BF_RD(CLKCTRL_XTAL, DRI_CLK24M_GATE); 66 case CLK_DRI: return !BF_RD(CLKCTRL_XTAL, DRI_CLK24M_GATE);
59 case CLK_PWM: return !BF_RD(CLKCTRL_XTAL, PWM_CLK24M_GATE); 67 case CLK_PWM: return !BF_RD(CLKCTRL_XTAL, PWM_CLK24M_GATE);
@@ -70,9 +78,14 @@ void imx233_clkctrl_set_div(enum imx233_clock_t clk, int div)
70 * assume that we always derive emi and cpu from ref_XX */ 78 * assume that we always derive emi and cpu from ref_XX */
71 switch(clk) 79 switch(clk)
72 { 80 {
81#if IMX233_SUBTARGET >= 3700
73 case CLK_PIX: BF_WR(CLKCTRL_PIX, DIV, div); break; 82 case CLK_PIX: BF_WR(CLKCTRL_PIX, DIV, div); break;
74 case CLK_CPU: BF_WR(CLKCTRL_CPU, DIV_CPU, div); break; 83 case CLK_CPU: BF_WR(CLKCTRL_CPU, DIV_CPU, div); break;
75 case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV_EMI, div); break; 84 case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV_EMI, div); break;
85#else
86 case CLK_CPU: BF_WR(CLKCTRL_CPU, DIV, div); break;
87 case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV, div); break;
88#endif
76 case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV, div); break; 89 case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV, div); break;
77 case CLK_HBUS: BF_WR(CLKCTRL_HBUS, DIV, div); break; 90 case CLK_HBUS: BF_WR(CLKCTRL_HBUS, DIV, div); break;
78 case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV, div); break; 91 case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV, div); break;
@@ -82,11 +95,17 @@ void imx233_clkctrl_set_div(enum imx233_clock_t clk, int div)
82 95
83int imx233_clkctrl_get_div(enum imx233_clock_t clk) 96int imx233_clkctrl_get_div(enum imx233_clock_t clk)
84{ 97{
98 /* assume that we always derive emi and cpu from ref_XX */
85 switch(clk) 99 switch(clk)
86 { 100 {
101#if IMX233_SUBTARGET >= 3700
87 case CLK_PIX: return BF_RD(CLKCTRL_PIX, DIV); 102 case CLK_PIX: return BF_RD(CLKCTRL_PIX, DIV);
88 case CLK_CPU: return BF_RD(CLKCTRL_CPU, DIV_CPU); 103 case CLK_CPU: return BF_RD(CLKCTRL_CPU, DIV_CPU);
89 case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV_EMI); 104 case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV_EMI);
105#else
106 case CLK_CPU: return BF_RD(CLKCTRL_CPU, DIV);
107 case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV);
108#endif
90 case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV); 109 case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV);
91 case CLK_HBUS: return BF_RD(CLKCTRL_HBUS, DIV); 110 case CLK_HBUS: return BF_RD(CLKCTRL_HBUS, DIV);
92 case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV); 111 case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV);
@@ -94,6 +113,7 @@ int imx233_clkctrl_get_div(enum imx233_clock_t clk)
94 } 113 }
95} 114}
96 115
116#if IMX233_SUBTARGET >= 3700
97void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv) 117void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv)
98{ 118{
99#define handle_frac(dev) \ 119#define handle_frac(dev) \
@@ -125,7 +145,9 @@ int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk)
125 return BF_RD(CLKCTRL_FRAC, dev##FRAC); 145 return BF_RD(CLKCTRL_FRAC, dev##FRAC);
126 switch(clk) 146 switch(clk)
127 { 147 {
148#if IMX233_SUBTARGET >= 3700
128 handle_frac(PIX) 149 handle_frac(PIX)
150#endif
129 handle_frac(IO) 151 handle_frac(IO)
130 handle_frac(CPU) 152 handle_frac(CPU)
131 handle_frac(EMI) 153 handle_frac(EMI)
@@ -139,7 +161,9 @@ void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass)
139 uint32_t msk; 161 uint32_t msk;
140 switch(clk) 162 switch(clk)
141 { 163 {
164#if IMX233_SUBTARGET >= 3700
142 case CLK_PIX: msk = BM_CLKCTRL_CLKSEQ_BYPASS_PIX; break; 165 case CLK_PIX: msk = BM_CLKCTRL_CLKSEQ_BYPASS_PIX; break;
166#endif
143 case CLK_SSP: msk = BM_CLKCTRL_CLKSEQ_BYPASS_SSP; break; 167 case CLK_SSP: msk = BM_CLKCTRL_CLKSEQ_BYPASS_SSP; break;
144 case CLK_CPU: msk = BM_CLKCTRL_CLKSEQ_BYPASS_CPU; break; 168 case CLK_CPU: msk = BM_CLKCTRL_CLKSEQ_BYPASS_CPU; break;
145 case CLK_EMI: msk = BM_CLKCTRL_CLKSEQ_BYPASS_EMI; break; 169 case CLK_EMI: msk = BM_CLKCTRL_CLKSEQ_BYPASS_EMI; break;
@@ -156,13 +180,16 @@ bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk)
156{ 180{
157 switch(clk) 181 switch(clk)
158 { 182 {
183#if IMX233_SUBTARGET >= 3700
159 case CLK_PIX: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_PIX); 184 case CLK_PIX: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_PIX);
185#endif
160 case CLK_SSP: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_SSP); 186 case CLK_SSP: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_SSP);
161 case CLK_CPU: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_CPU); 187 case CLK_CPU: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_CPU);
162 case CLK_EMI: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_EMI); 188 case CLK_EMI: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_EMI);
163 default: return false; 189 default: return false;
164 } 190 }
165} 191}
192#endif
166 193
167void imx233_clkctrl_enable_usb(bool enable) 194void imx233_clkctrl_enable_usb(bool enable)
168{ 195{
@@ -193,6 +220,7 @@ unsigned imx233_clkctrl_get_auto_slow_div(void)
193 220
194void imx233_clkctrl_enable_auto_slow(bool enable) 221void imx233_clkctrl_enable_auto_slow(bool enable)
195{ 222{
223 /* NOTE: don't use SET/CLR because it doesn't exist on stmp3600 */
196 BF_WR(CLKCTRL_HBUS, AUTO_SLOW_MODE, enable); 224 BF_WR(CLKCTRL_HBUS, AUTO_SLOW_MODE, enable);
197} 225}
198 226
@@ -211,6 +239,7 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk)
211 return 24000; 239 return 24000;
212 case CLK_CPU: 240 case CLK_CPU:
213 { 241 {
242#if IMX233_SUBTARGET >= 3700
214 unsigned ref; 243 unsigned ref;
215 /* In bypass mode: clk_p derived from clk_xtal via int/binfrac divider 244 /* In bypass mode: clk_p derived from clk_xtal via int/binfrac divider
216 * otherwise, clk_p derived from clk_cpu via int div and clk_cpu 245 * otherwise, clk_p derived from clk_cpu via int div and clk_cpu
@@ -233,13 +262,18 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk)
233 ref = (ref * 18) / imx233_clkctrl_get_frac_div(CLK_CPU); 262 ref = (ref * 18) / imx233_clkctrl_get_frac_div(CLK_CPU);
234 return ref / imx233_clkctrl_get_div(CLK_CPU); 263 return ref / imx233_clkctrl_get_div(CLK_CPU);
235 } 264 }
265#else
266 return imx233_clkctrl_get_freq(CLK_PLL) / imx233_clkctrl_get_div(CLK_CPU);
267#endif
236 } 268 }
237 case CLK_HBUS: 269 case CLK_HBUS:
238 { 270 {
239 /* Derived from clk_p via integer/fractional div */ 271 /* Derived from clk_p via integer/fractional div */
240 unsigned ref = imx233_clkctrl_get_freq(CLK_CPU); 272 unsigned ref = imx233_clkctrl_get_freq(CLK_CPU);
273#if IMX233_SUBTARGET >= 3700
241 if(imx233_clkctrl_get_frac_div(CLK_HBUS) != 0) 274 if(imx233_clkctrl_get_frac_div(CLK_HBUS) != 0)
242 ref = (ref * imx233_clkctrl_get_frac_div(CLK_HBUS)) / 32; 275 ref = (ref * imx233_clkctrl_get_frac_div(CLK_HBUS)) / 32;
276#endif
243 if(imx233_clkctrl_get_div(CLK_HBUS) != 0) 277 if(imx233_clkctrl_get_div(CLK_HBUS) != 0)
244 ref /= imx233_clkctrl_get_div(CLK_HBUS); 278 ref /= imx233_clkctrl_get_div(CLK_HBUS);
245 return ref; 279 return ref;
@@ -248,10 +282,13 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk)
248 { 282 {
249 /* Derived from clk_pll via fracdiv */ 283 /* Derived from clk_pll via fracdiv */
250 unsigned ref = imx233_clkctrl_get_freq(CLK_PLL); 284 unsigned ref = imx233_clkctrl_get_freq(CLK_PLL);
285#if IMX233_SUBTARGET >= 3700
251 if(imx233_clkctrl_get_frac_div(CLK_IO) != 0) 286 if(imx233_clkctrl_get_frac_div(CLK_IO) != 0)
252 ref = (ref * 18) / imx233_clkctrl_get_frac_div(CLK_IO); 287 ref = (ref * 18) / imx233_clkctrl_get_frac_div(CLK_IO);
288#endif
253 return ref; 289 return ref;
254 } 290 }
291#if IMX233_SUBTARGET >= 3700
255 case CLK_PIX: 292 case CLK_PIX:
256 { 293 {
257 unsigned ref; 294 unsigned ref;
@@ -268,20 +305,24 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk)
268 } 305 }
269 return ref / imx233_clkctrl_get_div(CLK_PIX); 306 return ref / imx233_clkctrl_get_div(CLK_PIX);
270 } 307 }
308#endif
271 case CLK_SSP: 309 case CLK_SSP:
272 { 310 {
273 unsigned ref; 311 unsigned ref;
274 /* Derived from clk_pll or clk_xtal */ 312 /* Derived from clk_pll or clk_xtal */
275 if(!imx233_clkctrl_is_enabled(CLK_SSP)) 313 if(!imx233_clkctrl_is_enabled(CLK_SSP))
276 ref = 0; 314 ref = 0;
315#if IMX233_SUBTARGET >= 3700
277 else if(imx233_clkctrl_get_bypass(CLK_SSP)) 316 else if(imx233_clkctrl_get_bypass(CLK_SSP))
278 ref = imx233_clkctrl_get_freq(CLK_XTAL); 317 ref = imx233_clkctrl_get_freq(CLK_XTAL);
279 else 318 else
319#endif
280 ref = imx233_clkctrl_get_freq(CLK_IO); 320 ref = imx233_clkctrl_get_freq(CLK_IO);
281 return ref / imx233_clkctrl_get_div(CLK_SSP); 321 return ref / imx233_clkctrl_get_div(CLK_SSP);
282 } 322 }
283 case CLK_EMI: 323 case CLK_EMI:
284 { 324 {
325#if IMX233_SUBTARGET >= 3700
285 unsigned ref; 326 unsigned ref;
286 /* Derived from clk_pll or clk_xtal */ 327 /* Derived from clk_pll or clk_xtal */
287 if(imx233_clkctrl_get_bypass(CLK_EMI)) 328 if(imx233_clkctrl_get_bypass(CLK_EMI))
@@ -299,6 +340,9 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk)
299 ref = (ref * 18) / imx233_clkctrl_get_frac_div(CLK_EMI); 340 ref = (ref * 18) / imx233_clkctrl_get_frac_div(CLK_EMI);
300 return ref / imx233_clkctrl_get_div(CLK_EMI); 341 return ref / imx233_clkctrl_get_div(CLK_EMI);
301 } 342 }
343#else
344 return imx233_clkctrl_get_freq(CLK_PLL) / imx233_clkctrl_get_div(CLK_EMI);
345#endif
302 } 346 }
303 case CLK_XBUS: 347 case CLK_XBUS:
304 return imx233_clkctrl_get_freq(CLK_XTAL) / imx233_clkctrl_get_div(CLK_XBUS); 348 return imx233_clkctrl_get_freq(CLK_XTAL) / imx233_clkctrl_get_div(CLK_XBUS);
@@ -310,8 +354,16 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk)
310void imx233_clkctrl_init(void) 354void imx233_clkctrl_init(void)
311{ 355{
312 /* set auto-slow monitor to all */ 356 /* set auto-slow monitor to all */
313 HW_CLKCTRL_HBUS_SET = BF_OR8(CLKCTRL_HBUS, 357#if IMX233_SUBTARGET >= 3700
358 HW_CLKCTRL_HBUS_SET = BF_OR6(CLKCTRL_HBUS,
314 APBHDMA_AS_ENABLE(1), TRAFFIC_JAM_AS_ENABLE(1), TRAFFIC_AS_ENABLE(1), 359 APBHDMA_AS_ENABLE(1), TRAFFIC_JAM_AS_ENABLE(1), TRAFFIC_AS_ENABLE(1),
315 APBXDMA_AS_ENABLE(1), CPU_INSTR_AS_ENABLE(1), CPU_DATA_AS_ENABLE(1), 360 APBXDMA_AS_ENABLE(1), CPU_INSTR_AS_ENABLE(1), CPU_DATA_AS_ENABLE(1));
316 DCP_AS_ENABLE(1), PXP_AS_ENABLE(1)); 361#else
362 HW_CLKCTRL_HBUS = HW_CLKCTRL_HBUS | BF_OR7(CLKCTRL_HBUS, EMI_BUSY_FAST(1),
363 APBHDMA_BUSY_FAST(1), APBXDMA_BUSY_FAST(1), TRAFFIC_JAM_FAST(1),
364 TRAFFIC_FAST(1), CPU_DATA_FAST(1), CPU_INSTR_FAST(1));
365#endif
366#if IMX233_SUBTARGET >= 3780
367 HW_CLKCTRL_HBUS_SET = BF_OR2(CLKCTRL_HBUS, DCP_AS_ENABLE(1), PXP_AS_ENABLE(1));
368#endif
317} 369}
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.h b/firmware/target/arm/imx233/clkctrl-imx233.h
index ddd8bc9221..7dc21c2b30 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.h
+++ b/firmware/target/arm/imx233/clkctrl-imx233.h
@@ -41,9 +41,8 @@ static inline void core_sleep(void)
41 41
42enum imx233_clock_t 42enum imx233_clock_t
43{ 43{
44 CLK_PIX, /* freq, div, frac, bypass, enable */
45 CLK_SSP, /* freq, div, bypass, enable */ 44 CLK_SSP, /* freq, div, bypass, enable */
46 CLK_IO, /* freq, frac */ 45 CLK_IO, /* freq, frac (stmp3700+) */
47 CLK_CPU, /* freq, div, frac, bypass */ 46 CLK_CPU, /* freq, div, frac, bypass */
48 CLK_HBUS, /* freq, div, frac */ 47 CLK_HBUS, /* freq, div, frac */
49 CLK_PLL, /* freq, enable */ 48 CLK_PLL, /* freq, enable */
@@ -55,6 +54,9 @@ enum imx233_clock_t
55 CLK_PWM, /* enable */ 54 CLK_PWM, /* enable */
56 CLK_TIMROT, /* enable */ 55 CLK_TIMROT, /* enable */
57 CLK_UART, /* enable */ 56 CLK_UART, /* enable */
57#if IMX233_SUBTARGET >= 3700
58 CLK_PIX, /* freq, div, frac, bypass, enable */
59#endif
58}; 60};
59 61
60void imx233_clkctrl_init(void); 62void imx233_clkctrl_init(void);
@@ -63,12 +65,14 @@ void imx233_clkctrl_enable(enum imx233_clock_t clk, bool enable);
63bool imx233_clkctrl_is_enabled(enum imx233_clock_t cl); 65bool imx233_clkctrl_is_enabled(enum imx233_clock_t cl);
64void imx233_clkctrl_set_div(enum imx233_clock_t clk, int div); 66void imx233_clkctrl_set_div(enum imx233_clock_t clk, int div);
65int imx233_clkctrl_get_div(enum imx233_clock_t clk); 67int imx233_clkctrl_get_div(enum imx233_clock_t clk);
68#if IMX233_SUBTARGET >= 3700
66/* call with fracdiv=0 to disable it */ 69/* call with fracdiv=0 to disable it */
67void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv); 70void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv);
68/* 0 means fractional dividor disable */ 71/* 0 means fractional dividor disable */
69int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk); 72int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk);
70void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass); 73void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass);
71bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk); 74bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk);
75#endif
72void imx233_clkctrl_enable_usb(bool enable); 76void imx233_clkctrl_enable_usb(bool enable);
73bool imx233_clkctrl_is_usb_enabled(void); 77bool imx233_clkctrl_is_usb_enabled(void);
74/* returns frequency in KHz */ 78/* returns frequency in KHz */