@@ -814,6 +814,76 @@ static void stm32_clock_switch_to_hsi(void)
814814 }
815815}
816816
817+ /* #defines used by set_up_plls() to re-configure only PLLs not used by XiP */
818+ #ifdef CONFIG_STM32_APP_IN_EXT_FLASH
819+
820+ #if defined(OCTOSPI1 ) || defined(OCTOSPI2 )
821+
822+ #define XIP_USE_PLL1 \
823+ (LL_RCC_GetOSPIClockSource(LL_RCC_OSPI_CLKSOURCE) == LL_RCC_OSPI_CLKSOURCE_PLL1Q)
824+ #define XIP_USE_PLL1P 0
825+ #define XIP_USE_PLL1Q XIP_USE_PLL1
826+
827+ #define XIP_USE_PLL2 \
828+ (LL_RCC_GetOSPIClockSource(LL_RCC_OSPI_CLKSOURCE) == LL_RCC_OSPI_CLKSOURCE_PLL2R)
829+ #define XIP_USE_PLL2R XIP_USE_PLL2
830+ #define XIP_USE_PLL2S 0
831+ #define XIP_USE_PLL2T 0
832+
833+ #elif defined(QUADSPI )
834+
835+ #define XIP_USE_PLL1 \
836+ (LL_RCC_GetQSPIClockSource(LL_RCC_QSPI_CLKSOURCE) == LL_RCC_QSPI_CLKSOURCE_PLL1Q)
837+ #define XIP_USE_PLL1P 0
838+ #define XIP_USE_PLL1Q XIP_USE_PLL1
839+
840+ #define XIP_USE_PLL2 \
841+ (LL_RCC_GetQSPIClockSource(LL_RCC_QSPI_CLKSOURCE) == LL_RCC_QSPI_CLKSOURCE_PLL2R)
842+ #define XIP_USE_PLL2R XIP_USE_PLL2
843+ #define XIP_USE_PLL2S 0
844+ #define XIP_USE_PLL2T 0
845+
846+ #elif defined(CONFIG_SOC_SERIES_STM32H7RSX )
847+
848+ /* If PLL1 is used as SYSCLK, we can't switch to HSI during PLL reconfiguration, because of clock
849+ * constraints: The XSPI AXI clock has to be greater or equal than the XSPI kernel clock.
850+ * No need to check if XSPI is clocked by HCLK5 or not, PLL1(P) is blocked anyway */
851+ #define XIP_USE_PLL1 (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL1)
852+ #define XIP_USE_PLL1P XIP_USE_PLL1
853+ #define XIP_USE_PLL1Q 0
854+
855+ #define XIP_USE_PLL2 \
856+ (LL_RCC_GetXSPI1SwitchPosition() == LL_RCC_SWP_XSPI1_PLL2S || \
857+ LL_RCC_GetXSPI1SwitchPosition() == LL_RCC_SWP_XSPI1_PLL2T || \
858+ LL_RCC_GetXSPI2SwitchPosition() == LL_RCC_SWP_XSPI2_PLL2S || \
859+ LL_RCC_GetXSPI2SwitchPosition() == LL_RCC_SWP_XSPI2_PLL2T)
860+ #define XIP_USE_PLL2R 0
861+ #define XIP_USE_PLL2S \
862+ (LL_RCC_GetXSPI1SwitchPosition() == LL_RCC_SWP_XSPI1_PLL2S || \
863+ LL_RCC_GetXSPI2SwitchPosition() == LL_RCC_SWP_XSPI2_PLL2S)
864+ #define XIP_USE_PLL2T \
865+ (LL_RCC_GetXSPI1SwitchPosition() == LL_RCC_SWP_XSPI1_PLL2T || \
866+ LL_RCC_GetXSPI2SwitchPosition() == LL_RCC_SWP_XSPI2_PLL2T)
867+
868+ #else /* no OCTO/QUAD/X SPI */
869+
870+ #error "CONFIG_STM32_MEMMAP & CONFIG_STM32_APP_IN_EXT_FLASH defined but no XiP SPI peripheral found"
871+
872+ #endif
873+
874+ #else /* CONFIG_STM32_APP_IN_EXT_FLASH */
875+ /* Set all checks to false because XiP is not used */
876+
877+ #define XIP_USE_PLL1 0
878+ #define XIP_USE_PLL1P 0
879+ #define XIP_USE_PLL1Q 0
880+ #define XIP_USE_PLL2 0
881+ #define XIP_USE_PLL2R 0
882+ #define XIP_USE_PLL2S 0
883+ #define XIP_USE_PLL2T 0
884+
885+ #endif /* CONFIG_STM32_APP_IN_EXT_FLASH */
886+
817887__unused
818888static int set_up_plls (void )
819889{
@@ -828,164 +898,161 @@ static int set_up_plls(void)
828898 * (Switching to HSI makes sure we have a SYSCLK source in
829899 * case we're currently running from the PLL we're about to
830900 * turn off and reconfigure.)
831- *
901+ * But only if the PLL1 is not by (Q/O/X)SPI while in XiP.
832902 */
833- if (LL_RCC_GetSysClkSource () == LL_RCC_SYS_CLKSOURCE_STATUS_PLL1 ) {
903+ if (LL_RCC_GetSysClkSource () == LL_RCC_SYS_CLKSOURCE_STATUS_PLL1 && ! XIP_USE_PLL1 ) {
834904 stm32_clock_switch_to_hsi ();
835905 LL_RCC_SetAHBPrescaler (LL_RCC_SYSCLK_DIV_1 );
836906 }
837907
838- #if defined(CONFIG_STM32_MEMMAP ) && defined(CONFIG_BOOTLOADER_MCUBOOT )
839- /*
840- * Don't disable PLL during application initialization
841- * that runs in memmap mode when (Q/O)SPI uses PLL
842- * as its clock source.
843- */
844- #if defined(OCTOSPI1 ) || defined(OCTOSPI2 )
845- if (LL_RCC_GetOSPIClockSource (LL_RCC_OSPI_CLKSOURCE ) != LL_RCC_OSPI_CLKSOURCE_PLL1Q ) {
908+ /* Only disable PLLs not used to clock (Q/O/X)SPI */
909+ if (!XIP_USE_PLL1 ) {
846910 LL_RCC_PLL1_Disable ();
847911 }
848- if (LL_RCC_GetOSPIClockSource ( LL_RCC_OSPI_CLKSOURCE ) != LL_RCC_OSPI_CLKSOURCE_PLL2R ) {
912+ if (! XIP_USE_PLL2 ) {
849913 LL_RCC_PLL2_Disable ();
850914 }
851- #elif defined(QUADSPI )
852- if (LL_RCC_GetQSPIClockSource (LL_RCC_QSPI_CLKSOURCE ) != LL_RCC_QSPI_CLKSOURCE_PLL1Q ) {
853- LL_RCC_PLL1_Disable ();
854- }
855- if (LL_RCC_GetQSPIClockSource (LL_RCC_QSPI_CLKSOURCE ) != LL_RCC_QSPI_CLKSOURCE_PLL2R ) {
856- LL_RCC_PLL2_Disable ();
857- }
858- #else
859- LL_RCC_PLL1_Disable ();
860- LL_RCC_PLL2_Disable ();
861- #endif
862- #else
863- LL_RCC_PLL1_Disable ();
864- LL_RCC_PLL2_Disable ();
865- #endif
866915 LL_RCC_PLL3_Disable ();
867916
868- /* Configure PLL source */
869-
917+ /* Configure PLL source only if not XiP */
918+ #ifndef CONFIG_STM32_APP_IN_EXT_FLASH
870919 /* Can be HSE , HSI 64Mhz/HSIDIV, CSI 4MHz*/
871- if (IS_ENABLED (STM32_PLL_SRC_HSE ) ||
872- IS_ENABLED (STM32_PLL2_SRC_HSE ) ||
873- IS_ENABLED (STM32_PLL3_SRC_HSE )) {
920+ if (IS_ENABLED (STM32_PLL_SRC_HSE ) || IS_ENABLED (STM32_PLL2_SRC_HSE ) ||
921+ IS_ENABLED (STM32_PLL3_SRC_HSE )) {
874922 /* Main PLL configuration and activation */
875923 LL_RCC_PLL_SetSource (LL_RCC_PLLSOURCE_HSE );
876- } else if (IS_ENABLED (STM32_PLL_SRC_CSI ) ||
877- IS_ENABLED (STM32_PLL2_SRC_CSI ) ||
878- IS_ENABLED (STM32_PLL3_SRC_CSI )) {
924+ } else if (IS_ENABLED (STM32_PLL_SRC_CSI ) || IS_ENABLED (STM32_PLL2_SRC_CSI ) ||
925+ IS_ENABLED (STM32_PLL3_SRC_CSI )) {
879926 /* Main PLL configuration and activation */
880927 LL_RCC_PLL_SetSource (LL_RCC_PLLSOURCE_CSI );
881- } else if (IS_ENABLED (STM32_PLL_SRC_HSI ) ||
882- IS_ENABLED (STM32_PLL2_SRC_HSI ) ||
883- IS_ENABLED (STM32_PLL3_SRC_HSI )) {
928+ } else if (IS_ENABLED (STM32_PLL_SRC_HSI ) || IS_ENABLED (STM32_PLL2_SRC_HSI ) ||
929+ IS_ENABLED (STM32_PLL3_SRC_HSI )) {
884930 /* Main PLL configuration and activation */
885931 LL_RCC_PLL_SetSource (LL_RCC_PLLSOURCE_HSI );
886932 } else {
887933 return - ENOTSUP ;
888934 }
935+ #endif
889936
890937#if defined(STM32_PLL_ENABLED )
891- r = get_vco_input_range (STM32_PLL_M_DIVISOR , & vco_input_range );
892- if (r < 0 ) {
893- return r ;
894- }
938+ /* use the isReady flag to skip reconfiguration if PLL was not disabled above */
939+ if (!LL_RCC_PLL1_IsReady ()) {
940+ r = get_vco_input_range (STM32_PLL_M_DIVISOR , & vco_input_range );
941+ if (r < 0 ) {
942+ return r ;
943+ }
895944
896- vco_output_range = get_vco_output_range (vco_input_range );
945+ vco_output_range = get_vco_output_range (vco_input_range );
946+
947+ LL_RCC_PLL1_SetM (STM32_PLL_M_DIVISOR );
897948
898- LL_RCC_PLL1_SetM (STM32_PLL_M_DIVISOR );
949+ LL_RCC_PLL1_SetVCOInputRange (vco_input_range );
950+ LL_RCC_PLL1_SetVCOOutputRange (vco_output_range );
899951
900- LL_RCC_PLL1_SetVCOInputRange (vco_input_range );
901- LL_RCC_PLL1_SetVCOOutputRange (vco_output_range );
952+ LL_RCC_PLL1_SetN (STM32_PLL_N_MULTIPLIER );
902953
903- LL_RCC_PLL1_SetN (STM32_PLL_N_MULTIPLIER );
954+ LL_RCC_PLL1FRACN_Disable ();
955+ if (IS_ENABLED (STM32_PLL_FRACN_ENABLED )) {
956+ LL_RCC_PLL1_SetFRACN (STM32_PLL_FRACN_VALUE );
957+ LL_RCC_PLL1FRACN_Enable ();
958+ }
904959
905- LL_RCC_PLL1FRACN_Disable ();
906- if (IS_ENABLED (STM32_PLL_FRACN_ENABLED )) {
907- LL_RCC_PLL1_SetFRACN (STM32_PLL_FRACN_VALUE );
908- LL_RCC_PLL1FRACN_Enable ();
960+ LL_RCC_PLL1_Enable ();
961+ while (LL_RCC_PLL1_IsReady () != 1U ) {
962+ }
909963 }
910964
911- if (IS_ENABLED (STM32_PLL_P_ENABLED )) {
965+ /* Reconfigure PLL outputs only if enabled in DTS (and not used by XiP) */
966+
967+ if (IS_ENABLED (STM32_PLL_P_ENABLED ) && !XIP_USE_PLL1P ) {
968+ LL_RCC_PLL1P_Disable ();
912969 LL_RCC_PLL1_SetP (STM32_PLL_P_DIVISOR );
913970 LL_RCC_PLL1P_Enable ();
914971 }
915972
916- if (IS_ENABLED (STM32_PLL_Q_ENABLED )) {
973+ if (IS_ENABLED (STM32_PLL_Q_ENABLED ) && !XIP_USE_PLL1Q ) {
974+ LL_RCC_PLL1Q_Disable ();
917975 LL_RCC_PLL1_SetQ (STM32_PLL_Q_DIVISOR );
918976 LL_RCC_PLL1Q_Enable ();
919977 }
920978
921979 if (IS_ENABLED (STM32_PLL_R_ENABLED )) {
980+ LL_RCC_PLL1R_Disable ();
922981 LL_RCC_PLL1_SetR (STM32_PLL_R_DIVISOR );
923982 LL_RCC_PLL1R_Enable ();
924983 }
925984
926985#if defined(CONFIG_SOC_SERIES_STM32H7RSX )
927986 if (IS_ENABLED (STM32_PLL_S_ENABLED )) {
987+ LL_RCC_PLL1S_Disable ();
928988 LL_RCC_PLL1_SetS (STM32_PLL_S_DIVISOR );
929989 LL_RCC_PLL1S_Enable ();
930990 }
931991#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
932- LL_RCC_PLL1_Enable ();
933- while (LL_RCC_PLL1_IsReady () != 1U ) {
934- }
935992
936993#endif /* STM32_PLL_ENABLED */
937994
938995#if defined(STM32_PLL2_ENABLED )
939- r = get_vco_input_range (STM32_PLL2_M_DIVISOR , & vco_input_range );
940- if (r < 0 ) {
941- return r ;
942- }
996+ /* use the isReady flag to skip reconfiguration if PLL was not disabled above */
997+ if (!LL_RCC_PLL2_IsReady ()) {
998+ r = get_vco_input_range (STM32_PLL2_M_DIVISOR , & vco_input_range );
999+ if (r < 0 ) {
1000+ return r ;
1001+ }
9431002
944- vco_output_range = get_vco_output_range (vco_input_range );
1003+ vco_output_range = get_vco_output_range (vco_input_range );
9451004
946- LL_RCC_PLL2_SetM (STM32_PLL2_M_DIVISOR );
1005+ LL_RCC_PLL2_SetM (STM32_PLL2_M_DIVISOR );
9471006
948- LL_RCC_PLL2_SetVCOInputRange (vco_input_range );
949- LL_RCC_PLL2_SetVCOOutputRange (vco_output_range );
1007+ LL_RCC_PLL2_SetVCOInputRange (vco_input_range );
1008+ LL_RCC_PLL2_SetVCOOutputRange (vco_output_range );
9501009
951- LL_RCC_PLL2_SetN (STM32_PLL2_N_MULTIPLIER );
1010+ LL_RCC_PLL2_SetN (STM32_PLL2_N_MULTIPLIER );
9521011
953- LL_RCC_PLL2FRACN_Disable ();
954- if (IS_ENABLED (STM32_PLL2_FRACN_ENABLED )) {
955- LL_RCC_PLL2_SetFRACN (STM32_PLL2_FRACN_VALUE );
956- LL_RCC_PLL2FRACN_Enable ();
1012+ LL_RCC_PLL2FRACN_Disable ();
1013+ if (IS_ENABLED (STM32_PLL2_FRACN_ENABLED )) {
1014+ LL_RCC_PLL2_SetFRACN (STM32_PLL2_FRACN_VALUE );
1015+ LL_RCC_PLL2FRACN_Enable ();
1016+ }
1017+
1018+ LL_RCC_PLL2_Enable ();
1019+ while (LL_RCC_PLL2_IsReady () != 1U ) {
1020+ }
9571021 }
9581022
1023+ /* Reconfigure PLL outputs only if enabled in DTS (and not used by XiP) */
1024+
9591025 if (IS_ENABLED (STM32_PLL2_P_ENABLED )) {
1026+ LL_RCC_PLL2P_Disable ();
9601027 LL_RCC_PLL2_SetP (STM32_PLL2_P_DIVISOR );
9611028 LL_RCC_PLL2P_Enable ();
9621029 }
9631030
9641031 if (IS_ENABLED (STM32_PLL2_Q_ENABLED )) {
1032+ LL_RCC_PLL2Q_Disable ();
9651033 LL_RCC_PLL2_SetQ (STM32_PLL2_Q_DIVISOR );
9661034 LL_RCC_PLL2Q_Enable ();
9671035 }
9681036
969- if (IS_ENABLED (STM32_PLL2_R_ENABLED )) {
1037+ if (IS_ENABLED (STM32_PLL2_R_ENABLED ) && !XIP_USE_PLL2R ) {
1038+ LL_RCC_PLL2R_Disable ();
9701039 LL_RCC_PLL2_SetR (STM32_PLL2_R_DIVISOR );
9711040 LL_RCC_PLL2R_Enable ();
9721041 }
9731042
9741043#if defined(CONFIG_SOC_SERIES_STM32H7RSX )
975- if (IS_ENABLED (STM32_PLL2_S_ENABLED )) {
1044+ if (IS_ENABLED (STM32_PLL2_S_ENABLED ) && !XIP_USE_PLL2S ) {
1045+ LL_RCC_PLL2S_Disable ();
9761046 LL_RCC_PLL2_SetS (STM32_PLL2_S_DIVISOR );
9771047 LL_RCC_PLL2S_Enable ();
9781048 }
9791049
980- if (IS_ENABLED (STM32_PLL2_T_ENABLED )) {
1050+ if (IS_ENABLED (STM32_PLL2_T_ENABLED ) && !XIP_USE_PLL2T ) {
1051+ LL_RCC_PLL2T_Disable ();
9811052 LL_RCC_PLL2_SetT (STM32_PLL2_T_DIVISOR );
9821053 LL_RCC_PLL2T_Enable ();
9831054 }
984-
9851055#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
986- LL_RCC_PLL2_Enable ();
987- while (LL_RCC_PLL2_IsReady () != 1U ) {
988- }
9891056
9901057#endif /* STM32_PLL2_ENABLED */
9911058
@@ -1038,7 +1105,7 @@ static int set_up_plls(void)
10381105
10391106#endif /* STM32_PLL3_ENABLED */
10401107
1041- #else
1108+ #else /* STM32_PLL_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED */
10421109 /* Init PLL source to None */
10431110 LL_RCC_PLL_SetSource (LL_RCC_PLLSOURCE_NONE );
10441111
0 commit comments