2 * STM32L4X5 RCC (Reset and clock control)
4 * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5 * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
7 * SPDX-License-Identifier: GPL-2.0-or-later
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
12 * The reference used is the STMicroElectronics RM0351 Reference manual
13 * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
15 * Inspired by the BCM2835 CPRMAN clock manager implementation by Luc Michel.
18 #include "qemu/osdep.h"
20 #include "qemu/module.h"
21 #include "qemu/timer.h"
22 #include "qapi/error.h"
23 #include "migration/vmstate.h"
24 #include "hw/misc/stm32l4x5_rcc.h"
25 #include "hw/misc/stm32l4x5_rcc_internals.h"
28 #include "hw/qdev-clock.h"
29 #include "hw/qdev-properties.h"
30 #include "hw/qdev-properties-system.h"
31 #include "hw/registerfields.h"
34 #define HSE_DEFAULT_FRQ 48000000ULL
35 #define HSI_FRQ 16000000ULL
36 #define MSI_DEFAULT_FRQ 4000000ULL
37 #define LSE_FRQ 32768ULL
38 #define LSI_FRQ 32000ULL
41 * Function to simply acknowledge and propagate changes in a clock mux
43 * `bypass_source` allows to bypass the period of the current source and just
44 * consider it equal to 0. This is useful during the hold phase of reset.
46 static void clock_mux_update(RccClockMuxState
*mux
, bool bypass_source
)
49 Clock
*current_source
= mux
->srcs
[mux
->src
];
50 uint32_t freq_multiplier
= 0;
51 bool clk_changed
= false;
54 * To avoid rounding errors, we use the clock period instead of the
56 * This means that the multiplier of the mux becomes the divider of
57 * the clock and the divider of the mux becomes the multiplier of the
60 if (!bypass_source
&& mux
->enabled
&& mux
->divider
) {
61 freq_multiplier
= mux
->divider
;
64 clk_changed
|= clock_set_mul_div(mux
->out
, freq_multiplier
, mux
->multiplier
);
65 clk_changed
|= clock_set(mux
->out
, clock_get(current_source
));
67 clock_propagate(mux
->out
);
70 src_freq
= clock_get_hz(current_source
);
71 /* TODO: can we simply detect if the config changed so that we reduce log spam ? */
72 trace_stm32l4x5_rcc_mux_update(mux
->id
, mux
->src
, src_freq
,
73 mux
->multiplier
, mux
->divider
);
76 static void clock_mux_src_update(void *opaque
, ClockEvent event
)
78 RccClockMuxState
**backref
= opaque
;
79 RccClockMuxState
*s
= *backref
;
81 * The backref value is equal to:
82 * s->backref + (sizeof(RccClockMuxState *) * update_src).
83 * By subtracting we can get back the index of the updated clock.
85 const uint32_t update_src
= backref
- s
->backref
;
86 /* Only update if the clock that was updated is the current source */
87 if (update_src
== s
->src
) {
88 clock_mux_update(s
, false);
92 static void clock_mux_init(Object
*obj
)
94 RccClockMuxState
*s
= RCC_CLOCK_MUX(obj
);
97 for (i
= 0; i
< RCC_NUM_CLOCK_MUX_SRC
; i
++) {
98 char *name
= g_strdup_printf("srcs[%zu]", i
);
100 s
->srcs
[i
] = qdev_init_clock_in(DEVICE(s
), name
,
101 clock_mux_src_update
,
107 s
->out
= qdev_init_clock_out(DEVICE(s
), "out");
110 static void clock_mux_reset_enter(Object
*obj
, ResetType type
)
112 RccClockMuxState
*s
= RCC_CLOCK_MUX(obj
);
113 set_clock_mux_init_info(s
, s
->id
);
116 static void clock_mux_reset_hold(Object
*obj
, ResetType type
)
118 RccClockMuxState
*s
= RCC_CLOCK_MUX(obj
);
119 clock_mux_update(s
, true);
122 static void clock_mux_reset_exit(Object
*obj
, ResetType type
)
124 RccClockMuxState
*s
= RCC_CLOCK_MUX(obj
);
125 clock_mux_update(s
, false);
128 static const VMStateDescription clock_mux_vmstate
= {
129 .name
= TYPE_RCC_CLOCK_MUX
,
131 .minimum_version_id
= 1,
132 .fields
= (VMStateField
[]) {
133 VMSTATE_UINT32(id
, RccClockMuxState
),
134 VMSTATE_ARRAY_CLOCK(srcs
, RccClockMuxState
,
135 RCC_NUM_CLOCK_MUX_SRC
),
136 VMSTATE_BOOL(enabled
, RccClockMuxState
),
137 VMSTATE_UINT32(src
, RccClockMuxState
),
138 VMSTATE_UINT32(multiplier
, RccClockMuxState
),
139 VMSTATE_UINT32(divider
, RccClockMuxState
),
140 VMSTATE_END_OF_LIST()
144 static void clock_mux_class_init(ObjectClass
*klass
, void *data
)
146 DeviceClass
*dc
= DEVICE_CLASS(klass
);
147 ResettableClass
*rc
= RESETTABLE_CLASS(klass
);
149 rc
->phases
.enter
= clock_mux_reset_enter
;
150 rc
->phases
.hold
= clock_mux_reset_hold
;
151 rc
->phases
.exit
= clock_mux_reset_exit
;
152 dc
->vmsd
= &clock_mux_vmstate
;
155 static void clock_mux_set_enable(RccClockMuxState
*mux
, bool enabled
)
157 if (mux
->enabled
== enabled
) {
162 trace_stm32l4x5_rcc_mux_enable(mux
->id
);
164 trace_stm32l4x5_rcc_mux_disable(mux
->id
);
167 mux
->enabled
= enabled
;
168 clock_mux_update(mux
, false);
171 static void clock_mux_set_factor(RccClockMuxState
*mux
,
172 uint32_t multiplier
, uint32_t divider
)
174 if (mux
->multiplier
== multiplier
&& mux
->divider
== divider
) {
177 trace_stm32l4x5_rcc_mux_set_factor(mux
->id
,
178 mux
->multiplier
, multiplier
, mux
->divider
, divider
);
180 mux
->multiplier
= multiplier
;
181 mux
->divider
= divider
;
182 clock_mux_update(mux
, false);
185 static void clock_mux_set_source(RccClockMuxState
*mux
, RccClockMuxSource src
)
187 if (mux
->src
== src
) {
191 trace_stm32l4x5_rcc_mux_set_src(mux
->id
, mux
->src
, src
);
193 clock_mux_update(mux
, false);
197 * Acknowledge and propagate changes in a PLL frequency.
198 * `bypass_source` allows to bypass the period of the current source and just
199 * consider it equal to 0. This is useful during the hold phase of reset.
201 static void pll_update(RccPllState
*pll
, bool bypass_source
)
203 uint64_t vco_freq
, old_channel_freq
, channel_freq
;
206 /* The common PLLM factor is handled by the PLL mux */
207 vco_freq
= muldiv64(clock_get_hz(pll
->in
), pll
->vco_multiplier
, 1);
209 for (i
= 0; i
< RCC_NUM_CHANNEL_PLL_OUT
; i
++) {
210 if (!pll
->channel_exists
[i
]) {
214 old_channel_freq
= clock_get_hz(pll
->channels
[i
]);
217 !pll
->channel_enabled
[i
] ||
218 !pll
->channel_divider
[i
]) {
221 channel_freq
= muldiv64(vco_freq
,
223 pll
->channel_divider
[i
]);
226 /* No change, early continue to avoid log spam and useless propagation */
227 if (old_channel_freq
== channel_freq
) {
231 clock_update_hz(pll
->channels
[i
], channel_freq
);
232 trace_stm32l4x5_rcc_pll_update(pll
->id
, i
, vco_freq
,
233 old_channel_freq
, channel_freq
);
237 static void pll_src_update(void *opaque
, ClockEvent event
)
239 RccPllState
*s
= opaque
;
240 pll_update(s
, false);
243 static void pll_init(Object
*obj
)
245 RccPllState
*s
= RCC_PLL(obj
);
248 s
->in
= qdev_init_clock_in(DEVICE(s
), "in",
249 pll_src_update
, s
, ClockUpdate
);
251 const char *names
[] = {
252 "out-p", "out-q", "out-r",
255 for (i
= 0; i
< RCC_NUM_CHANNEL_PLL_OUT
; i
++) {
256 s
->channels
[i
] = qdev_init_clock_out(DEVICE(s
), names
[i
]);
260 static void pll_reset_enter(Object
*obj
, ResetType type
)
262 RccPllState
*s
= RCC_PLL(obj
);
263 set_pll_init_info(s
, s
->id
);
266 static void pll_reset_hold(Object
*obj
, ResetType type
)
268 RccPllState
*s
= RCC_PLL(obj
);
272 static void pll_reset_exit(Object
*obj
, ResetType type
)
274 RccPllState
*s
= RCC_PLL(obj
);
275 pll_update(s
, false);
278 static const VMStateDescription pll_vmstate
= {
279 .name
= TYPE_RCC_PLL
,
281 .minimum_version_id
= 1,
282 .fields
= (VMStateField
[]) {
283 VMSTATE_UINT32(id
, RccPllState
),
284 VMSTATE_CLOCK(in
, RccPllState
),
285 VMSTATE_ARRAY_CLOCK(channels
, RccPllState
,
286 RCC_NUM_CHANNEL_PLL_OUT
),
287 VMSTATE_BOOL(enabled
, RccPllState
),
288 VMSTATE_UINT32(vco_multiplier
, RccPllState
),
289 VMSTATE_BOOL_ARRAY(channel_enabled
, RccPllState
, RCC_NUM_CHANNEL_PLL_OUT
),
290 VMSTATE_BOOL_ARRAY(channel_exists
, RccPllState
, RCC_NUM_CHANNEL_PLL_OUT
),
291 VMSTATE_UINT32_ARRAY(channel_divider
, RccPllState
, RCC_NUM_CHANNEL_PLL_OUT
),
292 VMSTATE_END_OF_LIST()
296 static void pll_class_init(ObjectClass
*klass
, void *data
)
298 DeviceClass
*dc
= DEVICE_CLASS(klass
);
299 ResettableClass
*rc
= RESETTABLE_CLASS(klass
);
301 rc
->phases
.enter
= pll_reset_enter
;
302 rc
->phases
.hold
= pll_reset_hold
;
303 rc
->phases
.exit
= pll_reset_exit
;
304 dc
->vmsd
= &pll_vmstate
;
307 static void pll_set_vco_multiplier(RccPllState
*pll
, uint32_t vco_multiplier
)
309 if (pll
->vco_multiplier
== vco_multiplier
) {
313 if (vco_multiplier
< 8 || vco_multiplier
> 86) {
314 qemu_log_mask(LOG_GUEST_ERROR
,
315 "%s: VCO multiplier is out of bound (%u) for PLL %u\n",
316 __func__
, vco_multiplier
, pll
->id
);
320 trace_stm32l4x5_rcc_pll_set_vco_multiplier(pll
->id
,
321 pll
->vco_multiplier
, vco_multiplier
);
323 pll
->vco_multiplier
= vco_multiplier
;
324 pll_update(pll
, false);
327 static void pll_set_enable(RccPllState
*pll
, bool enabled
)
329 if (pll
->enabled
== enabled
) {
333 pll
->enabled
= enabled
;
334 pll_update(pll
, false);
337 static void pll_set_channel_enable(RccPllState
*pll
,
338 PllCommonChannels channel
,
341 if (pll
->channel_enabled
[channel
] == enabled
) {
346 trace_stm32l4x5_rcc_pll_channel_enable(pll
->id
, channel
);
348 trace_stm32l4x5_rcc_pll_channel_disable(pll
->id
, channel
);
351 pll
->channel_enabled
[channel
] = enabled
;
352 pll_update(pll
, false);
355 static void pll_set_channel_divider(RccPllState
*pll
,
356 PllCommonChannels channel
,
359 if (pll
->channel_divider
[channel
] == divider
) {
363 trace_stm32l4x5_rcc_pll_set_channel_divider(pll
->id
,
364 channel
, pll
->channel_divider
[channel
], divider
);
366 pll
->channel_divider
[channel
] = divider
;
367 pll_update(pll
, false);
370 static void rcc_update_irq(Stm32l4x5RccState
*s
)
373 * TODO: Handle LSECSSF and CSSF flags when the CSS is implemented.
375 if (s
->cifr
& CIFR_IRQ_MASK
) {
376 qemu_irq_raise(s
->irq
);
378 qemu_irq_lower(s
->irq
);
382 static void rcc_update_msi(Stm32l4x5RccState
*s
, uint32_t previous_value
)
386 static const uint32_t msirange
[] = {
387 100000, 200000, 400000, 800000, 1000000, 2000000,
388 4000000, 8000000, 16000000, 24000000, 32000000, 48000000
390 /* MSIRANGE and MSIRGSEL */
391 val
= extract32(s
->cr
, R_CR_MSIRGSEL_SHIFT
, R_CR_MSIRGSEL_LENGTH
);
393 /* MSIRGSEL is set, use the MSIRANGE field */
394 val
= extract32(s
->cr
, R_CR_MSIRANGE_SHIFT
, R_CR_MSIRANGE_LENGTH
);
396 /* MSIRGSEL is not set, use the MSISRANGE field */
397 val
= extract32(s
->csr
, R_CSR_MSISRANGE_SHIFT
, R_CSR_MSISRANGE_LENGTH
);
400 if (val
< ARRAY_SIZE(msirange
)) {
401 clock_update_hz(s
->msi_rc
, msirange
[val
]);
404 * There is a hardware write protection if the value is out of bound.
405 * Restore the previous value.
407 s
->cr
= (s
->cr
& ~R_CSR_MSISRANGE_MASK
) |
408 (previous_value
& R_CSR_MSISRANGE_MASK
);
413 * TODO: Add write-protection for all registers:
417 static void rcc_update_cr_register(Stm32l4x5RccState
*s
, uint32_t previous_value
)
420 const RccClockMuxSource current_pll_src
=
421 CLOCK_MUX_INIT_INFO
[RCC_CLOCK_MUX_PLL_INPUT
].src_mapping
[
422 s
->clock_muxes
[RCC_CLOCK_MUX_PLL_INPUT
].src
];
424 /* PLLSAI2ON and update PLLSAI2RDY */
425 val
= FIELD_EX32(s
->cr
, CR
, PLLSAI2ON
);
426 pll_set_enable(&s
->plls
[RCC_PLL_PLLSAI2
], val
);
427 s
->cr
= (s
->cr
& ~R_CR_PLLSAI2RDY_MASK
) |
428 (val
<< R_CR_PLLSAI2RDY_SHIFT
);
429 if (s
->cier
& R_CIER_PLLSAI2RDYIE_MASK
) {
430 s
->cifr
|= R_CIFR_PLLSAI2RDYF_MASK
;
433 /* PLLSAI1ON and update PLLSAI1RDY */
434 val
= FIELD_EX32(s
->cr
, CR
, PLLSAI1ON
);
435 pll_set_enable(&s
->plls
[RCC_PLL_PLLSAI1
], val
);
436 s
->cr
= (s
->cr
& ~R_CR_PLLSAI1RDY_MASK
) |
437 (val
<< R_CR_PLLSAI1RDY_SHIFT
);
438 if (s
->cier
& R_CIER_PLLSAI1RDYIE_MASK
) {
439 s
->cifr
|= R_CIFR_PLLSAI1RDYF_MASK
;
443 * PLLON and update PLLRDY
444 * PLLON cannot be reset if the PLL clock is used as the system clock.
446 val
= FIELD_EX32(s
->cr
, CR
, PLLON
);
447 if (FIELD_EX32(s
->cfgr
, CFGR
, SWS
) != 0b11) {
448 pll_set_enable(&s
->plls
[RCC_PLL_PLL
], val
);
449 s
->cr
= (s
->cr
& ~R_CR_PLLRDY_MASK
) |
450 (val
<< R_CR_PLLRDY_SHIFT
);
451 if (s
->cier
& R_CIER_PLLRDYIE_MASK
) {
452 s
->cifr
|= R_CIFR_PLLRDYF_MASK
;
455 s
->cr
|= R_CR_PLLON_MASK
;
462 * HSEON and update HSERDY.
463 * HSEON cannot be reset if the HSE oscillator is used directly or
464 * indirectly as the system clock.
466 val
= FIELD_EX32(s
->cr
, CR
, HSEON
);
467 if (FIELD_EX32(s
->cfgr
, CFGR
, SWS
) != 0b10 &&
468 current_pll_src
!= RCC_CLOCK_MUX_SRC_HSE
) {
469 s
->cr
= (s
->cr
& ~R_CR_HSERDY_MASK
) |
470 (val
<< R_CR_HSERDY_SHIFT
);
472 clock_update_hz(s
->hse
, s
->hse_frequency
);
473 if (s
->cier
& R_CIER_HSERDYIE_MASK
) {
474 s
->cifr
|= R_CIFR_HSERDYF_MASK
;
477 clock_update(s
->hse
, 0);
480 s
->cr
|= R_CR_HSEON_MASK
;
487 * HSION and update HSIRDY
488 * HSION is set by hardware if the HSI16 is used directly
489 * or indirectly as system clock.
491 if (FIELD_EX32(s
->cfgr
, CFGR
, SWS
) == 0b01 ||
492 current_pll_src
== RCC_CLOCK_MUX_SRC_HSI
) {
493 s
->cr
|= (R_CR_HSION_MASK
| R_CR_HSIRDY_MASK
);
494 clock_update_hz(s
->hsi16_rc
, HSI_FRQ
);
495 if (s
->cier
& R_CIER_HSIRDYIE_MASK
) {
496 s
->cifr
|= R_CIFR_HSIRDYF_MASK
;
499 val
= FIELD_EX32(s
->cr
, CR
, HSION
);
501 clock_update_hz(s
->hsi16_rc
, HSI_FRQ
);
502 s
->cr
|= R_CR_HSIRDY_MASK
;
503 if (s
->cier
& R_CIER_HSIRDYIE_MASK
) {
504 s
->cifr
|= R_CIFR_HSIRDYF_MASK
;
507 clock_update(s
->hsi16_rc
, 0);
508 s
->cr
&= ~R_CR_HSIRDY_MASK
;
515 * MSION and update MSIRDY
516 * Set by hardware when used directly or indirectly as system clock.
518 if (FIELD_EX32(s
->cfgr
, CFGR
, SWS
) == 0b00 ||
519 current_pll_src
== RCC_CLOCK_MUX_SRC_MSI
) {
520 s
->cr
|= (R_CR_MSION_MASK
| R_CR_MSIRDY_MASK
);
521 if (!(previous_value
& R_CR_MSION_MASK
) && (s
->cier
& R_CIER_MSIRDYIE_MASK
)) {
522 s
->cifr
|= R_CIFR_MSIRDYF_MASK
;
524 rcc_update_msi(s
, previous_value
);
526 val
= FIELD_EX32(s
->cr
, CR
, MSION
);
528 s
->cr
|= R_CR_MSIRDY_MASK
;
529 rcc_update_msi(s
, previous_value
);
530 if (s
->cier
& R_CIER_MSIRDYIE_MASK
) {
531 s
->cifr
|= R_CIFR_MSIRDYF_MASK
;
534 s
->cr
&= ~R_CR_MSIRDY_MASK
;
535 clock_update(s
->msi_rc
, 0);
541 static void rcc_update_cfgr_register(Stm32l4x5RccState
*s
)
545 val
= FIELD_EX32(s
->cfgr
, CFGR
, MCOPRE
);
547 qemu_log_mask(LOG_GUEST_ERROR
,
548 "%s: Invalid MCOPRE value: 0x%"PRIx32
"\n",
550 clock_mux_set_enable(&s
->clock_muxes
[RCC_CLOCK_MUX_MCO
], false);
552 clock_mux_set_factor(&s
->clock_muxes
[RCC_CLOCK_MUX_MCO
],
557 val
= FIELD_EX32(s
->cfgr
, CFGR
, MCOSEL
);
559 qemu_log_mask(LOG_GUEST_ERROR
,
560 "%s: Invalid MCOSEL value: 0x%"PRIx32
"\n",
562 clock_mux_set_enable(&s
->clock_muxes
[RCC_CLOCK_MUX_MCO
], false);
565 clock_mux_set_enable(&s
->clock_muxes
[RCC_CLOCK_MUX_MCO
], false);
567 clock_mux_set_enable(&s
->clock_muxes
[RCC_CLOCK_MUX_MCO
], true);
568 clock_mux_set_source(&s
->clock_muxes
[RCC_CLOCK_MUX_MCO
],
577 val
= FIELD_EX32(s
->cfgr
, CFGR
, PPRE2
);
579 clock_mux_set_factor(&s
->clock_muxes
[RCC_CLOCK_MUX_PCLK2
],
582 clock_mux_set_factor(&s
->clock_muxes
[RCC_CLOCK_MUX_PCLK2
],
583 1, 1 << (val
- 0b11));
587 val
= FIELD_EX32(s
->cfgr
, CFGR
, PPRE1
);
589 clock_mux_set_factor(&s
->clock_muxes
[RCC_CLOCK_MUX_PCLK1
],
592 clock_mux_set_factor(&s
->clock_muxes
[RCC_CLOCK_MUX_PCLK1
],
593 1, 1 << (val
- 0b11));
597 val
= FIELD_EX32(s
->cfgr
, CFGR
, HPRE
);
599 clock_mux_set_factor(&s
->clock_muxes
[RCC_CLOCK_MUX_HCLK
],
602 clock_mux_set_factor(&s
->clock_muxes
[RCC_CLOCK_MUX_HCLK
],
603 1, 1 << (val
- 0b111));
607 val
= FIELD_EX32(s
->cfgr
, CFGR
, SW
);
608 clock_mux_set_source(&s
->clock_muxes
[RCC_CLOCK_MUX_SYSCLK
],
610 s
->cfgr
&= ~R_CFGR_SWS_MASK
;
611 s
->cfgr
|= val
<< R_CFGR_SWS_SHIFT
;
614 static void rcc_update_ahb1enr(Stm32l4x5RccState
*s
)
616 #define AHB1ENR_SET_ENABLE(_peripheral_name) \
617 clock_mux_set_enable(&s->clock_muxes[RCC_CLOCK_MUX_##_peripheral_name], \
618 FIELD_EX32(s->ahb1enr, AHB1ENR, _peripheral_name##EN))
620 /* DMA2DEN: reserved for STM32L475xx */
621 AHB1ENR_SET_ENABLE(TSC
);
622 AHB1ENR_SET_ENABLE(CRC
);
623 AHB1ENR_SET_ENABLE(FLASH
);
624 AHB1ENR_SET_ENABLE(DMA2
);
625 AHB1ENR_SET_ENABLE(DMA1
);
627 #undef AHB1ENR_SET_ENABLE
630 static void rcc_update_ahb2enr(Stm32l4x5RccState
*s
)
632 #define AHB2ENR_SET_ENABLE(_peripheral_name) \
633 clock_mux_set_enable(&s->clock_muxes[RCC_CLOCK_MUX_##_peripheral_name], \
634 FIELD_EX32(s->ahb2enr, AHB2ENR, _peripheral_name##EN))
636 AHB2ENR_SET_ENABLE(RNG
);
637 /* HASHEN: reserved for STM32L475xx */
638 AHB2ENR_SET_ENABLE(AES
);
639 /* DCMIEN: reserved for STM32L475xx */
640 AHB2ENR_SET_ENABLE(ADC
);
641 AHB2ENR_SET_ENABLE(OTGFS
);
642 /* GPIOIEN: reserved for STM32L475xx */
643 AHB2ENR_SET_ENABLE(GPIOA
);
644 AHB2ENR_SET_ENABLE(GPIOB
);
645 AHB2ENR_SET_ENABLE(GPIOC
);
646 AHB2ENR_SET_ENABLE(GPIOD
);
647 AHB2ENR_SET_ENABLE(GPIOE
);
648 AHB2ENR_SET_ENABLE(GPIOF
);
649 AHB2ENR_SET_ENABLE(GPIOG
);
650 AHB2ENR_SET_ENABLE(GPIOH
);
652 #undef AHB2ENR_SET_ENABLE
655 static void rcc_update_ahb3enr(Stm32l4x5RccState
*s
)
657 #define AHB3ENR_SET_ENABLE(_peripheral_name) \
658 clock_mux_set_enable(&s->clock_muxes[RCC_CLOCK_MUX_##_peripheral_name], \
659 FIELD_EX32(s->ahb3enr, AHB3ENR, _peripheral_name##EN))
661 AHB3ENR_SET_ENABLE(QSPI
);
662 AHB3ENR_SET_ENABLE(FMC
);
664 #undef AHB3ENR_SET_ENABLE
667 static void rcc_update_apb1enr(Stm32l4x5RccState
*s
)
669 #define APB1ENR1_SET_ENABLE(_peripheral_name) \
670 clock_mux_set_enable(&s->clock_muxes[RCC_CLOCK_MUX_##_peripheral_name], \
671 FIELD_EX32(s->apb1enr1, APB1ENR1, _peripheral_name##EN))
672 #define APB1ENR2_SET_ENABLE(_peripheral_name) \
673 clock_mux_set_enable(&s->clock_muxes[RCC_CLOCK_MUX_##_peripheral_name], \
674 FIELD_EX32(s->apb1enr2, APB1ENR2, _peripheral_name##EN))
677 APB1ENR1_SET_ENABLE(LPTIM1
);
678 APB1ENR1_SET_ENABLE(OPAMP
);
679 APB1ENR1_SET_ENABLE(DAC1
);
680 APB1ENR1_SET_ENABLE(PWR
);
681 /* CAN2: reserved for STM32L4x5 */
682 APB1ENR1_SET_ENABLE(CAN1
);
683 /* CRSEN: reserved for STM32L4x5 */
684 APB1ENR1_SET_ENABLE(I2C3
);
685 APB1ENR1_SET_ENABLE(I2C2
);
686 APB1ENR1_SET_ENABLE(I2C1
);
687 APB1ENR1_SET_ENABLE(UART5
);
688 APB1ENR1_SET_ENABLE(UART4
);
689 APB1ENR1_SET_ENABLE(USART3
);
690 APB1ENR1_SET_ENABLE(USART2
);
691 APB1ENR1_SET_ENABLE(SPI3
);
692 APB1ENR1_SET_ENABLE(SPI2
);
693 APB1ENR1_SET_ENABLE(WWDG
);
694 /* RTCAPB: reserved for STM32L4x5 */
695 APB1ENR1_SET_ENABLE(LCD
);
696 APB1ENR1_SET_ENABLE(TIM7
);
697 APB1ENR1_SET_ENABLE(TIM6
);
698 APB1ENR1_SET_ENABLE(TIM5
);
699 APB1ENR1_SET_ENABLE(TIM4
);
700 APB1ENR1_SET_ENABLE(TIM3
);
701 APB1ENR1_SET_ENABLE(TIM2
);
704 APB1ENR2_SET_ENABLE(LPTIM2
);
705 APB1ENR2_SET_ENABLE(SWPMI1
);
706 /* I2C4EN: reserved for STM32L4x5 */
707 APB1ENR2_SET_ENABLE(LPUART1
);
709 #undef APB1ENR1_SET_ENABLE
710 #undef APB1ENR2_SET_ENABLE
713 static void rcc_update_apb2enr(Stm32l4x5RccState
*s
)
715 #define APB2ENR_SET_ENABLE(_peripheral_name) \
716 clock_mux_set_enable(&s->clock_muxes[RCC_CLOCK_MUX_##_peripheral_name], \
717 FIELD_EX32(s->apb2enr, APB2ENR, _peripheral_name##EN))
719 APB2ENR_SET_ENABLE(DFSDM1
);
720 APB2ENR_SET_ENABLE(SAI2
);
721 APB2ENR_SET_ENABLE(SAI1
);
722 APB2ENR_SET_ENABLE(TIM17
);
723 APB2ENR_SET_ENABLE(TIM16
);
724 APB2ENR_SET_ENABLE(TIM15
);
725 APB2ENR_SET_ENABLE(USART1
);
726 APB2ENR_SET_ENABLE(TIM8
);
727 APB2ENR_SET_ENABLE(SPI1
);
728 APB2ENR_SET_ENABLE(TIM1
);
729 APB2ENR_SET_ENABLE(SDMMC1
);
730 APB2ENR_SET_ENABLE(FW
);
731 APB2ENR_SET_ENABLE(SYSCFG
);
733 #undef APB2ENR_SET_ENABLE
737 * The 3 PLLs share the same register layout
738 * so we can use the same function for all of them
739 * Note: no frequency bounds checking is done here.
741 static void rcc_update_pllsaixcfgr(Stm32l4x5RccState
*s
, RccPll pll_id
)
748 case RCC_PLL_PLLSAI1
:
749 reg
= s
->pllsai1cfgr
;
751 case RCC_PLL_PLLSAI2
:
752 reg
= s
->pllsai2cfgr
;
755 qemu_log_mask(LOG_GUEST_ERROR
,
756 "%s: Invalid PLL ID: %u\n", __func__
, pll_id
);
761 val
= FIELD_EX32(reg
, PLLCFGR
, PLLPDIV
);
762 /* 1 is a reserved value */
765 val
= FIELD_EX32(reg
, PLLCFGR
, PLLP
);
766 pll_set_channel_divider(&s
->plls
[pll_id
], RCC_PLL_COMMON_CHANNEL_P
,
768 } else if (val
> 1) {
769 pll_set_channel_divider(&s
->plls
[pll_id
], RCC_PLL_COMMON_CHANNEL_P
,
775 val
= FIELD_EX32(reg
, PLLCFGR
, PLLR
);
776 pll_set_channel_divider(&s
->plls
[pll_id
], RCC_PLL_COMMON_CHANNEL_R
,
780 val
= FIELD_EX32(reg
, PLLCFGR
, PLLREN
);
781 pll_set_channel_enable(&s
->plls
[pll_id
], RCC_PLL_COMMON_CHANNEL_R
, val
);
784 val
= FIELD_EX32(reg
, PLLCFGR
, PLLQ
);
785 pll_set_channel_divider(&s
->plls
[pll_id
], RCC_PLL_COMMON_CHANNEL_Q
,
789 val
= FIELD_EX32(reg
, PLLCFGR
, PLLQEN
);
790 pll_set_channel_enable(&s
->plls
[pll_id
], RCC_PLL_COMMON_CHANNEL_Q
, val
);
793 val
= FIELD_EX32(reg
, PLLCFGR
, PLLPEN
);
794 pll_set_channel_enable(&s
->plls
[pll_id
], RCC_PLL_COMMON_CHANNEL_P
, val
);
797 val
= FIELD_EX32(reg
, PLLCFGR
, PLLN
);
798 pll_set_vco_multiplier(&s
->plls
[pll_id
], val
);
801 static void rcc_update_pllcfgr(Stm32l4x5RccState
*s
)
805 /* Use common layout */
806 rcc_update_pllsaixcfgr(s
, RCC_PLL_PLL
);
808 /* Fetch specific fields for pllcfgr */
811 val
= FIELD_EX32(s
->pllcfgr
, PLLCFGR
, PLLM
);
812 clock_mux_set_factor(&s
->clock_muxes
[RCC_CLOCK_MUX_PLL_INPUT
], 1, (val
+ 1));
815 val
= FIELD_EX32(s
->pllcfgr
, PLLCFGR
, PLLSRC
);
817 clock_mux_set_enable(&s
->clock_muxes
[RCC_CLOCK_MUX_PLL_INPUT
], false);
819 clock_mux_set_source(&s
->clock_muxes
[RCC_CLOCK_MUX_PLL_INPUT
], val
- 1);
820 clock_mux_set_enable(&s
->clock_muxes
[RCC_CLOCK_MUX_PLL_INPUT
], true);
824 static void rcc_update_ccipr(Stm32l4x5RccState
*s
)
826 #define CCIPR_SET_SOURCE(_peripheral_name) \
827 clock_mux_set_source(&s->clock_muxes[RCC_CLOCK_MUX_##_peripheral_name], \
828 FIELD_EX32(s->ccipr, CCIPR, _peripheral_name##SEL))
830 CCIPR_SET_SOURCE(DFSDM1
);
831 CCIPR_SET_SOURCE(SWPMI1
);
832 CCIPR_SET_SOURCE(ADC
);
833 CCIPR_SET_SOURCE(CLK48
);
834 CCIPR_SET_SOURCE(SAI2
);
835 CCIPR_SET_SOURCE(SAI1
);
836 CCIPR_SET_SOURCE(LPTIM2
);
837 CCIPR_SET_SOURCE(LPTIM1
);
838 CCIPR_SET_SOURCE(I2C3
);
839 CCIPR_SET_SOURCE(I2C2
);
840 CCIPR_SET_SOURCE(I2C1
);
841 CCIPR_SET_SOURCE(LPUART1
);
842 CCIPR_SET_SOURCE(UART5
);
843 CCIPR_SET_SOURCE(UART4
);
844 CCIPR_SET_SOURCE(USART3
);
845 CCIPR_SET_SOURCE(USART2
);
846 CCIPR_SET_SOURCE(USART1
);
848 #undef CCIPR_SET_SOURCE
851 static void rcc_update_bdcr(Stm32l4x5RccState
*s
)
856 val
= FIELD_EX32(s
->bdcr
, BDCR
, LSCOSEL
);
857 clock_mux_set_source(&s
->clock_muxes
[RCC_CLOCK_MUX_LSCO
], val
);
859 val
= FIELD_EX32(s
->bdcr
, BDCR
, LSCOEN
);
860 clock_mux_set_enable(&s
->clock_muxes
[RCC_CLOCK_MUX_LSCO
], val
);
864 * The documentation is not clear if the RTCEN flag disables the RTC and
865 * the LCD common mux or if it only affects the RTC.
866 * As the LCDEN flag exists, we assume here that it only affects the RTC.
868 val
= FIELD_EX32(s
->bdcr
, BDCR
, RTCEN
);
869 clock_mux_set_enable(&s
->clock_muxes
[RCC_CLOCK_MUX_RTC
], val
);
870 /* LCD and RTC share the same clock */
871 val
= FIELD_EX32(s
->bdcr
, BDCR
, RTCSEL
);
872 clock_mux_set_source(&s
->clock_muxes
[RCC_CLOCK_MUX_LCD_AND_RTC_COMMON
], val
);
878 /* LSEON: Update LSERDY at the same time */
879 val
= FIELD_EX32(s
->bdcr
, BDCR
, LSEON
);
881 clock_update_hz(s
->lse_crystal
, LSE_FRQ
);
882 s
->bdcr
|= R_BDCR_LSERDY_MASK
;
883 if (s
->cier
& R_CIER_LSERDYIE_MASK
) {
884 s
->cifr
|= R_CIFR_LSERDYF_MASK
;
887 clock_update(s
->lse_crystal
, 0);
888 s
->bdcr
&= ~R_BDCR_LSERDY_MASK
;
894 static void rcc_update_csr(Stm32l4x5RccState
*s
)
898 /* Reset flags: Not implemented */
899 /* MSISRANGE: Not implemented after reset */
901 /* LSION: Update LSIRDY at the same time */
902 val
= FIELD_EX32(s
->csr
, CSR
, LSION
);
904 clock_update_hz(s
->lsi_rc
, LSI_FRQ
);
905 s
->csr
|= R_CSR_LSIRDY_MASK
;
906 if (s
->cier
& R_CIER_LSIRDYIE_MASK
) {
907 s
->cifr
|= R_CIFR_LSIRDYF_MASK
;
911 * TODO: Handle when the LSI is set independently of LSION.
912 * E.g. when the LSI is set by the RTC.
913 * See the reference manual for more details.
915 clock_update(s
->lsi_rc
, 0);
916 s
->csr
&= ~R_CSR_LSIRDY_MASK
;
922 static void stm32l4x5_rcc_reset_hold(Object
*obj
, ResetType type
)
924 Stm32l4x5RccState
*s
= STM32L4X5_RCC(obj
);
927 * Factory-programmed calibration data
928 * From the reference manual: 0x10XX 00XX
929 * Value taken from a real card.
931 s
->icscr
= 0x106E0082;
933 s
->pllcfgr
= 0x00001000;
934 s
->pllsai1cfgr
= 0x00001000;
935 s
->pllsai2cfgr
= 0x00001000;
944 s
->ahb1enr
= 0x00000100;
950 s
->ahb1smenr
= 0x00011303;
951 s
->ahb2smenr
= 0x000532FF;
952 s
->ahb3smenr
= 0x00000101;
953 s
->apb1smenr1
= 0xF2FECA3F;
954 s
->apb1smenr2
= 0x00000025;
955 s
->apb2smenr
= 0x01677C01;
961 static uint64_t stm32l4x5_rcc_read(void *opaque
, hwaddr addr
,
964 Stm32l4x5RccState
*s
= opaque
;
965 uint64_t retvalue
= 0;
978 retvalue
= s
->pllcfgr
;
981 retvalue
= s
->pllsai1cfgr
;
984 retvalue
= s
->pllsai2cfgr
;
993 /* CICR is write only, return the reset value = 0 */
996 retvalue
= s
->ahb1rstr
;
999 retvalue
= s
->ahb2rstr
;
1002 retvalue
= s
->ahb3rstr
;
1005 retvalue
= s
->apb1rstr1
;
1008 retvalue
= s
->apb1rstr2
;
1011 retvalue
= s
->apb2rstr
;
1014 retvalue
= s
->ahb1enr
;
1017 retvalue
= s
->ahb2enr
;
1020 retvalue
= s
->ahb3enr
;
1023 retvalue
= s
->apb1enr1
;
1026 retvalue
= s
->apb1enr2
;
1029 retvalue
= s
->apb2enr
;
1032 retvalue
= s
->ahb1smenr
;
1035 retvalue
= s
->ahb2smenr
;
1038 retvalue
= s
->ahb3smenr
;
1041 retvalue
= s
->apb1smenr1
;
1044 retvalue
= s
->apb1smenr2
;
1047 retvalue
= s
->apb2smenr
;
1050 retvalue
= s
->ccipr
;
1059 qemu_log_mask(LOG_GUEST_ERROR
,
1060 "%s: Bad offset 0x%"HWADDR_PRIx
"\n", __func__
, addr
);
1064 trace_stm32l4x5_rcc_read(addr
, retvalue
);
1069 static void stm32l4x5_rcc_write(void *opaque
, hwaddr addr
,
1070 uint64_t val64
, unsigned int size
)
1072 Stm32l4x5RccState
*s
= opaque
;
1073 uint32_t previous_value
= 0;
1074 const uint32_t value
= val64
;
1076 trace_stm32l4x5_rcc_write(addr
, value
);
1080 previous_value
= s
->cr
;
1081 s
->cr
= (s
->cr
& CR_READ_SET_MASK
) |
1082 (value
& (CR_READ_SET_MASK
| ~CR_READ_ONLY_MASK
));
1083 rcc_update_cr_register(s
, previous_value
);
1086 s
->icscr
= value
& ~ICSCR_READ_ONLY_MASK
;
1087 qemu_log_mask(LOG_UNIMP
,
1088 "%s: Side-effects not implemented for ICSCR\n", __func__
);
1091 s
->cfgr
= value
& ~CFGR_READ_ONLY_MASK
;
1092 rcc_update_cfgr_register(s
);
1096 rcc_update_pllcfgr(s
);
1099 s
->pllsai1cfgr
= value
;
1100 rcc_update_pllsaixcfgr(s
, RCC_PLL_PLLSAI1
);
1103 s
->pllsai2cfgr
= value
;
1104 rcc_update_pllsaixcfgr(s
, RCC_PLL_PLLSAI2
);
1108 qemu_log_mask(LOG_UNIMP
,
1109 "%s: Side-effects not implemented for CIER\n", __func__
);
1112 qemu_log_mask(LOG_GUEST_ERROR
,
1113 "%s: Write attempt into read-only register (CIFR) 0x%"PRIx32
"\n",
1117 /* Clear interrupt flags by writing a 1 to the CICR register */
1121 /* Reset behaviors are not implemented */
1123 s
->ahb1rstr
= value
;
1124 qemu_log_mask(LOG_UNIMP
,
1125 "%s: Side-effects not implemented for AHB1RSTR\n", __func__
);
1128 s
->ahb2rstr
= value
;
1129 qemu_log_mask(LOG_UNIMP
,
1130 "%s: Side-effects not implemented for AHB2RSTR\n", __func__
);
1133 s
->ahb3rstr
= value
;
1134 qemu_log_mask(LOG_UNIMP
,
1135 "%s: Side-effects not implemented for AHB3RSTR\n", __func__
);
1138 s
->apb1rstr1
= value
;
1139 qemu_log_mask(LOG_UNIMP
,
1140 "%s: Side-effects not implemented for APB1RSTR1\n", __func__
);
1143 s
->apb1rstr2
= value
;
1144 qemu_log_mask(LOG_UNIMP
,
1145 "%s: Side-effects not implemented for APB1RSTR2\n", __func__
);
1148 s
->apb2rstr
= value
;
1149 qemu_log_mask(LOG_UNIMP
,
1150 "%s: Side-effects not implemented for APB2RSTR\n", __func__
);
1154 rcc_update_ahb1enr(s
);
1158 rcc_update_ahb2enr(s
);
1162 rcc_update_ahb3enr(s
);
1165 s
->apb1enr1
= value
;
1166 rcc_update_apb1enr(s
);
1169 s
->apb1enr2
= value
;
1170 rcc_update_apb1enr(s
);
1173 s
->apb2enr
= (s
->apb2enr
& APB2ENR_READ_SET_MASK
) | value
;
1174 rcc_update_apb2enr(s
);
1176 /* Behaviors for Sleep and Stop modes are not implemented */
1178 s
->ahb1smenr
= value
;
1179 qemu_log_mask(LOG_UNIMP
,
1180 "%s: Side-effects not implemented for AHB1SMENR\n", __func__
);
1183 s
->ahb2smenr
= value
;
1184 qemu_log_mask(LOG_UNIMP
,
1185 "%s: Side-effects not implemented for AHB2SMENR\n", __func__
);
1188 s
->ahb3smenr
= value
;
1189 qemu_log_mask(LOG_UNIMP
,
1190 "%s: Side-effects not implemented for AHB3SMENR\n", __func__
);
1193 s
->apb1smenr1
= value
;
1194 qemu_log_mask(LOG_UNIMP
,
1195 "%s: Side-effects not implemented for APB1SMENR1\n", __func__
);
1198 s
->apb1smenr2
= value
;
1199 qemu_log_mask(LOG_UNIMP
,
1200 "%s: Side-effects not implemented for APB1SMENR2\n", __func__
);
1203 s
->apb2smenr
= value
;
1204 qemu_log_mask(LOG_UNIMP
,
1205 "%s: Side-effects not implemented for APB2SMENR\n", __func__
);
1209 rcc_update_ccipr(s
);
1212 s
->bdcr
= value
& ~BDCR_READ_ONLY_MASK
;
1216 s
->csr
= value
& ~CSR_READ_ONLY_MASK
;
1220 qemu_log_mask(LOG_GUEST_ERROR
,
1221 "%s: Bad offset 0x%"HWADDR_PRIx
"\n", __func__
, addr
);
1225 static const MemoryRegionOps stm32l4x5_rcc_ops
= {
1226 .read
= stm32l4x5_rcc_read
,
1227 .write
= stm32l4x5_rcc_write
,
1228 .endianness
= DEVICE_NATIVE_ENDIAN
,
1230 .max_access_size
= 4,
1231 .min_access_size
= 4,
1235 .max_access_size
= 4,
1236 .min_access_size
= 4,
1241 static const ClockPortInitArray stm32l4x5_rcc_clocks
= {
1242 QDEV_CLOCK_IN(Stm32l4x5RccState
, hsi16_rc
, NULL
, 0),
1243 QDEV_CLOCK_IN(Stm32l4x5RccState
, msi_rc
, NULL
, 0),
1244 QDEV_CLOCK_IN(Stm32l4x5RccState
, hse
, NULL
, 0),
1245 QDEV_CLOCK_IN(Stm32l4x5RccState
, lsi_rc
, NULL
, 0),
1246 QDEV_CLOCK_IN(Stm32l4x5RccState
, lse_crystal
, NULL
, 0),
1247 QDEV_CLOCK_IN(Stm32l4x5RccState
, sai1_extclk
, NULL
, 0),
1248 QDEV_CLOCK_IN(Stm32l4x5RccState
, sai2_extclk
, NULL
, 0),
1253 static void stm32l4x5_rcc_init(Object
*obj
)
1255 Stm32l4x5RccState
*s
= STM32L4X5_RCC(obj
);
1258 sysbus_init_irq(SYS_BUS_DEVICE(obj
), &s
->irq
);
1260 memory_region_init_io(&s
->mmio
, obj
, &stm32l4x5_rcc_ops
, s
,
1261 TYPE_STM32L4X5_RCC
, 0x400);
1262 sysbus_init_mmio(SYS_BUS_DEVICE(obj
), &s
->mmio
);
1264 qdev_init_clocks(DEVICE(s
), stm32l4x5_rcc_clocks
);
1266 for (i
= 0; i
< RCC_NUM_PLL
; i
++) {
1267 object_initialize_child(obj
, PLL_INIT_INFO
[i
].name
,
1268 &s
->plls
[i
], TYPE_RCC_PLL
);
1269 set_pll_init_info(&s
->plls
[i
], i
);
1272 for (i
= 0; i
< RCC_NUM_CLOCK_MUX
; i
++) {
1275 object_initialize_child(obj
, CLOCK_MUX_INIT_INFO
[i
].name
,
1277 TYPE_RCC_CLOCK_MUX
);
1278 set_clock_mux_init_info(&s
->clock_muxes
[i
], i
);
1280 if (!CLOCK_MUX_INIT_INFO
[i
].hidden
) {
1281 /* Expose muxes output as RCC outputs */
1282 alias
= g_strdup_printf("%s-out", CLOCK_MUX_INIT_INFO
[i
].name
);
1283 qdev_alias_clock(DEVICE(&s
->clock_muxes
[i
]), "out", DEVICE(obj
), alias
);
1288 s
->gnd
= clock_new(obj
, "gnd");
1291 static void connect_mux_sources(Stm32l4x5RccState
*s
,
1292 RccClockMuxState
*mux
,
1293 const RccClockMuxSource
*clk_mapping
)
1297 Clock
* const CLK_SRC_MAPPING
[] = {
1298 [RCC_CLOCK_MUX_SRC_GND
] = s
->gnd
,
1299 [RCC_CLOCK_MUX_SRC_HSI
] = s
->hsi16_rc
,
1300 [RCC_CLOCK_MUX_SRC_HSE
] = s
->hse
,
1301 [RCC_CLOCK_MUX_SRC_MSI
] = s
->msi_rc
,
1302 [RCC_CLOCK_MUX_SRC_LSI
] = s
->lsi_rc
,
1303 [RCC_CLOCK_MUX_SRC_LSE
] = s
->lse_crystal
,
1304 [RCC_CLOCK_MUX_SRC_SAI1_EXTCLK
] = s
->sai1_extclk
,
1305 [RCC_CLOCK_MUX_SRC_SAI2_EXTCLK
] = s
->sai2_extclk
,
1306 [RCC_CLOCK_MUX_SRC_PLL
] =
1307 s
->plls
[RCC_PLL_PLL
].channels
[RCC_PLL_CHANNEL_PLLCLK
],
1308 [RCC_CLOCK_MUX_SRC_PLLSAI1
] =
1309 s
->plls
[RCC_PLL_PLLSAI1
].channels
[RCC_PLLSAI1_CHANNEL_PLLSAI1CLK
],
1310 [RCC_CLOCK_MUX_SRC_PLLSAI2
] =
1311 s
->plls
[RCC_PLL_PLLSAI2
].channels
[RCC_PLLSAI2_CHANNEL_PLLSAI2CLK
],
1312 [RCC_CLOCK_MUX_SRC_PLLSAI3
] =
1313 s
->plls
[RCC_PLL_PLL
].channels
[RCC_PLL_CHANNEL_PLLSAI3CLK
],
1314 [RCC_CLOCK_MUX_SRC_PLL48M1
] =
1315 s
->plls
[RCC_PLL_PLL
].channels
[RCC_PLL_CHANNEL_PLL48M1CLK
],
1316 [RCC_CLOCK_MUX_SRC_PLL48M2
] =
1317 s
->plls
[RCC_PLL_PLLSAI1
].channels
[RCC_PLLSAI1_CHANNEL_PLL48M2CLK
],
1318 [RCC_CLOCK_MUX_SRC_PLLADC1
] =
1319 s
->plls
[RCC_PLL_PLLSAI1
].channels
[RCC_PLLSAI1_CHANNEL_PLLADC1CLK
],
1320 [RCC_CLOCK_MUX_SRC_PLLADC2
] =
1321 s
->plls
[RCC_PLL_PLLSAI2
] .channels
[RCC_PLLSAI2_CHANNEL_PLLADC2CLK
],
1322 [RCC_CLOCK_MUX_SRC_SYSCLK
] = s
->clock_muxes
[RCC_CLOCK_MUX_SYSCLK
].out
,
1323 [RCC_CLOCK_MUX_SRC_HCLK
] = s
->clock_muxes
[RCC_CLOCK_MUX_HCLK
].out
,
1324 [RCC_CLOCK_MUX_SRC_PCLK1
] = s
->clock_muxes
[RCC_CLOCK_MUX_PCLK1
].out
,
1325 [RCC_CLOCK_MUX_SRC_PCLK2
] = s
->clock_muxes
[RCC_CLOCK_MUX_PCLK2
].out
,
1326 [RCC_CLOCK_MUX_SRC_HSE_OVER_32
] = s
->clock_muxes
[RCC_CLOCK_MUX_HSE_OVER_32
].out
,
1327 [RCC_CLOCK_MUX_SRC_LCD_AND_RTC_COMMON
] =
1328 s
->clock_muxes
[RCC_CLOCK_MUX_LCD_AND_RTC_COMMON
].out
,
1331 assert(ARRAY_SIZE(CLK_SRC_MAPPING
) == RCC_CLOCK_MUX_SRC_NUMBER
);
1333 for (i
= 0; i
< RCC_NUM_CLOCK_MUX_SRC
; i
++) {
1334 RccClockMuxSource mapping
= clk_mapping
[i
];
1335 clock_set_source(mux
->srcs
[i
], CLK_SRC_MAPPING
[mapping
]);
1340 static const VMStateDescription vmstate_stm32l4x5_rcc
= {
1341 .name
= TYPE_STM32L4X5_RCC
,
1343 .minimum_version_id
= 1,
1344 .fields
= (VMStateField
[]) {
1345 VMSTATE_UINT32(cr
, Stm32l4x5RccState
),
1346 VMSTATE_UINT32(icscr
, Stm32l4x5RccState
),
1347 VMSTATE_UINT32(cfgr
, Stm32l4x5RccState
),
1348 VMSTATE_UINT32(pllcfgr
, Stm32l4x5RccState
),
1349 VMSTATE_UINT32(pllsai1cfgr
, Stm32l4x5RccState
),
1350 VMSTATE_UINT32(pllsai2cfgr
, Stm32l4x5RccState
),
1351 VMSTATE_UINT32(cier
, Stm32l4x5RccState
),
1352 VMSTATE_UINT32(cifr
, Stm32l4x5RccState
),
1353 VMSTATE_UINT32(ahb1rstr
, Stm32l4x5RccState
),
1354 VMSTATE_UINT32(ahb2rstr
, Stm32l4x5RccState
),
1355 VMSTATE_UINT32(ahb3rstr
, Stm32l4x5RccState
),
1356 VMSTATE_UINT32(apb1rstr1
, Stm32l4x5RccState
),
1357 VMSTATE_UINT32(apb1rstr2
, Stm32l4x5RccState
),
1358 VMSTATE_UINT32(apb2rstr
, Stm32l4x5RccState
),
1359 VMSTATE_UINT32(ahb1enr
, Stm32l4x5RccState
),
1360 VMSTATE_UINT32(ahb2enr
, Stm32l4x5RccState
),
1361 VMSTATE_UINT32(ahb3enr
, Stm32l4x5RccState
),
1362 VMSTATE_UINT32(apb1enr1
, Stm32l4x5RccState
),
1363 VMSTATE_UINT32(apb1enr2
, Stm32l4x5RccState
),
1364 VMSTATE_UINT32(apb2enr
, Stm32l4x5RccState
),
1365 VMSTATE_UINT32(ahb1smenr
, Stm32l4x5RccState
),
1366 VMSTATE_UINT32(ahb2smenr
, Stm32l4x5RccState
),
1367 VMSTATE_UINT32(ahb3smenr
, Stm32l4x5RccState
),
1368 VMSTATE_UINT32(apb1smenr1
, Stm32l4x5RccState
),
1369 VMSTATE_UINT32(apb1smenr2
, Stm32l4x5RccState
),
1370 VMSTATE_UINT32(apb2smenr
, Stm32l4x5RccState
),
1371 VMSTATE_UINT32(ccipr
, Stm32l4x5RccState
),
1372 VMSTATE_UINT32(bdcr
, Stm32l4x5RccState
),
1373 VMSTATE_UINT32(csr
, Stm32l4x5RccState
),
1374 VMSTATE_CLOCK(hsi16_rc
, Stm32l4x5RccState
),
1375 VMSTATE_CLOCK(msi_rc
, Stm32l4x5RccState
),
1376 VMSTATE_CLOCK(hse
, Stm32l4x5RccState
),
1377 VMSTATE_CLOCK(lsi_rc
, Stm32l4x5RccState
),
1378 VMSTATE_CLOCK(lse_crystal
, Stm32l4x5RccState
),
1379 VMSTATE_CLOCK(sai1_extclk
, Stm32l4x5RccState
),
1380 VMSTATE_CLOCK(sai2_extclk
, Stm32l4x5RccState
),
1381 VMSTATE_END_OF_LIST()
1386 static void stm32l4x5_rcc_realize(DeviceState
*dev
, Error
**errp
)
1388 Stm32l4x5RccState
*s
= STM32L4X5_RCC(dev
);
1391 if (s
->hse_frequency
< 4000000ULL ||
1392 s
->hse_frequency
> 48000000ULL) {
1394 "HSE frequency is outside of the allowed [4-48]Mhz range: %" PRIx64
"",
1399 for (i
= 0; i
< RCC_NUM_PLL
; i
++) {
1400 RccPllState
*pll
= &s
->plls
[i
];
1402 clock_set_source(pll
->in
, s
->clock_muxes
[RCC_CLOCK_MUX_PLL_INPUT
].out
);
1404 if (!qdev_realize(DEVICE(pll
), NULL
, errp
)) {
1409 for (i
= 0; i
< RCC_NUM_CLOCK_MUX
; i
++) {
1410 RccClockMuxState
*clock_mux
= &s
->clock_muxes
[i
];
1412 connect_mux_sources(s
, clock_mux
, CLOCK_MUX_INIT_INFO
[i
].src_mapping
);
1414 if (!qdev_realize(DEVICE(clock_mux
), NULL
, errp
)) {
1420 * Start clocks after everything is connected
1421 * to propagate the frequencies along the tree.
1423 clock_update_hz(s
->msi_rc
, MSI_DEFAULT_FRQ
);
1424 clock_update_hz(s
->sai1_extclk
, s
->sai1_extclk_frequency
);
1425 clock_update_hz(s
->sai2_extclk
, s
->sai2_extclk_frequency
);
1426 clock_update(s
->gnd
, 0);
1429 static Property stm32l4x5_rcc_properties
[] = {
1430 DEFINE_PROP_UINT64("hse_frequency", Stm32l4x5RccState
,
1431 hse_frequency
, HSE_DEFAULT_FRQ
),
1432 DEFINE_PROP_UINT64("sai1_extclk_frequency", Stm32l4x5RccState
,
1433 sai1_extclk_frequency
, 0),
1434 DEFINE_PROP_UINT64("sai2_extclk_frequency", Stm32l4x5RccState
,
1435 sai2_extclk_frequency
, 0),
1436 DEFINE_PROP_END_OF_LIST(),
1439 static void stm32l4x5_rcc_class_init(ObjectClass
*klass
, void *data
)
1441 DeviceClass
*dc
= DEVICE_CLASS(klass
);
1442 ResettableClass
*rc
= RESETTABLE_CLASS(klass
);
1444 assert(ARRAY_SIZE(CLOCK_MUX_INIT_INFO
) == RCC_NUM_CLOCK_MUX
);
1446 rc
->phases
.hold
= stm32l4x5_rcc_reset_hold
;
1447 device_class_set_props(dc
, stm32l4x5_rcc_properties
);
1448 dc
->realize
= stm32l4x5_rcc_realize
;
1449 dc
->vmsd
= &vmstate_stm32l4x5_rcc
;
1452 static const TypeInfo stm32l4x5_rcc_types
[] = {
1454 .name
= TYPE_STM32L4X5_RCC
,
1455 .parent
= TYPE_SYS_BUS_DEVICE
,
1456 .instance_size
= sizeof(Stm32l4x5RccState
),
1457 .instance_init
= stm32l4x5_rcc_init
,
1458 .class_init
= stm32l4x5_rcc_class_init
,
1460 .name
= TYPE_RCC_CLOCK_MUX
,
1461 .parent
= TYPE_DEVICE
,
1462 .instance_size
= sizeof(RccClockMuxState
),
1463 .instance_init
= clock_mux_init
,
1464 .class_init
= clock_mux_class_init
,
1466 .name
= TYPE_RCC_PLL
,
1467 .parent
= TYPE_DEVICE
,
1468 .instance_size
= sizeof(RccPllState
),
1469 .instance_init
= pll_init
,
1470 .class_init
= pll_class_init
,
1474 DEFINE_TYPES(stm32l4x5_rcc_types
)