hw/misc/stm32l4x5_rcc: Add an internal PLL Clock object
This object represents the PLLs and their channels. The PLLs allow for a
more fine-grained control of the clocks frequency.
The migration handling is based on hw/misc/zynq_sclr.c.
Three phase reset will be handled in a later commit.
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
Message-id: 20240303140643.81957-4-arnaud.minier@telecom-paris.fr
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/include/hw/misc/stm32l4x5_rcc.h b/include/hw/misc/stm32l4x5_rcc.h
index 6719be9..0fbfba5 100644
--- a/include/hw/misc/stm32l4x5_rcc.h
+++ b/include/hw/misc/stm32l4x5_rcc.h
@@ -26,6 +26,15 @@
/* In the Stm32l4x5 clock tree, mux have at most 7 sources */
#define RCC_NUM_CLOCK_MUX_SRC 7
+
+typedef enum PllCommonChannels {
+ RCC_PLL_COMMON_CHANNEL_P = 0,
+ RCC_PLL_COMMON_CHANNEL_Q = 1,
+ RCC_PLL_COMMON_CHANNEL_R = 2,
+
+ RCC_NUM_CHANNEL_PLL_OUT = 3
+} PllCommonChannels;
+
/* NB: Prescaler are assimilated to mux with one source and one output */
typedef enum RccClockMux {
/* Internal muxes that arent't exposed publicly to other peripherals */
@@ -124,6 +133,14 @@
RCC_NUM_CLOCK_MUX
} RccClockMux;
+typedef enum RccPll {
+ RCC_PLL_PLL,
+ RCC_PLL_PLLSAI1,
+ RCC_PLL_PLLSAI2,
+
+ RCC_NUM_PLL
+} RccPll;
+
typedef struct RccClockMuxState {
DeviceState parent_obj;
@@ -142,6 +159,26 @@
struct RccClockMuxState *backref[RCC_NUM_CLOCK_MUX_SRC];
} RccClockMuxState;
+typedef struct RccPllState {
+ DeviceState parent_obj;
+
+ RccPll id;
+ Clock *in;
+ uint32_t vco_multiplier;
+ Clock *channels[RCC_NUM_CHANNEL_PLL_OUT];
+ /* Global pll enabled flag */
+ bool enabled;
+ /* 'enabled' refers to the runtime configuration */
+ bool channel_enabled[RCC_NUM_CHANNEL_PLL_OUT];
+ /*
+ * 'exists' refers to the physical configuration
+ * It should only be set at pll initialization.
+ * e.g. pllsai2 doesn't have a Q output.
+ */
+ bool channel_exists[RCC_NUM_CHANNEL_PLL_OUT];
+ uint32_t channel_divider[RCC_NUM_CHANNEL_PLL_OUT];
+} RccPllState;
+
struct Stm32l4x5RccState {
SysBusDevice parent_obj;
@@ -187,6 +224,9 @@
Clock *sai1_extclk;
Clock *sai2_extclk;
+ /* PLLs */
+ RccPllState plls[RCC_NUM_PLL];
+
/* Muxes ~= outputs */
RccClockMuxState clock_muxes[RCC_NUM_CLOCK_MUX];