altos/stm32f4: Fix clock configuration
[fw/altos] / src / stm32f4 / stm32f4.h
1 /*
2  * Copyright © 2018 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #ifndef _STM32F4_H_
16 #define _STM32F4_H_
17
18 #include <stdint.h>
19
20 typedef volatile uint32_t       vuint32_t;
21 typedef volatile void *         vvoid_t;
22 typedef volatile uint16_t       vuint16_t;
23 typedef volatile uint8_t        vuint8_t;
24
25 struct stm_pwr {
26         vuint32_t       cr;
27         vuint32_t       csr;
28 };
29
30 extern struct stm_pwr stm_pwr;
31
32 #define stm_pwr (*((struct stm_pwr *) 0x40007000))
33
34 #define STM_PWR_CR_FISSR        21
35 #define STM_PWR_CR_FMSSR        20
36 #define STM_PWR_CR_VOS          14
37 #define  STM_PWR_CR_VOS_SCALE_MODE_3    1
38 #define  STM_PWR_CR_VOS_SCALE_MODE_2    2
39 #define  STM_PWR_CR_VOS_SCALE_MODE_1    3
40 #define  STM_PWR_CR_VOS_SCALE_MODE_MASK 3
41 #define STM_PWR_CR_ADCDC1       13
42 #define STM_PWR_CR_MRLVDS       11
43 #define STM_PWR_CR_LPLVDS       10
44 #define STM_PWR_CR_FPDS         9
45 #define STM_PWR_CR_DBP          8
46 #define STM_PWR_CR_PLS          5
47 #define STM_PWR_CR_PVDE         4
48 #define STM_PWR_CR_CSBF         3
49 #define STM_PWR_CR_CWUF         2
50 #define STM_PWR_CR_PDDS         1
51 #define STM_PWR_CR_LPDS         0
52
53 struct stm_rcc {
54         vuint32_t       cr;
55         vuint32_t       pllcfgr;
56         vuint32_t       cfgr;
57         vuint32_t       cir;
58
59         vuint32_t       ahb1rstr;
60         vuint32_t       ahb2rstr;
61         vuint32_t       ahb3rstr;
62         uint32_t        pad_1c;
63
64         vuint32_t       apb1rstr;
65         vuint32_t       apb2rstr;
66         vuint32_t       pad_28;
67         vuint32_t       pad_2c;
68
69         vuint32_t       ahb1enr;
70         vuint32_t       ahb2enr;
71         vuint32_t       ahbdnr;
72         vuint32_t       pad_3c;
73
74         vuint32_t       apb1enr;
75         vuint32_t       apb2enr;
76         vuint32_t       pad_48;
77         vuint32_t       pad_4c;
78
79         vuint32_t       ahb1lpenr;
80         vuint32_t       ahb2lpenr;
81         vuint32_t       ahb3lpenr;
82         vuint32_t       pad_5c;
83
84         vuint32_t       apb1lpenr;
85         vuint32_t       apb2lpenr;
86         vuint32_t       pad_68;
87         vuint32_t       pad_6c;
88
89         vuint32_t       bdcr;
90         vuint32_t       csr;
91         vuint32_t       pad_78;
92         vuint32_t       pad_7c;
93
94         vuint32_t       sscgr;
95         vuint32_t       plli2scfgr;
96         vuint32_t       pad_88;
97         vuint32_t       dckcfgr;
98
99         vuint32_t       ckgatenr;
100         vuint32_t       dckcfgr2;
101 };
102
103 extern struct stm_rcc stm_rcc;
104
105 #define stm_rcc (*((struct stm_rcc *) 0x40023800))
106
107 /* Internal HSI is 16MHz */
108 #define STM_HSI_FREQ            16000000
109
110 #define STM_RCC_CR_PLLI2SRDY    (27)
111 #define STM_RCC_CR_PLLI2SON     (26)
112 #define STM_RCC_CR_PLLRDY       (25)
113 #define STM_RCC_CR_PLLON        (24)
114 #define STM_RCC_CR_CSSON        (19)
115 #define STM_RCC_CR_HSEBYP       (18)
116 #define STM_RCC_CR_HSERDY       (17)
117 #define STM_RCC_CR_HSEON        (16)
118 #define STM_RCC_CR_HSICAL       (8)
119 #define STM_RCC_CR_HSITRIM      (3)
120 #define STM_RCC_CR_HSIRDY       (1)
121 #define STM_RCC_CR_HSION        (0)
122
123 #define STM_RCC_PLLCFGR_PLLM    0
124 #define  STM_RCC_PLLCFGR_PLLM_MASK      0x3f
125 #define STM_RCC_PLLCFGR_PLLN    6
126 #define  STM_RCC_PLLCFGR_PLLN_MASK      0x1ff
127 #define STM_RCC_PLLCFGR_PLLP    16
128 #define  STM_RCC_PLLCFGR_PLLP_DIV_2     0
129 #define  STM_RCC_PLLCFGR_PLLP_DIV_4     1
130 #define  STM_RCC_PLLCFGR_PLLP_DIV_6     2
131 #define  STM_RCC_PLLCFGR_PLLP_DIV_8     3
132 #define  STM_RCC_PLLCFGR_PLLP_MASK      0x3
133 #define STM_RCC_PLLCFGR_PLLSRC  22
134 #define  STM_RCC_PLLCFGR_PLLSRC_HSI     0
135 #define  STM_RCC_PLLCFGR_PLLSRC_HSE     1
136 #define STM_RCC_PLLCFGR_PLLQ    24
137 #define  STM_RCC_PLLCFGR_PLLQ_MASK      0xf
138 #define STM_RCC_PLLCFGR_PLLR    28
139 #define  STM_RCC_PLLCFGR_PLLR_MASK      0x7
140
141 #define STM_RCC_CFGR_MCO2       (30)
142 #define STM_RCC_CFGR_MCO2PRE    (27)
143 #define STM_RCC_CFGR_MCO1PRE    (24)
144 #define STM_RCC_CFGR_MCO1       (21)
145 #define STM_RCC_CFGR_RTCPRE     (16)
146
147 #define STM_RCC_CFGR_PPRE2      (13)
148 #define  STM_RCC_CFGR_PPRE2_DIV_1       0
149 #define  STM_RCC_CFGR_PPRE2_DIV_2       4
150 #define  STM_RCC_CFGR_PPRE2_DIV_4       5
151 #define  STM_RCC_CFGR_PPRE2_DIV_8       6
152 #define  STM_RCC_CFGR_PPRE2_DIV_16      7
153 #define  STM_RCC_CFGR_PPRE2_MASK        7
154
155 #define STM_RCC_CFGR_PPRE1      (10)
156 #define  STM_RCC_CFGR_PPRE1_DIV_1       0
157 #define  STM_RCC_CFGR_PPRE1_DIV_2       4
158 #define  STM_RCC_CFGR_PPRE1_DIV_4       5
159 #define  STM_RCC_CFGR_PPRE1_DIV_8       6
160 #define  STM_RCC_CFGR_PPRE1_DIV_16      7
161 #define  STM_RCC_CFGR_PPRE1_MASK        7
162
163 #define STM_RCC_CFGR_HPRE       (4)
164 #define  STM_RCC_CFGR_HPRE_DIV_1        0x0
165 #define  STM_RCC_CFGR_HPRE_DIV_2        0x8
166 #define  STM_RCC_CFGR_HPRE_DIV_4        0x9
167 #define  STM_RCC_CFGR_HPRE_DIV_8        0xa
168 #define  STM_RCC_CFGR_HPRE_DIV_16       0xb
169 #define  STM_RCC_CFGR_HPRE_DIV_64       0xc
170 #define  STM_RCC_CFGR_HPRE_DIV_128      0xd
171 #define  STM_RCC_CFGR_HPRE_DIV_256      0xe
172 #define  STM_RCC_CFGR_HPRE_DIV_512      0xf
173 #define  STM_RCC_CFGR_HPRE_MASK         0xf
174
175 #define STM_RCC_CFGR_SWS        (2)
176 #define  STM_RCC_CFGR_SWS_HSI           0
177 #define  STM_RCC_CFGR_SWS_HSE           1
178 #define  STM_RCC_CFGR_SWS_PLL           2
179 #define  STM_RCC_CFGR_SWS_MASK          3
180
181 #define STM_RCC_CFGR_SW         (0)
182 #define  STM_RCC_CFGR_SW_HSI            0
183 #define  STM_RCC_CFGR_SW_HSE            1
184 #define  STM_RCC_CFGR_SW_PLL            2
185 #define  STM_RCC_CFGR_SW_MASK           3
186
187 #define STM_RCC_AHB1ENR_IOPAEN  0
188 #define STM_RCC_AHB1ENR_IOPBEN  1
189 #define STM_RCC_AHB1ENR_IOPCEN  2
190 #define STM_RCC_AHB1ENR_IOPDEN  3
191 #define STM_RCC_AHB1ENR_IOPEEN  4
192 #define STM_RCC_AHB1ENR_IOPFEN  5
193 #define STM_RCC_AHB1ENR_IOPGEN  6
194 #define STM_RCC_AHB1ENR_IOPHEN  7
195
196 #define STM_RCC_APB1ENR_UART8EN         31
197 #define STM_RCC_APB1ENR_UART7EN         30
198 #define STM_RCC_APB1ENR_DACEN           29
199 #define STM_RCC_APB1ENR_PWREN           28
200 #define STM_RCC_APB1ENR_CAN3EN          27
201 #define STM_RCC_APB1ENR_CAN2EN          26
202 #define STM_RCC_APB1ENR_CAN1EN          25
203 #define STM_RCC_APB1ENR_I2CFMP1EN       24
204 #define STM_RCC_APB1ENR_I2C3EN          23
205 #define STM_RCC_APB1ENR_I2C2EN          22
206 #define STM_RCC_APB1ENR_I2C1EN          21
207 #define STM_RCC_APB1ENR_UART5EN         20
208 #define STM_RCC_APB1ENR_UART4EN         19
209 #define STM_RCC_APB1ENR_USART3EN        18
210 #define STM_RCC_APB1ENR_USART2EN        17
211 #define STM_RCC_APB1ENR_SPI3EN          15
212 #define STM_RCC_APB1ENR_SPI2EN          14
213 #define STM_RCC_APB1ENR_WWDGEN          11
214 #define STM_RCC_APB1ENR_RTCAPBEN        10
215 #define STM_RCC_APB1ENR_LPTIMER1EN      9
216 #define STM_RCC_APB1ENR_TIM14EN         8
217 #define STM_RCC_APB1ENR_TIM13EN         7
218 #define STM_RCC_APB1ENR_TIM12EN         6
219 #define STM_RCC_APB1ENR_TIM7EN          5
220 #define STM_RCC_APB1ENR_TIM6EN          4
221 #define STM_RCC_APB1ENR_TIM5EN          3
222 #define STM_RCC_APB1ENR_TIM4EN          2
223 #define STM_RCC_APB1ENR_TIM3EN          1
224 #define STM_RCC_APB1ENR_TIM2EN          0
225
226 #define STM_RCC_CSR_RMVF                24
227
228 struct stm_ictr {
229         vuint32_t       ictr;
230 };
231
232 extern struct stm_ictr stm_ictr;
233
234 #define stm_ictr (*((struct stm_ictr *) 0xe000e004))
235
236 #define STM_ICTR_ICTR_INTLINESNUM       0
237 #define  STM_ICTR_ICTR_INTLINESNUM_MASK         0xf
238
239 struct stm_nvic {
240         vuint32_t       iser[8];        /* 0x000 0xe000e100 Set Enable Register */
241
242         uint8_t         _unused020[0x080 - 0x020];
243
244         vuint32_t       icer[8];        /* 0x080 0xe000e180 Clear Enable Register */
245
246         uint8_t         _unused0a0[0x100 - 0x0a0];
247
248         vuint32_t       ispr[8];        /* 0x100 0xe000e200 Set Pending Register */
249
250         uint8_t         _unused120[0x180 - 0x120];
251
252         vuint32_t       icpr[8];        /* 0x180 0xe000e280 Clear Pending Register */
253
254         uint8_t         _unused1a0[0x200 - 0x1a0];
255
256         vuint32_t       iabr[8];        /* 0x200 0xe000e300 Active Bit Register */
257
258         uint8_t         _unused220[0x300 - 0x220];
259
260         vuint32_t       ipr[60];        /* 0x300 0xe000e400 Priority Register */
261 };
262
263 extern struct stm_nvic stm_nvic;
264
265 #define stm_nvic (*((struct stm_nvic *) 0xe000e100))
266
267 #define IRQ_REG(irq)    ((irq) >> 5)
268 #define IRQ_BIT(irq)    ((irq) & 0x1f)
269 #define IRQ_MASK(irq)   (1 << IRQ_BIT(irq))
270 #define IRQ_BOOL(v,irq) (((v) >> IRQ_BIT(irq)) & 1)
271
272 static inline void
273 stm_nvic_set_enable(int irq) {
274         stm_nvic.iser[IRQ_REG(irq)] = IRQ_MASK(irq);
275 }
276
277 static inline void
278 stm_nvic_clear_enable(int irq) {
279         stm_nvic.icer[IRQ_REG(irq)] = IRQ_MASK(irq);
280 }
281
282 static inline int
283 stm_nvic_enabled(int irq) {
284         return IRQ_BOOL(stm_nvic.iser[IRQ_REG(irq)], irq);
285 }
286         
287 static inline void
288 stm_nvic_set_pending(int irq) {
289         stm_nvic.ispr[IRQ_REG(irq)] = IRQ_MASK(irq);
290 }
291
292 static inline void
293 stm_nvic_clear_pending(int irq) {
294         stm_nvic.icpr[IRQ_REG(irq)] = IRQ_MASK(irq);
295 }
296
297 static inline int
298 stm_nvic_pending(int irq) {
299         return IRQ_BOOL(stm_nvic.ispr[IRQ_REG(irq)], irq);
300 }
301
302 static inline int
303 stm_nvic_active(int irq) {
304         return IRQ_BOOL(stm_nvic.iabr[IRQ_REG(irq)], irq);
305 }
306
307 #define IRQ_PRIO_REG(irq)       ((irq) >> 2)
308 #define IRQ_PRIO_BIT(irq)       (((irq) & 3) << 3)
309 #define IRQ_PRIO_MASK(irq)      (0xff << IRQ_PRIO_BIT(irq))
310
311 static inline void
312 stm_nvic_set_priority(int irq, uint8_t prio) {
313         int             n = IRQ_PRIO_REG(irq);
314         uint32_t        v;
315
316         v = stm_nvic.ipr[n];
317         v &= ~IRQ_PRIO_MASK(irq);
318         v |= (prio) << IRQ_PRIO_BIT(irq);
319         stm_nvic.ipr[n] = v;
320 }
321
322 static inline uint8_t
323 stm_nvic_get_priority(int irq) {
324         return (stm_nvic.ipr[IRQ_PRIO_REG(irq)] >> IRQ_PRIO_BIT(irq)) & IRQ_PRIO_MASK(0);
325 }
326
327 struct stm_flash {
328         vuint32_t       acr;
329         vuint32_t       keyr;
330         vuint32_t       optkeyr;
331         vuint32_t       sr;
332
333         vuint32_t       cr;
334         vuint32_t       optcr;
335         vuint32_t       wrpr;
336 };
337
338 extern struct stm_flash stm_flash;
339
340 #define stm_flash (*((struct stm_flash *) 0x40023c00))
341
342 #define STM_FLASH_ACR_DCRST     12
343 #define STM_FLASH_ACR_ICRST     11
344 #define STM_FLASH_ACR_DCEN      10
345 #define STM_FLASH_ACR_ICEN      9
346 #define STM_FLASH_ACR_PRFTEN    8
347 #define STM_FLASH_ACR_LATENCY   0
348
349 struct stm_flash_size {
350         vuint16_t       f_size;
351 };
352
353 extern struct stm_flash_size stm_flash_size;
354
355 #define stm_flash_size  (*((struct stm_flash_size *) 0x1fff7a22))
356
357 struct stm_gpio {
358         vuint32_t       moder;
359         vuint32_t       otyper;
360         vuint32_t       ospeedr;
361         vuint32_t       pupdr;
362
363         vuint32_t       idr;
364         vuint32_t       odr;
365         vuint32_t       bsrr;
366         vuint32_t       lckr;
367
368         vuint32_t       afrl;
369         vuint32_t       afrh;
370 };
371
372 #define STM_MODER_SHIFT(pin)            ((pin) << 1)
373 #define STM_MODER_MASK                  3
374 #define STM_MODER_INPUT                 0
375 #define STM_MODER_OUTPUT                1
376 #define STM_MODER_ALTERNATE             2
377 #define STM_MODER_ANALOG                3
378
379 static inline void
380 stm_moder_set(struct stm_gpio *gpio, int pin, vuint32_t value) {
381         gpio->moder = ((gpio->moder &
382                         ~(STM_MODER_MASK << STM_MODER_SHIFT(pin))) |
383                        value << STM_MODER_SHIFT(pin));
384 }
385
386 static inline uint32_t
387 stm_moder_get(struct stm_gpio *gpio, int pin) {
388         return (gpio->moder >> STM_MODER_SHIFT(pin)) & STM_MODER_MASK;
389 }
390
391 #define STM_OTYPER_SHIFT(pin)           (pin)
392 #define STM_OTYPER_MASK                 1
393 #define STM_OTYPER_PUSH_PULL            0
394 #define STM_OTYPER_OPEN_DRAIN           1
395
396 static inline void
397 stm_otyper_set(struct stm_gpio *gpio, int pin, vuint32_t value) {
398         gpio->otyper = ((gpio->otyper &
399                          ~(STM_OTYPER_MASK << STM_OTYPER_SHIFT(pin))) |
400                         value << STM_OTYPER_SHIFT(pin));
401 }
402
403 static inline uint32_t
404 stm_otyper_get(struct stm_gpio *gpio, int pin) {
405         return (gpio->otyper >> STM_OTYPER_SHIFT(pin)) & STM_OTYPER_MASK;
406 }
407
408 #define STM_OSPEEDR_SHIFT(pin)          ((pin) << 1)
409 #define STM_OSPEEDR_MASK                3
410 #define STM_OSPEEDR_LOW                 0       /* 2-8MHz */
411 #define STM_OSPEEDR_MEDIUM              1       /* 12.5-50MHz */
412 #define STM_OSPEEDR_FAST                2       /* 25-100MHz */
413 #define STM_OSPEEDR_HIGH                3       /* 50-100MHz */
414
415 static inline void
416 stm_ospeedr_set(struct stm_gpio *gpio, int pin, vuint32_t value) {
417         gpio->ospeedr = ((gpio->ospeedr &
418                         ~(STM_OSPEEDR_MASK << STM_OSPEEDR_SHIFT(pin))) |
419                        value << STM_OSPEEDR_SHIFT(pin));
420 }
421
422 static inline uint32_t
423 stm_ospeedr_get(struct stm_gpio *gpio, int pin) {
424         return (gpio->ospeedr >> STM_OSPEEDR_SHIFT(pin)) & STM_OSPEEDR_MASK;
425 }
426
427 #define STM_PUPDR_SHIFT(pin)            ((pin) << 1)
428 #define STM_PUPDR_MASK                  3
429 #define STM_PUPDR_NONE                  0
430 #define STM_PUPDR_PULL_UP               1
431 #define STM_PUPDR_PULL_DOWN             2
432 #define STM_PUPDR_RESERVED              3
433
434 static inline void
435 stm_pupdr_set(struct stm_gpio *gpio, int pin, uint32_t value) {
436         gpio->pupdr = ((gpio->pupdr &
437                         ~(STM_PUPDR_MASK << STM_PUPDR_SHIFT(pin))) |
438                        value << STM_PUPDR_SHIFT(pin));
439 }
440
441 static inline uint32_t
442 stm_pupdr_get(struct stm_gpio *gpio, int pin) {
443         return (gpio->pupdr >> STM_PUPDR_SHIFT(pin)) & STM_PUPDR_MASK;
444 }
445
446 #define STM_AFR_SHIFT(pin)              ((pin) << 2)
447 #define STM_AFR_MASK                    0xf
448 #define STM_AFR_NONE                    0
449 #define STM_AFR_AF0                     0x0
450 #define STM_AFR_AF1                     0x1
451 #define STM_AFR_AF2                     0x2
452 #define STM_AFR_AF3                     0x3
453 #define STM_AFR_AF4                     0x4
454 #define STM_AFR_AF5                     0x5
455 #define STM_AFR_AF6                     0x6
456 #define STM_AFR_AF7                     0x7
457 #define STM_AFR_AF8                     0x8
458 #define STM_AFR_AF9                     0x9
459 #define STM_AFR_AF10                    0xa
460 #define STM_AFR_AF11                    0xb
461 #define STM_AFR_AF12                    0xc
462 #define STM_AFR_AF13                    0xd
463 #define STM_AFR_AF14                    0xe
464 #define STM_AFR_AF15                    0xf
465
466 static inline void
467 stm_afr_set(struct stm_gpio *gpio, int pin, uint32_t value) {
468         /*
469          * Set alternate pin mode too
470          */
471         stm_moder_set(gpio, pin, STM_MODER_ALTERNATE);
472         if (pin < 8)
473                 gpio->afrl = ((gpio->afrl &
474                                ~(STM_AFR_MASK << STM_AFR_SHIFT(pin))) |
475                               value << STM_AFR_SHIFT(pin));
476         else {
477                 pin -= 8;
478                 gpio->afrh = ((gpio->afrh &
479                                ~(STM_AFR_MASK << STM_AFR_SHIFT(pin))) |
480                               value << STM_AFR_SHIFT(pin));
481         }
482 }
483
484 static inline uint32_t
485 stm_afr_get(struct stm_gpio *gpio, int pin) {
486         if (pin < 8)
487                 return (gpio->afrl >> STM_AFR_SHIFT(pin)) & STM_AFR_MASK;
488         else {
489                 pin -= 8;
490                 return (gpio->afrh >> STM_AFR_SHIFT(pin)) & STM_AFR_MASK;
491         }
492 }
493
494 static inline void
495 stm_gpio_set(struct stm_gpio *gpio, int pin, uint8_t value) {
496         /* Use the bit set/reset register to do this atomically */
497         gpio->bsrr = ((uint32_t) (value ^ 1) << (pin + 16)) | ((uint32_t) value << pin);
498 }
499
500 static inline uint8_t
501 stm_gpio_get(struct stm_gpio *gpio, int pin) {
502         return (gpio->idr >> pin) & 1;
503 }
504
505 static inline uint16_t
506 stm_gpio_get_all(struct stm_gpio *gpio) {
507         return gpio->idr;
508 }
509
510 /*
511  * We can't define these in registers.ld or our fancy
512  * ao_enable_gpio macro will expand into a huge pile of code
513  * as the compiler won't do correct constant folding and
514  * dead-code elimination
515  */
516
517 extern struct stm_gpio stm_gpioa;
518 extern struct stm_gpio stm_gpiob;
519 extern struct stm_gpio stm_gpioc;
520 extern struct stm_gpio stm_gpiod;
521 extern struct stm_gpio stm_gpioe;
522 extern struct stm_gpio stm_gpiof;
523 extern struct stm_gpio stm_gpiog;
524 extern struct stm_gpio stm_gpioh;
525
526 #define stm_gpioa  (*((struct stm_gpio *) 0x40020000))
527 #define stm_gpiob  (*((struct stm_gpio *) 0x40020400))
528 #define stm_gpioc  (*((struct stm_gpio *) 0x40020800))
529 #define stm_gpiod  (*((struct stm_gpio *) 0x40020c00))
530 #define stm_gpioe  (*((struct stm_gpio *) 0x40021000))
531 #define stm_gpiof  (*((struct stm_gpio *) 0x40021400))
532 #define stm_gpiog  (*((struct stm_gpio *) 0x40021800))
533 #define stm_gpioh  (*((struct stm_gpio *) 0x40021c00))
534
535 struct stm_scb {
536         vuint32_t       cpuid;
537         vuint32_t       icsr;
538         vuint32_t       vtor;
539         vuint32_t       aircr;
540
541         vuint32_t       scr;
542         vuint32_t       ccr;
543         vuint32_t       shpr1;
544         vuint32_t       shpr2;
545
546         vuint32_t       shpr3;
547         vuint32_t       shcsr;
548         vuint32_t       cfsr;
549         vuint32_t       hfsr;
550
551         vuint32_t       dfsr;
552         vuint32_t       mmcar;
553         vuint32_t       bcar;
554         vuint32_t       afsr;
555
556         vuint32_t       id_pfr0;
557         vuint32_t       id_pfr1;
558         vuint32_t       id_dfr0;
559         vuint32_t       id_afr0;
560
561         vuint32_t       id_mmfr0;
562         vuint32_t       id_mmfr1;
563         vuint32_t       id_mmfr2;
564         vuint32_t       id_mmfr3;
565
566         vuint32_t       id_isar0;
567         vuint32_t       id_isar1;
568         vuint32_t       id_isar2;
569         vuint32_t       id_isar3;
570
571         vuint32_t       id_isar4;
572         vuint32_t       pad_d74;
573         vuint32_t       pad_d78;
574         vuint32_t       pad_d7c;
575
576         vuint32_t       pad_d80;
577         vuint32_t       pad_d84;
578         vuint32_t       cpacr;
579         vuint32_t       pad_d8c;
580
581         vuint8_t        pad_d90[0xf00 - 0xd90];
582
583         vuint32_t       stir;
584 };
585
586 extern struct stm_scb stm_scb;
587
588 #define stm_scb (*((struct stm_scb *) 0xe000ed00))
589
590 #define STM_SCB_CPACR_CP(n)     ((n) <<1)
591 #define  STM_SCB_CPACR_DENIED           0
592 #define  STM_SCB_CPACR_PRIVILEGED       1
593 #define  STM_SCB_CPACR_RESERVED         2
594 #define  STM_SCB_CPACR_FULL             3
595 #define STM_SCB_CPACR_FP0       STM_SCB_CPACR_CP(10)
596 #define STM_SCB_CPACR_FP1       STM_SCB_CPACR_CP(11)
597
598 /* The SYSTICK starts at 0xe000e010 */
599
600 struct stm_systick {
601         vuint32_t       csr;
602         vuint32_t       rvr;
603         vuint32_t       cvr;
604         vuint32_t       calib;
605 };
606
607 extern struct stm_systick stm_systick;
608
609 #define stm_systick     (*((struct stm_systick *) 0xe000e010))
610
611 #define STM_SYSTICK_CSR_ENABLE          0
612 #define STM_SYSTICK_CSR_TICKINT         1
613 #define STM_SYSTICK_CSR_CLKSOURCE       2
614 #define  STM_SYSTICK_CSR_CLKSOURCE_AHB_8                0
615 #define  STM_SYSTICK_CSR_CLKSOURCE_AHB                  1
616 #define STM_SYSTICK_CSR_COUNTFLAG       16
617
618 /* Errata 2.1.5
619
620    Delay after an RCC peripheral clock enabling
621
622    Description
623
624    A delay between an RCC peripheral clock enable and the effective
625    peripheral enabling should be taken into account in order to manage
626    the peripheral read/write to registers.
627
628    This delay depends on the peripheral’s mapping:
629
630    • If the peripheral is mapped on AHB: the delay should be equal to
631      2 AHB cycles.
632
633    • If the peripheral is mapped on APB: the delay should be equal to
634      1 + (AHB/APB prescaler) cycles.
635
636    Workarounds
637
638    1. Use the DSB instruction to stall the Cortex-M4 CPU pipeline
639       until the instruction is completed.
640
641    2. Insert “n” NOPs between the RCC enable bit write and the
642       peripheral register writes
643 */
644
645 static inline void
646 stm32f4_set_rcc(uint32_t *rcc, uint32_t value)
647 {
648         *rcc = value;
649         asm("dsb");
650 }
651
652 /* Errata 2.1.8
653
654    In some specific cases, DMA2 data corruption occurs when managing
655    AHB and APB2 peripherals in a concurrent way
656
657    Description
658
659    When the DMA2 is managing concurrent requests of AHB and APB2
660    peripherals, the transfer on the AHB could be performed several
661    times.
662
663    Impacted peripheral are:
664
665    • Quad-SPI: indirect mode read and write transfers
666
667    • FSMC: read and write operation with external device having FIFO
668
669    • GPIO: DMA2 transfers to GPIO registers (in memory-to-peripheral
670      transfer mode).The transfers from GPIOs register are not
671      impacted.
672
673
674    The data corruption is due to multiple DMA2 accesses over AHB
675    peripheral port impacting peripherals embedding a FIFO.
676
677    For transfer to the internal SRAM through the DMA2 AHB peripheral
678    port the accesses could be performed several times but without data
679    corruptions in cases of concurrent requests.
680
681    Workaround
682
683    • The DMA2 AHB memory port must be used when reading/writing
684      from/to Quad-SPI and FSMC instead of DMA2 AHB default peripheral
685      port.
686
687    • The DMA2 AHB memory port must be used when writing to GPIOs
688      instead of DMA2 AHB default peripheral port.
689
690    Refer to application note AN4031 section “Take benefits of DMA2
691    controller and system architecture flexibility” for more details
692    about DMA controller feature.
693
694 */
695
696
697
698 #endif /* _STM32F4_H_ */