summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/lpc31xx/lpc31_cgudrvr.h
blob: a408f56b22e3b75180ca7bb0184feb28653b272d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
/************************************************************************
 * arch/arm/src/lpc31xx/lpc31_cgudrvr.h
 *
 *   Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
 *   Author: Gregory Nutt <gnutt@nuttx.org>
 *
 * References:
 *   - NXP UM10314 LPC3130/31 User manual Rev. 1.01 � 9 September 2009
 *   - NXP lpc313x.cdl.drivers.zip example driver code
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name NuttX nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ************************************************************************/

#ifndef __ARCH_ARM_SRC_LPC31XX_LPC31_CGUDRVR_H
#define __ARCH_ARM_SRC_LPC31XX_LPC31_CGUDRVR_H

/************************************************************************
 * Included Files
 ************************************************************************/

#include <nuttx/config.h>

#include <stdint.h>
#include <stdbool.h>

#include "up_arch.h"
#include "lpc31_cgu.h"

/************************************************************************
 * Pre-processor Definitions
 ************************************************************************/

/* Maps a valid, x, relative to a base value, b, and converts that to a bit position */

#define _RBIT(x,b)                        (1<<((x)-(b)))

/* Clock ID ranges (see enum lpc31_clockid_e) *************************************************/

#define CLKID_FIRST                       CLKID_APB0CLK
#define CLKID_SYSBASE_FIRST               CLKID_APB0CLK           /* Domain 0: SYS_BASE */
#define CLKID_SYSBASE_LAST                CLKID_INTCCLK
#define _D0B(id)                          _RBIT(id,CLKID_SYSBASE_FIRST)

#define CLKID_AHB0APB0_FIRST              CLKID_AHB2APB0PCLK     /* Domain 1: AHB0APB0_BASE */
#define CLKID_AHB0APB0_LAST               CLKID_RNGPCLK
#define _D1B(id)                          _RBIT(id,CLKID_AHB0APB0_FIRST)

#define CLKID_AHB0APB1_FIRST              CLKID_AHB2APB1PCLK     /* Domain 2: AHB0APB1_BASE */
#define CLKID_AHB0APB1_LAST               CLKID_I2C1PCLK
#define _D2B(id)                          _RBIT(id,CLKID_AHB0APB1_FIRST)

#define CLKID_AHB0APB2_FIRST              CLKID_AHB2APB2PCLK     /* Domain 3: AHB0APB2_BASE */
#define CLKID_AHB0APB2_LAST               CLKID_SPIPCLKGATED
#define _D3B(id)                          _RBIT(id,CLKID_AHB0APB2_FIRST)

#define CLKID_AHB0APB3_FIRST              CLKID_AHB2APB3PCLK      /* Domain 4: AHB0APB3_BASE */
#define CLKID_AHB0APB3_LAST               CLKID_RESERVED70
#define _D4B(id)                          _RBIT(id,CLKID_AHB0APB3_FIRST)

#define CLKID_PCM_FIRST                   CLKID_PCMCLKIP          /* Domain 5: PCM_BASE */
#define CLKID_PCM_LAST                    CLKID_PCMCLKIP
#define _D5B(id)                          _RBIT(id,CLKID_PCM_FIRST)

#define CLKID_UART_FIRST                  CLKID_UARTUCLK          /* Domain 6: UART_BASE */
#define CLKID_UART_LAST                   CLKID_UARTUCLK
#define _D6B(id)                          _RBIT(id,CLKID_UART_FIRST)

#define CLKID_CLK1024FS_FIRST             CLKID_I2SEDGEDETECTCLK  /* Domain 7: CLK1024FS_BASE */
#define CLKID_CLK1024FS_LAST              CLKID_RESERVED86
#define _D7B(id)                          _RBIT(id,CLKID_CLK1024FS_FIRST)

#define CLKID_I2SRXBCK0_FIRST             CLKID_I2SRXBCK0         /* Domain 8: BCK0_BASE */
#define CLKID_I2SRXBCK0_LAST              CLKID_I2SRXBCK0
#define _D8B(id)                          _RBIT(id,CLKID_I2SRXBCK0_FIRST)

#define CLKID_I2SRXBCK1_FIRST             CLKID_I2SRXBCK1         /* Domain 9: BCK1_BASE */
#define CLKID_I2SRXBCK1_LAST              CLKID_I2SRXBCK1
#define _D9B(id)                          _RBIT(id,CLKID_SYSBASE_FIRST)

#define CLKID_SPI_FIRST                   CLKID_SPICLK            /* Domain 10: SPI_BASE */
#define CLKID_SPI_LAST                    CLKID_SPICLKGATED
#define _D10B(id)                         _RBIT(id,CLKID_I2SRXBCK1_FIRST)

#define CLKID_SYSCLKO_FIRST               CLKID_SYSCLKO           /* Domain 11: SYSCLKO_BASE */
#define CLKID_SYSCLKO_LAST                CLKID_SYSCLKO
#define _D11B(id)                         _RBIT(id,CLKID_SYSCLKO_FIRST)
#define CLKID_LAST                        CLKID_SYSCLKO

#define CGU_NDOMAINS                      12 /* The number of clock domains */
#define CLKID_INVALIDCLK                  -1 /* Indicates and invalid clock ID */
#define DOMAINID_INVALID                  -1 /* Indicates an invalid domain ID */
#define ESRNDX_INVALID                    -1 /* Indicates an invalid ESR register index */
#define BCRNDX_INVALID                    -1 /* Indicates an invalid BCR register index */

/* There are 24 fractional dividers, indexed 0 to 23.  The following definitions
 * provide (1) the number of fractional dividers available for each base frequency,
 * (2) start and end indices, and (3) extraction info for sub elements from the
 * fractional divider configuration register
 */

#define FRACDIV_BASE0_CNT                 7  /* 7 fractional dividers available */
#define FRACDIV_BASE0_LOW                 0  /* First is index 0 */
#define FRACDIV_BASE0_HIGH                6  /* Last is index 6 */
#define FRACDIV_BASE0_FDIV0W              8

#define FRACDIV_BASE1_CNT                 2  /* 2 fractional dividers available */
#define FRACDIV_BASE1_LOW                 7  /* First is index 7 */
#define FRACDIV_BASE1_HIGH                8  /* Last is index 8 */
#define FRACDIV_BASE1_FDIV0W              8

#define FRACDIV_BASE2_CNT                 2  /* 2 fractional dividers available */
#define FRACDIV_BASE2_LOW                 9  /* First is index 9 */
#define FRACDIV_BASE2_HIGH                10 /* Last is index 10 */
#define FRACDIV_BASE2_FDIV0W              8

#define FRACDIV_BASE3_CNT                 3  /* 3 fractional dividers available */
#define FRACDIV_BASE3_LOW                 11 /* First is index 11 */
#define FRACDIV_BASE3_HIGH                13 /* Last is index 12 */
#define FRACDIV_BASE3_FDIV0W              8

#define FRACDIV_BASE4_CNT                 1  /* 1 fractional divider available */
#define FRACDIV_BASE4_LOW                 14 /* First is index 14 */
#define FRACDIV_BASE4_HIGH                14 /* Last is index 14 */
#define FRACDIV_BASE4_FDIV0W              8

#define FRACDIV_BASE5_CNT                 1  /* 1 fractional divider available */
#define FRACDIV_BASE5_LOW                 15 /* First is index 15 */
#define FRACDIV_BASE5_HIGH                15 /* Last is index 15 */
#define FRACDIV_BASE5_FDIV0W              8

#define FRACDIV_BASE6_CNT                 1  /* 1 fractional divider available */
#define FRACDIV_BASE6_LOW                 16 /* First is index 16 */
#define FRACDIV_BASE6_HIGH                16 /* Last is index 16 */
#define FRACDIV_BASE6_FDIV0W              8

#define FRACDIV_BASE7_CNT                 6  /* 6 fractional dividers available */
#define FRACDIV_BASE7_LOW                 17 /* First is index 17 */
#define FRACDIV_BASE7_HIGH                22 /* Last is index 22 */
#define FRACDIV_BASE7_FDIV0W              13

#define FRACDIV_BASE8_CNT                 0  /* No fractional divider available */
#define FRACDIV_BASE9_CNT                 0  /* No fractional divider available */

#define FRACDIV_BASE10_CNT                1  /* 1 fractional divider available */
#define FRACDIV_BASE10_LOW                23 /* First is index 23 */
#define FRACDIV_BASE10_HIGH               23 /* Last is index 23 */
#define FRACDIV_BASE10_FDIV0W             8

#define FRACDIV_BASE11_CNT                0  /* No fractional divider available */

#define CGU_NFRACDIV                      24 /* Number of fractional dividers: 0-23 */
#define CGU_NDYNFRACDIV                   7  /* Number of dynamic fractional dividers: 0-6 */
#define FDCNDX_INVALID                   -1  /* Indicates an invalid fractional
                                              * divider index */

/************************************************************************
 * Public Types
 ************************************************************************/

#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif

/* Clock domains */

enum lpc31_domainid_e
{
  DOMAINID_SYS = 0,    /* Domain 0: SYS_BASE */
  DOMAINID_AHB0APB0,   /* Domain 1: AHB0APB0_BASE */
  DOMAINID_AHB0APB1,   /* Domain 2: AHB0APB1_BASE */
  DOMAINID_AHB0APB2,   /* Domain 3: AHB0APB2_BASE */
  DOMAINID_AHB0APB3,   /* Domain 4: AHB0APB3_BASE */
  DOMAINID_PCM,        /* Domain 5: PCM_BASE */
  DOMAINID_UART,       /* Domain 6: UART_BASE */
  DOMAINID_CLK1024FS,  /* Domain 7: CLK1024FS_BASE */
  DOMAINID_BCK0,       /* Domain 8: BCK0_BASE */
  DOMAINID_BCK1,       /* Domain 9: BCK1_BASE */
  DOMAINID_SPI,        /* Domain 10: SPI_BASE */
  DOMAINID_SYSCLKO     /* Domain 11: SYSCLKO_BASE */
};

/* Clock IDs -- These are indices must correspond to the register
 * offsets in lpc31_cgu.h
 */

enum lpc31_clockid_e
{
  /* Domain 0: SYS_BASE */

  CLKID_APB0CLK = 0,      /*  0 APB0_CLK */
  CLKID_APB1CLK,          /*  1 APB1_CLK */
  CLKID_APB2CLK,          /*  2 APB2_CLK */
  CLKID_APB3CLK,          /*  3 APB3_CLK */
  CLKID_APB4CLK,          /*  4 APB4_CLK */
  CLKID_AHB2INTCCLK,      /*  5 AHB_TO_INTC_CLK */
  CLKID_AHB0CLK,          /*  6 AHB0_CLK */
  CLKID_EBICLK,           /*  7 EBI_CLK */
  CLKID_DMAPCLK,          /*  8 DMA_PCLK */
  CLKID_DMACLKGATED,      /*  9 DMA_CLK_GATED */
  CLKID_NANDFLASHS0CLK,   /* 10 NANDFLASH_S0_CLK */
  CLKID_NANDFLASHECCCLK,  /* 11 NANDFLASH_ECC_CLK */
  CLKID_NANDFLASHAESCLK,  /* 12 NANDFLASH_AES_CLK (Reserved on LPC313x) */ 
  CLKID_NANDFLASHNANDCLK, /* 13 NANDFLASH_NAND_CLK */
  CLKID_NANDFLASHPCLK,    /* 14 NANDFLASH_PCLK */
  CLKID_CLOCKOUT,         /* 15 CLOCK_OUT */
  CLKID_ARM926CORECLK,    /* 16 ARM926_CORE_CLK */
  CLKID_ARM926BUSIFCLK,   /* 17 ARM926_BUSIF_CLK */
  CLKID_ARM926RETIMECLK,  /* 18 ARM926_RETIME_CLK */
  CLKID_SDMMCHCLK,        /* 19 SD_MMC_HCLK */
  CLKID_SDMMCCCLKIN,      /* 20 SD_MMC_CCLK_IN */
  CLKID_USBOTGAHBCLK,     /* 21 USB_OTG_AHB_CLK */
  CLKID_ISRAM0CLK,        /* 22 ISRAM0_CLK */
  CLKID_REDCTLRSCLK,      /* 23 RED_CTL_RSCLK */
  CLKID_ISRAM1CLK,        /* 24 ISRAM1_CLK (LPC313x only) */
  CLKID_ISROMCLK,         /* 25 ISROM_CLK */
  CLKID_MPMCCFGCLK,       /* 26 MPMC_CFG_CLK */
  CLKID_MPMCCFGCLK2,      /* 27 MPMC_CFG_CLK2 */
  CLKID_MPMCCFGCLK3,      /* 28 MPMC_CFG_CLK3 */
  CLKID_INTCCLK,          /* 29 INTC_CLK */

  /* Domain 1: AHB0APB0_BASE */

  CLKID_AHB2APB0PCLK,     /* 30 AHB_TO_APB0_PCLK */
  CLKID_EVENTROUTERPCLK,  /* 31 EVENT_ROUTER_PCLK */
  CLKID_ADCPCLK,          /* 32 ADC_PCLK */
  CLKID_ADCCLK,           /* 33 ADC_CLK */
  CLKID_WDOGPCLK,         /* 34 WDOG_PCLK */
  CLKID_IOCONFPCLK,       /* 35 IOCONF_PCLK */
  CLKID_CGUPCLK,          /* 36 CGU_PCLK */
  CLKID_SYSCREGPCLK,      /* 37 SYSCREG_PCLK */
  CLKID_OTPPCLK,          /* 38 OTP_PCLK (Reserved on LPC313X) */
  CLKID_RNGPCLK,          /* 39 RNG_PCLK */

  /* Domain 2: AHB0APB1_BASE */

  CLKID_AHB2APB1PCLK,     /* 40 AHB_TO_APB1_PCLK */
  CLKID_TIMER0PCLK,       /* 41 TIMER0_PCLK */
  CLKID_TIMER1PCLK,       /* 42 TIMER1_PCLK */
  CLKID_TIMER2PCLK,       /* 43 TIMER2_PCLK */
  CLKID_TIMER3PCLK,       /* 44 TIMER3_PCLK */
  CLKID_PWMPCLK,          /* 45 PWM_PCLK */
  CLKID_PWMPCLKREGS,      /* 46 PWM_PCLK_REGS */
  CLKID_PWMCLK,           /* 47 PWM_CLK */
  CLKID_I2C0PCLK,         /* 48 I2C0_PCLK */
  CLKID_I2C1PCLK,         /* 49 I2C1_PCLK */

  /* Domain 3: AHB0APB2_BASE */

  CLKID_AHB2APB2PCLK,     /* 50 AHB_TO_APB2_PCLK */
  CLKID_PCMPCLK,          /* 51 PCM_PCLK */
  CLKID_PCMAPBPCLK,       /* 52 PCM_APB_PCLK */
  CLKID_UARTAPBCLK,       /* 53 UART_APB_CLK */
  CLKID_LCDPCLK,          /* 54 LCD_PCLK */
  CLKID_LCDCLK,           /* 55 LCD_CLK */
  CLKID_SPIPCLK,          /* 56 SPI_PCLK */
  CLKID_SPIPCLKGATED,     /* 57 SPI_PCLK_GATED */

  /* Domain 4: AHB0APB3BASE */
  CLKID_AHB2APB3PCLK,     /* 58 AHB_TO_APB3_PCLK */
  CLKID_I2SCFGPCLK,       /* 59 I2S_CFG_PCLK */
  CLKID_EDGEDETPCLK,      /* 60 EDGE_DET_PCLK */
  CLKID_I2STXFIFO0PCLK,   /* 61 I2STX_FIFO_0_PCLK */
  CLKID_I2STXIF0PCLK,     /* 62 I2STX_IF_0_PCLK */
  CLKID_I2STXFIFO1PCLK,   /* 63 I2STX_FIFO_1_PCLK */
  CLKID_I2STXIF1PCLK,     /* 64 I2STX_IF_1_PCLK */
  CLKID_I2SRXFIFO0PCLK,   /* 65 I2SRX_FIFO_0_PCLK */
  CLKID_I2SRXIF0PCLK,     /* 66 I2SRX_IF_0_PCLK */
  CLKID_I2SRXFIFO1PCLK,   /* 67 I2SRX_FIFO_1_PCLK */
  CLKID_I2SRXIF1PCLK,     /* 68 I2SRX_IF_1_PCLK */
  CLKID_RESERVED69,       /* 69 Reserved */
  CLKID_RESERVED70,       /* 70 Reserved */

  /* Domain 5: PCM_BASE */

  CLKID_PCMCLKIP,         /* 71 PCM_CLK_IP */

  /* Domain 6: UART_BASE */

  CLKID_UARTUCLK,         /* 72 UART_U_CLK */
  
  /* Domain 7: CLK1024FS_BASE */

  CLKID_I2SEDGEDETECTCLK, /* 73 I2S_EDGE_DETECT_CLK */
  CLKID_I2STXBCK0N,       /* 74 I2STX_BCK0_N */
  CLKID_I2STXWS0,         /* 75 I2STX_WS0 */
  CLKID_I2STXCLK0,        /* 76 I2STX_CLK0 */
  CLKID_I2STXBCK1N,       /* 77 I2STX_BCK1_N */
  CLKID_I2STXWS1,         /* 78 I2STX_WS1 */
  CLKID_CLK256FS,         /* 79 CLK_256FS */
  CLKID_I2SRXBCK0N,       /* 80 I2SRX_BCK0_N */
  CLKID_I2SRXWS0,         /* 81 I2SRX_WS0 */
  CLKID_I2SRXBCK1N,       /* 82 I2SRX_BCK1_N */
  CLKID_I2SRXWS1,         /* 83 I2SRX_WS1 */
  CLKID_RESERVED84,       /* 84 Reserved */
  CLKID_RESERVED85,       /* 85 Reserved */
  CLKID_RESERVED86,       /* 86 Reserved */

  /* Domain 8: BCK0_BASE */

  CLKID_I2SRXBCK0,        /* 87 I2SRX_BCK0 */

  /* Domain 9: BCK1_BASE */

  CLKID_I2SRXBCK1,        /* 88 I2SRX_BCK1 */

  /* Domain 10: SPI_BASE */

  CLKID_SPICLK,           /* 89 SPI_CLK */
  CLKID_SPICLKGATED,      /* 90 SPI_CLK_GATED */

  /* Domain 11: SYSCLKO_BASE */

  CLKID_SYSCLKO           /* 91 SYSCLK_O */
};

/* Indices into the CGU configuration reset control registers */

enum lpc31_resetid_e
{
  RESETID_APB0RST,        /*  0 AHB part of AHB_TO_APB0 bridge (Reserved) */
  RESETID_AHB2APB0RST,    /*  1 APB part of AHB_TO_APB0 bridge (Reserved) */
  RESETID_APB1RST,        /*  2 AHB part of AHB_TO_APB1 bridge */
  RESETID_AHB2PB1RST,     /*  3 APB part of AHB_TO_APB1 bridge */
  RESETID_APB2RST,        /*  4 AHB part of AHB_TO_APB2 bridge */
  RESETID_AHB2APB2RST,    /*  5 APB part of AHB_TO_APB2 bridge */
  RESETID_APB3RST,        /*  6 AHB part of AHB_TO_APB3 bridge */
  RESETID_AHB2APB3RST,    /*  7 APB part of AHB_TO_APB3 bridge */
  RESETID_APB4RST,        /*  8 AHB_TO_APB4 bridge */
  RESETID_AHB2INTCRST,    /*  9 AHB_TO_INTC */
  RESETID_AHB0RST,        /* 10 AHB0 */
  RESETID_EBIRST,         /* 11 EBI */
  RESETID_PCMAPBRST,      /* 12 APB domain of PCM */
  RESETID_PCMCLKIPRST,    /* 13 synchronous clk_ip domain of PCM */
  RESETID_PCMRSTASYNC,    /* 14 asynchronous clk_ip domain of PCM */
  RESETID_TIMER0RST,      /* 15 Timer0 */
  RESETID_TIMER1RST,      /* 16 Timer1 */
  RESETID_TIMER2RST,      /* 17 Timer2 */
  RESETID_TIMER3RST,      /* 18 Timer3 */
  RESETID_ADCPRST,        /* 19 controller of 10 bit ADC Interface */
  RESETID_ADCRST,         /* 20 A/D converter of ADC Interface */
  RESETID_PWMRST,         /* 21 PWM */
  RESETID_UARTRST,        /* 22 UART/IrDA */
  RESETID_I2C0RST,        /* 23 I2C0 */
  RESETID_I2C1RST,        /* 24 I2C1 */
  RESETID_I2SCFGRST,      /* 25 I2S_Config */
  RESETID_I2SNSOFRST,     /* 26 NSOF counter of I2S_CONFIG */
  RESETID_EDGEDETRST,     /* 27 Edge_det */
  RESETID_I2STXFF0RST,    /* 28 I2STX_FIFO_0 */
  RESETID_I2STXIF0RST,    /* 29 I2STX_IF_0 */
  RESETID_I2STXFF1RST,    /* 30 I2STX_FIFO_1 */
  RESETID_I2STXIF1RST,    /* 31 I2STX_IF_1 */
  RESETID_I2SRXFF0RST,    /* 32 I2SRX_FIFO_0 */
  RESETID_I2SRXIF0RST,    /* 33 I2SRX_IF_0 */
  RESETID_I2SRXFF1RST,    /* 34 I2SRX_FIFO_1 */
  RESETID_I2SRXIF1RST,    /* 35 I2SRX_IF_1 */
  RESETID_RESERVED40,     /* 36 Reserved */    
  RESETID_RESERVED41,     /* 37 Reserved */    
  RESETID_RESERVED42,     /* 38 Reserved */    
  RESETID_RESERVED43,     /* 39 Reserved */    
  RESETID_RESERVED44,     /* 40 Reserved */ 
  RESETID_LCDRST,         /* 41 LCD Interface */
  RESETID_SPIRSTAPB,      /* 42 apb_clk domain of SPI */
  RESETID_SPIRSTIP,       /* 43 ip_clk domain of SPI */
  RESETID_DMARST,         /* 44 DMA */
  RESETID_NANDECCRST,     /* 45 Nandflash Controller ECC clock */
  RESETID_NANDAESRST,     /* 46 Nandflash Controller AES clock (reserved for lpc313x) */
  RESETID_NANDCTRLRST,    /* 47 Nandflash Controller */
  RESETID_RNG,            /* 48 RNG */
  RESETID_SDMMCRST,       /* 49 MCI (on AHB clock) */
  RESETID_SDMMCRSTCKIN,   /* 50 CI synchronous (on IP clock) */
  RESETID_USBOTGAHBRST,   /* 51 USB_OTG */
  RESETID_REDCTLRST,      /* 52 Redundancy Controller */
  RESETID_AHBMPMCHRST,    /* 53 MPMC */
  RESETID_AHBMPMCRFRST,   /* 54 refresh generator used for MPMC */
  RESETID_INTCRST,        /* 55 Interrupt Controller */
};

/* This structure describes one CGU fractional divider configuration */

struct lpc31_fdivconfig_s
{
  uint8_t  stretch;       /* Fractional divider stretch enable. */
  uint8_t  n;             /* Fractional divider nominal nominator */
  uint16_t m;             /* Fractional divider nominal denominator */
};

/* The structure describes the configuration of one CGU sub-domain */

struct lpc31_subdomainconfig_s
{
  struct lpc31_fdivconfig_s fdiv; /* Fractional divider settings */
  uint32_t clkset;                  /* Bitset of all clocks in the sub-domain */
};

/* CGU clock initilization structure.  Describes the platform-specific
 * configuration of every clock domain.
 */

struct lpc31_clkinit_s
{
  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE0_CNT];
  } domain0;

  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE1_CNT];
  } domain1;

  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE2_CNT];
  } domain2;

  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE3_CNT];
  } domain3;

  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE4_CNT];
  } domain4;

  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE5_CNT];
  } domain5;

  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE6_CNT];
  } domain6;

  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE7_CNT];
  } domain7;

  struct
  {
    uint8_t finsel;
  } domain8;

  struct
  {
    uint8_t finsel;
  } domain9;

  struct
  {
    uint8_t finsel;
    struct lpc31_subdomainconfig_s sub[FRACDIV_BASE10_CNT];
  } domain10;

  struct
  {
    uint8_t finsel;
  } domain11;

#if 0 /* Dynamic fractional divider initialization not implemented */
  struct
  {
    uint16_t  sel;
    struct lpc31_fdivconfig_s cfg;
  } dynfdiv[CGU_NDYNFRACDIV];
#endif
};

/* This structure is used to pass PLL configuration data to
 * lpc31_pllconfig()
 */

struct lpc31_pllconfig_s
{
  uint8_t  hppll;         /* PLL selection: 0=HPLL0 1=HPLL1 */
  uint8_t  pdec;          /* PLL P-divider value: 0-0x7f */
  uint8_t  selr;          /* SELR bandwidth selection: 0-15 */
  uint8_t  seli;          /* SELI bandwidth selection: 0-63 */
  uint8_t  selp;          /* SELP bandwidth selection: 0-31 */
  uint16_t ndec;          /* PLL N-divider value: 0-0x3ff */
  uint16_t mode;          /* PLL mode: 9-bits */
  uint32_t freq;          /* Frequency of the PLL in MHz */
  uint32_t finsel;        /* Frequency input selection: CGU_HPFINSEL_* */
  uint32_t mdec;          /* PLL M-divider value: 0-0x1ffff */
};

/************************************************************************
 * Public Data
 ************************************************************************/

/* This array is managed by the chip-specific logic and provides the
 * programmed frequency of every input source
 */

EXTERN uint32_t g_boardfreqin[CGU_NFREQIN];

/* This instance of the lpc31_clkinit_s structure provides the initial,
 * default clock configuration for the board.  Every board must provide
 * an implementation of g_boardclks.  This rather complex structure is
 * used by the boot-up logic to configure initial lpc31xx clocking.
 */

EXTERN const struct lpc31_clkinit_s g_boardclks;

/************************************************************************
 * Inline Functions
 ************************************************************************/

/************************************************************************
 * Name: lpc31_getbasefreq
 *
 * Description:
 *   Return the base frequency associated with a clock domain
 *
 ************************************************************************/

static inline uint32_t lpc31_getbasefreq(enum lpc31_domainid_e dmnid)
{
  uint32_t regval;
  int     ndx;

  /* Fetch the SSR register associated with this clock domain */

  regval = getreg32(LPC31_CGU_SSR((int)dmnid));

  /* Extract the last frequency input selection */

  ndx    = (regval & CGU_SSR_FS_MASK) >> CGU_SSR_FS_SHIFT;

  /* And return the user-supplied value for that frequency input */

  return g_boardfreqin[ndx];
}

/************************************************************************
 * Name: lpc31_enableclock
 *
 * Description:
 *   Enable the specified clock
 *
 ************************************************************************/

static inline void lpc31_enableclock(enum lpc31_clockid_e clkid)
{
  uint32_t address = LPC31_CGU_PCR((int)clkid);
  uint32_t regval  = getreg32(address);

  regval          |= CGU_PCR_RUN;
  putreg32(regval, address);
}

/************************************************************************
 * Name: lpc31_disableclock
 *
 * Description:
 *   Disable the specified clock
 *
 ************************************************************************/

static inline void lpc31_disableclock(enum lpc31_clockid_e clkid)
{
  uint32_t address = LPC31_CGU_PCR((int)clkid);
  uint32_t regval  = getreg32(address);

  regval          &= ~CGU_PCR_RUN;
  putreg32(regval, address);
}

/************************************************************************
 * Public Functions
 ************************************************************************/

/****************************************************************************
 * Name: lpc31_defclk
 *
 * Description:
 *   Enable the specified clock if it is one of the default clocks needed
 *   by the board.
 *
 ****************************************************************************/

EXTERN bool lpc31_defclk(enum lpc31_clockid_e clkid);

/****************************************************************************
 * Name: lpc31_resetclks
 *
 * Description:
 *   Put all clocks into a known, initial state
 *
 ****************************************************************************/

EXTERN void lpc31_resetclks(void);

/************************************************************************
 * Name: lpc31_clkinit
 *
 * Description:
 *   Initialize all clock domains based on board-specific clock
 *   configuration data
 *
 ************************************************************************/

EXTERN void lpc31_clkinit(const struct lpc31_clkinit_s* cfg);

/************************************************************************
 * Name: lpc31_fdivinit
 *
 * Description:
 *   Enable and configure (or disable) a fractional divider.  For
 *   internal us only... see lpc31_setfdiv() the externally usable
 *   function.
 *
 ************************************************************************/

EXTERN uint32_t lpc31_fdivinit(int fdcndx,
                                 const struct lpc31_fdivconfig_s *fdiv,
                                 bool enable);

/************************************************************************
 * Name: lpc31_setfdiv
 *
 * Description:
 *   Set/reset subdomain frequency containing the specified clock using
 *   the provided divider settings
 *
 ************************************************************************/

EXTERN void lpc31_setfdiv(enum lpc31_domainid_e dmnid,
                            enum lpc31_clockid_e clkid,
                            const struct lpc31_fdivconfig_s *fdiv);

/****************************************************************************
 * Name: lpc31_pllconfig
 *
 * Description:
 *   Re-onfigure the PLL according to the provided selections.
 *
 ****************************************************************************/

EXTERN void lpc31_pllconfig(const struct lpc31_pllconfig_s * const cfg);

/************************************************************************
 * Name: lpc31_hp0pllconfig
 *
 * Description:
 *   Configure the HP0 PLL according to the board.h default selections.
 *
 ************************************************************************/

EXTERN void lpc31_hp0pllconfig(void);

/************************************************************************
 * Name: lpc31_hp1pllconfig
 *
 * Description:
 *   Configure the HP1 PLL according to the board.h default selections.
 *
 ************************************************************************/

EXTERN void lpc31_hp1pllconfig(void);

/************************************************************************
 * Name: lpc31_softreset
 *
 * Description:
 *   Perform a soft reset on the specified module.
 *
 ************************************************************************/

EXTERN void lpc31_softreset(enum lpc31_resetid_e resetid);

/************************************************************************
 * Name: lpc31_clkdomain
 *
 * Description:
 *   Given a clock ID, return the ID of the domain in which the clock
 *   resides.
 *
 ************************************************************************/

EXTERN enum lpc31_domainid_e lpc31_clkdomain(enum lpc31_clockid_e clkid);

/************************************************************************
 * Name: lpc31_esrndx
 *
 * Description:
 *   Given a clock ID, return the index of the corresponding ESR
 *   register (or ESRNDX_INVALID if there is no ESR associated with
 *   this clock ID).  Indexing of ESRs differs slightly from the clock
 *   ID:  There are 92 clock IDs but only 89 ESR regisers. There are no
 *  ESR registers for :
 *
 *
 *  CLKID_I2SRXBCK0         Clock ID 87: I2SRX_BCK0
 *  CLKID_I2SRXBCK1,        Clock ID 88: I2SRX_BCK1
 *
 * and
 *
 *  CLKID_SYSCLKO           Clock ID 91: SYSCLK_O
 *
 ************************************************************************/

EXTERN int lpc31_esrndx(enum lpc31_clockid_e clkid);

/************************************************************************
 * Name: lpc31_bcrndx
 *
 * Description:
 *   Only 5 of the 12 domains have an associated BCR register.  This
 *   function returns the index to the associated BCR register (if any)
 *   or BCRNDX_INVALID otherwise.
 *
 ************************************************************************/

EXTERN int lpc31_bcrndx(enum lpc31_domainid_e dmnid);

/************************************************************************
 * Name: lpc31_fdcndx
 *
 * Description:
 *   Given a clock ID and its domain ID, return the index of the
 *   corresponding fractional divider register (or FDCNDX_INVALID if
 *   there is no fractional divider associated with this clock).
 *
 ************************************************************************/

EXTERN int lpc31_fdcndx(enum lpc31_clockid_e clkid,
                          enum lpc31_domainid_e dmnid);

/************************************************************************
 * Name: lpc31_selectfreqin
 *
 * Description:
 *   Set the base frequency source selection for with a clock domain
 *
 ************************************************************************/

EXTERN void lpc31_selectfreqin(enum lpc31_domainid_e dmnid,
                                 uint32_t finsel);

/************************************************************************
 * Name: lpc31_clkfreq
 *
 * Description:
 *   Given a clock ID and its domain ID, return the frequency of the
 *   clock.
 *
 ************************************************************************/

EXTERN uint32_t lpc31_clkfreq(enum lpc31_clockid_e clkid,
                                enum lpc31_domainid_e dmnid);

/************************************************************************
 * Name: lpc31_enableexten
 *
 * Description:
 *   Enable external enabling for the the specified possible clocks.
 *
 ************************************************************************/

EXTERN void lpc31_enableexten(enum lpc31_clockid_e clkid);

/************************************************************************
 * Name: lpc31_disableexten
 *
 * Description:
 *   Disable external enabling for the the specified possible clocks.
 *
 ************************************************************************/

EXTERN void lpc31_disableexten(enum lpc31_clockid_e clkid);

#undef EXTERN
#ifdef __cplusplus
}
#endif

#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_LPC31XX_LPC31_CGUDRVR_H */