]> git.sur5r.net Git - freertos/blob - Demo/AVR32_UC3A_GCC/Atmel_SW_Framework/DRIVERS/PM/pm.c
Temporarily revert the AVR32 port back to the V6.0.5 files. Work will continue on...
[freertos] / Demo / AVR32_UC3A_GCC / Atmel_SW_Framework / DRIVERS / PM / pm.c
1 /* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */\r
2
3 /*This file has been prepared for Doxygen automatic documentation generation.*/\r
4 /*! \file *********************************************************************\r
5  *\r
6  * \brief Power Manager driver.\r
7  *\r
8  *\r
9  * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32\r
10  * - Supported devices:  All AVR32 devices.\r
11  * - AppNote:\r
12  *\r
13  * \author               Atmel Corporation: http://www.atmel.com \n\r
14  *                       Support and FAQ: http://support.atmel.no/\r
15  *\r
16  *****************************************************************************/\r
17 \r
18 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.\r
19  *\r
20  * Redistribution and use in source and binary forms, with or without\r
21  * modification, are permitted provided that the following conditions are met:\r
22  *\r
23  * 1. Redistributions of source code must retain the above copyright notice, this\r
24  * list of conditions and the following disclaimer.\r
25  *\r
26  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
27  * this list of conditions and the following disclaimer in the documentation\r
28  * and/or other materials provided with the distribution.\r
29  *\r
30  * 3. The name of Atmel may not be used to endorse or promote products derived\r
31  * from this software without specific prior written permission.\r
32  *\r
33  * 4. This software may only be redistributed and used in connection with an Atmel\r
34  * AVR product.\r
35  *\r
36  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED\r
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
38  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
39  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR\r
40  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
41  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
44  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
45  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\r
46  *\r
47  */\r
48 \r
49 #include "compiler.h"\r
50 #include "pm.h"\r
51 \r
52 \r
53 /*! \name PM Writable Bit-Field Registers\r
54  */\r
55 //! @{\r
56 \r
57 typedef union\r
58 {\r
59   unsigned long                 mcctrl;\r
60   avr32_pm_mcctrl_t             MCCTRL;\r
61 } u_avr32_pm_mcctrl_t;\r
62 \r
63 typedef union\r
64 {\r
65   unsigned long                 cksel;\r
66   avr32_pm_cksel_t              CKSEL;\r
67 } u_avr32_pm_cksel_t;\r
68 \r
69 typedef union\r
70 {\r
71   unsigned long                 pll;\r
72   avr32_pm_pll_t                PLL;\r
73 } u_avr32_pm_pll_t;\r
74 \r
75 typedef union\r
76 {\r
77   unsigned long                 oscctrl0;\r
78   avr32_pm_oscctrl0_t           OSCCTRL0;\r
79 } u_avr32_pm_oscctrl0_t;\r
80 \r
81 typedef union\r
82 {\r
83   unsigned long                 oscctrl1;\r
84   avr32_pm_oscctrl1_t           OSCCTRL1;\r
85 } u_avr32_pm_oscctrl1_t;\r
86 \r
87 typedef union\r
88 {\r
89   unsigned long                 oscctrl32;\r
90   avr32_pm_oscctrl32_t          OSCCTRL32;\r
91 } u_avr32_pm_oscctrl32_t;\r
92 \r
93 typedef union\r
94 {\r
95   unsigned long                 ier;\r
96   avr32_pm_ier_t                IER;\r
97 } u_avr32_pm_ier_t;\r
98 \r
99 typedef union\r
100 {\r
101   unsigned long                 idr;\r
102   avr32_pm_idr_t                IDR;\r
103 } u_avr32_pm_idr_t;\r
104 \r
105 typedef union\r
106 {\r
107   unsigned long                 icr;\r
108   avr32_pm_icr_t                ICR;\r
109 } u_avr32_pm_icr_t;\r
110 \r
111 typedef union\r
112 {\r
113   unsigned long                 gcctrl;\r
114   avr32_pm_gcctrl_t             GCCTRL;\r
115 } u_avr32_pm_gcctrl_t;\r
116 \r
117 typedef union\r
118 {\r
119   unsigned long                 rccr;\r
120   avr32_pm_rccr_t               RCCR;\r
121 } u_avr32_pm_rccr_t;\r
122 \r
123 typedef union\r
124 {\r
125   unsigned long                 bgcr;\r
126   avr32_pm_bgcr_t               BGCR;\r
127 } u_avr32_pm_bgcr_t;\r
128 \r
129 typedef union\r
130 {\r
131   unsigned long                 vregcr;\r
132   avr32_pm_vregcr_t             VREGCR;\r
133 } u_avr32_pm_vregcr_t;\r
134 \r
135 typedef union\r
136 {\r
137   unsigned long                 bod;\r
138   avr32_pm_bod_t                BOD;\r
139 } u_avr32_pm_bod_t;\r
140 \r
141 //! @}\r
142 \r
143 \r
144 /*! \brief Sets the mode of the oscillator 0.\r
145  *\r
146  * \param pm Base address of the Power Manager (i.e. &AVR32_PM).\r
147  * \param mode Oscillator 0 mode (i.e. AVR32_PM_OSCCTRL0_MODE_x).\r
148  */\r
149 static void pm_set_osc0_mode(volatile avr32_pm_t *pm, unsigned int mode)\r
150 {\r
151   // Read\r
152   u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};\r
153   // Modify\r
154   u_avr32_pm_oscctrl0.OSCCTRL0.mode = mode;\r
155   // Write\r
156   pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;\r
157 }\r
158 \r
159 \r
160 void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm)\r
161 {\r
162   pm_set_osc0_mode(pm, AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK);\r
163 }\r
164 \r
165 \r
166 void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0)\r
167 {\r
168   pm_set_osc0_mode(pm, (fosc0 <  900000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G0 :\r
169                        (fosc0 < 3000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G1 :\r
170                        (fosc0 < 8000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2 :\r
171                                            AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3);\r
172 }\r
173 \r
174 \r
175 void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup)\r
176 {\r
177   pm_enable_clk0_no_wait(pm, startup);\r
178   pm_wait_for_clk0_ready(pm);\r
179 }\r
180 \r
181 \r
182 void pm_disable_clk0(volatile avr32_pm_t *pm)\r
183 {\r
184   pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC0EN_MASK;\r
185 }\r
186 \r
187 \r
188 void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup)\r
189 {\r
190   // Read register\r
191   u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};\r
192   // Modify\r
193   u_avr32_pm_oscctrl0.OSCCTRL0.startup = startup;\r
194   // Write back\r
195   pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;\r
196 \r
197   pm->mcctrl |= AVR32_PM_MCCTRL_OSC0EN_MASK;\r
198 }\r
199 \r
200 \r
201 void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm)\r
202 {\r
203   while (!(pm->poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK));\r
204 }\r
205 \r
206 \r
207 /*! \brief Sets the mode of the oscillator 1.\r
208  *\r
209  * \param pm Base address of the Power Manager (i.e. &AVR32_PM).\r
210  * \param mode Oscillator 1 mode (i.e. AVR32_PM_OSCCTRL1_MODE_x).\r
211  */\r
212 static void pm_set_osc1_mode(volatile avr32_pm_t *pm, unsigned int mode)\r
213 {\r
214   // Read\r
215   u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};\r
216   // Modify\r
217   u_avr32_pm_oscctrl1.OSCCTRL1.mode = mode;\r
218   // Write\r
219   pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;\r
220 }\r
221 \r
222 \r
223 void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm)\r
224 {\r
225   pm_set_osc1_mode(pm, AVR32_PM_OSCCTRL1_MODE_EXT_CLOCK);\r
226 }\r
227 \r
228 \r
229 void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1)\r
230 {\r
231   pm_set_osc1_mode(pm, (fosc1 <  900000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G0 :\r
232                        (fosc1 < 3000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G1 :\r
233                        (fosc1 < 8000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G2 :\r
234                                            AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G3);\r
235 }\r
236 \r
237 \r
238 void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup)\r
239 {\r
240   pm_enable_clk1_no_wait(pm, startup);\r
241   pm_wait_for_clk1_ready(pm);\r
242 }\r
243 \r
244 \r
245 void pm_disable_clk1(volatile avr32_pm_t *pm)\r
246 {\r
247   pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC1EN_MASK;\r
248 }\r
249 \r
250 \r
251 void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup)\r
252 {\r
253   // Read register\r
254   u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};\r
255   // Modify\r
256   u_avr32_pm_oscctrl1.OSCCTRL1.startup = startup;\r
257   // Write back\r
258   pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;\r
259 \r
260   pm->mcctrl |= AVR32_PM_MCCTRL_OSC1EN_MASK;\r
261 }\r
262 \r
263 \r
264 void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm)\r
265 {\r
266   while (!(pm->poscsr & AVR32_PM_POSCSR_OSC1RDY_MASK));\r
267 }\r
268 \r
269 \r
270 /*! \brief Sets the mode of the 32-kHz oscillator.\r
271  *\r
272  * \param pm Base address of the Power Manager (i.e. &AVR32_PM).\r
273  * \param mode 32-kHz oscillator mode (i.e. AVR32_PM_OSCCTRL32_MODE_x).\r
274  */\r
275 static void pm_set_osc32_mode(volatile avr32_pm_t *pm, unsigned int mode)\r
276 {\r
277   // Read\r
278   u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};\r
279   // Modify\r
280   u_avr32_pm_oscctrl32.OSCCTRL32.mode = mode;\r
281   // Write\r
282   pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;\r
283 }\r
284 \r
285 \r
286 void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm)\r
287 {\r
288   pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK);\r
289 }\r
290 \r
291 \r
292 void pm_enable_osc32_crystal(volatile avr32_pm_t *pm)\r
293 {\r
294   pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_CRYSTAL);\r
295 }\r
296 \r
297 \r
298 void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup)\r
299 {\r
300   pm_enable_clk32_no_wait(pm, startup);\r
301   pm_wait_for_clk32_ready(pm);\r
302 }\r
303 \r
304 \r
305 void pm_disable_clk32(volatile avr32_pm_t *pm)\r
306 {\r
307   pm->oscctrl32 &= ~AVR32_PM_OSCCTRL32_OSC32EN_MASK;\r
308 }\r
309 \r
310 \r
311 void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup)\r
312 {\r
313   // Read register\r
314   u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};\r
315   // Modify\r
316   u_avr32_pm_oscctrl32.OSCCTRL32.osc32en = 1;\r
317   u_avr32_pm_oscctrl32.OSCCTRL32.startup = startup;\r
318   // Write back\r
319   pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;\r
320 }\r
321 \r
322 \r
323 void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm)\r
324 {\r
325   while (!(pm->poscsr & AVR32_PM_POSCSR_OSC32RDY_MASK));\r
326 }\r
327 \r
328 \r
329 void pm_cksel(volatile avr32_pm_t *pm,\r
330               unsigned int pbadiv,\r
331               unsigned int pbasel,\r
332               unsigned int pbbdiv,\r
333               unsigned int pbbsel,\r
334               unsigned int hsbdiv,\r
335               unsigned int hsbsel)\r
336 {\r
337   u_avr32_pm_cksel_t u_avr32_pm_cksel = {0};\r
338 \r
339   u_avr32_pm_cksel.CKSEL.cpusel = hsbsel;\r
340   u_avr32_pm_cksel.CKSEL.cpudiv = hsbdiv;\r
341   u_avr32_pm_cksel.CKSEL.hsbsel = hsbsel;\r
342   u_avr32_pm_cksel.CKSEL.hsbdiv = hsbdiv;\r
343   u_avr32_pm_cksel.CKSEL.pbasel = pbasel;\r
344   u_avr32_pm_cksel.CKSEL.pbadiv = pbadiv;\r
345   u_avr32_pm_cksel.CKSEL.pbbsel = pbbsel;\r
346   u_avr32_pm_cksel.CKSEL.pbbdiv = pbbdiv;\r
347 \r
348   pm->cksel = u_avr32_pm_cksel.cksel;\r
349 \r
350   // Wait for ckrdy bit and then clear it\r
351   while (!(pm->poscsr & AVR32_PM_POSCSR_CKRDY_MASK));\r
352 }\r
353 \r
354 \r
355 void pm_gc_setup(volatile avr32_pm_t *pm,\r
356                   unsigned int gc,\r
357                   unsigned int osc_or_pll, // Use Osc (=0) or PLL (=1)\r
358                   unsigned int pll_osc, // Sel Osc0/PLL0 or Osc1/PLL1\r
359                   unsigned int diven,\r
360                   unsigned int div)\r
361 {\r
362   u_avr32_pm_gcctrl_t u_avr32_pm_gcctrl = {0};\r
363 \r
364   u_avr32_pm_gcctrl.GCCTRL.oscsel = pll_osc;\r
365   u_avr32_pm_gcctrl.GCCTRL.pllsel = osc_or_pll;\r
366   u_avr32_pm_gcctrl.GCCTRL.diven  = diven;\r
367   u_avr32_pm_gcctrl.GCCTRL.div    = div;\r
368 \r
369   pm->gcctrl[gc] = u_avr32_pm_gcctrl.gcctrl;\r
370 }\r
371 \r
372 \r
373 void pm_gc_enable(volatile avr32_pm_t *pm,\r
374                   unsigned int gc)\r
375 {\r
376   pm->gcctrl[gc] |= AVR32_PM_GCCTRL_CEN_MASK;\r
377 }\r
378 \r
379 \r
380 void pm_gc_disable(volatile avr32_pm_t *pm,\r
381                    unsigned int gc)\r
382 {\r
383   pm->gcctrl[gc] &= ~AVR32_PM_GCCTRL_CEN_MASK;\r
384 }\r
385 \r
386 \r
387 void pm_pll_setup(volatile avr32_pm_t *pm,\r
388                   unsigned int pll,\r
389                   unsigned int mul,\r
390                   unsigned int div,\r
391                   unsigned int osc,\r
392                   unsigned int lockcount)\r
393 {\r
394   u_avr32_pm_pll_t u_avr32_pm_pll = {0};\r
395 \r
396   u_avr32_pm_pll.PLL.pllosc   = osc;\r
397   u_avr32_pm_pll.PLL.plldiv   = div;\r
398   u_avr32_pm_pll.PLL.pllmul   = mul;\r
399   u_avr32_pm_pll.PLL.pllcount = lockcount;\r
400 \r
401   pm->pll[pll] = u_avr32_pm_pll.pll;\r
402 }\r
403 \r
404 \r
405 void pm_pll_set_option(volatile avr32_pm_t *pm,\r
406                        unsigned int pll,\r
407                        unsigned int pll_freq,\r
408                        unsigned int pll_div2,\r
409                        unsigned int pll_wbwdisable)\r
410 {\r
411   u_avr32_pm_pll_t u_avr32_pm_pll = {pm->pll[pll]};\r
412   u_avr32_pm_pll.PLL.pllopt = pll_freq | (pll_div2 << 1) | (pll_wbwdisable << 2);\r
413   pm->pll[pll] = u_avr32_pm_pll.pll;\r
414 }\r
415 \r
416 \r
417 unsigned int pm_pll_get_option(volatile avr32_pm_t *pm,\r
418                                unsigned int pll)\r
419 {\r
420   return (pm->pll[pll] & AVR32_PM_PLLOPT_MASK) >> AVR32_PM_PLLOPT_OFFSET;\r
421 }\r
422 \r
423 \r
424 void pm_pll_enable(volatile avr32_pm_t *pm,\r
425                   unsigned int pll)\r
426 {\r
427   pm->pll[pll] |= AVR32_PM_PLLEN_MASK;\r
428 }\r
429 \r
430 \r
431 void pm_pll_disable(volatile avr32_pm_t *pm,\r
432                   unsigned int pll)\r
433 {\r
434   pm->pll[pll] &= ~AVR32_PM_PLLEN_MASK;\r
435 }\r
436 \r
437 \r
438 void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm)\r
439 {\r
440   while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK0_MASK));\r
441 }\r
442 \r
443 \r
444 void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm)\r
445 {\r
446   while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK1_MASK));\r
447 }\r
448 \r
449 \r
450 void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock)\r
451 {\r
452   // Read\r
453   u_avr32_pm_mcctrl_t u_avr32_pm_mcctrl = {pm->mcctrl};\r
454   // Modify\r
455   u_avr32_pm_mcctrl.MCCTRL.mcsel = clock;\r
456   // Write back\r
457   pm->mcctrl = u_avr32_pm_mcctrl.mcctrl;\r
458 }\r
459 \r
460 \r
461 void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup)\r
462 {\r
463   pm_enable_osc0_crystal(pm, fosc0);            // Enable the Osc0 in crystal mode\r
464   pm_enable_clk0(pm, startup);                  // Crystal startup time - This parameter is critical and depends on the characteristics of the crystal\r
465   pm_switch_to_clock(pm, AVR32_PM_MCSEL_OSC0);  // Then switch main clock to Osc0\r
466 }\r
467 \r
468 \r
469 void pm_bod_enable_irq(volatile avr32_pm_t *pm)\r
470 {\r
471   pm->ier = AVR32_PM_IER_BODDET_MASK;\r
472 }\r
473 \r
474 \r
475 void pm_bod_disable_irq(volatile avr32_pm_t *pm)\r
476 {\r
477   Bool global_interrupt_enabled = Is_global_interrupt_enabled();\r
478 \r
479   if (global_interrupt_enabled) Disable_global_interrupt();\r
480   pm->idr = AVR32_PM_IDR_BODDET_MASK;\r
481   pm->isr;\r
482   if (global_interrupt_enabled) Enable_global_interrupt();\r
483 }\r
484 \r
485 \r
486 void pm_bod_clear_irq(volatile avr32_pm_t *pm)\r
487 {\r
488   pm->icr = AVR32_PM_ICR_BODDET_MASK;\r
489 }\r
490 \r
491 \r
492 unsigned long pm_bod_get_irq_status(volatile avr32_pm_t *pm)\r
493 {\r
494   return ((pm->isr & AVR32_PM_ISR_BODDET_MASK) != 0);\r
495 }\r
496 \r
497 \r
498 unsigned long pm_bod_get_irq_enable_bit(volatile avr32_pm_t *pm)\r
499 {\r
500   return ((pm->imr & AVR32_PM_IMR_BODDET_MASK) != 0);\r
501 }\r
502 \r
503 \r
504 unsigned long pm_bod_get_level(volatile avr32_pm_t *pm)\r
505 {\r
506   return (pm->bod & AVR32_PM_BOD_LEVEL_MASK) >> AVR32_PM_BOD_LEVEL_OFFSET;\r
507 }\r
508 \r
509 \r
510 unsigned long pm_read_gplp(volatile avr32_pm_t *pm, unsigned long gplp)\r
511 {\r
512   return pm->gplp[gplp];\r
513 }\r
514 \r
515 \r
516 void pm_write_gplp(volatile avr32_pm_t *pm, unsigned long gplp, unsigned long value)\r
517 {\r
518   pm->gplp[gplp] = value;\r
519 }\r
520 \r
521 \r
522 long pm_enable_module(volatile avr32_pm_t *pm, unsigned long module)\r
523 {\r
524   unsigned long domain = module>>5;\r
525   unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain);\r
526 \r
527   // Implementation-specific shortcut: the ckMASK registers are contiguous and\r
528   // memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK.\r
529 \r
530   *regptr |= (1<<(module%32));\r
531 \r
532   return PASS;\r
533 }\r
534 \r
535 long pm_disable_module(volatile avr32_pm_t *pm, unsigned long module)\r
536 {\r
537   unsigned long domain = module>>5;\r
538   unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain);\r
539 \r
540   // Implementation-specific shortcut: the ckMASK registers are contiguous and\r
541   // memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK.\r
542 \r
543   *regptr &= ~(1<<(module%32));\r
544 \r
545   return PASS;\r
546 }\r