1615f31feSGabriel Fernandez /* 2615f31feSGabriel Fernandez * Copyright (C) 2024, STMicroelectronics - All Rights Reserved 3615f31feSGabriel Fernandez * 4615f31feSGabriel Fernandez * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 5615f31feSGabriel Fernandez */ 6615f31feSGabriel Fernandez 7615f31feSGabriel Fernandez #include <assert.h> 8615f31feSGabriel Fernandez #include <errno.h> 9615f31feSGabriel Fernandez #include <limits.h> 10615f31feSGabriel Fernandez #include <stdint.h> 11615f31feSGabriel Fernandez 12615f31feSGabriel Fernandez #include "clk-stm32-core.h" 13615f31feSGabriel Fernandez #include <common/fdt_wrappers.h> 14615f31feSGabriel Fernandez #include <drivers/clk.h> 15615f31feSGabriel Fernandez #include <drivers/delay_timer.h> 16615f31feSGabriel Fernandez #include <drivers/generic_delay_timer.h> 17615f31feSGabriel Fernandez #include <drivers/st/stm32mp2_clk.h> 18615f31feSGabriel Fernandez #include <drivers/st/stm32mp_clkfunc.h> 19615f31feSGabriel Fernandez #include <lib/mmio.h> 20615f31feSGabriel Fernandez #include <lib/spinlock.h> 21615f31feSGabriel Fernandez #include <lib/utils_def.h> 22615f31feSGabriel Fernandez #include <libfdt.h> 23615f31feSGabriel Fernandez 24615f31feSGabriel Fernandez #include <platform_def.h> 25615f31feSGabriel Fernandez 26615f31feSGabriel Fernandez struct stm32_osci_dt_cfg { 27615f31feSGabriel Fernandez unsigned long freq; 28615f31feSGabriel Fernandez uint32_t drive; 29615f31feSGabriel Fernandez bool bypass; 30615f31feSGabriel Fernandez bool digbyp; 31615f31feSGabriel Fernandez bool css; 32615f31feSGabriel Fernandez }; 33615f31feSGabriel Fernandez 34615f31feSGabriel Fernandez struct stm32_pll_dt_cfg { 35615f31feSGabriel Fernandez uint32_t src; 36615f31feSGabriel Fernandez uint32_t frac; 37615f31feSGabriel Fernandez uint32_t cfg[PLLCFG_NB]; 38615f31feSGabriel Fernandez uint32_t csg[PLLCSG_NB]; 39615f31feSGabriel Fernandez bool csg_enabled; 40615f31feSGabriel Fernandez bool enabled; 41615f31feSGabriel Fernandez }; 42615f31feSGabriel Fernandez 43615f31feSGabriel Fernandez struct stm32_clk_platdata { 44615f31feSGabriel Fernandez uintptr_t rcc_base; 45615f31feSGabriel Fernandez uint32_t nosci; 46615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci; 47615f31feSGabriel Fernandez uint32_t npll; 48615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll; 49615f31feSGabriel Fernandez uint32_t nflexgen; 50615f31feSGabriel Fernandez uint32_t *flexgen; 51615f31feSGabriel Fernandez uint32_t nbusclk; 52615f31feSGabriel Fernandez uint32_t *busclk; 53615f31feSGabriel Fernandez uint32_t nkernelclk; 54615f31feSGabriel Fernandez uint32_t *kernelclk; 55615f31feSGabriel Fernandez }; 56615f31feSGabriel Fernandez 57615f31feSGabriel Fernandez /* A35 Sub-System which manages its own PLL (PLL1) */ 58615f31feSGabriel Fernandez #define A35_SS_CHGCLKREQ 0x0000 59615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1 0x0080 60615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2 0x0090 61615f31feSGabriel Fernandez #define A35_SS_PLL_ENABLE 0x00a0 62615f31feSGabriel Fernandez 63615f31feSGabriel Fernandez #define A35_SS_CHGCLKREQ_ARM_CHGCLKREQ BIT(0) 64615f31feSGabriel Fernandez #define A35_SS_CHGCLKREQ_ARM_CHGCLKACK BIT(1) 65*40d0cebeSPatrick Delaunay #define A35_SS_CHGCLKREQ_ARM_DIVSEL BIT(16) 66*40d0cebeSPatrick Delaunay #define A35_SS_CHGCLKREQ_ARM_DIVSELACK BIT(17) 67615f31feSGabriel Fernandez 68615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1_FBDIV_MASK GENMASK(11, 0) 69615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1_FBDIV_SHIFT 0 70615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1_REFDIV_MASK GENMASK(21, 16) 71615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1_REFDIV_SHIFT 16 72615f31feSGabriel Fernandez 73615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2_POSTDIV1_MASK GENMASK(2, 0) 74615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2_POSTDIV1_SHIFT 0 75615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2_POSTDIV2_MASK GENMASK(5, 3) 76615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2_POSTDIV2_SHIFT 3 77615f31feSGabriel Fernandez 78615f31feSGabriel Fernandez #define A35_SS_PLL_ENABLE_PD BIT(0) 79615f31feSGabriel Fernandez #define A35_SS_PLL_ENABLE_LOCKP BIT(1) 80615f31feSGabriel Fernandez #define A35_SS_PLL_ENABLE_NRESET_SWPLL_FF BIT(2) 81615f31feSGabriel Fernandez 82615f31feSGabriel Fernandez #define TIMEOUT_US_200MS U(200000) 83615f31feSGabriel Fernandez #define TIMEOUT_US_1S U(1000000) 84615f31feSGabriel Fernandez 85615f31feSGabriel Fernandez #define PLLRDY_TIMEOUT TIMEOUT_US_200MS 86615f31feSGabriel Fernandez #define CLKSRC_TIMEOUT TIMEOUT_US_200MS 87615f31feSGabriel Fernandez #define CLKDIV_TIMEOUT TIMEOUT_US_200MS 88615f31feSGabriel Fernandez #define OSCRDY_TIMEOUT TIMEOUT_US_1S 89615f31feSGabriel Fernandez 90615f31feSGabriel Fernandez /* PLL minimal frequencies for clock sources */ 91615f31feSGabriel Fernandez #define PLL_REFCLK_MIN UL(5000000) 92615f31feSGabriel Fernandez #define PLL_FRAC_REFCLK_MIN UL(10000000) 93615f31feSGabriel Fernandez 94615f31feSGabriel Fernandez #define XBAR_CHANNEL_NB 64 95615f31feSGabriel Fernandez 96615f31feSGabriel Fernandez /* Warning, should be start to 1 */ 97615f31feSGabriel Fernandez enum clock { 98615f31feSGabriel Fernandez _CK_0_MHZ, 99615f31feSGabriel Fernandez 100615f31feSGabriel Fernandez /* ROOT CLOCKS */ 101615f31feSGabriel Fernandez _CK_HSI, 102615f31feSGabriel Fernandez _CK_HSE, 103615f31feSGabriel Fernandez _CK_MSI, 104615f31feSGabriel Fernandez _CK_LSI, 105615f31feSGabriel Fernandez _CK_LSE, 106615f31feSGabriel Fernandez _I2SCKIN, 107615f31feSGabriel Fernandez _SPDIFSYMB, 108615f31feSGabriel Fernandez _CK_PLL1, 109615f31feSGabriel Fernandez _CK_PLL2, 110088238adSNicolas Le Bayon #if !STM32MP21 111615f31feSGabriel Fernandez _CK_PLL3, 112088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 113615f31feSGabriel Fernandez _CK_PLL4, 114615f31feSGabriel Fernandez _CK_PLL5, 115615f31feSGabriel Fernandez _CK_PLL6, 116615f31feSGabriel Fernandez _CK_PLL7, 117615f31feSGabriel Fernandez _CK_PLL8, 118615f31feSGabriel Fernandez _CK_HSE_RTC, 119615f31feSGabriel Fernandez _CK_RTCCK, 120615f31feSGabriel Fernandez _CK_ICN_HS_MCU, 121615f31feSGabriel Fernandez _CK_ICN_SDMMC, 122615f31feSGabriel Fernandez _CK_ICN_DDR, 123615f31feSGabriel Fernandez _CK_ICN_HSL, 124615f31feSGabriel Fernandez _CK_ICN_NIC, 125615f31feSGabriel Fernandez _CK_ICN_LS_MCU, 126615f31feSGabriel Fernandez _CK_FLEXGEN_07, 127615f31feSGabriel Fernandez _CK_FLEXGEN_08, 128615f31feSGabriel Fernandez _CK_FLEXGEN_09, 129615f31feSGabriel Fernandez _CK_FLEXGEN_10, 130615f31feSGabriel Fernandez _CK_FLEXGEN_11, 131615f31feSGabriel Fernandez _CK_FLEXGEN_12, 132615f31feSGabriel Fernandez _CK_FLEXGEN_13, 133615f31feSGabriel Fernandez _CK_FLEXGEN_14, 134615f31feSGabriel Fernandez _CK_FLEXGEN_15, 135615f31feSGabriel Fernandez _CK_FLEXGEN_16, 136615f31feSGabriel Fernandez _CK_FLEXGEN_17, 137615f31feSGabriel Fernandez _CK_FLEXGEN_18, 138615f31feSGabriel Fernandez _CK_FLEXGEN_19, 139615f31feSGabriel Fernandez _CK_FLEXGEN_20, 140615f31feSGabriel Fernandez _CK_FLEXGEN_21, 141615f31feSGabriel Fernandez _CK_FLEXGEN_22, 142615f31feSGabriel Fernandez _CK_FLEXGEN_23, 143615f31feSGabriel Fernandez _CK_FLEXGEN_24, 144615f31feSGabriel Fernandez _CK_FLEXGEN_25, 145615f31feSGabriel Fernandez _CK_FLEXGEN_26, 146615f31feSGabriel Fernandez _CK_FLEXGEN_27, 147615f31feSGabriel Fernandez _CK_FLEXGEN_28, 148615f31feSGabriel Fernandez _CK_FLEXGEN_29, 149615f31feSGabriel Fernandez _CK_FLEXGEN_30, 150615f31feSGabriel Fernandez _CK_FLEXGEN_31, 151615f31feSGabriel Fernandez _CK_FLEXGEN_32, 152615f31feSGabriel Fernandez _CK_FLEXGEN_33, 153615f31feSGabriel Fernandez _CK_FLEXGEN_34, 154615f31feSGabriel Fernandez _CK_FLEXGEN_35, 155615f31feSGabriel Fernandez _CK_FLEXGEN_36, 156615f31feSGabriel Fernandez _CK_FLEXGEN_37, 157615f31feSGabriel Fernandez _CK_FLEXGEN_38, 158615f31feSGabriel Fernandez _CK_FLEXGEN_39, 159615f31feSGabriel Fernandez _CK_FLEXGEN_40, 160615f31feSGabriel Fernandez _CK_FLEXGEN_41, 161615f31feSGabriel Fernandez _CK_FLEXGEN_42, 162615f31feSGabriel Fernandez _CK_FLEXGEN_43, 163615f31feSGabriel Fernandez _CK_FLEXGEN_44, 164615f31feSGabriel Fernandez _CK_FLEXGEN_45, 165615f31feSGabriel Fernandez _CK_FLEXGEN_46, 166615f31feSGabriel Fernandez _CK_FLEXGEN_47, 167615f31feSGabriel Fernandez _CK_FLEXGEN_48, 168615f31feSGabriel Fernandez _CK_FLEXGEN_49, 169615f31feSGabriel Fernandez _CK_FLEXGEN_50, 170615f31feSGabriel Fernandez _CK_FLEXGEN_51, 171615f31feSGabriel Fernandez _CK_FLEXGEN_52, 172615f31feSGabriel Fernandez _CK_FLEXGEN_53, 173615f31feSGabriel Fernandez _CK_FLEXGEN_54, 174615f31feSGabriel Fernandez _CK_FLEXGEN_55, 175615f31feSGabriel Fernandez _CK_FLEXGEN_56, 176615f31feSGabriel Fernandez _CK_FLEXGEN_57, 177615f31feSGabriel Fernandez _CK_FLEXGEN_58, 178615f31feSGabriel Fernandez _CK_FLEXGEN_59, 179615f31feSGabriel Fernandez _CK_FLEXGEN_60, 180615f31feSGabriel Fernandez _CK_FLEXGEN_61, 181615f31feSGabriel Fernandez _CK_FLEXGEN_62, 182615f31feSGabriel Fernandez _CK_FLEXGEN_63, 183615f31feSGabriel Fernandez _CK_ICN_APB1, 184615f31feSGabriel Fernandez _CK_ICN_APB2, 185615f31feSGabriel Fernandez _CK_ICN_APB3, 186615f31feSGabriel Fernandez _CK_ICN_APB4, 187088238adSNicolas Le Bayon #if STM32MP21 188088238adSNicolas Le Bayon _CK_ICN_APB5, 189088238adSNicolas Le Bayon #endif /* STM32MP21 */ 190615f31feSGabriel Fernandez _CK_ICN_APBDBG, 191615f31feSGabriel Fernandez _CK_BKPSRAM, 192615f31feSGabriel Fernandez _CK_BSEC, 193615f31feSGabriel Fernandez _CK_CRC, 194615f31feSGabriel Fernandez _CK_CRYP1, 195615f31feSGabriel Fernandez _CK_CRYP2, 196615f31feSGabriel Fernandez _CK_DDR, 197615f31feSGabriel Fernandez _CK_DDRCAPB, 198615f31feSGabriel Fernandez _CK_DDRCP, 199615f31feSGabriel Fernandez _CK_DDRPHYC, 200615f31feSGabriel Fernandez _CK_FMC, 201615f31feSGabriel Fernandez _CK_GPIOA, 202615f31feSGabriel Fernandez _CK_GPIOB, 203615f31feSGabriel Fernandez _CK_GPIOC, 204615f31feSGabriel Fernandez _CK_GPIOD, 205615f31feSGabriel Fernandez _CK_GPIOE, 206615f31feSGabriel Fernandez _CK_GPIOF, 207615f31feSGabriel Fernandez _CK_GPIOG, 208615f31feSGabriel Fernandez _CK_GPIOH, 209615f31feSGabriel Fernandez _CK_GPIOI, 210088238adSNicolas Le Bayon #if !STM32MP21 211615f31feSGabriel Fernandez _CK_GPIOJ, 212615f31feSGabriel Fernandez _CK_GPIOK, 213088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 214615f31feSGabriel Fernandez _CK_GPIOZ, 215088238adSNicolas Le Bayon #if STM32MP21 216088238adSNicolas Le Bayon _CK_HASH1, 217088238adSNicolas Le Bayon _CK_HASH2, 218088238adSNicolas Le Bayon #else /* STM32MP21 */ 219615f31feSGabriel Fernandez _CK_HASH, 220088238adSNicolas Le Bayon #endif /* STM32MP21 */ 221615f31feSGabriel Fernandez _CK_I2C1, 222615f31feSGabriel Fernandez _CK_I2C2, 223088238adSNicolas Le Bayon #if !STM32MP23 224615f31feSGabriel Fernandez _CK_I2C3, 225088238adSNicolas Le Bayon #endif /* !STM32MP23 */ 226088238adSNicolas Le Bayon #if STM32MP25 227615f31feSGabriel Fernandez _CK_I2C4, 228615f31feSGabriel Fernandez _CK_I2C5, 229615f31feSGabriel Fernandez _CK_I2C6, 230088238adSNicolas Le Bayon #endif /* STM32MP25 */ 231088238adSNicolas Le Bayon #if !STM32MP21 232615f31feSGabriel Fernandez _CK_I2C7, 233615f31feSGabriel Fernandez _CK_I2C8, 234088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 235615f31feSGabriel Fernandez _CK_IWDG1, 236615f31feSGabriel Fernandez _CK_IWDG2, 237615f31feSGabriel Fernandez _CK_OSPI1, 238088238adSNicolas Le Bayon #if !STM32MP21 239615f31feSGabriel Fernandez _CK_OSPI2, 240615f31feSGabriel Fernandez _CK_OSPIIOM, 241088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 242615f31feSGabriel Fernandez _CK_PKA, 243615f31feSGabriel Fernandez _CK_RETRAM, 244088238adSNicolas Le Bayon #if STM32MP21 245088238adSNicolas Le Bayon _CK_RNG1, 246088238adSNicolas Le Bayon _CK_RNG2, 247088238adSNicolas Le Bayon #else /* STM32MP21 */ 248615f31feSGabriel Fernandez _CK_RNG, 249088238adSNicolas Le Bayon #endif /* STM32MP21 */ 250615f31feSGabriel Fernandez _CK_RTC, 251615f31feSGabriel Fernandez _CK_SAES, 252615f31feSGabriel Fernandez _CK_SDMMC1, 253615f31feSGabriel Fernandez _CK_SDMMC2, 254615f31feSGabriel Fernandez _CK_SRAM1, 255088238adSNicolas Le Bayon #if !STM32MP21 256615f31feSGabriel Fernandez _CK_SRAM2, 257088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 258615f31feSGabriel Fernandez _CK_STGEN, 259615f31feSGabriel Fernandez _CK_SYSCPU1, 260615f31feSGabriel Fernandez _CK_SYSRAM, 261615f31feSGabriel Fernandez _CK_UART4, 262615f31feSGabriel Fernandez _CK_UART5, 263615f31feSGabriel Fernandez _CK_UART7, 264088238adSNicolas Le Bayon #if STM32MP25 265615f31feSGabriel Fernandez _CK_UART8, 266615f31feSGabriel Fernandez _CK_UART9, 267088238adSNicolas Le Bayon #endif /* STM32MP25 */ 268615f31feSGabriel Fernandez _CK_USART1, 269615f31feSGabriel Fernandez _CK_USART2, 270615f31feSGabriel Fernandez _CK_USART3, 271615f31feSGabriel Fernandez _CK_USART6, 272088238adSNicolas Le Bayon #if STM32MP21 273088238adSNicolas Le Bayon _CK_USBHEHCI, 274088238adSNicolas Le Bayon _CK_USBHOHCI, 275088238adSNicolas Le Bayon #else /* STM32MP21 */ 276615f31feSGabriel Fernandez _CK_USB2EHCI, 277615f31feSGabriel Fernandez _CK_USB2OHCI, 278088238adSNicolas Le Bayon #endif /* STM32MP21 */ 279615f31feSGabriel Fernandez _CK_USB2PHY1, 280615f31feSGabriel Fernandez _CK_USB2PHY2, 281088238adSNicolas Le Bayon #if !STM32MP21 282615f31feSGabriel Fernandez _CK_USB3DR, 283615f31feSGabriel Fernandez _CK_USB3PCIEPHY, 284615f31feSGabriel Fernandez _CK_USBTC, 285088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 2862a20f3e6SGabriel Fernandez _CK_BUS_RISAF4, 287615f31feSGabriel Fernandez 288615f31feSGabriel Fernandez CK_LAST 289615f31feSGabriel Fernandez }; 290615f31feSGabriel Fernandez 291615f31feSGabriel Fernandez static const uint16_t muxsel_src[] = { 292615f31feSGabriel Fernandez _CK_HSI, _CK_HSE, _CK_MSI, _CK_0_MHZ 293615f31feSGabriel Fernandez }; 294615f31feSGabriel Fernandez 295615f31feSGabriel Fernandez static const uint16_t xbarsel_src[] = { 296615f31feSGabriel Fernandez _CK_PLL4, _CK_PLL5, _CK_PLL6, _CK_PLL7, _CK_PLL8, 297615f31feSGabriel Fernandez _CK_HSI, _CK_HSE, _CK_MSI, _CK_HSI, _CK_HSE, _CK_MSI, 298615f31feSGabriel Fernandez _SPDIFSYMB, _I2SCKIN, _CK_LSI, _CK_LSE 299615f31feSGabriel Fernandez }; 300615f31feSGabriel Fernandez 301615f31feSGabriel Fernandez static const uint16_t rtc_src[] = { 302615f31feSGabriel Fernandez _CK_0_MHZ, _CK_LSE, _CK_LSI, _CK_HSE_RTC 303615f31feSGabriel Fernandez }; 304615f31feSGabriel Fernandez 305615f31feSGabriel Fernandez static const uint16_t usb2phy1_src[] = { 306615f31feSGabriel Fernandez _CK_FLEXGEN_57, _CK_HSE 307615f31feSGabriel Fernandez }; 308615f31feSGabriel Fernandez 309615f31feSGabriel Fernandez static const uint16_t usb2phy2_src[] = { 310615f31feSGabriel Fernandez _CK_FLEXGEN_58, _CK_HSE 311615f31feSGabriel Fernandez }; 312615f31feSGabriel Fernandez 313088238adSNicolas Le Bayon #if !STM32MP21 314615f31feSGabriel Fernandez static const uint16_t usb3pciphy_src[] = { 315615f31feSGabriel Fernandez _CK_FLEXGEN_34, _CK_HSE 316615f31feSGabriel Fernandez }; 317615f31feSGabriel Fernandez 318615f31feSGabriel Fernandez static const uint16_t d3per_src[] = { 319615f31feSGabriel Fernandez _CK_MSI, _CK_LSI, _CK_LSE 320615f31feSGabriel Fernandez }; 321088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 322615f31feSGabriel Fernandez 323615f31feSGabriel Fernandez #define MUX_CONF(id, src, _offset, _shift, _witdh)[id] = {\ 324615f31feSGabriel Fernandez .id_parents = src,\ 325615f31feSGabriel Fernandez .num_parents = ARRAY_SIZE(src),\ 326615f31feSGabriel Fernandez .mux = &(struct mux_cfg) {\ 327615f31feSGabriel Fernandez .offset = (_offset),\ 328615f31feSGabriel Fernandez .shift = (_shift),\ 329615f31feSGabriel Fernandez .width = (_witdh),\ 330615f31feSGabriel Fernandez .bitrdy = UINT8_MAX,\ 331615f31feSGabriel Fernandez },\ 332615f31feSGabriel Fernandez } 333615f31feSGabriel Fernandez 334088238adSNicolas Le Bayon static const struct parent_cfg parent_mp2[] = { 335615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL0, muxsel_src, RCC_MUXSELCFGR, 0, 2), 336615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL1, muxsel_src, RCC_MUXSELCFGR, 4, 2), 337615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL2, muxsel_src, RCC_MUXSELCFGR, 8, 2), 338615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL3, muxsel_src, RCC_MUXSELCFGR, 12, 2), 339615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL4, muxsel_src, RCC_MUXSELCFGR, 16, 2), 340615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL5, muxsel_src, RCC_MUXSELCFGR, 20, 2), 341615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL6, muxsel_src, RCC_MUXSELCFGR, 24, 2), 342615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL7, muxsel_src, RCC_MUXSELCFGR, 28, 2), 343615f31feSGabriel Fernandez MUX_CONF(MUX_XBARSEL, xbarsel_src, RCC_XBAR0CFGR, 0, 4), 344615f31feSGabriel Fernandez MUX_CONF(MUX_RTC, rtc_src, RCC_BDCR, 16, 2), 345615f31feSGabriel Fernandez MUX_CONF(MUX_USB2PHY1, usb2phy1_src, RCC_USB2PHY1CFGR, 15, 1), 346615f31feSGabriel Fernandez MUX_CONF(MUX_USB2PHY2, usb2phy2_src, RCC_USB2PHY2CFGR, 15, 1), 347088238adSNicolas Le Bayon #if !STM32MP21 348615f31feSGabriel Fernandez MUX_CONF(MUX_USB3PCIEPHY, usb3pciphy_src, RCC_USB3PCIEPHYCFGR, 15, 1), 349615f31feSGabriel Fernandez MUX_CONF(MUX_D3PER, d3per_src, RCC_D3DCR, 16, 2), 350088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 351615f31feSGabriel Fernandez }; 352615f31feSGabriel Fernandez 353615f31feSGabriel Fernandez /* GATES */ 354615f31feSGabriel Fernandez enum enum_gate_cfg { 355615f31feSGabriel Fernandez GATE_ZERO, /* reserved for no gate */ 356615f31feSGabriel Fernandez GATE_LSE, 357615f31feSGabriel Fernandez GATE_RTCCK, 358615f31feSGabriel Fernandez GATE_LSI, 359615f31feSGabriel Fernandez GATE_HSI, 360615f31feSGabriel Fernandez GATE_MSI, 361615f31feSGabriel Fernandez GATE_HSE, 362615f31feSGabriel Fernandez GATE_LSI_RDY, 363615f31feSGabriel Fernandez GATE_MSI_RDY, 364615f31feSGabriel Fernandez GATE_LSE_RDY, 365615f31feSGabriel Fernandez GATE_HSE_RDY, 366615f31feSGabriel Fernandez GATE_HSI_RDY, 367615f31feSGabriel Fernandez GATE_SYSRAM, 368615f31feSGabriel Fernandez GATE_RETRAM, 369615f31feSGabriel Fernandez GATE_SRAM1, 370088238adSNicolas Le Bayon #if !STM32MP21 371615f31feSGabriel Fernandez GATE_SRAM2, 372088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 373615f31feSGabriel Fernandez 374615f31feSGabriel Fernandez GATE_DDRPHYC, 375615f31feSGabriel Fernandez GATE_SYSCPU1, 376615f31feSGabriel Fernandez GATE_CRC, 377088238adSNicolas Le Bayon #if !STM32MP21 378615f31feSGabriel Fernandez GATE_OSPIIOM, 379088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 380615f31feSGabriel Fernandez GATE_BKPSRAM, 381088238adSNicolas Le Bayon #if STM32MP21 382088238adSNicolas Le Bayon GATE_HASH1, 383088238adSNicolas Le Bayon GATE_HASH2, 384088238adSNicolas Le Bayon GATE_RNG1, 385088238adSNicolas Le Bayon GATE_RNG2, 386088238adSNicolas Le Bayon #else /* STM32MP21 */ 387615f31feSGabriel Fernandez GATE_HASH, 388615f31feSGabriel Fernandez GATE_RNG, 389088238adSNicolas Le Bayon #endif /* STM32MP21 */ 390615f31feSGabriel Fernandez GATE_CRYP1, 391615f31feSGabriel Fernandez GATE_CRYP2, 392615f31feSGabriel Fernandez GATE_SAES, 393615f31feSGabriel Fernandez GATE_PKA, 394615f31feSGabriel Fernandez 395615f31feSGabriel Fernandez GATE_GPIOA, 396615f31feSGabriel Fernandez GATE_GPIOB, 397615f31feSGabriel Fernandez GATE_GPIOC, 398615f31feSGabriel Fernandez GATE_GPIOD, 399615f31feSGabriel Fernandez GATE_GPIOE, 400615f31feSGabriel Fernandez GATE_GPIOF, 401615f31feSGabriel Fernandez GATE_GPIOG, 402615f31feSGabriel Fernandez GATE_GPIOH, 403615f31feSGabriel Fernandez GATE_GPIOI, 404088238adSNicolas Le Bayon #if !STM32MP21 405615f31feSGabriel Fernandez GATE_GPIOJ, 406615f31feSGabriel Fernandez GATE_GPIOK, 407088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 408615f31feSGabriel Fernandez GATE_GPIOZ, 409615f31feSGabriel Fernandez GATE_RTC, 410615f31feSGabriel Fernandez 411615f31feSGabriel Fernandez GATE_DDRCP, 412615f31feSGabriel Fernandez 413615f31feSGabriel Fernandez /* WARNING 2 CLOCKS FOR ONE GATE */ 414088238adSNicolas Le Bayon #if STM32MP21 415088238adSNicolas Le Bayon GATE_USBHOHCI, 416088238adSNicolas Le Bayon GATE_USBHEHCI, 417088238adSNicolas Le Bayon #else /* STM32MP21 */ 418615f31feSGabriel Fernandez GATE_USB2OHCI, 419615f31feSGabriel Fernandez GATE_USB2EHCI, 420088238adSNicolas Le Bayon #endif /* STM32MP21 */ 421615f31feSGabriel Fernandez 422088238adSNicolas Le Bayon #if !STM32MP21 423615f31feSGabriel Fernandez GATE_USB3DR, 424088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 425615f31feSGabriel Fernandez 426615f31feSGabriel Fernandez GATE_BSEC, 427615f31feSGabriel Fernandez GATE_IWDG1, 428615f31feSGabriel Fernandez GATE_IWDG2, 429615f31feSGabriel Fernandez 430615f31feSGabriel Fernandez GATE_DDRCAPB, 431615f31feSGabriel Fernandez GATE_DDR, 432615f31feSGabriel Fernandez 433615f31feSGabriel Fernandez GATE_USART2, 434615f31feSGabriel Fernandez GATE_UART4, 435615f31feSGabriel Fernandez GATE_USART3, 436615f31feSGabriel Fernandez GATE_UART5, 437615f31feSGabriel Fernandez GATE_I2C1, 438615f31feSGabriel Fernandez GATE_I2C2, 439088238adSNicolas Le Bayon #if !STM32MP23 440615f31feSGabriel Fernandez GATE_I2C3, 441088238adSNicolas Le Bayon #endif /* !STM32MP23 */ 442088238adSNicolas Le Bayon #if STM32MP25 443615f31feSGabriel Fernandez GATE_I2C5, 444615f31feSGabriel Fernandez GATE_I2C4, 445615f31feSGabriel Fernandez GATE_I2C6, 446088238adSNicolas Le Bayon #endif /* STM32MP25 */ 447088238adSNicolas Le Bayon #if !STM32MP21 448615f31feSGabriel Fernandez GATE_I2C7, 449088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 450615f31feSGabriel Fernandez GATE_USART1, 451615f31feSGabriel Fernandez GATE_USART6, 452615f31feSGabriel Fernandez GATE_UART7, 453088238adSNicolas Le Bayon #if STM32MP25 454615f31feSGabriel Fernandez GATE_UART8, 455615f31feSGabriel Fernandez GATE_UART9, 456088238adSNicolas Le Bayon #endif /* STM32MP25 */ 457615f31feSGabriel Fernandez GATE_STGEN, 458088238adSNicolas Le Bayon #if !STM32MP21 459615f31feSGabriel Fernandez GATE_USB3PCIEPHY, 460615f31feSGabriel Fernandez GATE_USBTC, 461615f31feSGabriel Fernandez GATE_I2C8, 462088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 463615f31feSGabriel Fernandez GATE_OSPI1, 464088238adSNicolas Le Bayon #if !STM32MP21 465615f31feSGabriel Fernandez GATE_OSPI2, 466088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 467615f31feSGabriel Fernandez GATE_FMC, 468615f31feSGabriel Fernandez GATE_SDMMC1, 469615f31feSGabriel Fernandez GATE_SDMMC2, 470615f31feSGabriel Fernandez GATE_USB2PHY1, 471615f31feSGabriel Fernandez GATE_USB2PHY2, 472615f31feSGabriel Fernandez LAST_GATE 473615f31feSGabriel Fernandez }; 474615f31feSGabriel Fernandez 475615f31feSGabriel Fernandez #define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\ 476615f31feSGabriel Fernandez .offset = (_offset),\ 477615f31feSGabriel Fernandez .bit_idx = (_bit_idx),\ 478615f31feSGabriel Fernandez .set_clr = (_offset_clr),\ 479615f31feSGabriel Fernandez } 480615f31feSGabriel Fernandez 481088238adSNicolas Le Bayon static const struct gate_cfg gates_mp2[LAST_GATE] = { 482615f31feSGabriel Fernandez GATE_CFG(GATE_LSE, RCC_BDCR, 0, 0), 483088238adSNicolas Le Bayon #if STM32MP21 484088238adSNicolas Le Bayon GATE_CFG(GATE_LSI, RCC_LSICR, 0, 0), 485088238adSNicolas Le Bayon #else /* STM32MP21 */ 486615f31feSGabriel Fernandez GATE_CFG(GATE_LSI, RCC_BDCR, 9, 0), 487088238adSNicolas Le Bayon #endif /* STM32MP21 */ 488615f31feSGabriel Fernandez GATE_CFG(GATE_RTCCK, RCC_BDCR, 20, 0), 489615f31feSGabriel Fernandez GATE_CFG(GATE_HSI, RCC_OCENSETR, 0, 1), 490615f31feSGabriel Fernandez GATE_CFG(GATE_HSE, RCC_OCENSETR, 8, 1), 491088238adSNicolas Le Bayon #if STM32MP21 492088238adSNicolas Le Bayon GATE_CFG(GATE_MSI, RCC_OCENSETR, 2, 0), 493088238adSNicolas Le Bayon #else /* STM32MP21 */ 494615f31feSGabriel Fernandez GATE_CFG(GATE_MSI, RCC_D3DCR, 0, 0), 495088238adSNicolas Le Bayon #endif /* STM32MP21 */ 496615f31feSGabriel Fernandez 497088238adSNicolas Le Bayon #if STM32MP21 498088238adSNicolas Le Bayon GATE_CFG(GATE_LSI_RDY, RCC_LSICR, 1, 0), 499088238adSNicolas Le Bayon #else /* STM32MP21 */ 500615f31feSGabriel Fernandez GATE_CFG(GATE_LSI_RDY, RCC_BDCR, 10, 0), 501088238adSNicolas Le Bayon #endif /* STM32MP21 */ 502615f31feSGabriel Fernandez GATE_CFG(GATE_LSE_RDY, RCC_BDCR, 2, 0), 503088238adSNicolas Le Bayon #if STM32MP21 504088238adSNicolas Le Bayon GATE_CFG(GATE_MSI_RDY, RCC_OCRDYR, 2, 0), 505088238adSNicolas Le Bayon #else /* STM32MP21 */ 506615f31feSGabriel Fernandez GATE_CFG(GATE_MSI_RDY, RCC_D3DCR, 2, 0), 507088238adSNicolas Le Bayon #endif /* STM32MP21 */ 508615f31feSGabriel Fernandez GATE_CFG(GATE_HSE_RDY, RCC_OCRDYR, 8, 0), 509615f31feSGabriel Fernandez GATE_CFG(GATE_HSI_RDY, RCC_OCRDYR, 0, 0), 510615f31feSGabriel Fernandez GATE_CFG(GATE_SYSRAM, RCC_SYSRAMCFGR, 1, 0), 511615f31feSGabriel Fernandez GATE_CFG(GATE_RETRAM, RCC_RETRAMCFGR, 1, 0), 512615f31feSGabriel Fernandez GATE_CFG(GATE_SRAM1, RCC_SRAM1CFGR, 1, 0), 513088238adSNicolas Le Bayon #if !STM32MP21 514615f31feSGabriel Fernandez GATE_CFG(GATE_SRAM2, RCC_SRAM2CFGR, 1, 0), 515088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 516615f31feSGabriel Fernandez GATE_CFG(GATE_DDRPHYC, RCC_DDRPHYCAPBCFGR, 1, 0), 517615f31feSGabriel Fernandez GATE_CFG(GATE_SYSCPU1, RCC_SYSCPU1CFGR, 1, 0), 518615f31feSGabriel Fernandez GATE_CFG(GATE_CRC, RCC_CRCCFGR, 1, 0), 519088238adSNicolas Le Bayon #if !STM32MP21 520615f31feSGabriel Fernandez GATE_CFG(GATE_OSPIIOM, RCC_OSPIIOMCFGR, 1, 0), 521088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 522615f31feSGabriel Fernandez GATE_CFG(GATE_BKPSRAM, RCC_BKPSRAMCFGR, 1, 0), 523088238adSNicolas Le Bayon #if STM32MP21 524088238adSNicolas Le Bayon GATE_CFG(GATE_HASH1, RCC_HASH1CFGR, 1, 0), 525088238adSNicolas Le Bayon GATE_CFG(GATE_HASH2, RCC_HASH2CFGR, 1, 0), 526088238adSNicolas Le Bayon GATE_CFG(GATE_RNG1, RCC_RNG1CFGR, 1, 0), 527088238adSNicolas Le Bayon GATE_CFG(GATE_RNG2, RCC_RNG2CFGR, 1, 0), 528088238adSNicolas Le Bayon #else /* STM32MP21 */ 529615f31feSGabriel Fernandez GATE_CFG(GATE_HASH, RCC_HASHCFGR, 1, 0), 530615f31feSGabriel Fernandez GATE_CFG(GATE_RNG, RCC_RNGCFGR, 1, 0), 531088238adSNicolas Le Bayon #endif /* STM32MP21 */ 532615f31feSGabriel Fernandez GATE_CFG(GATE_CRYP1, RCC_CRYP1CFGR, 1, 0), 533615f31feSGabriel Fernandez GATE_CFG(GATE_CRYP2, RCC_CRYP2CFGR, 1, 0), 534615f31feSGabriel Fernandez GATE_CFG(GATE_SAES, RCC_SAESCFGR, 1, 0), 535615f31feSGabriel Fernandez GATE_CFG(GATE_PKA, RCC_PKACFGR, 1, 0), 536615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOA, RCC_GPIOACFGR, 1, 0), 537615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOB, RCC_GPIOBCFGR, 1, 0), 538615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOC, RCC_GPIOCCFGR, 1, 0), 539615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOD, RCC_GPIODCFGR, 1, 0), 540615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOE, RCC_GPIOECFGR, 1, 0), 541615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOF, RCC_GPIOFCFGR, 1, 0), 542615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOG, RCC_GPIOGCFGR, 1, 0), 543615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOH, RCC_GPIOHCFGR, 1, 0), 544615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOI, RCC_GPIOICFGR, 1, 0), 545088238adSNicolas Le Bayon #if !STM32MP21 546615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOJ, RCC_GPIOJCFGR, 1, 0), 547615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOK, RCC_GPIOKCFGR, 1, 0), 548088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 549615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOZ, RCC_GPIOZCFGR, 1, 0), 550615f31feSGabriel Fernandez GATE_CFG(GATE_RTC, RCC_RTCCFGR, 1, 0), 551615f31feSGabriel Fernandez GATE_CFG(GATE_DDRCP, RCC_DDRCPCFGR, 1, 0), 552615f31feSGabriel Fernandez 553615f31feSGabriel Fernandez /* WARNING 2 CLOCKS FOR ONE GATE */ 554088238adSNicolas Le Bayon #if STM32MP21 555088238adSNicolas Le Bayon GATE_CFG(GATE_USBHOHCI, RCC_USBHCFGR, 1, 0), 556088238adSNicolas Le Bayon GATE_CFG(GATE_USBHEHCI, RCC_USBHCFGR, 1, 0), 557088238adSNicolas Le Bayon #else /* STM32MP21 */ 558615f31feSGabriel Fernandez GATE_CFG(GATE_USB2OHCI, RCC_USB2CFGR, 1, 0), 559615f31feSGabriel Fernandez GATE_CFG(GATE_USB2EHCI, RCC_USB2CFGR, 1, 0), 560615f31feSGabriel Fernandez GATE_CFG(GATE_USB3DR, RCC_USB3DRCFGR, 1, 0), 561088238adSNicolas Le Bayon #endif /* STM32MP21 */ 562615f31feSGabriel Fernandez GATE_CFG(GATE_BSEC, RCC_BSECCFGR, 1, 0), 563615f31feSGabriel Fernandez GATE_CFG(GATE_IWDG1, RCC_IWDG1CFGR, 1, 0), 564615f31feSGabriel Fernandez GATE_CFG(GATE_IWDG2, RCC_IWDG2CFGR, 1, 0), 565615f31feSGabriel Fernandez GATE_CFG(GATE_DDRCAPB, RCC_DDRCAPBCFGR, 1, 0), 566615f31feSGabriel Fernandez GATE_CFG(GATE_DDR, RCC_DDRCFGR, 1, 0), 567615f31feSGabriel Fernandez GATE_CFG(GATE_USART2, RCC_USART2CFGR, 1, 0), 568615f31feSGabriel Fernandez GATE_CFG(GATE_UART4, RCC_UART4CFGR, 1, 0), 569615f31feSGabriel Fernandez GATE_CFG(GATE_USART3, RCC_USART3CFGR, 1, 0), 570615f31feSGabriel Fernandez GATE_CFG(GATE_UART5, RCC_UART5CFGR, 1, 0), 571615f31feSGabriel Fernandez GATE_CFG(GATE_I2C1, RCC_I2C1CFGR, 1, 0), 572615f31feSGabriel Fernandez GATE_CFG(GATE_I2C2, RCC_I2C2CFGR, 1, 0), 573088238adSNicolas Le Bayon #if !STM32MP23 574615f31feSGabriel Fernandez GATE_CFG(GATE_I2C3, RCC_I2C3CFGR, 1, 0), 575088238adSNicolas Le Bayon #endif /* !STM32MP23 */ 576088238adSNicolas Le Bayon #if STM32MP25 577615f31feSGabriel Fernandez GATE_CFG(GATE_I2C5, RCC_I2C5CFGR, 1, 0), 578615f31feSGabriel Fernandez GATE_CFG(GATE_I2C4, RCC_I2C4CFGR, 1, 0), 579615f31feSGabriel Fernandez GATE_CFG(GATE_I2C6, RCC_I2C6CFGR, 1, 0), 580088238adSNicolas Le Bayon #endif /* STM32MP25 */ 581088238adSNicolas Le Bayon #if !STM32MP21 582615f31feSGabriel Fernandez GATE_CFG(GATE_I2C7, RCC_I2C7CFGR, 1, 0), 583088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 584615f31feSGabriel Fernandez GATE_CFG(GATE_USART1, RCC_USART1CFGR, 1, 0), 585615f31feSGabriel Fernandez GATE_CFG(GATE_USART6, RCC_USART6CFGR, 1, 0), 586615f31feSGabriel Fernandez GATE_CFG(GATE_UART7, RCC_UART7CFGR, 1, 0), 587088238adSNicolas Le Bayon #if STM32MP25 588615f31feSGabriel Fernandez GATE_CFG(GATE_UART8, RCC_UART8CFGR, 1, 0), 589615f31feSGabriel Fernandez GATE_CFG(GATE_UART9, RCC_UART9CFGR, 1, 0), 590088238adSNicolas Le Bayon #endif /* STM32MP25 */ 591615f31feSGabriel Fernandez GATE_CFG(GATE_STGEN, RCC_STGENCFGR, 1, 0), 592088238adSNicolas Le Bayon #if !STM32MP21 593615f31feSGabriel Fernandez GATE_CFG(GATE_USB3PCIEPHY, RCC_USB3PCIEPHYCFGR, 1, 0), 594615f31feSGabriel Fernandez GATE_CFG(GATE_USBTC, RCC_USBTCCFGR, 1, 0), 595615f31feSGabriel Fernandez GATE_CFG(GATE_I2C8, RCC_I2C8CFGR, 1, 0), 596088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 597615f31feSGabriel Fernandez GATE_CFG(GATE_OSPI1, RCC_OSPI1CFGR, 1, 0), 598088238adSNicolas Le Bayon #if !STM32MP21 599615f31feSGabriel Fernandez GATE_CFG(GATE_OSPI2, RCC_OSPI2CFGR, 1, 0), 600088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 601615f31feSGabriel Fernandez GATE_CFG(GATE_FMC, RCC_FMCCFGR, 1, 0), 602615f31feSGabriel Fernandez GATE_CFG(GATE_SDMMC1, RCC_SDMMC1CFGR, 1, 0), 603615f31feSGabriel Fernandez GATE_CFG(GATE_SDMMC2, RCC_SDMMC2CFGR, 1, 0), 604615f31feSGabriel Fernandez GATE_CFG(GATE_USB2PHY1, RCC_USB2PHY1CFGR, 1, 0), 605615f31feSGabriel Fernandez GATE_CFG(GATE_USB2PHY2, RCC_USB2PHY2CFGR, 1, 0), 606615f31feSGabriel Fernandez }; 607615f31feSGabriel Fernandez 608615f31feSGabriel Fernandez static const struct clk_div_table apb_div_table[] = { 609615f31feSGabriel Fernandez { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, { 4, 16 }, 610615f31feSGabriel Fernandez { 5, 16 }, { 6, 16 }, { 7, 16 }, { 0 }, 611615f31feSGabriel Fernandez }; 612615f31feSGabriel Fernandez 613615f31feSGabriel Fernandez #undef DIV_CFG 614615f31feSGabriel Fernandez #define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\ 615615f31feSGabriel Fernandez .offset = _offset,\ 616615f31feSGabriel Fernandez .shift = _shift,\ 617615f31feSGabriel Fernandez .width = _width,\ 618615f31feSGabriel Fernandez .flags = _flags,\ 619615f31feSGabriel Fernandez .table = _table,\ 620615f31feSGabriel Fernandez .bitrdy = _bitrdy,\ 621615f31feSGabriel Fernandez } 622615f31feSGabriel Fernandez 623088238adSNicolas Le Bayon static const struct div_cfg dividers_mp2[] = { 624615f31feSGabriel Fernandez DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31), 625615f31feSGabriel Fernandez DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31), 626615f31feSGabriel Fernandez DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31), 627615f31feSGabriel Fernandez DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31), 628088238adSNicolas Le Bayon #if STM32MP21 629088238adSNicolas Le Bayon DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, 31), 630088238adSNicolas Le Bayon #endif /* STM32MP21 */ 631615f31feSGabriel Fernandez DIV_CFG(DIV_APBDBG, RCC_APBDBGDIVR, 0, 3, 0, apb_div_table, 31), 632615f31feSGabriel Fernandez DIV_CFG(DIV_LSMCU, RCC_LSMCUDIVR, 0, 1, 0, NULL, 31), 633615f31feSGabriel Fernandez DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, 0), 634615f31feSGabriel Fernandez }; 635615f31feSGabriel Fernandez 636615f31feSGabriel Fernandez enum stm32_osc { 637615f31feSGabriel Fernandez OSC_HSI, 638615f31feSGabriel Fernandez OSC_HSE, 639615f31feSGabriel Fernandez OSC_MSI, 640615f31feSGabriel Fernandez OSC_LSI, 641615f31feSGabriel Fernandez OSC_LSE, 642615f31feSGabriel Fernandez OSC_I2SCKIN, 643615f31feSGabriel Fernandez OSC_SPDIFSYMB, 644615f31feSGabriel Fernandez NB_OSCILLATOR 645615f31feSGabriel Fernandez }; 646615f31feSGabriel Fernandez 647088238adSNicolas Le Bayon static struct clk_oscillator_data stm32mp2_osc_data[] = { 648615f31feSGabriel Fernandez OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY, 649615f31feSGabriel Fernandez NULL, NULL, NULL), 650615f31feSGabriel Fernandez 651615f31feSGabriel Fernandez OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY, 652615f31feSGabriel Fernandez NULL, NULL, NULL), 653615f31feSGabriel Fernandez 654615f31feSGabriel Fernandez OSCILLATOR(OSC_MSI, _CK_MSI, "clk-msi", GATE_MSI, GATE_MSI_RDY, 655615f31feSGabriel Fernandez NULL, NULL, NULL), 656615f31feSGabriel Fernandez 657615f31feSGabriel Fernandez OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY, 658615f31feSGabriel Fernandez BYPASS(RCC_OCENSETR, 10, 7), 659615f31feSGabriel Fernandez CSS(RCC_OCENSETR, 11), 660615f31feSGabriel Fernandez NULL), 661615f31feSGabriel Fernandez 662615f31feSGabriel Fernandez OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY, 663615f31feSGabriel Fernandez BYPASS(RCC_BDCR, 1, 3), 664615f31feSGabriel Fernandez CSS(RCC_BDCR, 8), 665615f31feSGabriel Fernandez DRIVE(RCC_BDCR, 4, 2, 2)), 666615f31feSGabriel Fernandez 667615f31feSGabriel Fernandez OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE, 668615f31feSGabriel Fernandez NULL, NULL, NULL), 669615f31feSGabriel Fernandez 670615f31feSGabriel Fernandez OSCILLATOR(OSC_SPDIFSYMB, _SPDIFSYMB, "spdif_symb", NO_GATE, NO_GATE, 671615f31feSGabriel Fernandez NULL, NULL, NULL), 672615f31feSGabriel Fernandez }; 673615f31feSGabriel Fernandez 674615f31feSGabriel Fernandez #ifdef IMAGE_BL2 675615f31feSGabriel Fernandez static const char *clk_stm32_get_oscillator_name(enum stm32_osc id) 676615f31feSGabriel Fernandez { 677615f31feSGabriel Fernandez if (id < NB_OSCILLATOR) { 678088238adSNicolas Le Bayon return stm32mp2_osc_data[id].name; 679615f31feSGabriel Fernandez } 680615f31feSGabriel Fernandez 681615f31feSGabriel Fernandez return NULL; 682615f31feSGabriel Fernandez } 683615f31feSGabriel Fernandez #endif 684615f31feSGabriel Fernandez 685615f31feSGabriel Fernandez enum pll_id { 686615f31feSGabriel Fernandez _PLL1, 687615f31feSGabriel Fernandez _PLL2, 688615f31feSGabriel Fernandez _PLL3, 689615f31feSGabriel Fernandez _PLL4, 690615f31feSGabriel Fernandez _PLL5, 691615f31feSGabriel Fernandez _PLL6, 692615f31feSGabriel Fernandez _PLL7, 693615f31feSGabriel Fernandez _PLL8, 694615f31feSGabriel Fernandez _PLL_NB 695615f31feSGabriel Fernandez }; 696615f31feSGabriel Fernandez 697615f31feSGabriel Fernandez /* PLL configuration registers offsets from RCC_PLLxCFGR1 */ 698615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR1 0x00 699615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR2 0x04 700615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR3 0x08 701615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR4 0x0C 702615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR5 0x10 703615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR6 0x18 704615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR7 0x1C 705615f31feSGabriel Fernandez 706615f31feSGabriel Fernandez struct stm32_clk_pll { 707615f31feSGabriel Fernandez uint16_t clk_id; 708615f31feSGabriel Fernandez uint16_t reg_pllxcfgr1; 709615f31feSGabriel Fernandez }; 710615f31feSGabriel Fernandez 711615f31feSGabriel Fernandez #define CLK_PLL_CFG(_idx, _clk_id, _reg)\ 712615f31feSGabriel Fernandez [(_idx)] = {\ 713615f31feSGabriel Fernandez .clk_id = (_clk_id),\ 714615f31feSGabriel Fernandez .reg_pllxcfgr1 = (_reg),\ 715615f31feSGabriel Fernandez } 716615f31feSGabriel Fernandez 717088238adSNicolas Le Bayon static const struct stm32_clk_pll stm32mp2_clk_pll[_PLL_NB] = { 718615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL1, _CK_PLL1, A35_SS_CHGCLKREQ), 719615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL2, _CK_PLL2, RCC_PLL2CFGR1), 720088238adSNicolas Le Bayon #if !STM32MP21 721615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL3, _CK_PLL3, RCC_PLL3CFGR1), 722088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 723615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL4, _CK_PLL4, RCC_PLL4CFGR1), 724615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL5, _CK_PLL5, RCC_PLL5CFGR1), 725615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL6, _CK_PLL6, RCC_PLL6CFGR1), 726615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL7, _CK_PLL7, RCC_PLL7CFGR1), 727615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL8, _CK_PLL8, RCC_PLL8CFGR1), 728615f31feSGabriel Fernandez }; 729615f31feSGabriel Fernandez 730615f31feSGabriel Fernandez static const struct stm32_clk_pll *clk_stm32_pll_data(unsigned int idx) 731615f31feSGabriel Fernandez { 732088238adSNicolas Le Bayon return &stm32mp2_clk_pll[idx]; 733615f31feSGabriel Fernandez } 734615f31feSGabriel Fernandez 735615f31feSGabriel Fernandez static unsigned long clk_get_pll_fvco(struct stm32_clk_priv *priv, 736615f31feSGabriel Fernandez const struct stm32_clk_pll *pll, 737615f31feSGabriel Fernandez unsigned long prate) 738615f31feSGabriel Fernandez { 739615f31feSGabriel Fernandez unsigned long refclk, fvco; 740615f31feSGabriel Fernandez uint32_t fracin, fbdiv, refdiv; 741615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 742615f31feSGabriel Fernandez uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2; 743615f31feSGabriel Fernandez uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3; 744615f31feSGabriel Fernandez 745615f31feSGabriel Fernandez refclk = prate; 746615f31feSGabriel Fernandez 747615f31feSGabriel Fernandez fracin = mmio_read_32(pllxcfgr3) & RCC_PLLxCFGR3_FRACIN_MASK; 748615f31feSGabriel Fernandez fbdiv = (mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FBDIV_MASK) >> 749615f31feSGabriel Fernandez RCC_PLLxCFGR2_FBDIV_SHIFT; 750615f31feSGabriel Fernandez refdiv = mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FREFDIV_MASK; 751615f31feSGabriel Fernandez 752615f31feSGabriel Fernandez if (fracin != 0U) { 753615f31feSGabriel Fernandez uint64_t numerator, denominator; 754615f31feSGabriel Fernandez 755615f31feSGabriel Fernandez numerator = ((uint64_t)fbdiv << 24) + fracin; 756615f31feSGabriel Fernandez numerator = refclk * numerator; 757615f31feSGabriel Fernandez denominator = (uint64_t)refdiv << 24; 758615f31feSGabriel Fernandez fvco = (unsigned long)(numerator / denominator); 759615f31feSGabriel Fernandez } else { 760615f31feSGabriel Fernandez fvco = (unsigned long)(refclk * fbdiv / refdiv); 761615f31feSGabriel Fernandez } 762615f31feSGabriel Fernandez 763615f31feSGabriel Fernandez return fvco; 764615f31feSGabriel Fernandez } 765615f31feSGabriel Fernandez 766615f31feSGabriel Fernandez struct stm32_pll_cfg { 767615f31feSGabriel Fernandez uint16_t pll_id; 768615f31feSGabriel Fernandez }; 769615f31feSGabriel Fernandez 770615f31feSGabriel Fernandez static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 771615f31feSGabriel Fernandez { 772615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 773615f31feSGabriel Fernandez 774615f31feSGabriel Fernandez return ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLEN) != 0U); 775615f31feSGabriel Fernandez } 776615f31feSGabriel Fernandez 777615f31feSGabriel Fernandez static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 778615f31feSGabriel Fernandez { 779615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 780615f31feSGabriel Fernandez 781615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN); 782615f31feSGabriel Fernandez } 783615f31feSGabriel Fernandez 784615f31feSGabriel Fernandez static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 785615f31feSGabriel Fernandez { 786615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 787615f31feSGabriel Fernandez 788615f31feSGabriel Fernandez /* Stop PLL */ 789615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN); 790615f31feSGabriel Fernandez } 791615f31feSGabriel Fernandez 792615f31feSGabriel Fernandez static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv, 793615f31feSGabriel Fernandez const struct stm32_clk_pll *pll) 794615f31feSGabriel Fernandez { 795615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 796615f31feSGabriel Fernandez uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT); 797615f31feSGabriel Fernandez 798615f31feSGabriel Fernandez /* Wait PLL lock */ 799615f31feSGabriel Fernandez while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) == 0U) { 800615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 801615f31feSGabriel Fernandez ERROR("PLL%d start failed @ 0x%x: 0x%x\n", 802615f31feSGabriel Fernandez pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcfgr1, 803615f31feSGabriel Fernandez mmio_read_32(pllxcfgr1)); 804615f31feSGabriel Fernandez return -ETIMEDOUT; 805615f31feSGabriel Fernandez } 806615f31feSGabriel Fernandez } 807615f31feSGabriel Fernandez 808615f31feSGabriel Fernandez return 0; 809615f31feSGabriel Fernandez } 810615f31feSGabriel Fernandez 811615f31feSGabriel Fernandez static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv, 812615f31feSGabriel Fernandez const struct stm32_clk_pll *pll) 813615f31feSGabriel Fernandez { 814615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 815615f31feSGabriel Fernandez uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT); 816615f31feSGabriel Fernandez 817615f31feSGabriel Fernandez /* Wait PLL stopped */ 818615f31feSGabriel Fernandez while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) != 0U) { 819615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 820615f31feSGabriel Fernandez ERROR("PLL%d stop failed @ 0x%lx: 0x%x\n", 821615f31feSGabriel Fernandez pll->clk_id - _CK_PLL1 + 1, pllxcfgr1, mmio_read_32(pllxcfgr1)); 822615f31feSGabriel Fernandez return -ETIMEDOUT; 823615f31feSGabriel Fernandez } 824615f31feSGabriel Fernandez } 825615f31feSGabriel Fernandez 826615f31feSGabriel Fernandez return 0; 827615f31feSGabriel Fernandez } 828615f31feSGabriel Fernandez 829615f31feSGabriel Fernandez static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 830615f31feSGabriel Fernandez { 831615f31feSGabriel Fernandez if (_clk_stm32_pll_is_enabled(priv, pll)) { 832615f31feSGabriel Fernandez return 0; 833615f31feSGabriel Fernandez } 834615f31feSGabriel Fernandez 835615f31feSGabriel Fernandez _clk_stm32_pll_set_on(priv, pll); 836615f31feSGabriel Fernandez 837615f31feSGabriel Fernandez return _clk_stm32_pll_wait_ready_on(priv, pll); 838615f31feSGabriel Fernandez } 839615f31feSGabriel Fernandez 840615f31feSGabriel Fernandez static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 841615f31feSGabriel Fernandez { 842615f31feSGabriel Fernandez if (!_clk_stm32_pll_is_enabled(priv, pll)) { 843615f31feSGabriel Fernandez return; 844615f31feSGabriel Fernandez } 845615f31feSGabriel Fernandez 846615f31feSGabriel Fernandez _clk_stm32_pll_set_off(priv, pll); 847615f31feSGabriel Fernandez 848615f31feSGabriel Fernandez _clk_stm32_pll_wait_ready_off(priv, pll); 849615f31feSGabriel Fernandez } 850615f31feSGabriel Fernandez 851615f31feSGabriel Fernandez static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id) 852615f31feSGabriel Fernandez { 853615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 854615f31feSGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 855615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id); 856615f31feSGabriel Fernandez 857615f31feSGabriel Fernandez return _clk_stm32_pll_is_enabled(priv, pll); 858615f31feSGabriel Fernandez } 859615f31feSGabriel Fernandez 860615f31feSGabriel Fernandez static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id) 861615f31feSGabriel Fernandez { 862615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 863615f31feSGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 864615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id); 865615f31feSGabriel Fernandez 866615f31feSGabriel Fernandez return _clk_stm32_pll_enable(priv, pll); 867615f31feSGabriel Fernandez } 868615f31feSGabriel Fernandez 869615f31feSGabriel Fernandez static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id) 870615f31feSGabriel Fernandez { 871615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 872615f31feSGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 873615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id); 874615f31feSGabriel Fernandez 875615f31feSGabriel Fernandez _clk_stm32_pll_disable(priv, pll); 876615f31feSGabriel Fernandez } 877615f31feSGabriel Fernandez 878615f31feSGabriel Fernandez static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id, 879615f31feSGabriel Fernandez unsigned long prate) 880615f31feSGabriel Fernandez { 881615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 882615f31feSGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 883615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id); 884615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 885615f31feSGabriel Fernandez uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4; 886615f31feSGabriel Fernandez uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6; 887615f31feSGabriel Fernandez uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7; 888615f31feSGabriel Fernandez unsigned long dfout; 889615f31feSGabriel Fernandez uint32_t postdiv1, postdiv2; 890615f31feSGabriel Fernandez 891615f31feSGabriel Fernandez postdiv1 = mmio_read_32(pllxcfgr6) & RCC_PLLxCFGR6_POSTDIV1_MASK; 892615f31feSGabriel Fernandez postdiv2 = mmio_read_32(pllxcfgr7) & RCC_PLLxCFGR7_POSTDIV2_MASK; 893615f31feSGabriel Fernandez 894615f31feSGabriel Fernandez if ((mmio_read_32(pllxcfgr4) & RCC_PLLxCFGR4_BYPASS) != 0U) { 895615f31feSGabriel Fernandez dfout = prate; 896615f31feSGabriel Fernandez } else { 897615f31feSGabriel Fernandez if ((postdiv1 == 0U) || (postdiv2 == 0U)) { 898615f31feSGabriel Fernandez dfout = prate; 899615f31feSGabriel Fernandez } else { 900615f31feSGabriel Fernandez dfout = clk_get_pll_fvco(priv, pll, prate) / (postdiv1 * postdiv2); 901615f31feSGabriel Fernandez } 902615f31feSGabriel Fernandez } 903615f31feSGabriel Fernandez 904615f31feSGabriel Fernandez return dfout; 905615f31feSGabriel Fernandez } 906615f31feSGabriel Fernandez 907615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_pll_ops = { 908615f31feSGabriel Fernandez .recalc_rate = clk_stm32_pll_recalc_rate, 909615f31feSGabriel Fernandez .enable = clk_stm32_pll_enable, 910615f31feSGabriel Fernandez .disable = clk_stm32_pll_disable, 911615f31feSGabriel Fernandez .is_enabled = clk_stm32_pll_is_enabled, 912615f31feSGabriel Fernandez }; 913615f31feSGabriel Fernandez 914615f31feSGabriel Fernandez #define CLK_PLL(idx, _idx, _parent, _pll_id, _flags)[idx] = {\ 915615f31feSGabriel Fernandez .binding = _idx,\ 916615f31feSGabriel Fernandez .parent = _parent,\ 917615f31feSGabriel Fernandez .flags = (_flags),\ 918615f31feSGabriel Fernandez .clock_cfg = &(struct stm32_pll_cfg) {\ 919615f31feSGabriel Fernandez .pll_id = _pll_id,\ 920615f31feSGabriel Fernandez },\ 921615f31feSGabriel Fernandez .ops = STM32_PLL_OPS,\ 922615f31feSGabriel Fernandez } 923615f31feSGabriel Fernandez 924615f31feSGabriel Fernandez static unsigned long clk_get_pll1_fvco(unsigned long refclk) 925615f31feSGabriel Fernandez { 926615f31feSGabriel Fernandez uintptr_t pll_freq1_reg = A35SSC_BASE + A35_SS_PLL_FREQ1; 927615f31feSGabriel Fernandez uint32_t reg, fbdiv, refdiv; 928615f31feSGabriel Fernandez 929615f31feSGabriel Fernandez reg = mmio_read_32(pll_freq1_reg); 930615f31feSGabriel Fernandez 931615f31feSGabriel Fernandez fbdiv = (reg & A35_SS_PLL_FREQ1_FBDIV_MASK) >> A35_SS_PLL_FREQ1_FBDIV_SHIFT; 932615f31feSGabriel Fernandez refdiv = (reg & A35_SS_PLL_FREQ1_REFDIV_MASK) >> A35_SS_PLL_FREQ1_REFDIV_SHIFT; 933615f31feSGabriel Fernandez 934615f31feSGabriel Fernandez return (unsigned long)(refclk * fbdiv / refdiv); 935615f31feSGabriel Fernandez } 936615f31feSGabriel Fernandez 937615f31feSGabriel Fernandez static unsigned long clk_stm32_pll1_recalc_rate(struct stm32_clk_priv *priv, 938615f31feSGabriel Fernandez int id, unsigned long prate) 939615f31feSGabriel Fernandez { 940615f31feSGabriel Fernandez uintptr_t pll_freq2_reg = A35SSC_BASE + A35_SS_PLL_FREQ2; 941615f31feSGabriel Fernandez uint32_t postdiv1, postdiv2; 942615f31feSGabriel Fernandez unsigned long dfout; 943615f31feSGabriel Fernandez 944615f31feSGabriel Fernandez postdiv1 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV1_MASK) >> 945615f31feSGabriel Fernandez A35_SS_PLL_FREQ2_POSTDIV1_SHIFT; 946615f31feSGabriel Fernandez postdiv2 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV2_MASK) >> 947615f31feSGabriel Fernandez A35_SS_PLL_FREQ2_POSTDIV2_SHIFT; 948615f31feSGabriel Fernandez 949615f31feSGabriel Fernandez if ((postdiv1 == 0U) || (postdiv2 == 0U)) { 950615f31feSGabriel Fernandez dfout = prate; 951615f31feSGabriel Fernandez } else { 952615f31feSGabriel Fernandez dfout = clk_get_pll1_fvco(prate) / (postdiv1 * postdiv2); 953615f31feSGabriel Fernandez } 954615f31feSGabriel Fernandez 955615f31feSGabriel Fernandez return dfout; 956615f31feSGabriel Fernandez } 957615f31feSGabriel Fernandez 958615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_pll1_ops = { 959615f31feSGabriel Fernandez .recalc_rate = clk_stm32_pll1_recalc_rate, 960615f31feSGabriel Fernandez }; 961615f31feSGabriel Fernandez 962615f31feSGabriel Fernandez #define CLK_PLL1(idx, _idx, _parent, _pll_id, _flags)[idx] = {\ 963615f31feSGabriel Fernandez .binding = _idx,\ 964615f31feSGabriel Fernandez .parent = _parent,\ 965615f31feSGabriel Fernandez .flags = (_flags),\ 966615f31feSGabriel Fernandez .clock_cfg = &(struct stm32_pll_cfg) {\ 967615f31feSGabriel Fernandez .pll_id = _pll_id,\ 968615f31feSGabriel Fernandez },\ 969615f31feSGabriel Fernandez .ops = STM32_PLL1_OPS,\ 970615f31feSGabriel Fernandez } 971615f31feSGabriel Fernandez 972615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg { 973615f31feSGabriel Fernandez uint8_t id; 974615f31feSGabriel Fernandez }; 975615f31feSGabriel Fernandez 976615f31feSGabriel Fernandez static unsigned long clk_flexgen_recalc(struct stm32_clk_priv *priv, int idx, 977615f31feSGabriel Fernandez unsigned long prate) 978615f31feSGabriel Fernandez { 979615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 980615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 981615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 982615f31feSGabriel Fernandez uint32_t prediv, findiv; 983615f31feSGabriel Fernandez uint8_t channel = cfg->id; 984615f31feSGabriel Fernandez unsigned long freq = prate; 985615f31feSGabriel Fernandez 986615f31feSGabriel Fernandez prediv = mmio_read_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel)) & 987615f31feSGabriel Fernandez RCC_PREDIVxCFGR_PREDIVx_MASK; 988615f31feSGabriel Fernandez findiv = mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) & 989615f31feSGabriel Fernandez RCC_FINDIVxCFGR_FINDIVx_MASK; 990615f31feSGabriel Fernandez 991615f31feSGabriel Fernandez if (freq == 0UL) { 992615f31feSGabriel Fernandez return 0U; 993615f31feSGabriel Fernandez } 994615f31feSGabriel Fernandez 995615f31feSGabriel Fernandez switch (prediv) { 996615f31feSGabriel Fernandez case 0x0: 997615f31feSGabriel Fernandez case 0x1: 998615f31feSGabriel Fernandez case 0x3: 999615f31feSGabriel Fernandez case 0x3FF: 1000615f31feSGabriel Fernandez break; 1001615f31feSGabriel Fernandez 1002615f31feSGabriel Fernandez default: 1003615f31feSGabriel Fernandez ERROR("Unsupported PREDIV value (%x)\n", prediv); 1004615f31feSGabriel Fernandez panic(); 1005615f31feSGabriel Fernandez break; 1006615f31feSGabriel Fernandez } 1007615f31feSGabriel Fernandez 1008615f31feSGabriel Fernandez freq /= (prediv + 1U); 1009615f31feSGabriel Fernandez freq /= (findiv + 1U); 1010615f31feSGabriel Fernandez 1011615f31feSGabriel Fernandez return freq; 1012615f31feSGabriel Fernandez } 1013615f31feSGabriel Fernandez 1014615f31feSGabriel Fernandez static int clk_flexgen_get_parent(struct stm32_clk_priv *priv, int idx) 1015615f31feSGabriel Fernandez { 1016615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 1017615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 1018615f31feSGabriel Fernandez uint32_t sel; 1019615f31feSGabriel Fernandez uint32_t address; 1020615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1021615f31feSGabriel Fernandez 1022615f31feSGabriel Fernandez address = RCC_XBAR0CFGR + (cfg->id * 4); 1023615f31feSGabriel Fernandez 1024615f31feSGabriel Fernandez sel = mmio_read_32(rcc_base + address) & RCC_XBARxCFGR_XBARxSEL_MASK; 1025615f31feSGabriel Fernandez 1026615f31feSGabriel Fernandez return sel; 1027615f31feSGabriel Fernandez } 1028615f31feSGabriel Fernandez 1029615f31feSGabriel Fernandez static int clk_flexgen_gate_enable(struct stm32_clk_priv *priv, int idx) 1030615f31feSGabriel Fernandez { 1031615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 1032615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 1033615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1034615f31feSGabriel Fernandez uint8_t channel = cfg->id; 1035615f31feSGabriel Fernandez 1036615f31feSGabriel Fernandez mmio_setbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel), 1037615f31feSGabriel Fernandez RCC_FINDIVxCFGR_FINDIVxEN); 1038615f31feSGabriel Fernandez 1039615f31feSGabriel Fernandez return 0; 1040615f31feSGabriel Fernandez } 1041615f31feSGabriel Fernandez 1042615f31feSGabriel Fernandez static void clk_flexgen_gate_disable(struct stm32_clk_priv *priv, int id) 1043615f31feSGabriel Fernandez { 1044615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 1045615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 1046615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1047615f31feSGabriel Fernandez uint8_t channel = cfg->id; 1048615f31feSGabriel Fernandez 1049615f31feSGabriel Fernandez mmio_clrbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel), 1050615f31feSGabriel Fernandez RCC_FINDIVxCFGR_FINDIVxEN); 1051615f31feSGabriel Fernandez } 1052615f31feSGabriel Fernandez 1053615f31feSGabriel Fernandez static bool clk_flexgen_gate_is_enabled(struct stm32_clk_priv *priv, int id) 1054615f31feSGabriel Fernandez { 1055615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 1056615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 1057615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1058615f31feSGabriel Fernandez uint8_t channel = cfg->id; 1059615f31feSGabriel Fernandez 1060615f31feSGabriel Fernandez return !!(mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) & 1061615f31feSGabriel Fernandez RCC_FINDIVxCFGR_FINDIVxEN); 1062615f31feSGabriel Fernandez } 1063615f31feSGabriel Fernandez 1064615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_flexgen_ops = { 1065615f31feSGabriel Fernandez .recalc_rate = clk_flexgen_recalc, 1066615f31feSGabriel Fernandez .get_parent = clk_flexgen_get_parent, 1067615f31feSGabriel Fernandez .enable = clk_flexgen_gate_enable, 1068615f31feSGabriel Fernandez .disable = clk_flexgen_gate_disable, 1069615f31feSGabriel Fernandez .is_enabled = clk_flexgen_gate_is_enabled, 1070615f31feSGabriel Fernandez }; 1071615f31feSGabriel Fernandez 1072615f31feSGabriel Fernandez #define FLEXGEN(idx, _idx, _flags, _id)[idx] = {\ 1073615f31feSGabriel Fernandez .binding = _idx,\ 1074615f31feSGabriel Fernandez .parent = MUX(MUX_XBARSEL),\ 1075615f31feSGabriel Fernandez .flags = (_flags),\ 1076615f31feSGabriel Fernandez .clock_cfg = &(struct stm32_clk_flexgen_cfg) {\ 1077615f31feSGabriel Fernandez .id = _id,\ 1078615f31feSGabriel Fernandez },\ 1079615f31feSGabriel Fernandez .ops = STM32_FLEXGEN_OPS,\ 1080615f31feSGabriel Fernandez } 1081615f31feSGabriel Fernandez 1082615f31feSGabriel Fernandez #define RCC_0_MHZ UL(0) 1083615f31feSGabriel Fernandez #define RCC_4_MHZ UL(4000000) 1084615f31feSGabriel Fernandez #define RCC_16_MHZ UL(16000000) 1085615f31feSGabriel Fernandez 1086615f31feSGabriel Fernandez #ifdef IMAGE_BL2 1087088238adSNicolas Le Bayon #if !STM32MP21 1088615f31feSGabriel Fernandez static int clk_stm32_osc_msi_set_rate(struct stm32_clk_priv *priv, int id, unsigned long rate, 1089615f31feSGabriel Fernandez unsigned long prate) 1090615f31feSGabriel Fernandez { 1091615f31feSGabriel Fernandez uintptr_t address = priv->base + RCC_BDCR; 1092615f31feSGabriel Fernandez uint32_t mask = RCC_BDCR_MSIFREQSEL; 1093615f31feSGabriel Fernandez int ret = -1; 1094615f31feSGabriel Fernandez 1095615f31feSGabriel Fernandez switch (rate) { 1096615f31feSGabriel Fernandez case RCC_4_MHZ: 1097615f31feSGabriel Fernandez mmio_clrbits_32(address, mask); 1098615f31feSGabriel Fernandez ret = 0; 1099615f31feSGabriel Fernandez break; 1100615f31feSGabriel Fernandez 1101615f31feSGabriel Fernandez case RCC_16_MHZ: 1102615f31feSGabriel Fernandez mmio_setbits_32(address, mask); 1103615f31feSGabriel Fernandez ret = 0; 1104615f31feSGabriel Fernandez break; 1105615f31feSGabriel Fernandez 1106615f31feSGabriel Fernandez default: 1107615f31feSGabriel Fernandez break; 1108615f31feSGabriel Fernandez } 1109615f31feSGabriel Fernandez 1110615f31feSGabriel Fernandez return ret; 1111615f31feSGabriel Fernandez } 1112088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1113615f31feSGabriel Fernandez #endif /* IMAGE_BL2 */ 1114615f31feSGabriel Fernandez 1115615f31feSGabriel Fernandez static unsigned long clk_stm32_osc_msi_recalc_rate(struct stm32_clk_priv *priv, 1116615f31feSGabriel Fernandez int id __unused, 1117615f31feSGabriel Fernandez unsigned long prate __unused) 1118615f31feSGabriel Fernandez { 1119088238adSNicolas Le Bayon #if STM32MP21 1120088238adSNicolas Le Bayon return RCC_16_MHZ; 1121088238adSNicolas Le Bayon #else /* STM32MP21 */ 1122615f31feSGabriel Fernandez uintptr_t address = priv->base + RCC_BDCR; 1123615f31feSGabriel Fernandez 1124615f31feSGabriel Fernandez if ((mmio_read_32(address) & RCC_BDCR_MSIFREQSEL) == 0U) { 1125615f31feSGabriel Fernandez return RCC_4_MHZ; 1126615f31feSGabriel Fernandez } else { 1127615f31feSGabriel Fernandez return RCC_16_MHZ; 1128615f31feSGabriel Fernandez } 1129088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1130615f31feSGabriel Fernandez } 1131615f31feSGabriel Fernandez 1132615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_osc_msi_ops = { 1133615f31feSGabriel Fernandez .recalc_rate = clk_stm32_osc_msi_recalc_rate, 1134615f31feSGabriel Fernandez .is_enabled = clk_stm32_osc_gate_is_enabled, 1135615f31feSGabriel Fernandez .enable = clk_stm32_osc_gate_enable, 1136615f31feSGabriel Fernandez .disable = clk_stm32_osc_gate_disable, 1137615f31feSGabriel Fernandez .init = clk_stm32_osc_init, 1138615f31feSGabriel Fernandez }; 1139615f31feSGabriel Fernandez 1140615f31feSGabriel Fernandez #define CLK_OSC_MSI(idx, _idx, _parent, _osc_id) \ 1141615f31feSGabriel Fernandez [(idx)] = (struct clk_stm32){ \ 1142615f31feSGabriel Fernandez .binding = (_idx),\ 1143615f31feSGabriel Fernandez .parent = (_parent),\ 1144615f31feSGabriel Fernandez .flags = CLK_IS_CRITICAL,\ 1145615f31feSGabriel Fernandez .clock_cfg = &(struct stm32_osc_cfg){\ 1146615f31feSGabriel Fernandez .osc_id = (_osc_id),\ 1147615f31feSGabriel Fernandez },\ 1148615f31feSGabriel Fernandez .ops = STM32_OSC_MSI_OPS,\ 1149615f31feSGabriel Fernandez } 1150615f31feSGabriel Fernandez 1151615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_rtc_ops = { 1152615f31feSGabriel Fernandez .enable = clk_stm32_gate_enable, 1153615f31feSGabriel Fernandez .disable = clk_stm32_gate_disable, 1154615f31feSGabriel Fernandez .is_enabled = clk_stm32_gate_is_enabled, 1155615f31feSGabriel Fernandez }; 1156615f31feSGabriel Fernandez 1157615f31feSGabriel Fernandez #define CLK_RTC(idx, _binding, _parent, _flags, _gate_id)[idx] = {\ 1158615f31feSGabriel Fernandez .binding = (_binding),\ 1159615f31feSGabriel Fernandez .parent = (_parent),\ 1160615f31feSGabriel Fernandez .flags = (_flags),\ 1161615f31feSGabriel Fernandez .clock_cfg = &(struct clk_stm32_gate_cfg) {\ 1162615f31feSGabriel Fernandez .id = (_gate_id),\ 1163615f31feSGabriel Fernandez },\ 1164615f31feSGabriel Fernandez .ops = STM32_RTC_OPS,\ 1165615f31feSGabriel Fernandez } 1166615f31feSGabriel Fernandez 1167615f31feSGabriel Fernandez enum { 1168615f31feSGabriel Fernandez STM32_PLL_OPS = STM32_LAST_OPS, 1169615f31feSGabriel Fernandez STM32_PLL1_OPS, 1170615f31feSGabriel Fernandez STM32_FLEXGEN_OPS, 1171615f31feSGabriel Fernandez STM32_OSC_MSI_OPS, 1172615f31feSGabriel Fernandez STM32_RTC_OPS, 1173615f31feSGabriel Fernandez 1174088238adSNicolas Le Bayon MP2_LAST_OPS 1175615f31feSGabriel Fernandez }; 1176615f31feSGabriel Fernandez 1177088238adSNicolas Le Bayon static const struct stm32_clk_ops *ops_array_mp2[MP2_LAST_OPS] = { 1178615f31feSGabriel Fernandez [NO_OPS] = NULL, 1179615f31feSGabriel Fernandez [FIXED_FACTOR_OPS] = &clk_fixed_factor_ops, 1180615f31feSGabriel Fernandez [GATE_OPS] = &clk_gate_ops, 1181615f31feSGabriel Fernandez [STM32_MUX_OPS] = &clk_mux_ops, 1182615f31feSGabriel Fernandez [STM32_DIVIDER_OPS] = &clk_stm32_divider_ops, 1183615f31feSGabriel Fernandez [STM32_GATE_OPS] = &clk_stm32_gate_ops, 1184615f31feSGabriel Fernandez [STM32_TIMER_OPS] = &clk_timer_ops, 1185615f31feSGabriel Fernandez [STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops, 1186615f31feSGabriel Fernandez [STM32_OSC_OPS] = &clk_stm32_osc_ops, 1187615f31feSGabriel Fernandez [STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops, 1188615f31feSGabriel Fernandez 1189615f31feSGabriel Fernandez [STM32_PLL_OPS] = &clk_stm32_pll_ops, 1190615f31feSGabriel Fernandez [STM32_PLL1_OPS] = &clk_stm32_pll1_ops, 1191615f31feSGabriel Fernandez [STM32_FLEXGEN_OPS] = &clk_stm32_flexgen_ops, 1192615f31feSGabriel Fernandez [STM32_OSC_MSI_OPS] = &clk_stm32_osc_msi_ops, 1193615f31feSGabriel Fernandez [STM32_RTC_OPS] = &clk_stm32_rtc_ops 1194615f31feSGabriel Fernandez }; 1195615f31feSGabriel Fernandez 1196088238adSNicolas Le Bayon static const struct clk_stm32 stm32mp2_clk[CK_LAST] = { 1197615f31feSGabriel Fernandez CLK_FIXED_RATE(_CK_0_MHZ, _NO_ID, RCC_0_MHZ), 1198615f31feSGabriel Fernandez 1199615f31feSGabriel Fernandez /* ROOT CLOCKS */ 1200615f31feSGabriel Fernandez CLK_OSC(_CK_HSE, HSE_CK, CLK_IS_ROOT, OSC_HSE), 1201615f31feSGabriel Fernandez CLK_OSC(_CK_LSE, LSE_CK, CLK_IS_ROOT, OSC_LSE), 1202615f31feSGabriel Fernandez CLK_OSC(_CK_HSI, HSI_CK, CLK_IS_ROOT, OSC_HSI), 1203615f31feSGabriel Fernandez CLK_OSC(_CK_LSI, LSI_CK, CLK_IS_ROOT, OSC_LSI), 1204615f31feSGabriel Fernandez CLK_OSC_MSI(_CK_MSI, MSI_CK, CLK_IS_ROOT, OSC_MSI), 1205615f31feSGabriel Fernandez 1206615f31feSGabriel Fernandez CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN), 1207615f31feSGabriel Fernandez CLK_OSC_FIXED(_SPDIFSYMB, _NO_ID, CLK_IS_ROOT, OSC_SPDIFSYMB), 1208615f31feSGabriel Fernandez 1209615f31feSGabriel Fernandez STM32_DIV(_CK_HSE_RTC, _NO_ID, _CK_HSE, 0, DIV_RTC), 1210615f31feSGabriel Fernandez 1211615f31feSGabriel Fernandez CLK_RTC(_CK_RTCCK, RTC_CK, MUX(MUX_RTC), 0, GATE_RTCCK), 1212615f31feSGabriel Fernandez 1213615f31feSGabriel Fernandez CLK_PLL1(_CK_PLL1, PLL1_CK, MUX(MUX_MUXSEL5), _PLL1, 0), 1214615f31feSGabriel Fernandez 1215615f31feSGabriel Fernandez CLK_PLL(_CK_PLL2, PLL2_CK, MUX(MUX_MUXSEL6), _PLL2, 0), 1216088238adSNicolas Le Bayon #if !STM32MP21 1217615f31feSGabriel Fernandez CLK_PLL(_CK_PLL3, PLL3_CK, MUX(MUX_MUXSEL7), _PLL3, 0), 1218088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1219615f31feSGabriel Fernandez CLK_PLL(_CK_PLL4, PLL4_CK, MUX(MUX_MUXSEL0), _PLL4, 0), 1220615f31feSGabriel Fernandez CLK_PLL(_CK_PLL5, PLL5_CK, MUX(MUX_MUXSEL1), _PLL5, 0), 1221615f31feSGabriel Fernandez CLK_PLL(_CK_PLL6, PLL6_CK, MUX(MUX_MUXSEL2), _PLL6, 0), 1222615f31feSGabriel Fernandez CLK_PLL(_CK_PLL7, PLL7_CK, MUX(MUX_MUXSEL3), _PLL7, 0), 1223615f31feSGabriel Fernandez CLK_PLL(_CK_PLL8, PLL8_CK, MUX(MUX_MUXSEL4), _PLL8, 0), 1224615f31feSGabriel Fernandez 1225615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_HS_MCU, CK_ICN_HS_MCU, CLK_IS_CRITICAL, 0), 1226615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_SDMMC, CK_ICN_SDMMC, CLK_IS_CRITICAL, 1), 1227615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_DDR, CK_ICN_DDR, CLK_IS_CRITICAL, 2), 1228615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_HSL, CK_ICN_HSL, CLK_IS_CRITICAL, 4), 1229615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_NIC, CK_ICN_NIC, CLK_IS_CRITICAL, 5), 1230615f31feSGabriel Fernandez 1231615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_LS_MCU, CK_ICN_LS_MCU, _CK_ICN_HS_MCU, 0, DIV_LSMCU), 1232615f31feSGabriel Fernandez 1233615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_07, CK_FLEXGEN_07, 0, 7), 1234615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_08, CK_FLEXGEN_08, 0, 8), 1235615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_09, CK_FLEXGEN_09, 0, 9), 1236615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_10, CK_FLEXGEN_10, 0, 10), 1237615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_11, CK_FLEXGEN_11, 0, 11), 1238615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_12, CK_FLEXGEN_12, 0, 12), 1239615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_13, CK_FLEXGEN_13, 0, 13), 1240615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_14, CK_FLEXGEN_14, 0, 14), 1241615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_15, CK_FLEXGEN_15, 0, 15), 1242615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_16, CK_FLEXGEN_16, 0, 16), 1243615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_17, CK_FLEXGEN_17, 0, 17), 1244615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_18, CK_FLEXGEN_18, 0, 18), 1245615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_19, CK_FLEXGEN_19, 0, 19), 1246615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_20, CK_FLEXGEN_20, 0, 20), 1247615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_21, CK_FLEXGEN_21, 0, 21), 1248615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_22, CK_FLEXGEN_22, 0, 22), 1249615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_23, CK_FLEXGEN_23, 0, 23), 1250615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_24, CK_FLEXGEN_24, 0, 24), 1251615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_25, CK_FLEXGEN_25, 0, 25), 1252615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_26, CK_FLEXGEN_26, 0, 26), 1253615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_27, CK_FLEXGEN_27, 0, 27), 1254615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_28, CK_FLEXGEN_28, 0, 28), 1255615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_29, CK_FLEXGEN_29, 0, 29), 1256615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_30, CK_FLEXGEN_30, 0, 30), 1257615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_31, CK_FLEXGEN_31, 0, 31), 1258615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_32, CK_FLEXGEN_32, 0, 32), 1259615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_33, CK_FLEXGEN_33, 0, 33), 1260615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_34, CK_FLEXGEN_34, 0, 34), 1261615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_35, CK_FLEXGEN_35, 0, 35), 1262615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_36, CK_FLEXGEN_36, 0, 36), 1263615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_37, CK_FLEXGEN_37, 0, 37), 1264615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_38, CK_FLEXGEN_38, 0, 38), 1265615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_39, CK_FLEXGEN_39, 0, 39), 1266615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_40, CK_FLEXGEN_40, 0, 40), 1267615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_41, CK_FLEXGEN_41, 0, 41), 1268615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_42, CK_FLEXGEN_42, 0, 42), 1269615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_43, CK_FLEXGEN_43, 0, 43), 1270615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_44, CK_FLEXGEN_44, 0, 44), 1271615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_45, CK_FLEXGEN_45, 0, 45), 1272615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_46, CK_FLEXGEN_46, 0, 46), 1273615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_47, CK_FLEXGEN_47, 0, 47), 1274615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_48, CK_FLEXGEN_48, 0, 48), 1275615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_49, CK_FLEXGEN_49, 0, 49), 1276615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_50, CK_FLEXGEN_50, 0, 50), 1277615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_51, CK_FLEXGEN_51, 0, 51), 1278615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_52, CK_FLEXGEN_52, 0, 52), 1279615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_53, CK_FLEXGEN_53, 0, 53), 1280615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_54, CK_FLEXGEN_54, 0, 54), 1281615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_55, CK_FLEXGEN_55, 0, 55), 1282615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_56, CK_FLEXGEN_56, 0, 56), 1283615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_57, CK_FLEXGEN_57, 0, 57), 1284615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_58, CK_FLEXGEN_58, 0, 58), 1285615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_59, CK_FLEXGEN_59, 0, 59), 1286615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_60, CK_FLEXGEN_60, 0, 60), 1287615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_61, CK_FLEXGEN_61, 0, 61), 1288615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_62, CK_FLEXGEN_62, 0, 62), 1289615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_63, CK_FLEXGEN_63, 0, 63), 1290615f31feSGabriel Fernandez 1291615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APB1, CK_ICN_APB1, _CK_ICN_LS_MCU, 0, DIV_APB1), 1292615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APB2, CK_ICN_APB2, _CK_ICN_LS_MCU, 0, DIV_APB2), 1293615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APB3, CK_ICN_APB3, _CK_ICN_LS_MCU, 0, DIV_APB3), 1294615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APB4, CK_ICN_APB4, _CK_ICN_LS_MCU, 0, DIV_APB4), 1295088238adSNicolas Le Bayon #if STM32MP21 1296088238adSNicolas Le Bayon STM32_DIV(_CK_ICN_APB5, CK_ICN_APB5, _CK_ICN_LS_MCU, 0, DIV_APB5), 1297088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1298615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APBDBG, CK_ICN_APBDBG, _CK_ICN_LS_MCU, 0, DIV_APBDBG), 1299615f31feSGabriel Fernandez 1300615f31feSGabriel Fernandez /* KERNEL CLOCK */ 1301615f31feSGabriel Fernandez STM32_GATE(_CK_SYSRAM, CK_BUS_SYSRAM, _CK_ICN_HS_MCU, 0, GATE_SYSRAM), 1302615f31feSGabriel Fernandez STM32_GATE(_CK_RETRAM, CK_BUS_RETRAM, _CK_ICN_HS_MCU, 0, GATE_RETRAM), 1303615f31feSGabriel Fernandez STM32_GATE(_CK_SRAM1, CK_BUS_SRAM1, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM1), 1304088238adSNicolas Le Bayon #if !STM32MP21 1305615f31feSGabriel Fernandez STM32_GATE(_CK_SRAM2, CK_BUS_SRAM2, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM2), 1306088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1307615f31feSGabriel Fernandez 1308615f31feSGabriel Fernandez STM32_GATE(_CK_DDRPHYC, CK_BUS_DDRPHYC, _CK_ICN_LS_MCU, 0, GATE_DDRPHYC), 1309615f31feSGabriel Fernandez STM32_GATE(_CK_SYSCPU1, CK_BUS_SYSCPU1, _CK_ICN_LS_MCU, 0, GATE_SYSCPU1), 1310615f31feSGabriel Fernandez STM32_GATE(_CK_CRC, CK_BUS_CRC, _CK_ICN_LS_MCU, 0, GATE_CRC), 1311088238adSNicolas Le Bayon #if !STM32MP21 1312615f31feSGabriel Fernandez STM32_GATE(_CK_OSPIIOM, CK_BUS_OSPIIOM, _CK_ICN_LS_MCU, 0, GATE_OSPIIOM), 1313088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1314615f31feSGabriel Fernandez STM32_GATE(_CK_BKPSRAM, CK_BUS_BKPSRAM, _CK_ICN_LS_MCU, 0, GATE_BKPSRAM), 1315088238adSNicolas Le Bayon #if STM32MP21 1316088238adSNicolas Le Bayon STM32_GATE(_CK_HASH1, CK_BUS_HASH1, _CK_ICN_LS_MCU, 0, GATE_HASH1), 1317088238adSNicolas Le Bayon STM32_GATE(_CK_HASH2, CK_BUS_HASH2, _CK_ICN_LS_MCU, 0, GATE_HASH2), 1318088238adSNicolas Le Bayon STM32_GATE(_CK_RNG1, CK_BUS_RNG1, _CK_ICN_LS_MCU, 0, GATE_RNG1), 1319088238adSNicolas Le Bayon STM32_GATE(_CK_RNG2, CK_BUS_RNG2, _CK_ICN_LS_MCU, 0, GATE_RNG2), 1320088238adSNicolas Le Bayon #else /* STM32MP21 */ 1321615f31feSGabriel Fernandez STM32_GATE(_CK_HASH, CK_BUS_HASH, _CK_ICN_LS_MCU, 0, GATE_HASH), 1322615f31feSGabriel Fernandez STM32_GATE(_CK_RNG, CK_BUS_RNG, _CK_ICN_LS_MCU, 0, GATE_RNG), 1323088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1324615f31feSGabriel Fernandez STM32_GATE(_CK_CRYP1, CK_BUS_CRYP1, _CK_ICN_LS_MCU, 0, GATE_CRYP1), 1325615f31feSGabriel Fernandez STM32_GATE(_CK_CRYP2, CK_BUS_CRYP2, _CK_ICN_LS_MCU, 0, GATE_CRYP2), 1326615f31feSGabriel Fernandez STM32_GATE(_CK_SAES, CK_BUS_SAES, _CK_ICN_LS_MCU, 0, GATE_SAES), 1327615f31feSGabriel Fernandez STM32_GATE(_CK_PKA, CK_BUS_PKA, _CK_ICN_LS_MCU, 0, GATE_PKA), 1328615f31feSGabriel Fernandez 1329615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOA, CK_BUS_GPIOA, _CK_ICN_LS_MCU, 0, GATE_GPIOA), 1330615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOB, CK_BUS_GPIOB, _CK_ICN_LS_MCU, 0, GATE_GPIOB), 1331615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOC, CK_BUS_GPIOC, _CK_ICN_LS_MCU, 0, GATE_GPIOC), 1332615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOD, CK_BUS_GPIOD, _CK_ICN_LS_MCU, 0, GATE_GPIOD), 1333615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOE, CK_BUS_GPIOE, _CK_ICN_LS_MCU, 0, GATE_GPIOE), 1334615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOF, CK_BUS_GPIOF, _CK_ICN_LS_MCU, 0, GATE_GPIOF), 1335615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOG, CK_BUS_GPIOG, _CK_ICN_LS_MCU, 0, GATE_GPIOG), 1336615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOH, CK_BUS_GPIOH, _CK_ICN_LS_MCU, 0, GATE_GPIOH), 1337615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOI, CK_BUS_GPIOI, _CK_ICN_LS_MCU, 0, GATE_GPIOI), 1338088238adSNicolas Le Bayon #if !STM32MP21 1339615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOJ, CK_BUS_GPIOJ, _CK_ICN_LS_MCU, 0, GATE_GPIOJ), 1340615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOK, CK_BUS_GPIOK, _CK_ICN_LS_MCU, 0, GATE_GPIOK), 1341088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1342615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOZ, CK_BUS_GPIOZ, _CK_ICN_LS_MCU, 0, GATE_GPIOZ), 1343615f31feSGabriel Fernandez STM32_GATE(_CK_RTC, CK_BUS_RTC, _CK_ICN_LS_MCU, 0, GATE_RTC), 1344615f31feSGabriel Fernandez 13452a20f3e6SGabriel Fernandez STM32_GATE(_CK_BUS_RISAF4, CK_BUS_RISAF4, _CK_ICN_LS_MCU, CLK_IS_CRITICAL, GATE_DDRCP), 13462a20f3e6SGabriel Fernandez STM32_GATE(_CK_DDRCP, CK_BUS_DDR, _CK_ICN_DDR, CLK_IS_CRITICAL, GATE_DDRCP), 1347615f31feSGabriel Fernandez 1348615f31feSGabriel Fernandez /* WARNING 2 CLOCKS FOR ONE GATE */ 1349088238adSNicolas Le Bayon #if STM32MP21 1350088238adSNicolas Le Bayon STM32_GATE(_CK_USBHOHCI, CK_BUS_USBHOHCI, _CK_ICN_HSL, 0, GATE_USBHOHCI), 1351088238adSNicolas Le Bayon STM32_GATE(_CK_USBHEHCI, CK_BUS_USBHEHCI, _CK_ICN_HSL, 0, GATE_USBHEHCI), 1352088238adSNicolas Le Bayon #else /* STM32MP21 */ 1353615f31feSGabriel Fernandez STM32_GATE(_CK_USB2OHCI, CK_BUS_USB2OHCI, _CK_ICN_HSL, 0, GATE_USB2OHCI), 1354615f31feSGabriel Fernandez STM32_GATE(_CK_USB2EHCI, CK_BUS_USB2EHCI, _CK_ICN_HSL, 0, GATE_USB2EHCI), 1355088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1356615f31feSGabriel Fernandez 1357088238adSNicolas Le Bayon #if !STM32MP21 1358615f31feSGabriel Fernandez STM32_GATE(_CK_USB3DR, CK_BUS_USB3DR, _CK_ICN_HSL, 0, GATE_USB3DR), 1359088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1360615f31feSGabriel Fernandez 1361615f31feSGabriel Fernandez STM32_GATE(_CK_BSEC, CK_BUS_BSEC, _CK_ICN_APB3, 0, GATE_BSEC), 1362615f31feSGabriel Fernandez STM32_GATE(_CK_IWDG1, CK_BUS_IWDG1, _CK_ICN_APB3, 0, GATE_IWDG1), 1363615f31feSGabriel Fernandez STM32_GATE(_CK_IWDG2, CK_BUS_IWDG2, _CK_ICN_APB3, 0, GATE_IWDG2), 1364615f31feSGabriel Fernandez 1365615f31feSGabriel Fernandez STM32_GATE(_CK_DDRCAPB, CK_BUS_DDRC, _CK_ICN_APB4, 0, GATE_DDRCAPB), 1366615f31feSGabriel Fernandez STM32_GATE(_CK_DDR, CK_BUS_DDRCFG, _CK_ICN_APB4, 0, GATE_DDR), 1367615f31feSGabriel Fernandez 1368615f31feSGabriel Fernandez STM32_GATE(_CK_USART2, CK_KER_USART2, _CK_FLEXGEN_08, 0, GATE_USART2), 1369615f31feSGabriel Fernandez STM32_GATE(_CK_UART4, CK_KER_UART4, _CK_FLEXGEN_08, 0, GATE_UART4), 1370615f31feSGabriel Fernandez STM32_GATE(_CK_USART3, CK_KER_USART3, _CK_FLEXGEN_09, 0, GATE_USART3), 1371615f31feSGabriel Fernandez STM32_GATE(_CK_UART5, CK_KER_UART5, _CK_FLEXGEN_09, 0, GATE_UART5), 1372088238adSNicolas Le Bayon #if STM32MP21 1373088238adSNicolas Le Bayon STM32_GATE(_CK_I2C1, CK_KER_I2C1, _CK_FLEXGEN_13, 0, GATE_I2C1), 1374088238adSNicolas Le Bayon STM32_GATE(_CK_I2C2, CK_KER_I2C2, _CK_FLEXGEN_13, 0, GATE_I2C2), 1375088238adSNicolas Le Bayon STM32_GATE(_CK_USART1, CK_KER_USART1, _CK_FLEXGEN_18, 0, GATE_USART1), 1376088238adSNicolas Le Bayon STM32_GATE(_CK_USART6, CK_KER_USART6, _CK_FLEXGEN_19, 0, GATE_USART6), 1377088238adSNicolas Le Bayon STM32_GATE(_CK_UART7, CK_KER_UART7, _CK_FLEXGEN_20, 0, GATE_UART7), 1378088238adSNicolas Le Bayon STM32_GATE(_CK_I2C3, CK_KER_I2C3, _CK_FLEXGEN_38, 0, GATE_I2C3), 1379088238adSNicolas Le Bayon #else /* STM32MP21 */ 1380615f31feSGabriel Fernandez STM32_GATE(_CK_I2C1, CK_KER_I2C1, _CK_FLEXGEN_12, 0, GATE_I2C1), 1381615f31feSGabriel Fernandez STM32_GATE(_CK_I2C2, CK_KER_I2C2, _CK_FLEXGEN_12, 0, GATE_I2C2), 1382088238adSNicolas Le Bayon #if STM32MP25 1383615f31feSGabriel Fernandez STM32_GATE(_CK_I2C3, CK_KER_I2C3, _CK_FLEXGEN_13, 0, GATE_I2C3), 1384615f31feSGabriel Fernandez STM32_GATE(_CK_I2C5, CK_KER_I2C5, _CK_FLEXGEN_13, 0, GATE_I2C5), 1385615f31feSGabriel Fernandez STM32_GATE(_CK_I2C4, CK_KER_I2C4, _CK_FLEXGEN_14, 0, GATE_I2C4), 1386615f31feSGabriel Fernandez STM32_GATE(_CK_I2C6, CK_KER_I2C6, _CK_FLEXGEN_14, 0, GATE_I2C6), 1387088238adSNicolas Le Bayon #endif /* STM32MP25 */ 1388615f31feSGabriel Fernandez STM32_GATE(_CK_I2C7, CK_KER_I2C7, _CK_FLEXGEN_15, 0, GATE_I2C7), 1389615f31feSGabriel Fernandez STM32_GATE(_CK_USART1, CK_KER_USART1, _CK_FLEXGEN_19, 0, GATE_USART1), 1390615f31feSGabriel Fernandez STM32_GATE(_CK_USART6, CK_KER_USART6, _CK_FLEXGEN_20, 0, GATE_USART6), 1391615f31feSGabriel Fernandez STM32_GATE(_CK_UART7, CK_KER_UART7, _CK_FLEXGEN_21, 0, GATE_UART7), 1392088238adSNicolas Le Bayon #if STM32MP25 1393615f31feSGabriel Fernandez STM32_GATE(_CK_UART8, CK_KER_UART8, _CK_FLEXGEN_21, 0, GATE_UART8), 1394615f31feSGabriel Fernandez STM32_GATE(_CK_UART9, CK_KER_UART9, _CK_FLEXGEN_22, 0, GATE_UART9), 1395088238adSNicolas Le Bayon #endif /* STM32MP25 */ 1396088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1397615f31feSGabriel Fernandez STM32_GATE(_CK_STGEN, CK_KER_STGEN, _CK_FLEXGEN_33, 0, GATE_STGEN), 1398088238adSNicolas Le Bayon #if !STM32MP21 1399615f31feSGabriel Fernandez STM32_GATE(_CK_USB3PCIEPHY, CK_KER_USB3PCIEPHY, _CK_FLEXGEN_34, 0, GATE_USB3PCIEPHY), 1400615f31feSGabriel Fernandez STM32_GATE(_CK_USBTC, CK_KER_USBTC, _CK_FLEXGEN_35, 0, GATE_USBTC), 1401615f31feSGabriel Fernandez STM32_GATE(_CK_I2C8, CK_KER_I2C8, _CK_FLEXGEN_38, 0, GATE_I2C8), 1402088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1403615f31feSGabriel Fernandez STM32_GATE(_CK_OSPI1, CK_KER_OSPI1, _CK_FLEXGEN_48, 0, GATE_OSPI1), 1404088238adSNicolas Le Bayon #if !STM32MP21 1405615f31feSGabriel Fernandez STM32_GATE(_CK_OSPI2, CK_KER_OSPI2, _CK_FLEXGEN_49, 0, GATE_OSPI2), 1406088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1407615f31feSGabriel Fernandez STM32_GATE(_CK_FMC, CK_KER_FMC, _CK_FLEXGEN_50, 0, GATE_FMC), 1408615f31feSGabriel Fernandez STM32_GATE(_CK_SDMMC1, CK_KER_SDMMC1, _CK_FLEXGEN_51, 0, GATE_SDMMC1), 1409615f31feSGabriel Fernandez STM32_GATE(_CK_SDMMC2, CK_KER_SDMMC2, _CK_FLEXGEN_52, 0, GATE_SDMMC2), 1410615f31feSGabriel Fernandez STM32_GATE(_CK_USB2PHY1, CK_KER_USB2PHY1, _CK_FLEXGEN_57, 0, GATE_USB2PHY1), 1411615f31feSGabriel Fernandez STM32_GATE(_CK_USB2PHY2, CK_KER_USB2PHY2, _CK_FLEXGEN_58, 0, GATE_USB2PHY2), 1412615f31feSGabriel Fernandez }; 1413615f31feSGabriel Fernandez 1414615f31feSGabriel Fernandez enum clksrc_id { 1415615f31feSGabriel Fernandez CLKSRC_CA35SS, 1416615f31feSGabriel Fernandez CLKSRC_PLL1, 1417615f31feSGabriel Fernandez CLKSRC_PLL2, 1418088238adSNicolas Le Bayon #if !STM32MP21 1419615f31feSGabriel Fernandez CLKSRC_PLL3, 1420088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1421615f31feSGabriel Fernandez CLKSRC_PLL4, 1422615f31feSGabriel Fernandez CLKSRC_PLL5, 1423615f31feSGabriel Fernandez CLKSRC_PLL6, 1424615f31feSGabriel Fernandez CLKSRC_PLL7, 1425615f31feSGabriel Fernandez CLKSRC_PLL8, 1426615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL0, 1427615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL1, 1428615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL2, 1429615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL3, 1430615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL4, 1431615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL5, 1432615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL6, 1433615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL7, 1434615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL8, 1435615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL9, 1436615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL10, 1437615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL11, 1438615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL12, 1439615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL13, 1440615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL14, 1441615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL15, 1442615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL16, 1443615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL17, 1444615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL18, 1445615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL19, 1446615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL20, 1447615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL21, 1448615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL22, 1449615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL23, 1450615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL24, 1451615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL25, 1452615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL26, 1453615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL27, 1454615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL28, 1455615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL29, 1456615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL30, 1457615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL31, 1458615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL32, 1459615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL33, 1460615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL34, 1461615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL35, 1462615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL36, 1463615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL37, 1464615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL38, 1465615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL39, 1466615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL40, 1467615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL41, 1468615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL42, 1469615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL43, 1470615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL44, 1471615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL45, 1472615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL46, 1473615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL47, 1474615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL48, 1475615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL49, 1476615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL50, 1477615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL51, 1478615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL52, 1479615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL53, 1480615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL54, 1481615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL55, 1482615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL56, 1483615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL57, 1484615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL58, 1485615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL59, 1486615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL60, 1487615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL61, 1488615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL62, 1489615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL63, 1490615f31feSGabriel Fernandez CLKSRC_RTC, 1491615f31feSGabriel Fernandez CLKSRC_MCO1, 1492615f31feSGabriel Fernandez CLKSRC_MCO2, 1493615f31feSGabriel Fernandez CLKSRC_NB 1494615f31feSGabriel Fernandez }; 1495615f31feSGabriel Fernandez 1496615f31feSGabriel Fernandez static void stm32mp2_a35_ss_on_hsi(void) 1497615f31feSGabriel Fernandez { 1498615f31feSGabriel Fernandez uintptr_t a35_ss_address = A35SSC_BASE; 1499615f31feSGabriel Fernandez uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ; 1500615f31feSGabriel Fernandez uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE; 1501*40d0cebeSPatrick Delaunay uint32_t chgclkreq; 1502615f31feSGabriel Fernandez uint64_t timeout; 1503615f31feSGabriel Fernandez 1504*40d0cebeSPatrick Delaunay chgclkreq = mmio_read_32(chgclkreq_reg); 1505*40d0cebeSPatrick Delaunay if ((chgclkreq & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) == A35_SS_CHGCLKREQ_ARM_CHGCLKACK) { 1506615f31feSGabriel Fernandez /* Nothing to do, clock source is already set on bypass clock */ 1507615f31feSGabriel Fernandez return; 1508615f31feSGabriel Fernandez } 1509615f31feSGabriel Fernandez 1510*40d0cebeSPatrick Delaunay /* for clkext2f frequency at 400MHZ, default flexgen63 config, divider by 2 is required */ 1511*40d0cebeSPatrick Delaunay if ((chgclkreq & A35_SS_CHGCLKREQ_ARM_DIVSEL) == A35_SS_CHGCLKREQ_ARM_DIVSEL) { 1512*40d0cebeSPatrick Delaunay mmio_clrbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_DIVSEL); 1513*40d0cebeSPatrick Delaunay timeout = timeout_init_us(CLKSRC_TIMEOUT); 1514*40d0cebeSPatrick Delaunay while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_DIVSELACK) == 1515*40d0cebeSPatrick Delaunay A35_SS_CHGCLKREQ_ARM_DIVSELACK) { 1516*40d0cebeSPatrick Delaunay if (timeout_elapsed(timeout)) { 1517*40d0cebeSPatrick Delaunay EARLY_ERROR("Cannot set div on A35 bypass clock\n"); 1518*40d0cebeSPatrick Delaunay panic(); 1519*40d0cebeSPatrick Delaunay } 1520*40d0cebeSPatrick Delaunay } 1521*40d0cebeSPatrick Delaunay } 1522*40d0cebeSPatrick Delaunay 1523615f31feSGabriel Fernandez mmio_setbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ); 1524615f31feSGabriel Fernandez 1525615f31feSGabriel Fernandez timeout = timeout_init_us(CLKSRC_TIMEOUT); 1526615f31feSGabriel Fernandez while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) != 1527615f31feSGabriel Fernandez A35_SS_CHGCLKREQ_ARM_CHGCLKACK) { 1528615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1529615f31feSGabriel Fernandez EARLY_ERROR("Cannot switch A35 to bypass clock\n"); 1530615f31feSGabriel Fernandez panic(); 1531615f31feSGabriel Fernandez } 1532615f31feSGabriel Fernandez } 1533615f31feSGabriel Fernandez 1534615f31feSGabriel Fernandez mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF); 1535615f31feSGabriel Fernandez } 1536615f31feSGabriel Fernandez 1537615f31feSGabriel Fernandez #ifdef IMAGE_BL2 1538615f31feSGabriel Fernandez static void stm32mp2_clk_muxsel_on_hsi(struct stm32_clk_priv *priv) 1539615f31feSGabriel Fernandez { 1540615f31feSGabriel Fernandez mmio_clrbits_32(priv->base + RCC_MUXSELCFGR, 1541615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL0_MASK | 1542615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL1_MASK | 1543615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL2_MASK | 1544615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL3_MASK | 1545615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL4_MASK | 1546615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL5_MASK | 1547615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL6_MASK | 1548615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL7_MASK); 1549615f31feSGabriel Fernandez } 1550615f31feSGabriel Fernandez 1551615f31feSGabriel Fernandez static void stm32mp2_clk_xbar_on_hsi(struct stm32_clk_priv *priv) 1552615f31feSGabriel Fernandez { 1553615f31feSGabriel Fernandez uintptr_t xbar0cfgr = priv->base + RCC_XBAR0CFGR; 1554615f31feSGabriel Fernandez uint32_t i; 1555615f31feSGabriel Fernandez 1556615f31feSGabriel Fernandez for (i = 0; i < XBAR_CHANNEL_NB; i++) { 1557615f31feSGabriel Fernandez mmio_clrsetbits_32(xbar0cfgr + (0x4 * i), 1558615f31feSGabriel Fernandez RCC_XBAR0CFGR_XBAR0SEL_MASK, 1559615f31feSGabriel Fernandez XBAR_SRC_HSI); 1560615f31feSGabriel Fernandez } 1561615f31feSGabriel Fernandez } 1562615f31feSGabriel Fernandez 1563615f31feSGabriel Fernandez static int stm32mp2_a35_pll1_start(void) 1564615f31feSGabriel Fernandez { 1565615f31feSGabriel Fernandez uintptr_t a35_ss_address = A35SSC_BASE; 1566615f31feSGabriel Fernandez uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE; 1567615f31feSGabriel Fernandez uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ; 1568615f31feSGabriel Fernandez uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT); 1569615f31feSGabriel Fernandez 1570615f31feSGabriel Fernandez mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD); 1571615f31feSGabriel Fernandez 1572615f31feSGabriel Fernandez /* Wait PLL lock */ 1573615f31feSGabriel Fernandez while ((mmio_read_32(pll_enable_reg) & A35_SS_PLL_ENABLE_LOCKP) == 0U) { 1574615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1575615f31feSGabriel Fernandez EARLY_ERROR("PLL1 start failed @ 0x%lx: 0x%x\n", 1576615f31feSGabriel Fernandez pll_enable_reg, mmio_read_32(pll_enable_reg)); 1577615f31feSGabriel Fernandez return -ETIMEDOUT; 1578615f31feSGabriel Fernandez } 1579615f31feSGabriel Fernandez } 1580615f31feSGabriel Fernandez 1581615f31feSGabriel Fernandez /* De-assert reset on PLL output clock path */ 1582615f31feSGabriel Fernandez mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF); 1583615f31feSGabriel Fernandez 1584615f31feSGabriel Fernandez /* Switch CPU clock to PLL clock */ 1585615f31feSGabriel Fernandez mmio_clrbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ); 1586615f31feSGabriel Fernandez 1587615f31feSGabriel Fernandez /* Wait for clock change acknowledge */ 1588615f31feSGabriel Fernandez timeout = timeout_init_us(CLKSRC_TIMEOUT); 1589615f31feSGabriel Fernandez while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) != 0U) { 1590615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1591615f31feSGabriel Fernandez EARLY_ERROR("CA35SS switch to PLL1 failed @ 0x%lx: 0x%x\n", 1592615f31feSGabriel Fernandez chgclkreq_reg, mmio_read_32(chgclkreq_reg)); 1593615f31feSGabriel Fernandez return -ETIMEDOUT; 1594615f31feSGabriel Fernandez } 1595615f31feSGabriel Fernandez } 1596615f31feSGabriel Fernandez 1597615f31feSGabriel Fernandez return 0; 1598615f31feSGabriel Fernandez } 1599615f31feSGabriel Fernandez 1600615f31feSGabriel Fernandez static void stm32mp2_a35_pll1_config(uint32_t fbdiv, uint32_t refdiv, uint32_t postdiv1, 1601615f31feSGabriel Fernandez uint32_t postdiv2) 1602615f31feSGabriel Fernandez { 1603615f31feSGabriel Fernandez uintptr_t a35_ss_address = A35SSC_BASE; 1604615f31feSGabriel Fernandez uintptr_t pll_freq1_reg = a35_ss_address + A35_SS_PLL_FREQ1; 1605615f31feSGabriel Fernandez uintptr_t pll_freq2_reg = a35_ss_address + A35_SS_PLL_FREQ2; 1606615f31feSGabriel Fernandez 1607615f31feSGabriel Fernandez mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_REFDIV_MASK, 1608615f31feSGabriel Fernandez (refdiv << A35_SS_PLL_FREQ1_REFDIV_SHIFT) & 1609615f31feSGabriel Fernandez A35_SS_PLL_FREQ1_REFDIV_MASK); 1610615f31feSGabriel Fernandez 1611615f31feSGabriel Fernandez mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_FBDIV_MASK, 1612615f31feSGabriel Fernandez (fbdiv << A35_SS_PLL_FREQ1_FBDIV_SHIFT) & 1613615f31feSGabriel Fernandez A35_SS_PLL_FREQ1_FBDIV_MASK); 1614615f31feSGabriel Fernandez 1615615f31feSGabriel Fernandez mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV1_MASK, 1616615f31feSGabriel Fernandez (postdiv1 << A35_SS_PLL_FREQ2_POSTDIV1_SHIFT) & 1617615f31feSGabriel Fernandez A35_SS_PLL_FREQ2_POSTDIV1_MASK); 1618615f31feSGabriel Fernandez 1619615f31feSGabriel Fernandez mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV2_MASK, 1620615f31feSGabriel Fernandez (postdiv2 << A35_SS_PLL_FREQ2_POSTDIV2_SHIFT) & 1621615f31feSGabriel Fernandez A35_SS_PLL_FREQ2_POSTDIV2_MASK); 1622615f31feSGabriel Fernandez } 1623615f31feSGabriel Fernandez 1624615f31feSGabriel Fernandez static int clk_stm32_pll_config_output(struct stm32_clk_priv *priv, 1625615f31feSGabriel Fernandez const struct stm32_clk_pll *pll, 1626615f31feSGabriel Fernandez uint32_t *pllcfg, 1627615f31feSGabriel Fernandez uint32_t fracv) 1628615f31feSGabriel Fernandez { 1629615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 1630615f31feSGabriel Fernandez uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2; 1631615f31feSGabriel Fernandez uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3; 1632615f31feSGabriel Fernandez uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4; 1633615f31feSGabriel Fernandez uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6; 1634615f31feSGabriel Fernandez uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7; 1635615f31feSGabriel Fernandez unsigned long refclk; 1636615f31feSGabriel Fernandez 1637615f31feSGabriel Fernandez refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id); 1638615f31feSGabriel Fernandez 1639615f31feSGabriel Fernandez if (fracv == 0U) { 1640615f31feSGabriel Fernandez /* PLL in integer mode */ 1641615f31feSGabriel Fernandez 1642615f31feSGabriel Fernandez /* 1643615f31feSGabriel Fernandez * No need to check max clock, as oscillator reference clocks 1644615f31feSGabriel Fernandez * will always be less than 1.2GHz 1645615f31feSGabriel Fernandez */ 1646615f31feSGabriel Fernandez if (refclk < PLL_REFCLK_MIN) { 1647615f31feSGabriel Fernandez panic(); 1648615f31feSGabriel Fernandez } 1649615f31feSGabriel Fernandez 1650615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK); 1651615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN); 1652615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN); 1653615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS); 1654615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST); 1655615f31feSGabriel Fernandez } else { 1656615f31feSGabriel Fernandez /* PLL in frac mode */ 1657615f31feSGabriel Fernandez 1658615f31feSGabriel Fernandez /* 1659615f31feSGabriel Fernandez * No need to check max clock, as oscillator reference clocks 1660615f31feSGabriel Fernandez * will always be less than 1.2GHz 1661615f31feSGabriel Fernandez */ 1662615f31feSGabriel Fernandez if (refclk < PLL_FRAC_REFCLK_MIN) { 1663615f31feSGabriel Fernandez panic(); 1664615f31feSGabriel Fernandez } 1665615f31feSGabriel Fernandez 1666615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK, 1667615f31feSGabriel Fernandez fracv & RCC_PLLxCFGR3_FRACIN_MASK); 1668615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS); 1669615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN); 1670615f31feSGabriel Fernandez } 1671615f31feSGabriel Fernandez 1672615f31feSGabriel Fernandez assert(pllcfg[REFDIV] != 0U); 1673615f31feSGabriel Fernandez 1674615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FBDIV_MASK, 1675615f31feSGabriel Fernandez (pllcfg[FBDIV] << RCC_PLLxCFGR2_FBDIV_SHIFT) & 1676615f31feSGabriel Fernandez RCC_PLLxCFGR2_FBDIV_MASK); 1677615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FREFDIV_MASK, 1678615f31feSGabriel Fernandez pllcfg[REFDIV] & RCC_PLLxCFGR2_FREFDIV_MASK); 1679615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr6, RCC_PLLxCFGR6_POSTDIV1_MASK, 1680615f31feSGabriel Fernandez pllcfg[POSTDIV1] & RCC_PLLxCFGR6_POSTDIV1_MASK); 1681615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr7, RCC_PLLxCFGR7_POSTDIV2_MASK, 1682615f31feSGabriel Fernandez pllcfg[POSTDIV2] & RCC_PLLxCFGR7_POSTDIV2_MASK); 1683615f31feSGabriel Fernandez 1684615f31feSGabriel Fernandez if ((pllcfg[POSTDIV1] == 0U) || (pllcfg[POSTDIV2] == 0U)) { 1685615f31feSGabriel Fernandez /* Bypass mode */ 1686615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS); 1687615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN); 1688615f31feSGabriel Fernandez } else { 1689615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS); 1690615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN); 1691615f31feSGabriel Fernandez } 1692615f31feSGabriel Fernandez 1693615f31feSGabriel Fernandez return 0; 1694615f31feSGabriel Fernandez } 1695615f31feSGabriel Fernandez 1696615f31feSGabriel Fernandez static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv, 1697615f31feSGabriel Fernandez const struct stm32_clk_pll *pll, 1698615f31feSGabriel Fernandez uint32_t *csg) 1699615f31feSGabriel Fernandez { 1700615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 1701615f31feSGabriel Fernandez uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3; 1702615f31feSGabriel Fernandez uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4; 1703615f31feSGabriel Fernandez uintptr_t pllxcfgr5 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR5; 1704615f31feSGabriel Fernandez 1705615f31feSGabriel Fernandez 1706615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_DIVVAL_MASK, 1707615f31feSGabriel Fernandez csg[DIVVAL] & RCC_PLLxCFGR5_DIVVAL_MASK); 1708615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_SPREAD_MASK, 1709615f31feSGabriel Fernandez (csg[SPREAD] << RCC_PLLxCFGR5_SPREAD_SHIFT) & 1710615f31feSGabriel Fernandez RCC_PLLxCFGR5_SPREAD_MASK); 1711615f31feSGabriel Fernandez 1712615f31feSGabriel Fernandez if (csg[DOWNSPREAD] != 0) { 1713615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD); 1714615f31feSGabriel Fernandez } else { 1715615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD); 1716615f31feSGabriel Fernandez } 1717615f31feSGabriel Fernandez 1718615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS); 1719615f31feSGabriel Fernandez 1720615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN); 1721615f31feSGabriel Fernandez udelay(1); 1722615f31feSGabriel Fernandez 1723615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN); 1724615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN); 1725615f31feSGabriel Fernandez } 1726615f31feSGabriel Fernandez 1727615f31feSGabriel Fernandez static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data); 1728615f31feSGabriel Fernandez 1729615f31feSGabriel Fernandez static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx) 1730615f31feSGabriel Fernandez { 1731615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1732615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 1733615f31feSGabriel Fernandez 1734615f31feSGabriel Fernandez return &pdata->pll[pll_idx]; 1735615f31feSGabriel Fernandez } 1736615f31feSGabriel Fernandez 1737615f31feSGabriel Fernandez static int _clk_stm32_pll1_init(struct stm32_clk_priv *priv, int pll_idx, 1738615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf) 1739615f31feSGabriel Fernandez { 1740615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx); 1741615f31feSGabriel Fernandez unsigned long refclk; 1742615f31feSGabriel Fernandez int ret = 0; 1743615f31feSGabriel Fernandez 1744615f31feSGabriel Fernandez stm32mp2_a35_ss_on_hsi(); 1745615f31feSGabriel Fernandez 1746615f31feSGabriel Fernandez ret = stm32_clk_configure_mux(priv, pll_conf->src); 1747615f31feSGabriel Fernandez if (ret != 0) { 1748615f31feSGabriel Fernandez panic(); 1749615f31feSGabriel Fernandez } 1750615f31feSGabriel Fernandez 1751615f31feSGabriel Fernandez refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id); 1752615f31feSGabriel Fernandez 1753615f31feSGabriel Fernandez /* 1754615f31feSGabriel Fernandez * No need to check max clock, as oscillator reference clocks will 1755615f31feSGabriel Fernandez * always be less than 1.2 GHz 1756615f31feSGabriel Fernandez */ 1757615f31feSGabriel Fernandez if (refclk < PLL_REFCLK_MIN) { 1758615f31feSGabriel Fernandez EARLY_ERROR("%s: %d\n", __func__, __LINE__); 1759615f31feSGabriel Fernandez panic(); 1760615f31feSGabriel Fernandez } 1761615f31feSGabriel Fernandez 1762615f31feSGabriel Fernandez stm32mp2_a35_pll1_config(pll_conf->cfg[FBDIV], pll_conf->cfg[REFDIV], 1763615f31feSGabriel Fernandez pll_conf->cfg[POSTDIV1], pll_conf->cfg[POSTDIV2]); 1764615f31feSGabriel Fernandez 1765615f31feSGabriel Fernandez ret = stm32mp2_a35_pll1_start(); 1766615f31feSGabriel Fernandez if (ret != 0) { 1767615f31feSGabriel Fernandez panic(); 1768615f31feSGabriel Fernandez } 1769615f31feSGabriel Fernandez 1770615f31feSGabriel Fernandez return 0; 1771615f31feSGabriel Fernandez } 1772615f31feSGabriel Fernandez 1773615f31feSGabriel Fernandez static int clk_stm32_pll_wait_mux_ready(struct stm32_clk_priv *priv, 1774615f31feSGabriel Fernandez const struct stm32_clk_pll *pll) 1775615f31feSGabriel Fernandez { 1776615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 1777615f31feSGabriel Fernandez uint64_t timeout = timeout_init_us(CLKSRC_TIMEOUT); 1778615f31feSGabriel Fernandez 1779615f31feSGabriel Fernandez while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_CKREFST) != 1780615f31feSGabriel Fernandez RCC_PLLxCFGR1_CKREFST) { 1781615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1782615f31feSGabriel Fernandez EARLY_ERROR("PLL%d ref clock not started\n", pll->clk_id - _CK_PLL1 + 1); 1783615f31feSGabriel Fernandez return -ETIMEDOUT; 1784615f31feSGabriel Fernandez } 1785615f31feSGabriel Fernandez } 1786615f31feSGabriel Fernandez 1787615f31feSGabriel Fernandez return 0; 1788615f31feSGabriel Fernandez } 1789615f31feSGabriel Fernandez 1790615f31feSGabriel Fernandez static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx, 1791615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf) 1792615f31feSGabriel Fernandez { 1793615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx); 1794615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 1795615f31feSGabriel Fernandez bool spread_spectrum = false; 1796615f31feSGabriel Fernandez int ret = 0; 1797615f31feSGabriel Fernandez 1798615f31feSGabriel Fernandez _clk_stm32_pll_disable(priv, pll); 1799615f31feSGabriel Fernandez 1800615f31feSGabriel Fernandez ret = stm32_clk_configure_mux(priv, pll_conf->src); 1801615f31feSGabriel Fernandez if (ret != 0) { 1802615f31feSGabriel Fernandez panic(); 1803615f31feSGabriel Fernandez } 1804615f31feSGabriel Fernandez 1805615f31feSGabriel Fernandez ret = clk_stm32_pll_wait_mux_ready(priv, pll); 1806615f31feSGabriel Fernandez if (ret != 0) { 1807615f31feSGabriel Fernandez panic(); 1808615f31feSGabriel Fernandez } 1809615f31feSGabriel Fernandez 1810615f31feSGabriel Fernandez ret = clk_stm32_pll_config_output(priv, pll, pll_conf->cfg, pll_conf->frac); 1811615f31feSGabriel Fernandez if (ret != 0) { 1812615f31feSGabriel Fernandez panic(); 1813615f31feSGabriel Fernandez } 1814615f31feSGabriel Fernandez 1815615f31feSGabriel Fernandez if (pll_conf->csg_enabled) { 1816615f31feSGabriel Fernandez clk_stm32_pll_config_csg(priv, pll, pll_conf->csg); 1817615f31feSGabriel Fernandez spread_spectrum = true; 1818615f31feSGabriel Fernandez } 1819615f31feSGabriel Fernandez 1820615f31feSGabriel Fernandez _clk_stm32_pll_enable(priv, pll); 1821615f31feSGabriel Fernandez 1822615f31feSGabriel Fernandez if (spread_spectrum) { 1823615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST); 1824615f31feSGabriel Fernandez } 1825615f31feSGabriel Fernandez 1826615f31feSGabriel Fernandez return 0; 1827615f31feSGabriel Fernandez } 1828615f31feSGabriel Fernandez 1829615f31feSGabriel Fernandez static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx) 1830615f31feSGabriel Fernandez { 1831615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx); 1832615f31feSGabriel Fernandez 1833615f31feSGabriel Fernandez if (pll_conf->enabled) { 1834615f31feSGabriel Fernandez if (pll_idx == _PLL1) { 1835615f31feSGabriel Fernandez return _clk_stm32_pll1_init(priv, pll_idx, pll_conf); 1836615f31feSGabriel Fernandez } else { 1837615f31feSGabriel Fernandez return _clk_stm32_pll_init(priv, pll_idx, pll_conf); 1838615f31feSGabriel Fernandez } 1839615f31feSGabriel Fernandez } 1840615f31feSGabriel Fernandez 1841615f31feSGabriel Fernandez return 0; 1842615f31feSGabriel Fernandez } 1843615f31feSGabriel Fernandez 1844615f31feSGabriel Fernandez static int stm32mp2_clk_pll_configure(struct stm32_clk_priv *priv) 1845615f31feSGabriel Fernandez { 1846615f31feSGabriel Fernandez enum pll_id i; 1847615f31feSGabriel Fernandez int err; 1848615f31feSGabriel Fernandez 1849615f31feSGabriel Fernandez for (i = _PLL1; i < _PLL_NB; i++) { 1850088238adSNicolas Le Bayon #if STM32MP21 1851088238adSNicolas Le Bayon if (i == _PLL3) { 1852088238adSNicolas Le Bayon continue; 1853088238adSNicolas Le Bayon } 1854088238adSNicolas Le Bayon #endif 1855615f31feSGabriel Fernandez err = clk_stm32_pll_init(priv, i); 1856615f31feSGabriel Fernandez if (err) { 1857615f31feSGabriel Fernandez return err; 1858615f31feSGabriel Fernandez } 1859615f31feSGabriel Fernandez } 1860615f31feSGabriel Fernandez 1861615f31feSGabriel Fernandez return 0; 1862615f31feSGabriel Fernandez } 1863615f31feSGabriel Fernandez 1864615f31feSGabriel Fernandez static int wait_predivsr(uint16_t channel) 1865615f31feSGabriel Fernandez { 1866615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1867615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1868615f31feSGabriel Fernandez uintptr_t previvsr; 1869615f31feSGabriel Fernandez uint32_t channel_bit; 1870615f31feSGabriel Fernandez uint64_t timeout; 1871615f31feSGabriel Fernandez 1872615f31feSGabriel Fernandez if (channel < __WORD_BIT) { 1873615f31feSGabriel Fernandez previvsr = rcc_base + RCC_PREDIVSR1; 1874615f31feSGabriel Fernandez channel_bit = BIT(channel); 1875615f31feSGabriel Fernandez } else { 1876615f31feSGabriel Fernandez previvsr = rcc_base + RCC_PREDIVSR2; 1877615f31feSGabriel Fernandez channel_bit = BIT(channel - __WORD_BIT); 1878615f31feSGabriel Fernandez } 1879615f31feSGabriel Fernandez 1880615f31feSGabriel Fernandez timeout = timeout_init_us(CLKDIV_TIMEOUT); 1881615f31feSGabriel Fernandez while ((mmio_read_32(previvsr) & channel_bit) != 0U) { 1882615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1883615f31feSGabriel Fernandez EARLY_ERROR("Pre divider status: %x\n", 1884615f31feSGabriel Fernandez mmio_read_32(previvsr)); 1885615f31feSGabriel Fernandez return -ETIMEDOUT; 1886615f31feSGabriel Fernandez } 1887615f31feSGabriel Fernandez } 1888615f31feSGabriel Fernandez 1889615f31feSGabriel Fernandez return 0; 1890615f31feSGabriel Fernandez } 1891615f31feSGabriel Fernandez 1892615f31feSGabriel Fernandez static int wait_findivsr(uint16_t channel) 1893615f31feSGabriel Fernandez { 1894615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1895615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1896615f31feSGabriel Fernandez uintptr_t finvivsr; 1897615f31feSGabriel Fernandez uint32_t channel_bit; 1898615f31feSGabriel Fernandez uint64_t timeout; 1899615f31feSGabriel Fernandez 1900615f31feSGabriel Fernandez if (channel < __WORD_BIT) { 1901615f31feSGabriel Fernandez finvivsr = rcc_base + RCC_FINDIVSR1; 1902615f31feSGabriel Fernandez channel_bit = BIT(channel); 1903615f31feSGabriel Fernandez } else { 1904615f31feSGabriel Fernandez finvivsr = rcc_base + RCC_FINDIVSR2; 1905615f31feSGabriel Fernandez channel_bit = BIT(channel - __WORD_BIT); 1906615f31feSGabriel Fernandez } 1907615f31feSGabriel Fernandez 1908615f31feSGabriel Fernandez timeout = timeout_init_us(CLKDIV_TIMEOUT); 1909615f31feSGabriel Fernandez while ((mmio_read_32(finvivsr) & channel_bit) != 0U) { 1910615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1911615f31feSGabriel Fernandez EARLY_ERROR("Final divider status: %x\n", 1912615f31feSGabriel Fernandez mmio_read_32(finvivsr)); 1913615f31feSGabriel Fernandez return -ETIMEDOUT; 1914615f31feSGabriel Fernandez } 1915615f31feSGabriel Fernandez } 1916615f31feSGabriel Fernandez 1917615f31feSGabriel Fernandez return 0; 1918615f31feSGabriel Fernandez } 1919615f31feSGabriel Fernandez 1920615f31feSGabriel Fernandez static int wait_xbar_sts(uint16_t channel) 1921615f31feSGabriel Fernandez { 1922615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1923615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1924615f31feSGabriel Fernandez uintptr_t xbar_cfgr = rcc_base + RCC_XBAR0CFGR + (0x4U * channel); 1925615f31feSGabriel Fernandez uint64_t timeout; 1926615f31feSGabriel Fernandez 1927615f31feSGabriel Fernandez timeout = timeout_init_us(CLKDIV_TIMEOUT); 1928615f31feSGabriel Fernandez while ((mmio_read_32(xbar_cfgr) & RCC_XBAR0CFGR_XBAR0STS) != 0U) { 1929615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1930615f31feSGabriel Fernandez EARLY_ERROR("XBAR%uCFGR: %x\n", channel, 1931615f31feSGabriel Fernandez mmio_read_32(xbar_cfgr)); 1932615f31feSGabriel Fernandez return -ETIMEDOUT; 1933615f31feSGabriel Fernandez } 1934615f31feSGabriel Fernandez } 1935615f31feSGabriel Fernandez 1936615f31feSGabriel Fernandez return 0; 1937615f31feSGabriel Fernandez } 1938615f31feSGabriel Fernandez 1939615f31feSGabriel Fernandez static void flexclkgen_config_channel(uint16_t channel, unsigned int clk_src, 1940615f31feSGabriel Fernandez unsigned int prediv, unsigned int findiv) 1941615f31feSGabriel Fernandez { 1942615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1943615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1944615f31feSGabriel Fernandez 1945615f31feSGabriel Fernandez if (wait_predivsr(channel) != 0) { 1946615f31feSGabriel Fernandez panic(); 1947615f31feSGabriel Fernandez } 1948615f31feSGabriel Fernandez 1949615f31feSGabriel Fernandez mmio_clrsetbits_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel), 1950615f31feSGabriel Fernandez RCC_PREDIV0CFGR_PREDIV0_MASK, 1951615f31feSGabriel Fernandez prediv); 1952615f31feSGabriel Fernandez 1953615f31feSGabriel Fernandez if (wait_predivsr(channel) != 0) { 1954615f31feSGabriel Fernandez panic(); 1955615f31feSGabriel Fernandez } 1956615f31feSGabriel Fernandez 1957615f31feSGabriel Fernandez if (wait_findivsr(channel) != 0) { 1958615f31feSGabriel Fernandez panic(); 1959615f31feSGabriel Fernandez } 1960615f31feSGabriel Fernandez 1961615f31feSGabriel Fernandez mmio_clrsetbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel), 1962615f31feSGabriel Fernandez RCC_FINDIV0CFGR_FINDIV0_MASK, 1963615f31feSGabriel Fernandez findiv); 1964615f31feSGabriel Fernandez 1965615f31feSGabriel Fernandez if (wait_findivsr(channel) != 0) { 1966615f31feSGabriel Fernandez panic(); 1967615f31feSGabriel Fernandez } 1968615f31feSGabriel Fernandez 1969615f31feSGabriel Fernandez if (wait_xbar_sts(channel) != 0) { 1970615f31feSGabriel Fernandez panic(); 1971615f31feSGabriel Fernandez } 1972615f31feSGabriel Fernandez 1973615f31feSGabriel Fernandez mmio_clrsetbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel), 1974615f31feSGabriel Fernandez RCC_XBARxCFGR_XBARxSEL_MASK, 1975615f31feSGabriel Fernandez clk_src); 1976615f31feSGabriel Fernandez mmio_setbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel), 1977615f31feSGabriel Fernandez RCC_XBARxCFGR_XBARxEN); 1978615f31feSGabriel Fernandez 1979615f31feSGabriel Fernandez if (wait_xbar_sts(channel) != 0) { 1980615f31feSGabriel Fernandez panic(); 1981615f31feSGabriel Fernandez } 1982615f31feSGabriel Fernandez } 1983615f31feSGabriel Fernandez 1984615f31feSGabriel Fernandez static int stm32mp2_clk_flexgen_configure(struct stm32_clk_priv *priv) 1985615f31feSGabriel Fernandez { 1986615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 1987615f31feSGabriel Fernandez uint32_t i; 1988615f31feSGabriel Fernandez 1989615f31feSGabriel Fernandez for (i = 0U; i < pdata->nflexgen; i++) { 1990615f31feSGabriel Fernandez uint32_t val = pdata->flexgen[i]; 1991615f31feSGabriel Fernandez uint32_t cmd, cmd_data; 1992615f31feSGabriel Fernandez unsigned int channel, clk_src, pdiv, fdiv; 1993615f31feSGabriel Fernandez 1994615f31feSGabriel Fernandez cmd = (val & CMD_MASK) >> CMD_SHIFT; 1995615f31feSGabriel Fernandez cmd_data = val & ~CMD_MASK; 1996615f31feSGabriel Fernandez 1997615f31feSGabriel Fernandez if (cmd != CMD_FLEXGEN) { 1998615f31feSGabriel Fernandez continue; 1999615f31feSGabriel Fernandez } 2000615f31feSGabriel Fernandez 2001615f31feSGabriel Fernandez channel = (cmd_data & FLEX_ID_MASK) >> FLEX_ID_SHIFT; 2002615f31feSGabriel Fernandez clk_src = (cmd_data & FLEX_SEL_MASK) >> FLEX_SEL_SHIFT; 2003615f31feSGabriel Fernandez pdiv = (cmd_data & FLEX_PDIV_MASK) >> FLEX_PDIV_SHIFT; 2004615f31feSGabriel Fernandez fdiv = (cmd_data & FLEX_FDIV_MASK) >> FLEX_FDIV_SHIFT; 2005615f31feSGabriel Fernandez 2006615f31feSGabriel Fernandez switch (channel) { 2007615f31feSGabriel Fernandez case 33U: /* STGEN */ 2008615f31feSGabriel Fernandez break; 2009615f31feSGabriel Fernandez 2010615f31feSGabriel Fernandez default: 2011615f31feSGabriel Fernandez flexclkgen_config_channel(channel, clk_src, pdiv, fdiv); 2012615f31feSGabriel Fernandez break; 2013615f31feSGabriel Fernandez } 2014615f31feSGabriel Fernandez } 2015615f31feSGabriel Fernandez 2016615f31feSGabriel Fernandez return 0; 2017615f31feSGabriel Fernandez } 2018615f31feSGabriel Fernandez 2019615f31feSGabriel Fernandez static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv) 2020615f31feSGabriel Fernandez { 2021615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2022615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE]; 2023615f31feSGabriel Fernandez bool digbyp = osci->digbyp; 2024615f31feSGabriel Fernandez bool bypass = osci->bypass; 2025615f31feSGabriel Fernandez bool css = osci->css; 2026615f31feSGabriel Fernandez 2027615f31feSGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) { 2028615f31feSGabriel Fernandez return; 2029615f31feSGabriel Fernandez } 2030615f31feSGabriel Fernandez 2031615f31feSGabriel Fernandez clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass); 2032615f31feSGabriel Fernandez 2033615f31feSGabriel Fernandez _clk_stm32_enable(priv, _CK_HSE); 2034615f31feSGabriel Fernandez 2035615f31feSGabriel Fernandez clk_oscillator_set_css(priv, _CK_HSE, css); 2036615f31feSGabriel Fernandez } 2037615f31feSGabriel Fernandez 2038615f31feSGabriel Fernandez static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv) 2039615f31feSGabriel Fernandez { 2040615f31feSGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE); 2041615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2042615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE]; 2043615f31feSGabriel Fernandez bool digbyp = osci->digbyp; 2044615f31feSGabriel Fernandez bool bypass = osci->bypass; 2045615f31feSGabriel Fernandez uint8_t drive = osci->drive; 2046615f31feSGabriel Fernandez 2047615f31feSGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) { 2048615f31feSGabriel Fernandez return; 2049615f31feSGabriel Fernandez } 2050615f31feSGabriel Fernandez 2051615f31feSGabriel Fernandez /* Do not reconfigure LSE if already enabled */ 2052615f31feSGabriel Fernandez if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) { 2053615f31feSGabriel Fernandez return; 2054615f31feSGabriel Fernandez } 2055615f31feSGabriel Fernandez 2056615f31feSGabriel Fernandez clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass); 2057615f31feSGabriel Fernandez 2058615f31feSGabriel Fernandez clk_oscillator_set_drive(priv, _CK_LSE, drive); 2059615f31feSGabriel Fernandez 2060615f31feSGabriel Fernandez _clk_stm32_gate_enable(priv, osc_data->gate_id); 2061615f31feSGabriel Fernandez } 2062615f31feSGabriel Fernandez 2063615f31feSGabriel Fernandez static int stm32mp2_clk_switch_to_hsi(struct stm32_clk_priv *priv) 2064615f31feSGabriel Fernandez { 2065615f31feSGabriel Fernandez stm32mp2_a35_ss_on_hsi(); 2066615f31feSGabriel Fernandez stm32mp2_clk_muxsel_on_hsi(priv); 2067615f31feSGabriel Fernandez stm32mp2_clk_xbar_on_hsi(priv); 2068615f31feSGabriel Fernandez 2069615f31feSGabriel Fernandez return 0; 2070615f31feSGabriel Fernandez } 2071615f31feSGabriel Fernandez 2072615f31feSGabriel Fernandez static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv) 2073615f31feSGabriel Fernandez { 2074615f31feSGabriel Fernandez int ret = 0; 2075615f31feSGabriel Fernandez 2076615f31feSGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) { 2077615f31feSGabriel Fernandez ret = clk_oscillator_wait_ready_on(priv, _CK_LSE); 2078615f31feSGabriel Fernandez } 2079615f31feSGabriel Fernandez 2080615f31feSGabriel Fernandez return ret; 2081615f31feSGabriel Fernandez } 2082615f31feSGabriel Fernandez 2083615f31feSGabriel Fernandez static void stm32_enable_oscillator_msi(struct stm32_clk_priv *priv) 2084615f31feSGabriel Fernandez { 2085088238adSNicolas Le Bayon #if !STM32MP21 2086615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2087615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_MSI]; 2088615f31feSGabriel Fernandez int err; 2089615f31feSGabriel Fernandez 2090615f31feSGabriel Fernandez err = clk_stm32_osc_msi_set_rate(priv, _CK_MSI, osci->freq, 0); 2091615f31feSGabriel Fernandez if (err != 0) { 2092615f31feSGabriel Fernandez EARLY_ERROR("Invalid rate %lu MHz for MSI ! (4 or 16 only)\n", 2093615f31feSGabriel Fernandez osci->freq / 1000000U); 2094615f31feSGabriel Fernandez panic(); 2095615f31feSGabriel Fernandez } 2096088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 2097615f31feSGabriel Fernandez 2098615f31feSGabriel Fernandez _clk_stm32_enable(priv, _CK_MSI); 2099615f31feSGabriel Fernandez } 2100615f31feSGabriel Fernandez 2101615f31feSGabriel Fernandez static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv) 2102615f31feSGabriel Fernandez { 2103615f31feSGabriel Fernandez stm32_enable_oscillator_hse(priv); 2104615f31feSGabriel Fernandez stm32_enable_oscillator_lse(priv); 2105615f31feSGabriel Fernandez stm32_enable_oscillator_msi(priv); 2106615f31feSGabriel Fernandez _clk_stm32_enable(priv, _CK_LSI); 2107615f31feSGabriel Fernandez } 2108615f31feSGabriel Fernandez 2109615f31feSGabriel Fernandez static int stm32_clk_configure_div(struct stm32_clk_priv *priv, uint32_t data) 2110615f31feSGabriel Fernandez { 2111615f31feSGabriel Fernandez int div_id = (data & DIV_ID_MASK) >> DIV_ID_SHIFT; 2112615f31feSGabriel Fernandez int div_n = (data & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT; 2113615f31feSGabriel Fernandez 2114615f31feSGabriel Fernandez return clk_stm32_set_div(priv, div_id, div_n); 2115615f31feSGabriel Fernandez } 2116615f31feSGabriel Fernandez 2117615f31feSGabriel Fernandez static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data) 2118615f31feSGabriel Fernandez { 2119615f31feSGabriel Fernandez int mux_id = (data & MUX_ID_MASK) >> MUX_ID_SHIFT; 2120615f31feSGabriel Fernandez int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT; 2121615f31feSGabriel Fernandez 2122615f31feSGabriel Fernandez return clk_mux_set_parent(priv, mux_id, sel); 2123615f31feSGabriel Fernandez } 2124615f31feSGabriel Fernandez 2125615f31feSGabriel Fernandez static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data) 2126615f31feSGabriel Fernandez { 2127615f31feSGabriel Fernandez unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT; 2128615f31feSGabriel Fernandez 2129615f31feSGabriel Fernandez return clk_get_index(priv, binding_id); 2130615f31feSGabriel Fernandez } 2131615f31feSGabriel Fernandez 2132615f31feSGabriel Fernandez static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data) 2133615f31feSGabriel Fernandez { 2134615f31feSGabriel Fernandez int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT; 2135615f31feSGabriel Fernandez bool enable = ((data & CLK_ON_MASK) >> CLK_ON_SHIFT) != 0U; 2136615f31feSGabriel Fernandez int clk_id = 0; 2137615f31feSGabriel Fernandez int ret = 0; 2138615f31feSGabriel Fernandez 2139615f31feSGabriel Fernandez clk_id = stm32_clk_configure_clk_get_binding_id(priv, data); 2140615f31feSGabriel Fernandez if (clk_id < 0) { 2141615f31feSGabriel Fernandez return clk_id; 2142615f31feSGabriel Fernandez } 2143615f31feSGabriel Fernandez 2144615f31feSGabriel Fernandez if (sel != CLK_NOMUX) { 2145615f31feSGabriel Fernandez ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel); 2146615f31feSGabriel Fernandez if (ret != 0) { 2147615f31feSGabriel Fernandez return ret; 2148615f31feSGabriel Fernandez } 2149615f31feSGabriel Fernandez } 2150615f31feSGabriel Fernandez 2151615f31feSGabriel Fernandez if (enable) { 2152615f31feSGabriel Fernandez clk_stm32_enable_call_ops(priv, clk_id); 2153615f31feSGabriel Fernandez } else { 2154615f31feSGabriel Fernandez clk_stm32_disable_call_ops(priv, clk_id); 2155615f31feSGabriel Fernandez } 2156615f31feSGabriel Fernandez 2157615f31feSGabriel Fernandez return 0; 2158615f31feSGabriel Fernandez } 2159615f31feSGabriel Fernandez 2160615f31feSGabriel Fernandez static int stm32_clk_configure(struct stm32_clk_priv *priv, uint32_t val) 2161615f31feSGabriel Fernandez { 2162615f31feSGabriel Fernandez uint32_t cmd = (val & CMD_MASK) >> CMD_SHIFT; 2163615f31feSGabriel Fernandez uint32_t cmd_data = val & ~CMD_MASK; 2164615f31feSGabriel Fernandez int ret = -1; 2165615f31feSGabriel Fernandez 2166615f31feSGabriel Fernandez switch (cmd) { 2167615f31feSGabriel Fernandez case CMD_DIV: 2168615f31feSGabriel Fernandez ret = stm32_clk_configure_div(priv, cmd_data); 2169615f31feSGabriel Fernandez break; 2170615f31feSGabriel Fernandez 2171615f31feSGabriel Fernandez case CMD_MUX: 2172615f31feSGabriel Fernandez ret = stm32_clk_configure_mux(priv, cmd_data); 2173615f31feSGabriel Fernandez break; 2174615f31feSGabriel Fernandez 2175615f31feSGabriel Fernandez case CMD_CLK: 2176615f31feSGabriel Fernandez ret = stm32_clk_configure_clk(priv, cmd_data); 2177615f31feSGabriel Fernandez break; 2178615f31feSGabriel Fernandez 2179615f31feSGabriel Fernandez default: 2180615f31feSGabriel Fernandez EARLY_ERROR("%s: cmd unknown ! : 0x%x\n", __func__, val); 2181615f31feSGabriel Fernandez break; 2182615f31feSGabriel Fernandez } 2183615f31feSGabriel Fernandez 2184615f31feSGabriel Fernandez return ret; 2185615f31feSGabriel Fernandez } 2186615f31feSGabriel Fernandez 2187615f31feSGabriel Fernandez static int stm32_clk_bus_configure(struct stm32_clk_priv *priv) 2188615f31feSGabriel Fernandez { 2189615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2190615f31feSGabriel Fernandez uint32_t i; 2191615f31feSGabriel Fernandez 2192615f31feSGabriel Fernandez for (i = 0; i < pdata->nbusclk; i++) { 2193615f31feSGabriel Fernandez int ret; 2194615f31feSGabriel Fernandez 2195615f31feSGabriel Fernandez ret = stm32_clk_configure(priv, pdata->busclk[i]); 2196615f31feSGabriel Fernandez if (ret != 0) { 2197615f31feSGabriel Fernandez return ret; 2198615f31feSGabriel Fernandez } 2199615f31feSGabriel Fernandez } 2200615f31feSGabriel Fernandez 2201615f31feSGabriel Fernandez return 0; 2202615f31feSGabriel Fernandez } 2203615f31feSGabriel Fernandez 2204615f31feSGabriel Fernandez static int stm32_clk_kernel_configure(struct stm32_clk_priv *priv) 2205615f31feSGabriel Fernandez { 2206615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2207615f31feSGabriel Fernandez uint32_t i; 2208615f31feSGabriel Fernandez 2209615f31feSGabriel Fernandez for (i = 0U; i < pdata->nkernelclk; i++) { 2210615f31feSGabriel Fernandez int ret; 2211615f31feSGabriel Fernandez 2212615f31feSGabriel Fernandez ret = stm32_clk_configure(priv, pdata->kernelclk[i]); 2213615f31feSGabriel Fernandez if (ret != 0) { 2214615f31feSGabriel Fernandez return ret; 2215615f31feSGabriel Fernandez } 2216615f31feSGabriel Fernandez } 2217615f31feSGabriel Fernandez 2218615f31feSGabriel Fernandez return 0; 2219615f31feSGabriel Fernandez } 2220615f31feSGabriel Fernandez 2221615f31feSGabriel Fernandez static int stm32mp2_init_clock_tree(void) 2222615f31feSGabriel Fernandez { 2223615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 2224615f31feSGabriel Fernandez int ret; 2225615f31feSGabriel Fernandez 2226615f31feSGabriel Fernandez /* Set timer with STGEN without changing its clock source */ 2227615f31feSGabriel Fernandez stm32mp_stgen_restore_rate(); 2228615f31feSGabriel Fernandez generic_delay_timer_init(); 2229615f31feSGabriel Fernandez 2230615f31feSGabriel Fernandez stm32_clk_oscillators_enable(priv); 2231615f31feSGabriel Fernandez 2232615f31feSGabriel Fernandez /* Come back to HSI */ 2233615f31feSGabriel Fernandez ret = stm32mp2_clk_switch_to_hsi(priv); 2234615f31feSGabriel Fernandez if (ret != 0) { 2235615f31feSGabriel Fernandez panic(); 2236615f31feSGabriel Fernandez } 2237615f31feSGabriel Fernandez 2238615f31feSGabriel Fernandez ret = stm32mp2_clk_pll_configure(priv); 2239615f31feSGabriel Fernandez if (ret != 0) { 2240615f31feSGabriel Fernandez panic(); 2241615f31feSGabriel Fernandez } 2242615f31feSGabriel Fernandez 2243615f31feSGabriel Fernandez /* Wait LSE ready before to use it */ 2244615f31feSGabriel Fernandez ret = stm32_clk_oscillators_wait_lse_ready(priv); 2245615f31feSGabriel Fernandez if (ret != 0) { 2246615f31feSGabriel Fernandez panic(); 2247615f31feSGabriel Fernandez } 2248615f31feSGabriel Fernandez 2249615f31feSGabriel Fernandez ret = stm32mp2_clk_flexgen_configure(priv); 2250615f31feSGabriel Fernandez if (ret != 0) { 2251615f31feSGabriel Fernandez panic(); 2252615f31feSGabriel Fernandez } 2253615f31feSGabriel Fernandez 2254615f31feSGabriel Fernandez ret = stm32_clk_bus_configure(priv); 2255615f31feSGabriel Fernandez if (ret != 0) { 2256615f31feSGabriel Fernandez panic(); 2257615f31feSGabriel Fernandez } 2258615f31feSGabriel Fernandez 2259615f31feSGabriel Fernandez ret = stm32_clk_kernel_configure(priv); 2260615f31feSGabriel Fernandez if (ret != 0) { 2261615f31feSGabriel Fernandez panic(); 2262615f31feSGabriel Fernandez } 2263615f31feSGabriel Fernandez 2264615f31feSGabriel Fernandez return 0; 2265615f31feSGabriel Fernandez } 2266615f31feSGabriel Fernandez 2267615f31feSGabriel Fernandez static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name, 2268615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci) 2269615f31feSGabriel Fernandez { 2270615f31feSGabriel Fernandez int subnode = 0; 2271615f31feSGabriel Fernandez 2272615f31feSGabriel Fernandez /* Default value oscillator not found, freq=0 */ 2273615f31feSGabriel Fernandez osci->freq = 0; 2274615f31feSGabriel Fernandez 2275615f31feSGabriel Fernandez fdt_for_each_subnode(subnode, fdt, node) { 2276615f31feSGabriel Fernandez const char *cchar = NULL; 2277615f31feSGabriel Fernandez const fdt32_t *cuint = NULL; 2278615f31feSGabriel Fernandez int ret = 0; 2279615f31feSGabriel Fernandez 2280615f31feSGabriel Fernandez cchar = fdt_get_name(fdt, subnode, &ret); 2281615f31feSGabriel Fernandez if (cchar == NULL) { 2282615f31feSGabriel Fernandez return ret; 2283615f31feSGabriel Fernandez } 2284615f31feSGabriel Fernandez 2285615f31feSGabriel Fernandez if (strncmp(cchar, name, (size_t)ret) || 2286615f31feSGabriel Fernandez fdt_get_status(subnode) == DT_DISABLED) { 2287615f31feSGabriel Fernandez continue; 2288615f31feSGabriel Fernandez } 2289615f31feSGabriel Fernandez 2290615f31feSGabriel Fernandez cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret); 2291615f31feSGabriel Fernandez if (cuint == NULL) { 2292615f31feSGabriel Fernandez return ret; 2293615f31feSGabriel Fernandez } 2294615f31feSGabriel Fernandez 2295615f31feSGabriel Fernandez osci->freq = fdt32_to_cpu(*cuint); 2296615f31feSGabriel Fernandez 2297615f31feSGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) { 2298615f31feSGabriel Fernandez osci->bypass = true; 2299615f31feSGabriel Fernandez } 2300615f31feSGabriel Fernandez 2301615f31feSGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) { 2302615f31feSGabriel Fernandez osci->digbyp = true; 2303615f31feSGabriel Fernandez } 2304615f31feSGabriel Fernandez 2305615f31feSGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) { 2306615f31feSGabriel Fernandez osci->css = true; 2307615f31feSGabriel Fernandez } 2308615f31feSGabriel Fernandez 2309615f31feSGabriel Fernandez osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH); 2310615f31feSGabriel Fernandez 2311615f31feSGabriel Fernandez return 0; 2312615f31feSGabriel Fernandez } 2313615f31feSGabriel Fernandez 2314615f31feSGabriel Fernandez return 0; 2315615f31feSGabriel Fernandez } 2316615f31feSGabriel Fernandez 2317615f31feSGabriel Fernandez static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata) 2318615f31feSGabriel Fernandez { 2319615f31feSGabriel Fernandez int fdt_err = 0; 2320615f31feSGabriel Fernandez uint32_t i = 0; 2321615f31feSGabriel Fernandez int node = 0; 2322615f31feSGabriel Fernandez 2323615f31feSGabriel Fernandez node = fdt_path_offset(fdt, "/clocks"); 2324615f31feSGabriel Fernandez if (node < 0) { 2325615f31feSGabriel Fernandez return -FDT_ERR_NOTFOUND; 2326615f31feSGabriel Fernandez } 2327615f31feSGabriel Fernandez 2328615f31feSGabriel Fernandez for (i = 0; i < pdata->nosci; i++) { 2329615f31feSGabriel Fernandez const char *name = NULL; 2330615f31feSGabriel Fernandez 2331615f31feSGabriel Fernandez name = clk_stm32_get_oscillator_name((enum stm32_osc)i); 2332615f31feSGabriel Fernandez if (name == NULL) { 2333615f31feSGabriel Fernandez continue; 2334615f31feSGabriel Fernandez } 2335615f31feSGabriel Fernandez 2336615f31feSGabriel Fernandez fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]); 2337615f31feSGabriel Fernandez if (fdt_err < 0) { 2338615f31feSGabriel Fernandez panic(); 2339615f31feSGabriel Fernandez } 2340615f31feSGabriel Fernandez } 2341615f31feSGabriel Fernandez 2342615f31feSGabriel Fernandez return 0; 2343615f31feSGabriel Fernandez } 2344615f31feSGabriel Fernandez 2345615f31feSGabriel Fernandez static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll) 2346615f31feSGabriel Fernandez { 2347615f31feSGabriel Fernandez const fdt32_t *cuint = NULL; 2348615f31feSGabriel Fernandez int subnode_pll = 0; 2349615f31feSGabriel Fernandez uint32_t val = 0; 2350615f31feSGabriel Fernandez int err = 0; 2351615f31feSGabriel Fernandez 2352615f31feSGabriel Fernandez cuint = fdt_getprop(fdt, subnode, "st,pll", NULL); 2353615f31feSGabriel Fernandez if (!cuint) { 2354615f31feSGabriel Fernandez return -FDT_ERR_NOTFOUND; 2355615f31feSGabriel Fernandez } 2356615f31feSGabriel Fernandez 2357615f31feSGabriel Fernandez subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); 2358615f31feSGabriel Fernandez if (subnode_pll < 0) { 2359615f31feSGabriel Fernandez return -FDT_ERR_NOTFOUND; 2360615f31feSGabriel Fernandez } 2361615f31feSGabriel Fernandez 2362615f31feSGabriel Fernandez err = fdt_read_uint32_array(fdt, subnode_pll, "cfg", (int)PLLCFG_NB, pll->cfg); 2363615f31feSGabriel Fernandez if (err != 0) { 2364615f31feSGabriel Fernandez return err; 2365615f31feSGabriel Fernandez } 2366615f31feSGabriel Fernandez 2367615f31feSGabriel Fernandez err = fdt_read_uint32_array(fdt, subnode_pll, "csg", (int)PLLCSG_NB, pll->csg); 2368615f31feSGabriel Fernandez 2369615f31feSGabriel Fernandez pll->csg_enabled = (err == 0); 2370615f31feSGabriel Fernandez 2371615f31feSGabriel Fernandez if (err == -FDT_ERR_NOTFOUND) { 2372615f31feSGabriel Fernandez err = 0; 2373615f31feSGabriel Fernandez } 2374615f31feSGabriel Fernandez 2375615f31feSGabriel Fernandez if (err != 0) { 2376615f31feSGabriel Fernandez return err; 2377615f31feSGabriel Fernandez } 2378615f31feSGabriel Fernandez 2379615f31feSGabriel Fernandez pll->enabled = true; 2380615f31feSGabriel Fernandez 2381615f31feSGabriel Fernandez pll->frac = fdt_read_uint32_default(fdt, subnode_pll, "frac", 0); 2382615f31feSGabriel Fernandez 2383615f31feSGabriel Fernandez pll->src = UINT32_MAX; 2384615f31feSGabriel Fernandez 2385615f31feSGabriel Fernandez err = fdt_read_uint32(fdt, subnode_pll, "src", &val); 2386615f31feSGabriel Fernandez if (err == 0) { 2387615f31feSGabriel Fernandez pll->src = val; 2388615f31feSGabriel Fernandez } 2389615f31feSGabriel Fernandez 2390615f31feSGabriel Fernandez return 0; 2391615f31feSGabriel Fernandez } 2392615f31feSGabriel Fernandez 2393615f31feSGabriel Fernandez #define RCC_PLL_NAME_SIZE 12 2394615f31feSGabriel Fernandez 2395615f31feSGabriel Fernandez static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata) 2396615f31feSGabriel Fernandez { 2397615f31feSGabriel Fernandez unsigned int i = 0; 2398615f31feSGabriel Fernandez 2399615f31feSGabriel Fernandez for (i = _PLL1; i < pdata->npll; i++) { 2400615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll = pdata->pll + i; 2401615f31feSGabriel Fernandez char name[RCC_PLL_NAME_SIZE]; 2402615f31feSGabriel Fernandez int subnode = 0; 2403615f31feSGabriel Fernandez int err = 0; 2404615f31feSGabriel Fernandez 2405088238adSNicolas Le Bayon #if STM32MP21 2406088238adSNicolas Le Bayon if (i == _PLL3) { 2407088238adSNicolas Le Bayon continue; 2408088238adSNicolas Le Bayon } 2409088238adSNicolas Le Bayon #endif 2410615f31feSGabriel Fernandez snprintf(name, sizeof(name), "st,pll-%u", i + 1); 2411615f31feSGabriel Fernandez 2412615f31feSGabriel Fernandez subnode = fdt_subnode_offset(fdt, node, name); 2413615f31feSGabriel Fernandez if (!fdt_check_node(subnode)) { 2414615f31feSGabriel Fernandez continue; 2415615f31feSGabriel Fernandez } 2416615f31feSGabriel Fernandez 2417615f31feSGabriel Fernandez err = clk_stm32_parse_pll_fdt(fdt, subnode, pll); 2418615f31feSGabriel Fernandez if (err != 0) { 2419615f31feSGabriel Fernandez panic(); 2420615f31feSGabriel Fernandez } 2421615f31feSGabriel Fernandez } 2422615f31feSGabriel Fernandez 2423615f31feSGabriel Fernandez return 0; 2424615f31feSGabriel Fernandez } 2425615f31feSGabriel Fernandez 2426615f31feSGabriel Fernandez static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata) 2427615f31feSGabriel Fernandez { 2428615f31feSGabriel Fernandez void *fdt = NULL; 2429615f31feSGabriel Fernandez int node; 2430615f31feSGabriel Fernandez int err; 2431615f31feSGabriel Fernandez 2432615f31feSGabriel Fernandez if (fdt_get_address(&fdt) == 0) { 2433615f31feSGabriel Fernandez return -ENOENT; 2434615f31feSGabriel Fernandez } 2435615f31feSGabriel Fernandez 2436615f31feSGabriel Fernandez node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); 2437615f31feSGabriel Fernandez if (node < 0) { 2438615f31feSGabriel Fernandez panic(); 2439615f31feSGabriel Fernandez } 2440615f31feSGabriel Fernandez 2441615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata); 2442615f31feSGabriel Fernandez if (err != 0) { 2443615f31feSGabriel Fernandez return err; 2444615f31feSGabriel Fernandez } 2445615f31feSGabriel Fernandez 2446615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata); 2447615f31feSGabriel Fernandez if (err != 0) { 2448615f31feSGabriel Fernandez return err; 2449615f31feSGabriel Fernandez } 2450615f31feSGabriel Fernandez 2451615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_by_name(fdt, node, "st,busclk", pdata->busclk, &pdata->nbusclk); 2452615f31feSGabriel Fernandez if (err != 0) { 2453615f31feSGabriel Fernandez return err; 2454615f31feSGabriel Fernandez } 2455615f31feSGabriel Fernandez 2456615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_by_name(fdt, node, "st,flexgen", pdata->flexgen, 2457615f31feSGabriel Fernandez &pdata->nflexgen); 2458615f31feSGabriel Fernandez if (err != 0) { 2459615f31feSGabriel Fernandez return err; 2460615f31feSGabriel Fernandez } 2461615f31feSGabriel Fernandez 2462615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_by_name(fdt, node, "st,kerclk", pdata->kernelclk, 2463615f31feSGabriel Fernandez &pdata->nkernelclk); 2464615f31feSGabriel Fernandez if (err != 0) { 2465615f31feSGabriel Fernandez return err; 2466615f31feSGabriel Fernandez } 2467615f31feSGabriel Fernandez 2468615f31feSGabriel Fernandez return 0; 2469615f31feSGabriel Fernandez } 2470615f31feSGabriel Fernandez #endif /* IMAGE_BL2 */ 2471615f31feSGabriel Fernandez 2472088238adSNicolas Le Bayon static struct stm32_osci_dt_cfg mp2_osci[NB_OSCILLATOR]; 2473615f31feSGabriel Fernandez 2474088238adSNicolas Le Bayon static struct stm32_pll_dt_cfg mp2_pll[_PLL_NB]; 2475615f31feSGabriel Fernandez 2476615f31feSGabriel Fernandez #define DT_FLEXGEN_CLK_MAX 64 2477088238adSNicolas Le Bayon static uint32_t mp2_flexgen[DT_FLEXGEN_CLK_MAX]; 2478615f31feSGabriel Fernandez 2479088238adSNicolas Le Bayon #if STM32MP21 2480088238adSNicolas Le Bayon #define DT_BUS_CLK_MAX 7 2481088238adSNicolas Le Bayon #else /* STM32MP21 */ 2482615f31feSGabriel Fernandez #define DT_BUS_CLK_MAX 6 2483088238adSNicolas Le Bayon #endif /* STM32MP21 */ 2484088238adSNicolas Le Bayon static uint32_t mp2_busclk[DT_BUS_CLK_MAX]; 2485615f31feSGabriel Fernandez 2486615f31feSGabriel Fernandez #define DT_KERNEL_CLK_MAX 20 2487088238adSNicolas Le Bayon static uint32_t mp2_kernelclk[DT_KERNEL_CLK_MAX]; 2488615f31feSGabriel Fernandez 2489088238adSNicolas Le Bayon static struct stm32_clk_platdata stm32mp2_pdata = { 2490088238adSNicolas Le Bayon .osci = mp2_osci, 2491615f31feSGabriel Fernandez .nosci = NB_OSCILLATOR, 2492088238adSNicolas Le Bayon .pll = mp2_pll, 2493615f31feSGabriel Fernandez .npll = _PLL_NB, 2494088238adSNicolas Le Bayon .flexgen = mp2_flexgen, 2495615f31feSGabriel Fernandez .nflexgen = DT_FLEXGEN_CLK_MAX, 2496088238adSNicolas Le Bayon .busclk = mp2_busclk, 2497615f31feSGabriel Fernandez .nbusclk = DT_BUS_CLK_MAX, 2498088238adSNicolas Le Bayon .kernelclk = mp2_kernelclk, 2499615f31feSGabriel Fernandez .nkernelclk = DT_KERNEL_CLK_MAX, 2500615f31feSGabriel Fernandez }; 2501615f31feSGabriel Fernandez 2502088238adSNicolas Le Bayon static uint8_t refcounts_mp2[CK_LAST]; 2503615f31feSGabriel Fernandez 2504088238adSNicolas Le Bayon static struct stm32_clk_priv stm32mp2_clock_data = { 2505615f31feSGabriel Fernandez .base = RCC_BASE, 2506088238adSNicolas Le Bayon .num = ARRAY_SIZE(stm32mp2_clk), 2507088238adSNicolas Le Bayon .clks = stm32mp2_clk, 2508088238adSNicolas Le Bayon .parents = parent_mp2, 2509088238adSNicolas Le Bayon .nb_parents = ARRAY_SIZE(parent_mp2), 2510088238adSNicolas Le Bayon .gates = gates_mp2, 2511088238adSNicolas Le Bayon .nb_gates = ARRAY_SIZE(gates_mp2), 2512088238adSNicolas Le Bayon .div = dividers_mp2, 2513088238adSNicolas Le Bayon .nb_div = ARRAY_SIZE(dividers_mp2), 2514088238adSNicolas Le Bayon .osci_data = stm32mp2_osc_data, 2515088238adSNicolas Le Bayon .nb_osci_data = ARRAY_SIZE(stm32mp2_osc_data), 2516088238adSNicolas Le Bayon .gate_refcounts = refcounts_mp2, 2517088238adSNicolas Le Bayon .pdata = &stm32mp2_pdata, 2518088238adSNicolas Le Bayon .ops_array = ops_array_mp2, 2519615f31feSGabriel Fernandez }; 2520615f31feSGabriel Fernandez 2521615f31feSGabriel Fernandez int stm32mp2_clk_init(void) 2522615f31feSGabriel Fernandez { 2523615f31feSGabriel Fernandez uintptr_t base = RCC_BASE; 2524615f31feSGabriel Fernandez int ret; 2525615f31feSGabriel Fernandez 2526615f31feSGabriel Fernandez #ifdef IMAGE_BL2 2527088238adSNicolas Le Bayon ret = stm32_clk_parse_fdt(&stm32mp2_pdata); 2528615f31feSGabriel Fernandez if (ret != 0) { 2529615f31feSGabriel Fernandez return ret; 2530615f31feSGabriel Fernandez } 2531615f31feSGabriel Fernandez #endif 2532615f31feSGabriel Fernandez 2533088238adSNicolas Le Bayon ret = clk_stm32_init(&stm32mp2_clock_data, base); 2534615f31feSGabriel Fernandez if (ret != 0) { 2535615f31feSGabriel Fernandez return ret; 2536615f31feSGabriel Fernandez } 2537615f31feSGabriel Fernandez 2538615f31feSGabriel Fernandez #ifdef IMAGE_BL2 2539615f31feSGabriel Fernandez ret = stm32mp2_init_clock_tree(); 2540615f31feSGabriel Fernandez if (ret != 0) { 2541615f31feSGabriel Fernandez return ret; 2542615f31feSGabriel Fernandez } 2543615f31feSGabriel Fernandez 2544615f31feSGabriel Fernandez clk_stm32_enable_critical_clocks(); 2545615f31feSGabriel Fernandez #endif 2546615f31feSGabriel Fernandez 2547615f31feSGabriel Fernandez return 0; 2548615f31feSGabriel Fernandez } 2549615f31feSGabriel Fernandez 2550615f31feSGabriel Fernandez int stm32mp2_pll1_disable(void) 2551615f31feSGabriel Fernandez { 2552615f31feSGabriel Fernandez #ifdef IMAGE_BL2 2553615f31feSGabriel Fernandez return -EPERM; 2554615f31feSGabriel Fernandez #else 2555615f31feSGabriel Fernandez uintptr_t a35_ss_address = A35SSC_BASE; 2556615f31feSGabriel Fernandez uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE; 2557615f31feSGabriel Fernandez 2558615f31feSGabriel Fernandez stm32mp2_a35_ss_on_hsi(); 2559615f31feSGabriel Fernandez 2560615f31feSGabriel Fernandez mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD); 2561615f31feSGabriel Fernandez 2562615f31feSGabriel Fernandez return 0; 2563615f31feSGabriel Fernandez #endif 2564615f31feSGabriel Fernandez } 2565