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) 65615f31feSGabriel Fernandez 66615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1_FBDIV_MASK GENMASK(11, 0) 67615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1_FBDIV_SHIFT 0 68615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1_REFDIV_MASK GENMASK(21, 16) 69615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ1_REFDIV_SHIFT 16 70615f31feSGabriel Fernandez 71615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2_POSTDIV1_MASK GENMASK(2, 0) 72615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2_POSTDIV1_SHIFT 0 73615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2_POSTDIV2_MASK GENMASK(5, 3) 74615f31feSGabriel Fernandez #define A35_SS_PLL_FREQ2_POSTDIV2_SHIFT 3 75615f31feSGabriel Fernandez 76615f31feSGabriel Fernandez #define A35_SS_PLL_ENABLE_PD BIT(0) 77615f31feSGabriel Fernandez #define A35_SS_PLL_ENABLE_LOCKP BIT(1) 78615f31feSGabriel Fernandez #define A35_SS_PLL_ENABLE_NRESET_SWPLL_FF BIT(2) 79615f31feSGabriel Fernandez 80615f31feSGabriel Fernandez #define TIMEOUT_US_200MS U(200000) 81615f31feSGabriel Fernandez #define TIMEOUT_US_1S U(1000000) 82615f31feSGabriel Fernandez 83615f31feSGabriel Fernandez #define PLLRDY_TIMEOUT TIMEOUT_US_200MS 84615f31feSGabriel Fernandez #define CLKSRC_TIMEOUT TIMEOUT_US_200MS 85615f31feSGabriel Fernandez #define CLKDIV_TIMEOUT TIMEOUT_US_200MS 86615f31feSGabriel Fernandez #define OSCRDY_TIMEOUT TIMEOUT_US_1S 87615f31feSGabriel Fernandez 88615f31feSGabriel Fernandez /* PLL minimal frequencies for clock sources */ 89615f31feSGabriel Fernandez #define PLL_REFCLK_MIN UL(5000000) 90615f31feSGabriel Fernandez #define PLL_FRAC_REFCLK_MIN UL(10000000) 91615f31feSGabriel Fernandez 92615f31feSGabriel Fernandez #define XBAR_CHANNEL_NB 64 93615f31feSGabriel Fernandez 94615f31feSGabriel Fernandez /* Warning, should be start to 1 */ 95615f31feSGabriel Fernandez enum clock { 96615f31feSGabriel Fernandez _CK_0_MHZ, 97615f31feSGabriel Fernandez 98615f31feSGabriel Fernandez /* ROOT CLOCKS */ 99615f31feSGabriel Fernandez _CK_HSI, 100615f31feSGabriel Fernandez _CK_HSE, 101615f31feSGabriel Fernandez _CK_MSI, 102615f31feSGabriel Fernandez _CK_LSI, 103615f31feSGabriel Fernandez _CK_LSE, 104615f31feSGabriel Fernandez _I2SCKIN, 105615f31feSGabriel Fernandez _SPDIFSYMB, 106615f31feSGabriel Fernandez _CK_PLL1, 107615f31feSGabriel Fernandez _CK_PLL2, 108*088238adSNicolas Le Bayon #if !STM32MP21 109615f31feSGabriel Fernandez _CK_PLL3, 110*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 111615f31feSGabriel Fernandez _CK_PLL4, 112615f31feSGabriel Fernandez _CK_PLL5, 113615f31feSGabriel Fernandez _CK_PLL6, 114615f31feSGabriel Fernandez _CK_PLL7, 115615f31feSGabriel Fernandez _CK_PLL8, 116615f31feSGabriel Fernandez _CK_HSE_RTC, 117615f31feSGabriel Fernandez _CK_RTCCK, 118615f31feSGabriel Fernandez _CK_ICN_HS_MCU, 119615f31feSGabriel Fernandez _CK_ICN_SDMMC, 120615f31feSGabriel Fernandez _CK_ICN_DDR, 121615f31feSGabriel Fernandez _CK_ICN_HSL, 122615f31feSGabriel Fernandez _CK_ICN_NIC, 123615f31feSGabriel Fernandez _CK_ICN_LS_MCU, 124615f31feSGabriel Fernandez _CK_FLEXGEN_07, 125615f31feSGabriel Fernandez _CK_FLEXGEN_08, 126615f31feSGabriel Fernandez _CK_FLEXGEN_09, 127615f31feSGabriel Fernandez _CK_FLEXGEN_10, 128615f31feSGabriel Fernandez _CK_FLEXGEN_11, 129615f31feSGabriel Fernandez _CK_FLEXGEN_12, 130615f31feSGabriel Fernandez _CK_FLEXGEN_13, 131615f31feSGabriel Fernandez _CK_FLEXGEN_14, 132615f31feSGabriel Fernandez _CK_FLEXGEN_15, 133615f31feSGabriel Fernandez _CK_FLEXGEN_16, 134615f31feSGabriel Fernandez _CK_FLEXGEN_17, 135615f31feSGabriel Fernandez _CK_FLEXGEN_18, 136615f31feSGabriel Fernandez _CK_FLEXGEN_19, 137615f31feSGabriel Fernandez _CK_FLEXGEN_20, 138615f31feSGabriel Fernandez _CK_FLEXGEN_21, 139615f31feSGabriel Fernandez _CK_FLEXGEN_22, 140615f31feSGabriel Fernandez _CK_FLEXGEN_23, 141615f31feSGabriel Fernandez _CK_FLEXGEN_24, 142615f31feSGabriel Fernandez _CK_FLEXGEN_25, 143615f31feSGabriel Fernandez _CK_FLEXGEN_26, 144615f31feSGabriel Fernandez _CK_FLEXGEN_27, 145615f31feSGabriel Fernandez _CK_FLEXGEN_28, 146615f31feSGabriel Fernandez _CK_FLEXGEN_29, 147615f31feSGabriel Fernandez _CK_FLEXGEN_30, 148615f31feSGabriel Fernandez _CK_FLEXGEN_31, 149615f31feSGabriel Fernandez _CK_FLEXGEN_32, 150615f31feSGabriel Fernandez _CK_FLEXGEN_33, 151615f31feSGabriel Fernandez _CK_FLEXGEN_34, 152615f31feSGabriel Fernandez _CK_FLEXGEN_35, 153615f31feSGabriel Fernandez _CK_FLEXGEN_36, 154615f31feSGabriel Fernandez _CK_FLEXGEN_37, 155615f31feSGabriel Fernandez _CK_FLEXGEN_38, 156615f31feSGabriel Fernandez _CK_FLEXGEN_39, 157615f31feSGabriel Fernandez _CK_FLEXGEN_40, 158615f31feSGabriel Fernandez _CK_FLEXGEN_41, 159615f31feSGabriel Fernandez _CK_FLEXGEN_42, 160615f31feSGabriel Fernandez _CK_FLEXGEN_43, 161615f31feSGabriel Fernandez _CK_FLEXGEN_44, 162615f31feSGabriel Fernandez _CK_FLEXGEN_45, 163615f31feSGabriel Fernandez _CK_FLEXGEN_46, 164615f31feSGabriel Fernandez _CK_FLEXGEN_47, 165615f31feSGabriel Fernandez _CK_FLEXGEN_48, 166615f31feSGabriel Fernandez _CK_FLEXGEN_49, 167615f31feSGabriel Fernandez _CK_FLEXGEN_50, 168615f31feSGabriel Fernandez _CK_FLEXGEN_51, 169615f31feSGabriel Fernandez _CK_FLEXGEN_52, 170615f31feSGabriel Fernandez _CK_FLEXGEN_53, 171615f31feSGabriel Fernandez _CK_FLEXGEN_54, 172615f31feSGabriel Fernandez _CK_FLEXGEN_55, 173615f31feSGabriel Fernandez _CK_FLEXGEN_56, 174615f31feSGabriel Fernandez _CK_FLEXGEN_57, 175615f31feSGabriel Fernandez _CK_FLEXGEN_58, 176615f31feSGabriel Fernandez _CK_FLEXGEN_59, 177615f31feSGabriel Fernandez _CK_FLEXGEN_60, 178615f31feSGabriel Fernandez _CK_FLEXGEN_61, 179615f31feSGabriel Fernandez _CK_FLEXGEN_62, 180615f31feSGabriel Fernandez _CK_FLEXGEN_63, 181615f31feSGabriel Fernandez _CK_ICN_APB1, 182615f31feSGabriel Fernandez _CK_ICN_APB2, 183615f31feSGabriel Fernandez _CK_ICN_APB3, 184615f31feSGabriel Fernandez _CK_ICN_APB4, 185*088238adSNicolas Le Bayon #if STM32MP21 186*088238adSNicolas Le Bayon _CK_ICN_APB5, 187*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 188615f31feSGabriel Fernandez _CK_ICN_APBDBG, 189615f31feSGabriel Fernandez _CK_BKPSRAM, 190615f31feSGabriel Fernandez _CK_BSEC, 191615f31feSGabriel Fernandez _CK_CRC, 192615f31feSGabriel Fernandez _CK_CRYP1, 193615f31feSGabriel Fernandez _CK_CRYP2, 194615f31feSGabriel Fernandez _CK_DDR, 195615f31feSGabriel Fernandez _CK_DDRCAPB, 196615f31feSGabriel Fernandez _CK_DDRCP, 197615f31feSGabriel Fernandez _CK_DDRPHYC, 198615f31feSGabriel Fernandez _CK_FMC, 199615f31feSGabriel Fernandez _CK_GPIOA, 200615f31feSGabriel Fernandez _CK_GPIOB, 201615f31feSGabriel Fernandez _CK_GPIOC, 202615f31feSGabriel Fernandez _CK_GPIOD, 203615f31feSGabriel Fernandez _CK_GPIOE, 204615f31feSGabriel Fernandez _CK_GPIOF, 205615f31feSGabriel Fernandez _CK_GPIOG, 206615f31feSGabriel Fernandez _CK_GPIOH, 207615f31feSGabriel Fernandez _CK_GPIOI, 208*088238adSNicolas Le Bayon #if !STM32MP21 209615f31feSGabriel Fernandez _CK_GPIOJ, 210615f31feSGabriel Fernandez _CK_GPIOK, 211*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 212615f31feSGabriel Fernandez _CK_GPIOZ, 213*088238adSNicolas Le Bayon #if STM32MP21 214*088238adSNicolas Le Bayon _CK_HASH1, 215*088238adSNicolas Le Bayon _CK_HASH2, 216*088238adSNicolas Le Bayon #else /* STM32MP21 */ 217615f31feSGabriel Fernandez _CK_HASH, 218*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 219615f31feSGabriel Fernandez _CK_I2C1, 220615f31feSGabriel Fernandez _CK_I2C2, 221*088238adSNicolas Le Bayon #if !STM32MP23 222615f31feSGabriel Fernandez _CK_I2C3, 223*088238adSNicolas Le Bayon #endif /* !STM32MP23 */ 224*088238adSNicolas Le Bayon #if STM32MP25 225615f31feSGabriel Fernandez _CK_I2C4, 226615f31feSGabriel Fernandez _CK_I2C5, 227615f31feSGabriel Fernandez _CK_I2C6, 228*088238adSNicolas Le Bayon #endif /* STM32MP25 */ 229*088238adSNicolas Le Bayon #if !STM32MP21 230615f31feSGabriel Fernandez _CK_I2C7, 231615f31feSGabriel Fernandez _CK_I2C8, 232*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 233615f31feSGabriel Fernandez _CK_IWDG1, 234615f31feSGabriel Fernandez _CK_IWDG2, 235615f31feSGabriel Fernandez _CK_OSPI1, 236*088238adSNicolas Le Bayon #if !STM32MP21 237615f31feSGabriel Fernandez _CK_OSPI2, 238615f31feSGabriel Fernandez _CK_OSPIIOM, 239*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 240615f31feSGabriel Fernandez _CK_PKA, 241615f31feSGabriel Fernandez _CK_RETRAM, 242*088238adSNicolas Le Bayon #if STM32MP21 243*088238adSNicolas Le Bayon _CK_RNG1, 244*088238adSNicolas Le Bayon _CK_RNG2, 245*088238adSNicolas Le Bayon #else /* STM32MP21 */ 246615f31feSGabriel Fernandez _CK_RNG, 247*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 248615f31feSGabriel Fernandez _CK_RTC, 249615f31feSGabriel Fernandez _CK_SAES, 250615f31feSGabriel Fernandez _CK_SDMMC1, 251615f31feSGabriel Fernandez _CK_SDMMC2, 252615f31feSGabriel Fernandez _CK_SRAM1, 253*088238adSNicolas Le Bayon #if !STM32MP21 254615f31feSGabriel Fernandez _CK_SRAM2, 255*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 256615f31feSGabriel Fernandez _CK_STGEN, 257615f31feSGabriel Fernandez _CK_SYSCPU1, 258615f31feSGabriel Fernandez _CK_SYSRAM, 259615f31feSGabriel Fernandez _CK_UART4, 260615f31feSGabriel Fernandez _CK_UART5, 261615f31feSGabriel Fernandez _CK_UART7, 262*088238adSNicolas Le Bayon #if STM32MP25 263615f31feSGabriel Fernandez _CK_UART8, 264615f31feSGabriel Fernandez _CK_UART9, 265*088238adSNicolas Le Bayon #endif /* STM32MP25 */ 266615f31feSGabriel Fernandez _CK_USART1, 267615f31feSGabriel Fernandez _CK_USART2, 268615f31feSGabriel Fernandez _CK_USART3, 269615f31feSGabriel Fernandez _CK_USART6, 270*088238adSNicolas Le Bayon #if STM32MP21 271*088238adSNicolas Le Bayon _CK_USBHEHCI, 272*088238adSNicolas Le Bayon _CK_USBHOHCI, 273*088238adSNicolas Le Bayon #else /* STM32MP21 */ 274615f31feSGabriel Fernandez _CK_USB2EHCI, 275615f31feSGabriel Fernandez _CK_USB2OHCI, 276*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 277615f31feSGabriel Fernandez _CK_USB2PHY1, 278615f31feSGabriel Fernandez _CK_USB2PHY2, 279*088238adSNicolas Le Bayon #if !STM32MP21 280615f31feSGabriel Fernandez _CK_USB3DR, 281615f31feSGabriel Fernandez _CK_USB3PCIEPHY, 282615f31feSGabriel Fernandez _CK_USBTC, 283*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 284615f31feSGabriel Fernandez 285615f31feSGabriel Fernandez CK_LAST 286615f31feSGabriel Fernandez }; 287615f31feSGabriel Fernandez 288615f31feSGabriel Fernandez static const uint16_t muxsel_src[] = { 289615f31feSGabriel Fernandez _CK_HSI, _CK_HSE, _CK_MSI, _CK_0_MHZ 290615f31feSGabriel Fernandez }; 291615f31feSGabriel Fernandez 292615f31feSGabriel Fernandez static const uint16_t xbarsel_src[] = { 293615f31feSGabriel Fernandez _CK_PLL4, _CK_PLL5, _CK_PLL6, _CK_PLL7, _CK_PLL8, 294615f31feSGabriel Fernandez _CK_HSI, _CK_HSE, _CK_MSI, _CK_HSI, _CK_HSE, _CK_MSI, 295615f31feSGabriel Fernandez _SPDIFSYMB, _I2SCKIN, _CK_LSI, _CK_LSE 296615f31feSGabriel Fernandez }; 297615f31feSGabriel Fernandez 298615f31feSGabriel Fernandez static const uint16_t rtc_src[] = { 299615f31feSGabriel Fernandez _CK_0_MHZ, _CK_LSE, _CK_LSI, _CK_HSE_RTC 300615f31feSGabriel Fernandez }; 301615f31feSGabriel Fernandez 302615f31feSGabriel Fernandez static const uint16_t usb2phy1_src[] = { 303615f31feSGabriel Fernandez _CK_FLEXGEN_57, _CK_HSE 304615f31feSGabriel Fernandez }; 305615f31feSGabriel Fernandez 306615f31feSGabriel Fernandez static const uint16_t usb2phy2_src[] = { 307615f31feSGabriel Fernandez _CK_FLEXGEN_58, _CK_HSE 308615f31feSGabriel Fernandez }; 309615f31feSGabriel Fernandez 310*088238adSNicolas Le Bayon #if !STM32MP21 311615f31feSGabriel Fernandez static const uint16_t usb3pciphy_src[] = { 312615f31feSGabriel Fernandez _CK_FLEXGEN_34, _CK_HSE 313615f31feSGabriel Fernandez }; 314615f31feSGabriel Fernandez 315615f31feSGabriel Fernandez static const uint16_t d3per_src[] = { 316615f31feSGabriel Fernandez _CK_MSI, _CK_LSI, _CK_LSE 317615f31feSGabriel Fernandez }; 318*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 319615f31feSGabriel Fernandez 320615f31feSGabriel Fernandez #define MUX_CONF(id, src, _offset, _shift, _witdh)[id] = {\ 321615f31feSGabriel Fernandez .id_parents = src,\ 322615f31feSGabriel Fernandez .num_parents = ARRAY_SIZE(src),\ 323615f31feSGabriel Fernandez .mux = &(struct mux_cfg) {\ 324615f31feSGabriel Fernandez .offset = (_offset),\ 325615f31feSGabriel Fernandez .shift = (_shift),\ 326615f31feSGabriel Fernandez .width = (_witdh),\ 327615f31feSGabriel Fernandez .bitrdy = UINT8_MAX,\ 328615f31feSGabriel Fernandez },\ 329615f31feSGabriel Fernandez } 330615f31feSGabriel Fernandez 331*088238adSNicolas Le Bayon static const struct parent_cfg parent_mp2[] = { 332615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL0, muxsel_src, RCC_MUXSELCFGR, 0, 2), 333615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL1, muxsel_src, RCC_MUXSELCFGR, 4, 2), 334615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL2, muxsel_src, RCC_MUXSELCFGR, 8, 2), 335615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL3, muxsel_src, RCC_MUXSELCFGR, 12, 2), 336615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL4, muxsel_src, RCC_MUXSELCFGR, 16, 2), 337615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL5, muxsel_src, RCC_MUXSELCFGR, 20, 2), 338615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL6, muxsel_src, RCC_MUXSELCFGR, 24, 2), 339615f31feSGabriel Fernandez MUX_CONF(MUX_MUXSEL7, muxsel_src, RCC_MUXSELCFGR, 28, 2), 340615f31feSGabriel Fernandez MUX_CONF(MUX_XBARSEL, xbarsel_src, RCC_XBAR0CFGR, 0, 4), 341615f31feSGabriel Fernandez MUX_CONF(MUX_RTC, rtc_src, RCC_BDCR, 16, 2), 342615f31feSGabriel Fernandez MUX_CONF(MUX_USB2PHY1, usb2phy1_src, RCC_USB2PHY1CFGR, 15, 1), 343615f31feSGabriel Fernandez MUX_CONF(MUX_USB2PHY2, usb2phy2_src, RCC_USB2PHY2CFGR, 15, 1), 344*088238adSNicolas Le Bayon #if !STM32MP21 345615f31feSGabriel Fernandez MUX_CONF(MUX_USB3PCIEPHY, usb3pciphy_src, RCC_USB3PCIEPHYCFGR, 15, 1), 346615f31feSGabriel Fernandez MUX_CONF(MUX_D3PER, d3per_src, RCC_D3DCR, 16, 2), 347*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 348615f31feSGabriel Fernandez }; 349615f31feSGabriel Fernandez 350615f31feSGabriel Fernandez /* GATES */ 351615f31feSGabriel Fernandez enum enum_gate_cfg { 352615f31feSGabriel Fernandez GATE_ZERO, /* reserved for no gate */ 353615f31feSGabriel Fernandez GATE_LSE, 354615f31feSGabriel Fernandez GATE_RTCCK, 355615f31feSGabriel Fernandez GATE_LSI, 356615f31feSGabriel Fernandez GATE_HSI, 357615f31feSGabriel Fernandez GATE_MSI, 358615f31feSGabriel Fernandez GATE_HSE, 359615f31feSGabriel Fernandez GATE_LSI_RDY, 360615f31feSGabriel Fernandez GATE_MSI_RDY, 361615f31feSGabriel Fernandez GATE_LSE_RDY, 362615f31feSGabriel Fernandez GATE_HSE_RDY, 363615f31feSGabriel Fernandez GATE_HSI_RDY, 364615f31feSGabriel Fernandez GATE_SYSRAM, 365615f31feSGabriel Fernandez GATE_RETRAM, 366615f31feSGabriel Fernandez GATE_SRAM1, 367*088238adSNicolas Le Bayon #if !STM32MP21 368615f31feSGabriel Fernandez GATE_SRAM2, 369*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 370615f31feSGabriel Fernandez 371615f31feSGabriel Fernandez GATE_DDRPHYC, 372615f31feSGabriel Fernandez GATE_SYSCPU1, 373615f31feSGabriel Fernandez GATE_CRC, 374*088238adSNicolas Le Bayon #if !STM32MP21 375615f31feSGabriel Fernandez GATE_OSPIIOM, 376*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 377615f31feSGabriel Fernandez GATE_BKPSRAM, 378*088238adSNicolas Le Bayon #if STM32MP21 379*088238adSNicolas Le Bayon GATE_HASH1, 380*088238adSNicolas Le Bayon GATE_HASH2, 381*088238adSNicolas Le Bayon GATE_RNG1, 382*088238adSNicolas Le Bayon GATE_RNG2, 383*088238adSNicolas Le Bayon #else /* STM32MP21 */ 384615f31feSGabriel Fernandez GATE_HASH, 385615f31feSGabriel Fernandez GATE_RNG, 386*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 387615f31feSGabriel Fernandez GATE_CRYP1, 388615f31feSGabriel Fernandez GATE_CRYP2, 389615f31feSGabriel Fernandez GATE_SAES, 390615f31feSGabriel Fernandez GATE_PKA, 391615f31feSGabriel Fernandez 392615f31feSGabriel Fernandez GATE_GPIOA, 393615f31feSGabriel Fernandez GATE_GPIOB, 394615f31feSGabriel Fernandez GATE_GPIOC, 395615f31feSGabriel Fernandez GATE_GPIOD, 396615f31feSGabriel Fernandez GATE_GPIOE, 397615f31feSGabriel Fernandez GATE_GPIOF, 398615f31feSGabriel Fernandez GATE_GPIOG, 399615f31feSGabriel Fernandez GATE_GPIOH, 400615f31feSGabriel Fernandez GATE_GPIOI, 401*088238adSNicolas Le Bayon #if !STM32MP21 402615f31feSGabriel Fernandez GATE_GPIOJ, 403615f31feSGabriel Fernandez GATE_GPIOK, 404*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 405615f31feSGabriel Fernandez GATE_GPIOZ, 406615f31feSGabriel Fernandez GATE_RTC, 407615f31feSGabriel Fernandez 408615f31feSGabriel Fernandez GATE_DDRCP, 409615f31feSGabriel Fernandez 410615f31feSGabriel Fernandez /* WARNING 2 CLOCKS FOR ONE GATE */ 411*088238adSNicolas Le Bayon #if STM32MP21 412*088238adSNicolas Le Bayon GATE_USBHOHCI, 413*088238adSNicolas Le Bayon GATE_USBHEHCI, 414*088238adSNicolas Le Bayon #else /* STM32MP21 */ 415615f31feSGabriel Fernandez GATE_USB2OHCI, 416615f31feSGabriel Fernandez GATE_USB2EHCI, 417*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 418615f31feSGabriel Fernandez 419*088238adSNicolas Le Bayon #if !STM32MP21 420615f31feSGabriel Fernandez GATE_USB3DR, 421*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 422615f31feSGabriel Fernandez 423615f31feSGabriel Fernandez GATE_BSEC, 424615f31feSGabriel Fernandez GATE_IWDG1, 425615f31feSGabriel Fernandez GATE_IWDG2, 426615f31feSGabriel Fernandez 427615f31feSGabriel Fernandez GATE_DDRCAPB, 428615f31feSGabriel Fernandez GATE_DDR, 429615f31feSGabriel Fernandez 430615f31feSGabriel Fernandez GATE_USART2, 431615f31feSGabriel Fernandez GATE_UART4, 432615f31feSGabriel Fernandez GATE_USART3, 433615f31feSGabriel Fernandez GATE_UART5, 434615f31feSGabriel Fernandez GATE_I2C1, 435615f31feSGabriel Fernandez GATE_I2C2, 436*088238adSNicolas Le Bayon #if !STM32MP23 437615f31feSGabriel Fernandez GATE_I2C3, 438*088238adSNicolas Le Bayon #endif /* !STM32MP23 */ 439*088238adSNicolas Le Bayon #if STM32MP25 440615f31feSGabriel Fernandez GATE_I2C5, 441615f31feSGabriel Fernandez GATE_I2C4, 442615f31feSGabriel Fernandez GATE_I2C6, 443*088238adSNicolas Le Bayon #endif /* STM32MP25 */ 444*088238adSNicolas Le Bayon #if !STM32MP21 445615f31feSGabriel Fernandez GATE_I2C7, 446*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 447615f31feSGabriel Fernandez GATE_USART1, 448615f31feSGabriel Fernandez GATE_USART6, 449615f31feSGabriel Fernandez GATE_UART7, 450*088238adSNicolas Le Bayon #if STM32MP25 451615f31feSGabriel Fernandez GATE_UART8, 452615f31feSGabriel Fernandez GATE_UART9, 453*088238adSNicolas Le Bayon #endif /* STM32MP25 */ 454615f31feSGabriel Fernandez GATE_STGEN, 455*088238adSNicolas Le Bayon #if !STM32MP21 456615f31feSGabriel Fernandez GATE_USB3PCIEPHY, 457615f31feSGabriel Fernandez GATE_USBTC, 458615f31feSGabriel Fernandez GATE_I2C8, 459*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 460615f31feSGabriel Fernandez GATE_OSPI1, 461*088238adSNicolas Le Bayon #if !STM32MP21 462615f31feSGabriel Fernandez GATE_OSPI2, 463*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 464615f31feSGabriel Fernandez GATE_FMC, 465615f31feSGabriel Fernandez GATE_SDMMC1, 466615f31feSGabriel Fernandez GATE_SDMMC2, 467615f31feSGabriel Fernandez GATE_USB2PHY1, 468615f31feSGabriel Fernandez GATE_USB2PHY2, 469615f31feSGabriel Fernandez LAST_GATE 470615f31feSGabriel Fernandez }; 471615f31feSGabriel Fernandez 472615f31feSGabriel Fernandez #define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\ 473615f31feSGabriel Fernandez .offset = (_offset),\ 474615f31feSGabriel Fernandez .bit_idx = (_bit_idx),\ 475615f31feSGabriel Fernandez .set_clr = (_offset_clr),\ 476615f31feSGabriel Fernandez } 477615f31feSGabriel Fernandez 478*088238adSNicolas Le Bayon static const struct gate_cfg gates_mp2[LAST_GATE] = { 479615f31feSGabriel Fernandez GATE_CFG(GATE_LSE, RCC_BDCR, 0, 0), 480*088238adSNicolas Le Bayon #if STM32MP21 481*088238adSNicolas Le Bayon GATE_CFG(GATE_LSI, RCC_LSICR, 0, 0), 482*088238adSNicolas Le Bayon #else /* STM32MP21 */ 483615f31feSGabriel Fernandez GATE_CFG(GATE_LSI, RCC_BDCR, 9, 0), 484*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 485615f31feSGabriel Fernandez GATE_CFG(GATE_RTCCK, RCC_BDCR, 20, 0), 486615f31feSGabriel Fernandez GATE_CFG(GATE_HSI, RCC_OCENSETR, 0, 1), 487615f31feSGabriel Fernandez GATE_CFG(GATE_HSE, RCC_OCENSETR, 8, 1), 488*088238adSNicolas Le Bayon #if STM32MP21 489*088238adSNicolas Le Bayon GATE_CFG(GATE_MSI, RCC_OCENSETR, 2, 0), 490*088238adSNicolas Le Bayon #else /* STM32MP21 */ 491615f31feSGabriel Fernandez GATE_CFG(GATE_MSI, RCC_D3DCR, 0, 0), 492*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 493615f31feSGabriel Fernandez 494*088238adSNicolas Le Bayon #if STM32MP21 495*088238adSNicolas Le Bayon GATE_CFG(GATE_LSI_RDY, RCC_LSICR, 1, 0), 496*088238adSNicolas Le Bayon #else /* STM32MP21 */ 497615f31feSGabriel Fernandez GATE_CFG(GATE_LSI_RDY, RCC_BDCR, 10, 0), 498*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 499615f31feSGabriel Fernandez GATE_CFG(GATE_LSE_RDY, RCC_BDCR, 2, 0), 500*088238adSNicolas Le Bayon #if STM32MP21 501*088238adSNicolas Le Bayon GATE_CFG(GATE_MSI_RDY, RCC_OCRDYR, 2, 0), 502*088238adSNicolas Le Bayon #else /* STM32MP21 */ 503615f31feSGabriel Fernandez GATE_CFG(GATE_MSI_RDY, RCC_D3DCR, 2, 0), 504*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 505615f31feSGabriel Fernandez GATE_CFG(GATE_HSE_RDY, RCC_OCRDYR, 8, 0), 506615f31feSGabriel Fernandez GATE_CFG(GATE_HSI_RDY, RCC_OCRDYR, 0, 0), 507615f31feSGabriel Fernandez GATE_CFG(GATE_SYSRAM, RCC_SYSRAMCFGR, 1, 0), 508615f31feSGabriel Fernandez GATE_CFG(GATE_RETRAM, RCC_RETRAMCFGR, 1, 0), 509615f31feSGabriel Fernandez GATE_CFG(GATE_SRAM1, RCC_SRAM1CFGR, 1, 0), 510*088238adSNicolas Le Bayon #if !STM32MP21 511615f31feSGabriel Fernandez GATE_CFG(GATE_SRAM2, RCC_SRAM2CFGR, 1, 0), 512*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 513615f31feSGabriel Fernandez GATE_CFG(GATE_DDRPHYC, RCC_DDRPHYCAPBCFGR, 1, 0), 514615f31feSGabriel Fernandez GATE_CFG(GATE_SYSCPU1, RCC_SYSCPU1CFGR, 1, 0), 515615f31feSGabriel Fernandez GATE_CFG(GATE_CRC, RCC_CRCCFGR, 1, 0), 516*088238adSNicolas Le Bayon #if !STM32MP21 517615f31feSGabriel Fernandez GATE_CFG(GATE_OSPIIOM, RCC_OSPIIOMCFGR, 1, 0), 518*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 519615f31feSGabriel Fernandez GATE_CFG(GATE_BKPSRAM, RCC_BKPSRAMCFGR, 1, 0), 520*088238adSNicolas Le Bayon #if STM32MP21 521*088238adSNicolas Le Bayon GATE_CFG(GATE_HASH1, RCC_HASH1CFGR, 1, 0), 522*088238adSNicolas Le Bayon GATE_CFG(GATE_HASH2, RCC_HASH2CFGR, 1, 0), 523*088238adSNicolas Le Bayon GATE_CFG(GATE_RNG1, RCC_RNG1CFGR, 1, 0), 524*088238adSNicolas Le Bayon GATE_CFG(GATE_RNG2, RCC_RNG2CFGR, 1, 0), 525*088238adSNicolas Le Bayon #else /* STM32MP21 */ 526615f31feSGabriel Fernandez GATE_CFG(GATE_HASH, RCC_HASHCFGR, 1, 0), 527615f31feSGabriel Fernandez GATE_CFG(GATE_RNG, RCC_RNGCFGR, 1, 0), 528*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 529615f31feSGabriel Fernandez GATE_CFG(GATE_CRYP1, RCC_CRYP1CFGR, 1, 0), 530615f31feSGabriel Fernandez GATE_CFG(GATE_CRYP2, RCC_CRYP2CFGR, 1, 0), 531615f31feSGabriel Fernandez GATE_CFG(GATE_SAES, RCC_SAESCFGR, 1, 0), 532615f31feSGabriel Fernandez GATE_CFG(GATE_PKA, RCC_PKACFGR, 1, 0), 533615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOA, RCC_GPIOACFGR, 1, 0), 534615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOB, RCC_GPIOBCFGR, 1, 0), 535615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOC, RCC_GPIOCCFGR, 1, 0), 536615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOD, RCC_GPIODCFGR, 1, 0), 537615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOE, RCC_GPIOECFGR, 1, 0), 538615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOF, RCC_GPIOFCFGR, 1, 0), 539615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOG, RCC_GPIOGCFGR, 1, 0), 540615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOH, RCC_GPIOHCFGR, 1, 0), 541615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOI, RCC_GPIOICFGR, 1, 0), 542*088238adSNicolas Le Bayon #if !STM32MP21 543615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOJ, RCC_GPIOJCFGR, 1, 0), 544615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOK, RCC_GPIOKCFGR, 1, 0), 545*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 546615f31feSGabriel Fernandez GATE_CFG(GATE_GPIOZ, RCC_GPIOZCFGR, 1, 0), 547615f31feSGabriel Fernandez GATE_CFG(GATE_RTC, RCC_RTCCFGR, 1, 0), 548615f31feSGabriel Fernandez GATE_CFG(GATE_DDRCP, RCC_DDRCPCFGR, 1, 0), 549615f31feSGabriel Fernandez 550615f31feSGabriel Fernandez /* WARNING 2 CLOCKS FOR ONE GATE */ 551*088238adSNicolas Le Bayon #if STM32MP21 552*088238adSNicolas Le Bayon GATE_CFG(GATE_USBHOHCI, RCC_USBHCFGR, 1, 0), 553*088238adSNicolas Le Bayon GATE_CFG(GATE_USBHEHCI, RCC_USBHCFGR, 1, 0), 554*088238adSNicolas Le Bayon #else /* STM32MP21 */ 555615f31feSGabriel Fernandez GATE_CFG(GATE_USB2OHCI, RCC_USB2CFGR, 1, 0), 556615f31feSGabriel Fernandez GATE_CFG(GATE_USB2EHCI, RCC_USB2CFGR, 1, 0), 557615f31feSGabriel Fernandez GATE_CFG(GATE_USB3DR, RCC_USB3DRCFGR, 1, 0), 558*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 559615f31feSGabriel Fernandez GATE_CFG(GATE_BSEC, RCC_BSECCFGR, 1, 0), 560615f31feSGabriel Fernandez GATE_CFG(GATE_IWDG1, RCC_IWDG1CFGR, 1, 0), 561615f31feSGabriel Fernandez GATE_CFG(GATE_IWDG2, RCC_IWDG2CFGR, 1, 0), 562615f31feSGabriel Fernandez GATE_CFG(GATE_DDRCAPB, RCC_DDRCAPBCFGR, 1, 0), 563615f31feSGabriel Fernandez GATE_CFG(GATE_DDR, RCC_DDRCFGR, 1, 0), 564615f31feSGabriel Fernandez GATE_CFG(GATE_USART2, RCC_USART2CFGR, 1, 0), 565615f31feSGabriel Fernandez GATE_CFG(GATE_UART4, RCC_UART4CFGR, 1, 0), 566615f31feSGabriel Fernandez GATE_CFG(GATE_USART3, RCC_USART3CFGR, 1, 0), 567615f31feSGabriel Fernandez GATE_CFG(GATE_UART5, RCC_UART5CFGR, 1, 0), 568615f31feSGabriel Fernandez GATE_CFG(GATE_I2C1, RCC_I2C1CFGR, 1, 0), 569615f31feSGabriel Fernandez GATE_CFG(GATE_I2C2, RCC_I2C2CFGR, 1, 0), 570*088238adSNicolas Le Bayon #if !STM32MP23 571615f31feSGabriel Fernandez GATE_CFG(GATE_I2C3, RCC_I2C3CFGR, 1, 0), 572*088238adSNicolas Le Bayon #endif /* !STM32MP23 */ 573*088238adSNicolas Le Bayon #if STM32MP25 574615f31feSGabriel Fernandez GATE_CFG(GATE_I2C5, RCC_I2C5CFGR, 1, 0), 575615f31feSGabriel Fernandez GATE_CFG(GATE_I2C4, RCC_I2C4CFGR, 1, 0), 576615f31feSGabriel Fernandez GATE_CFG(GATE_I2C6, RCC_I2C6CFGR, 1, 0), 577*088238adSNicolas Le Bayon #endif /* STM32MP25 */ 578*088238adSNicolas Le Bayon #if !STM32MP21 579615f31feSGabriel Fernandez GATE_CFG(GATE_I2C7, RCC_I2C7CFGR, 1, 0), 580*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 581615f31feSGabriel Fernandez GATE_CFG(GATE_USART1, RCC_USART1CFGR, 1, 0), 582615f31feSGabriel Fernandez GATE_CFG(GATE_USART6, RCC_USART6CFGR, 1, 0), 583615f31feSGabriel Fernandez GATE_CFG(GATE_UART7, RCC_UART7CFGR, 1, 0), 584*088238adSNicolas Le Bayon #if STM32MP25 585615f31feSGabriel Fernandez GATE_CFG(GATE_UART8, RCC_UART8CFGR, 1, 0), 586615f31feSGabriel Fernandez GATE_CFG(GATE_UART9, RCC_UART9CFGR, 1, 0), 587*088238adSNicolas Le Bayon #endif /* STM32MP25 */ 588615f31feSGabriel Fernandez GATE_CFG(GATE_STGEN, RCC_STGENCFGR, 1, 0), 589*088238adSNicolas Le Bayon #if !STM32MP21 590615f31feSGabriel Fernandez GATE_CFG(GATE_USB3PCIEPHY, RCC_USB3PCIEPHYCFGR, 1, 0), 591615f31feSGabriel Fernandez GATE_CFG(GATE_USBTC, RCC_USBTCCFGR, 1, 0), 592615f31feSGabriel Fernandez GATE_CFG(GATE_I2C8, RCC_I2C8CFGR, 1, 0), 593*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 594615f31feSGabriel Fernandez GATE_CFG(GATE_OSPI1, RCC_OSPI1CFGR, 1, 0), 595*088238adSNicolas Le Bayon #if !STM32MP21 596615f31feSGabriel Fernandez GATE_CFG(GATE_OSPI2, RCC_OSPI2CFGR, 1, 0), 597*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 598615f31feSGabriel Fernandez GATE_CFG(GATE_FMC, RCC_FMCCFGR, 1, 0), 599615f31feSGabriel Fernandez GATE_CFG(GATE_SDMMC1, RCC_SDMMC1CFGR, 1, 0), 600615f31feSGabriel Fernandez GATE_CFG(GATE_SDMMC2, RCC_SDMMC2CFGR, 1, 0), 601615f31feSGabriel Fernandez GATE_CFG(GATE_USB2PHY1, RCC_USB2PHY1CFGR, 1, 0), 602615f31feSGabriel Fernandez GATE_CFG(GATE_USB2PHY2, RCC_USB2PHY2CFGR, 1, 0), 603615f31feSGabriel Fernandez }; 604615f31feSGabriel Fernandez 605615f31feSGabriel Fernandez static const struct clk_div_table apb_div_table[] = { 606615f31feSGabriel Fernandez { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, { 4, 16 }, 607615f31feSGabriel Fernandez { 5, 16 }, { 6, 16 }, { 7, 16 }, { 0 }, 608615f31feSGabriel Fernandez }; 609615f31feSGabriel Fernandez 610615f31feSGabriel Fernandez #undef DIV_CFG 611615f31feSGabriel Fernandez #define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\ 612615f31feSGabriel Fernandez .offset = _offset,\ 613615f31feSGabriel Fernandez .shift = _shift,\ 614615f31feSGabriel Fernandez .width = _width,\ 615615f31feSGabriel Fernandez .flags = _flags,\ 616615f31feSGabriel Fernandez .table = _table,\ 617615f31feSGabriel Fernandez .bitrdy = _bitrdy,\ 618615f31feSGabriel Fernandez } 619615f31feSGabriel Fernandez 620*088238adSNicolas Le Bayon static const struct div_cfg dividers_mp2[] = { 621615f31feSGabriel Fernandez DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31), 622615f31feSGabriel Fernandez DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31), 623615f31feSGabriel Fernandez DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31), 624615f31feSGabriel Fernandez DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31), 625*088238adSNicolas Le Bayon #if STM32MP21 626*088238adSNicolas Le Bayon DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, 31), 627*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 628615f31feSGabriel Fernandez DIV_CFG(DIV_APBDBG, RCC_APBDBGDIVR, 0, 3, 0, apb_div_table, 31), 629615f31feSGabriel Fernandez DIV_CFG(DIV_LSMCU, RCC_LSMCUDIVR, 0, 1, 0, NULL, 31), 630615f31feSGabriel Fernandez DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, 0), 631615f31feSGabriel Fernandez }; 632615f31feSGabriel Fernandez 633615f31feSGabriel Fernandez enum stm32_osc { 634615f31feSGabriel Fernandez OSC_HSI, 635615f31feSGabriel Fernandez OSC_HSE, 636615f31feSGabriel Fernandez OSC_MSI, 637615f31feSGabriel Fernandez OSC_LSI, 638615f31feSGabriel Fernandez OSC_LSE, 639615f31feSGabriel Fernandez OSC_I2SCKIN, 640615f31feSGabriel Fernandez OSC_SPDIFSYMB, 641615f31feSGabriel Fernandez NB_OSCILLATOR 642615f31feSGabriel Fernandez }; 643615f31feSGabriel Fernandez 644*088238adSNicolas Le Bayon static struct clk_oscillator_data stm32mp2_osc_data[] = { 645615f31feSGabriel Fernandez OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY, 646615f31feSGabriel Fernandez NULL, NULL, NULL), 647615f31feSGabriel Fernandez 648615f31feSGabriel Fernandez OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY, 649615f31feSGabriel Fernandez NULL, NULL, NULL), 650615f31feSGabriel Fernandez 651615f31feSGabriel Fernandez OSCILLATOR(OSC_MSI, _CK_MSI, "clk-msi", GATE_MSI, GATE_MSI_RDY, 652615f31feSGabriel Fernandez NULL, NULL, NULL), 653615f31feSGabriel Fernandez 654615f31feSGabriel Fernandez OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY, 655615f31feSGabriel Fernandez BYPASS(RCC_OCENSETR, 10, 7), 656615f31feSGabriel Fernandez CSS(RCC_OCENSETR, 11), 657615f31feSGabriel Fernandez NULL), 658615f31feSGabriel Fernandez 659615f31feSGabriel Fernandez OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY, 660615f31feSGabriel Fernandez BYPASS(RCC_BDCR, 1, 3), 661615f31feSGabriel Fernandez CSS(RCC_BDCR, 8), 662615f31feSGabriel Fernandez DRIVE(RCC_BDCR, 4, 2, 2)), 663615f31feSGabriel Fernandez 664615f31feSGabriel Fernandez OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE, 665615f31feSGabriel Fernandez NULL, NULL, NULL), 666615f31feSGabriel Fernandez 667615f31feSGabriel Fernandez OSCILLATOR(OSC_SPDIFSYMB, _SPDIFSYMB, "spdif_symb", NO_GATE, NO_GATE, 668615f31feSGabriel Fernandez NULL, NULL, NULL), 669615f31feSGabriel Fernandez }; 670615f31feSGabriel Fernandez 671615f31feSGabriel Fernandez #ifdef IMAGE_BL2 672615f31feSGabriel Fernandez static const char *clk_stm32_get_oscillator_name(enum stm32_osc id) 673615f31feSGabriel Fernandez { 674615f31feSGabriel Fernandez if (id < NB_OSCILLATOR) { 675*088238adSNicolas Le Bayon return stm32mp2_osc_data[id].name; 676615f31feSGabriel Fernandez } 677615f31feSGabriel Fernandez 678615f31feSGabriel Fernandez return NULL; 679615f31feSGabriel Fernandez } 680615f31feSGabriel Fernandez #endif 681615f31feSGabriel Fernandez 682615f31feSGabriel Fernandez enum pll_id { 683615f31feSGabriel Fernandez _PLL1, 684615f31feSGabriel Fernandez _PLL2, 685615f31feSGabriel Fernandez _PLL3, 686615f31feSGabriel Fernandez _PLL4, 687615f31feSGabriel Fernandez _PLL5, 688615f31feSGabriel Fernandez _PLL6, 689615f31feSGabriel Fernandez _PLL7, 690615f31feSGabriel Fernandez _PLL8, 691615f31feSGabriel Fernandez _PLL_NB 692615f31feSGabriel Fernandez }; 693615f31feSGabriel Fernandez 694615f31feSGabriel Fernandez /* PLL configuration registers offsets from RCC_PLLxCFGR1 */ 695615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR1 0x00 696615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR2 0x04 697615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR3 0x08 698615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR4 0x0C 699615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR5 0x10 700615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR6 0x18 701615f31feSGabriel Fernandez #define RCC_OFFSET_PLLXCFGR7 0x1C 702615f31feSGabriel Fernandez 703615f31feSGabriel Fernandez struct stm32_clk_pll { 704615f31feSGabriel Fernandez uint16_t clk_id; 705615f31feSGabriel Fernandez uint16_t reg_pllxcfgr1; 706615f31feSGabriel Fernandez }; 707615f31feSGabriel Fernandez 708615f31feSGabriel Fernandez #define CLK_PLL_CFG(_idx, _clk_id, _reg)\ 709615f31feSGabriel Fernandez [(_idx)] = {\ 710615f31feSGabriel Fernandez .clk_id = (_clk_id),\ 711615f31feSGabriel Fernandez .reg_pllxcfgr1 = (_reg),\ 712615f31feSGabriel Fernandez } 713615f31feSGabriel Fernandez 714*088238adSNicolas Le Bayon static const struct stm32_clk_pll stm32mp2_clk_pll[_PLL_NB] = { 715615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL1, _CK_PLL1, A35_SS_CHGCLKREQ), 716615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL2, _CK_PLL2, RCC_PLL2CFGR1), 717*088238adSNicolas Le Bayon #if !STM32MP21 718615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL3, _CK_PLL3, RCC_PLL3CFGR1), 719*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 720615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL4, _CK_PLL4, RCC_PLL4CFGR1), 721615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL5, _CK_PLL5, RCC_PLL5CFGR1), 722615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL6, _CK_PLL6, RCC_PLL6CFGR1), 723615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL7, _CK_PLL7, RCC_PLL7CFGR1), 724615f31feSGabriel Fernandez CLK_PLL_CFG(_PLL8, _CK_PLL8, RCC_PLL8CFGR1), 725615f31feSGabriel Fernandez }; 726615f31feSGabriel Fernandez 727615f31feSGabriel Fernandez static const struct stm32_clk_pll *clk_stm32_pll_data(unsigned int idx) 728615f31feSGabriel Fernandez { 729*088238adSNicolas Le Bayon return &stm32mp2_clk_pll[idx]; 730615f31feSGabriel Fernandez } 731615f31feSGabriel Fernandez 732615f31feSGabriel Fernandez static unsigned long clk_get_pll_fvco(struct stm32_clk_priv *priv, 733615f31feSGabriel Fernandez const struct stm32_clk_pll *pll, 734615f31feSGabriel Fernandez unsigned long prate) 735615f31feSGabriel Fernandez { 736615f31feSGabriel Fernandez unsigned long refclk, fvco; 737615f31feSGabriel Fernandez uint32_t fracin, fbdiv, refdiv; 738615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 739615f31feSGabriel Fernandez uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2; 740615f31feSGabriel Fernandez uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3; 741615f31feSGabriel Fernandez 742615f31feSGabriel Fernandez refclk = prate; 743615f31feSGabriel Fernandez 744615f31feSGabriel Fernandez fracin = mmio_read_32(pllxcfgr3) & RCC_PLLxCFGR3_FRACIN_MASK; 745615f31feSGabriel Fernandez fbdiv = (mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FBDIV_MASK) >> 746615f31feSGabriel Fernandez RCC_PLLxCFGR2_FBDIV_SHIFT; 747615f31feSGabriel Fernandez refdiv = mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FREFDIV_MASK; 748615f31feSGabriel Fernandez 749615f31feSGabriel Fernandez if (fracin != 0U) { 750615f31feSGabriel Fernandez uint64_t numerator, denominator; 751615f31feSGabriel Fernandez 752615f31feSGabriel Fernandez numerator = ((uint64_t)fbdiv << 24) + fracin; 753615f31feSGabriel Fernandez numerator = refclk * numerator; 754615f31feSGabriel Fernandez denominator = (uint64_t)refdiv << 24; 755615f31feSGabriel Fernandez fvco = (unsigned long)(numerator / denominator); 756615f31feSGabriel Fernandez } else { 757615f31feSGabriel Fernandez fvco = (unsigned long)(refclk * fbdiv / refdiv); 758615f31feSGabriel Fernandez } 759615f31feSGabriel Fernandez 760615f31feSGabriel Fernandez return fvco; 761615f31feSGabriel Fernandez } 762615f31feSGabriel Fernandez 763615f31feSGabriel Fernandez struct stm32_pll_cfg { 764615f31feSGabriel Fernandez uint16_t pll_id; 765615f31feSGabriel Fernandez }; 766615f31feSGabriel Fernandez 767615f31feSGabriel Fernandez static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 768615f31feSGabriel Fernandez { 769615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 770615f31feSGabriel Fernandez 771615f31feSGabriel Fernandez return ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLEN) != 0U); 772615f31feSGabriel Fernandez } 773615f31feSGabriel Fernandez 774615f31feSGabriel Fernandez static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 775615f31feSGabriel Fernandez { 776615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 777615f31feSGabriel Fernandez 778615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN); 779615f31feSGabriel Fernandez } 780615f31feSGabriel Fernandez 781615f31feSGabriel Fernandez static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 782615f31feSGabriel Fernandez { 783615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 784615f31feSGabriel Fernandez 785615f31feSGabriel Fernandez /* Stop PLL */ 786615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN); 787615f31feSGabriel Fernandez } 788615f31feSGabriel Fernandez 789615f31feSGabriel Fernandez static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv, 790615f31feSGabriel Fernandez const struct stm32_clk_pll *pll) 791615f31feSGabriel Fernandez { 792615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 793615f31feSGabriel Fernandez uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT); 794615f31feSGabriel Fernandez 795615f31feSGabriel Fernandez /* Wait PLL lock */ 796615f31feSGabriel Fernandez while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) == 0U) { 797615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 798615f31feSGabriel Fernandez ERROR("PLL%d start failed @ 0x%x: 0x%x\n", 799615f31feSGabriel Fernandez pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcfgr1, 800615f31feSGabriel Fernandez mmio_read_32(pllxcfgr1)); 801615f31feSGabriel Fernandez return -ETIMEDOUT; 802615f31feSGabriel Fernandez } 803615f31feSGabriel Fernandez } 804615f31feSGabriel Fernandez 805615f31feSGabriel Fernandez return 0; 806615f31feSGabriel Fernandez } 807615f31feSGabriel Fernandez 808615f31feSGabriel Fernandez static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv, 809615f31feSGabriel Fernandez const struct stm32_clk_pll *pll) 810615f31feSGabriel Fernandez { 811615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 812615f31feSGabriel Fernandez uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT); 813615f31feSGabriel Fernandez 814615f31feSGabriel Fernandez /* Wait PLL stopped */ 815615f31feSGabriel Fernandez while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) != 0U) { 816615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 817615f31feSGabriel Fernandez ERROR("PLL%d stop failed @ 0x%lx: 0x%x\n", 818615f31feSGabriel Fernandez pll->clk_id - _CK_PLL1 + 1, pllxcfgr1, mmio_read_32(pllxcfgr1)); 819615f31feSGabriel Fernandez return -ETIMEDOUT; 820615f31feSGabriel Fernandez } 821615f31feSGabriel Fernandez } 822615f31feSGabriel Fernandez 823615f31feSGabriel Fernandez return 0; 824615f31feSGabriel Fernandez } 825615f31feSGabriel Fernandez 826615f31feSGabriel Fernandez static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 827615f31feSGabriel Fernandez { 828615f31feSGabriel Fernandez if (_clk_stm32_pll_is_enabled(priv, pll)) { 829615f31feSGabriel Fernandez return 0; 830615f31feSGabriel Fernandez } 831615f31feSGabriel Fernandez 832615f31feSGabriel Fernandez _clk_stm32_pll_set_on(priv, pll); 833615f31feSGabriel Fernandez 834615f31feSGabriel Fernandez return _clk_stm32_pll_wait_ready_on(priv, pll); 835615f31feSGabriel Fernandez } 836615f31feSGabriel Fernandez 837615f31feSGabriel Fernandez static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 838615f31feSGabriel Fernandez { 839615f31feSGabriel Fernandez if (!_clk_stm32_pll_is_enabled(priv, pll)) { 840615f31feSGabriel Fernandez return; 841615f31feSGabriel Fernandez } 842615f31feSGabriel Fernandez 843615f31feSGabriel Fernandez _clk_stm32_pll_set_off(priv, pll); 844615f31feSGabriel Fernandez 845615f31feSGabriel Fernandez _clk_stm32_pll_wait_ready_off(priv, pll); 846615f31feSGabriel Fernandez } 847615f31feSGabriel Fernandez 848615f31feSGabriel Fernandez static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id) 849615f31feSGabriel Fernandez { 850615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 851615f31feSGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 852615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id); 853615f31feSGabriel Fernandez 854615f31feSGabriel Fernandez return _clk_stm32_pll_is_enabled(priv, pll); 855615f31feSGabriel Fernandez } 856615f31feSGabriel Fernandez 857615f31feSGabriel Fernandez static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id) 858615f31feSGabriel Fernandez { 859615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 860615f31feSGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 861615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id); 862615f31feSGabriel Fernandez 863615f31feSGabriel Fernandez return _clk_stm32_pll_enable(priv, pll); 864615f31feSGabriel Fernandez } 865615f31feSGabriel Fernandez 866615f31feSGabriel Fernandez static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id) 867615f31feSGabriel Fernandez { 868615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 869615f31feSGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 870615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id); 871615f31feSGabriel Fernandez 872615f31feSGabriel Fernandez _clk_stm32_pll_disable(priv, pll); 873615f31feSGabriel Fernandez } 874615f31feSGabriel Fernandez 875615f31feSGabriel Fernandez static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id, 876615f31feSGabriel Fernandez unsigned long prate) 877615f31feSGabriel Fernandez { 878615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 879615f31feSGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 880615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id); 881615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 882615f31feSGabriel Fernandez uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4; 883615f31feSGabriel Fernandez uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6; 884615f31feSGabriel Fernandez uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7; 885615f31feSGabriel Fernandez unsigned long dfout; 886615f31feSGabriel Fernandez uint32_t postdiv1, postdiv2; 887615f31feSGabriel Fernandez 888615f31feSGabriel Fernandez postdiv1 = mmio_read_32(pllxcfgr6) & RCC_PLLxCFGR6_POSTDIV1_MASK; 889615f31feSGabriel Fernandez postdiv2 = mmio_read_32(pllxcfgr7) & RCC_PLLxCFGR7_POSTDIV2_MASK; 890615f31feSGabriel Fernandez 891615f31feSGabriel Fernandez if ((mmio_read_32(pllxcfgr4) & RCC_PLLxCFGR4_BYPASS) != 0U) { 892615f31feSGabriel Fernandez dfout = prate; 893615f31feSGabriel Fernandez } else { 894615f31feSGabriel Fernandez if ((postdiv1 == 0U) || (postdiv2 == 0U)) { 895615f31feSGabriel Fernandez dfout = prate; 896615f31feSGabriel Fernandez } else { 897615f31feSGabriel Fernandez dfout = clk_get_pll_fvco(priv, pll, prate) / (postdiv1 * postdiv2); 898615f31feSGabriel Fernandez } 899615f31feSGabriel Fernandez } 900615f31feSGabriel Fernandez 901615f31feSGabriel Fernandez return dfout; 902615f31feSGabriel Fernandez } 903615f31feSGabriel Fernandez 904615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_pll_ops = { 905615f31feSGabriel Fernandez .recalc_rate = clk_stm32_pll_recalc_rate, 906615f31feSGabriel Fernandez .enable = clk_stm32_pll_enable, 907615f31feSGabriel Fernandez .disable = clk_stm32_pll_disable, 908615f31feSGabriel Fernandez .is_enabled = clk_stm32_pll_is_enabled, 909615f31feSGabriel Fernandez }; 910615f31feSGabriel Fernandez 911615f31feSGabriel Fernandez #define CLK_PLL(idx, _idx, _parent, _pll_id, _flags)[idx] = {\ 912615f31feSGabriel Fernandez .binding = _idx,\ 913615f31feSGabriel Fernandez .parent = _parent,\ 914615f31feSGabriel Fernandez .flags = (_flags),\ 915615f31feSGabriel Fernandez .clock_cfg = &(struct stm32_pll_cfg) {\ 916615f31feSGabriel Fernandez .pll_id = _pll_id,\ 917615f31feSGabriel Fernandez },\ 918615f31feSGabriel Fernandez .ops = STM32_PLL_OPS,\ 919615f31feSGabriel Fernandez } 920615f31feSGabriel Fernandez 921615f31feSGabriel Fernandez static unsigned long clk_get_pll1_fvco(unsigned long refclk) 922615f31feSGabriel Fernandez { 923615f31feSGabriel Fernandez uintptr_t pll_freq1_reg = A35SSC_BASE + A35_SS_PLL_FREQ1; 924615f31feSGabriel Fernandez uint32_t reg, fbdiv, refdiv; 925615f31feSGabriel Fernandez 926615f31feSGabriel Fernandez reg = mmio_read_32(pll_freq1_reg); 927615f31feSGabriel Fernandez 928615f31feSGabriel Fernandez fbdiv = (reg & A35_SS_PLL_FREQ1_FBDIV_MASK) >> A35_SS_PLL_FREQ1_FBDIV_SHIFT; 929615f31feSGabriel Fernandez refdiv = (reg & A35_SS_PLL_FREQ1_REFDIV_MASK) >> A35_SS_PLL_FREQ1_REFDIV_SHIFT; 930615f31feSGabriel Fernandez 931615f31feSGabriel Fernandez return (unsigned long)(refclk * fbdiv / refdiv); 932615f31feSGabriel Fernandez } 933615f31feSGabriel Fernandez 934615f31feSGabriel Fernandez static unsigned long clk_stm32_pll1_recalc_rate(struct stm32_clk_priv *priv, 935615f31feSGabriel Fernandez int id, unsigned long prate) 936615f31feSGabriel Fernandez { 937615f31feSGabriel Fernandez uintptr_t pll_freq2_reg = A35SSC_BASE + A35_SS_PLL_FREQ2; 938615f31feSGabriel Fernandez uint32_t postdiv1, postdiv2; 939615f31feSGabriel Fernandez unsigned long dfout; 940615f31feSGabriel Fernandez 941615f31feSGabriel Fernandez postdiv1 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV1_MASK) >> 942615f31feSGabriel Fernandez A35_SS_PLL_FREQ2_POSTDIV1_SHIFT; 943615f31feSGabriel Fernandez postdiv2 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV2_MASK) >> 944615f31feSGabriel Fernandez A35_SS_PLL_FREQ2_POSTDIV2_SHIFT; 945615f31feSGabriel Fernandez 946615f31feSGabriel Fernandez if ((postdiv1 == 0U) || (postdiv2 == 0U)) { 947615f31feSGabriel Fernandez dfout = prate; 948615f31feSGabriel Fernandez } else { 949615f31feSGabriel Fernandez dfout = clk_get_pll1_fvco(prate) / (postdiv1 * postdiv2); 950615f31feSGabriel Fernandez } 951615f31feSGabriel Fernandez 952615f31feSGabriel Fernandez return dfout; 953615f31feSGabriel Fernandez } 954615f31feSGabriel Fernandez 955615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_pll1_ops = { 956615f31feSGabriel Fernandez .recalc_rate = clk_stm32_pll1_recalc_rate, 957615f31feSGabriel Fernandez }; 958615f31feSGabriel Fernandez 959615f31feSGabriel Fernandez #define CLK_PLL1(idx, _idx, _parent, _pll_id, _flags)[idx] = {\ 960615f31feSGabriel Fernandez .binding = _idx,\ 961615f31feSGabriel Fernandez .parent = _parent,\ 962615f31feSGabriel Fernandez .flags = (_flags),\ 963615f31feSGabriel Fernandez .clock_cfg = &(struct stm32_pll_cfg) {\ 964615f31feSGabriel Fernandez .pll_id = _pll_id,\ 965615f31feSGabriel Fernandez },\ 966615f31feSGabriel Fernandez .ops = STM32_PLL1_OPS,\ 967615f31feSGabriel Fernandez } 968615f31feSGabriel Fernandez 969615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg { 970615f31feSGabriel Fernandez uint8_t id; 971615f31feSGabriel Fernandez }; 972615f31feSGabriel Fernandez 973615f31feSGabriel Fernandez static unsigned long clk_flexgen_recalc(struct stm32_clk_priv *priv, int idx, 974615f31feSGabriel Fernandez unsigned long prate) 975615f31feSGabriel Fernandez { 976615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 977615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 978615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 979615f31feSGabriel Fernandez uint32_t prediv, findiv; 980615f31feSGabriel Fernandez uint8_t channel = cfg->id; 981615f31feSGabriel Fernandez unsigned long freq = prate; 982615f31feSGabriel Fernandez 983615f31feSGabriel Fernandez prediv = mmio_read_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel)) & 984615f31feSGabriel Fernandez RCC_PREDIVxCFGR_PREDIVx_MASK; 985615f31feSGabriel Fernandez findiv = mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) & 986615f31feSGabriel Fernandez RCC_FINDIVxCFGR_FINDIVx_MASK; 987615f31feSGabriel Fernandez 988615f31feSGabriel Fernandez if (freq == 0UL) { 989615f31feSGabriel Fernandez return 0U; 990615f31feSGabriel Fernandez } 991615f31feSGabriel Fernandez 992615f31feSGabriel Fernandez switch (prediv) { 993615f31feSGabriel Fernandez case 0x0: 994615f31feSGabriel Fernandez case 0x1: 995615f31feSGabriel Fernandez case 0x3: 996615f31feSGabriel Fernandez case 0x3FF: 997615f31feSGabriel Fernandez break; 998615f31feSGabriel Fernandez 999615f31feSGabriel Fernandez default: 1000615f31feSGabriel Fernandez ERROR("Unsupported PREDIV value (%x)\n", prediv); 1001615f31feSGabriel Fernandez panic(); 1002615f31feSGabriel Fernandez break; 1003615f31feSGabriel Fernandez } 1004615f31feSGabriel Fernandez 1005615f31feSGabriel Fernandez freq /= (prediv + 1U); 1006615f31feSGabriel Fernandez freq /= (findiv + 1U); 1007615f31feSGabriel Fernandez 1008615f31feSGabriel Fernandez return freq; 1009615f31feSGabriel Fernandez } 1010615f31feSGabriel Fernandez 1011615f31feSGabriel Fernandez static int clk_flexgen_get_parent(struct stm32_clk_priv *priv, int idx) 1012615f31feSGabriel Fernandez { 1013615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 1014615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 1015615f31feSGabriel Fernandez uint32_t sel; 1016615f31feSGabriel Fernandez uint32_t address; 1017615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1018615f31feSGabriel Fernandez 1019615f31feSGabriel Fernandez address = RCC_XBAR0CFGR + (cfg->id * 4); 1020615f31feSGabriel Fernandez 1021615f31feSGabriel Fernandez sel = mmio_read_32(rcc_base + address) & RCC_XBARxCFGR_XBARxSEL_MASK; 1022615f31feSGabriel Fernandez 1023615f31feSGabriel Fernandez return sel; 1024615f31feSGabriel Fernandez } 1025615f31feSGabriel Fernandez 1026615f31feSGabriel Fernandez static int clk_flexgen_gate_enable(struct stm32_clk_priv *priv, int idx) 1027615f31feSGabriel Fernandez { 1028615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 1029615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 1030615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1031615f31feSGabriel Fernandez uint8_t channel = cfg->id; 1032615f31feSGabriel Fernandez 1033615f31feSGabriel Fernandez mmio_setbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel), 1034615f31feSGabriel Fernandez RCC_FINDIVxCFGR_FINDIVxEN); 1035615f31feSGabriel Fernandez 1036615f31feSGabriel Fernandez return 0; 1037615f31feSGabriel Fernandez } 1038615f31feSGabriel Fernandez 1039615f31feSGabriel Fernandez static void clk_flexgen_gate_disable(struct stm32_clk_priv *priv, int id) 1040615f31feSGabriel Fernandez { 1041615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 1042615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 1043615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1044615f31feSGabriel Fernandez uint8_t channel = cfg->id; 1045615f31feSGabriel Fernandez 1046615f31feSGabriel Fernandez mmio_clrbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel), 1047615f31feSGabriel Fernandez RCC_FINDIVxCFGR_FINDIVxEN); 1048615f31feSGabriel Fernandez } 1049615f31feSGabriel Fernandez 1050615f31feSGabriel Fernandez static bool clk_flexgen_gate_is_enabled(struct stm32_clk_priv *priv, int id) 1051615f31feSGabriel Fernandez { 1052615f31feSGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 1053615f31feSGabriel Fernandez struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg; 1054615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1055615f31feSGabriel Fernandez uint8_t channel = cfg->id; 1056615f31feSGabriel Fernandez 1057615f31feSGabriel Fernandez return !!(mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) & 1058615f31feSGabriel Fernandez RCC_FINDIVxCFGR_FINDIVxEN); 1059615f31feSGabriel Fernandez } 1060615f31feSGabriel Fernandez 1061615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_flexgen_ops = { 1062615f31feSGabriel Fernandez .recalc_rate = clk_flexgen_recalc, 1063615f31feSGabriel Fernandez .get_parent = clk_flexgen_get_parent, 1064615f31feSGabriel Fernandez .enable = clk_flexgen_gate_enable, 1065615f31feSGabriel Fernandez .disable = clk_flexgen_gate_disable, 1066615f31feSGabriel Fernandez .is_enabled = clk_flexgen_gate_is_enabled, 1067615f31feSGabriel Fernandez }; 1068615f31feSGabriel Fernandez 1069615f31feSGabriel Fernandez #define FLEXGEN(idx, _idx, _flags, _id)[idx] = {\ 1070615f31feSGabriel Fernandez .binding = _idx,\ 1071615f31feSGabriel Fernandez .parent = MUX(MUX_XBARSEL),\ 1072615f31feSGabriel Fernandez .flags = (_flags),\ 1073615f31feSGabriel Fernandez .clock_cfg = &(struct stm32_clk_flexgen_cfg) {\ 1074615f31feSGabriel Fernandez .id = _id,\ 1075615f31feSGabriel Fernandez },\ 1076615f31feSGabriel Fernandez .ops = STM32_FLEXGEN_OPS,\ 1077615f31feSGabriel Fernandez } 1078615f31feSGabriel Fernandez 1079615f31feSGabriel Fernandez #define RCC_0_MHZ UL(0) 1080615f31feSGabriel Fernandez #define RCC_4_MHZ UL(4000000) 1081615f31feSGabriel Fernandez #define RCC_16_MHZ UL(16000000) 1082615f31feSGabriel Fernandez 1083615f31feSGabriel Fernandez #ifdef IMAGE_BL2 1084*088238adSNicolas Le Bayon #if !STM32MP21 1085615f31feSGabriel Fernandez static int clk_stm32_osc_msi_set_rate(struct stm32_clk_priv *priv, int id, unsigned long rate, 1086615f31feSGabriel Fernandez unsigned long prate) 1087615f31feSGabriel Fernandez { 1088615f31feSGabriel Fernandez uintptr_t address = priv->base + RCC_BDCR; 1089615f31feSGabriel Fernandez uint32_t mask = RCC_BDCR_MSIFREQSEL; 1090615f31feSGabriel Fernandez int ret = -1; 1091615f31feSGabriel Fernandez 1092615f31feSGabriel Fernandez switch (rate) { 1093615f31feSGabriel Fernandez case RCC_4_MHZ: 1094615f31feSGabriel Fernandez mmio_clrbits_32(address, mask); 1095615f31feSGabriel Fernandez ret = 0; 1096615f31feSGabriel Fernandez break; 1097615f31feSGabriel Fernandez 1098615f31feSGabriel Fernandez case RCC_16_MHZ: 1099615f31feSGabriel Fernandez mmio_setbits_32(address, mask); 1100615f31feSGabriel Fernandez ret = 0; 1101615f31feSGabriel Fernandez break; 1102615f31feSGabriel Fernandez 1103615f31feSGabriel Fernandez default: 1104615f31feSGabriel Fernandez break; 1105615f31feSGabriel Fernandez } 1106615f31feSGabriel Fernandez 1107615f31feSGabriel Fernandez return ret; 1108615f31feSGabriel Fernandez } 1109*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1110615f31feSGabriel Fernandez #endif /* IMAGE_BL2 */ 1111615f31feSGabriel Fernandez 1112615f31feSGabriel Fernandez static unsigned long clk_stm32_osc_msi_recalc_rate(struct stm32_clk_priv *priv, 1113615f31feSGabriel Fernandez int id __unused, 1114615f31feSGabriel Fernandez unsigned long prate __unused) 1115615f31feSGabriel Fernandez { 1116*088238adSNicolas Le Bayon #if STM32MP21 1117*088238adSNicolas Le Bayon return RCC_16_MHZ; 1118*088238adSNicolas Le Bayon #else /* STM32MP21 */ 1119615f31feSGabriel Fernandez uintptr_t address = priv->base + RCC_BDCR; 1120615f31feSGabriel Fernandez 1121615f31feSGabriel Fernandez if ((mmio_read_32(address) & RCC_BDCR_MSIFREQSEL) == 0U) { 1122615f31feSGabriel Fernandez return RCC_4_MHZ; 1123615f31feSGabriel Fernandez } else { 1124615f31feSGabriel Fernandez return RCC_16_MHZ; 1125615f31feSGabriel Fernandez } 1126*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1127615f31feSGabriel Fernandez } 1128615f31feSGabriel Fernandez 1129615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_osc_msi_ops = { 1130615f31feSGabriel Fernandez .recalc_rate = clk_stm32_osc_msi_recalc_rate, 1131615f31feSGabriel Fernandez .is_enabled = clk_stm32_osc_gate_is_enabled, 1132615f31feSGabriel Fernandez .enable = clk_stm32_osc_gate_enable, 1133615f31feSGabriel Fernandez .disable = clk_stm32_osc_gate_disable, 1134615f31feSGabriel Fernandez .init = clk_stm32_osc_init, 1135615f31feSGabriel Fernandez }; 1136615f31feSGabriel Fernandez 1137615f31feSGabriel Fernandez #define CLK_OSC_MSI(idx, _idx, _parent, _osc_id) \ 1138615f31feSGabriel Fernandez [(idx)] = (struct clk_stm32){ \ 1139615f31feSGabriel Fernandez .binding = (_idx),\ 1140615f31feSGabriel Fernandez .parent = (_parent),\ 1141615f31feSGabriel Fernandez .flags = CLK_IS_CRITICAL,\ 1142615f31feSGabriel Fernandez .clock_cfg = &(struct stm32_osc_cfg){\ 1143615f31feSGabriel Fernandez .osc_id = (_osc_id),\ 1144615f31feSGabriel Fernandez },\ 1145615f31feSGabriel Fernandez .ops = STM32_OSC_MSI_OPS,\ 1146615f31feSGabriel Fernandez } 1147615f31feSGabriel Fernandez 1148615f31feSGabriel Fernandez static const struct stm32_clk_ops clk_stm32_rtc_ops = { 1149615f31feSGabriel Fernandez .enable = clk_stm32_gate_enable, 1150615f31feSGabriel Fernandez .disable = clk_stm32_gate_disable, 1151615f31feSGabriel Fernandez .is_enabled = clk_stm32_gate_is_enabled, 1152615f31feSGabriel Fernandez }; 1153615f31feSGabriel Fernandez 1154615f31feSGabriel Fernandez #define CLK_RTC(idx, _binding, _parent, _flags, _gate_id)[idx] = {\ 1155615f31feSGabriel Fernandez .binding = (_binding),\ 1156615f31feSGabriel Fernandez .parent = (_parent),\ 1157615f31feSGabriel Fernandez .flags = (_flags),\ 1158615f31feSGabriel Fernandez .clock_cfg = &(struct clk_stm32_gate_cfg) {\ 1159615f31feSGabriel Fernandez .id = (_gate_id),\ 1160615f31feSGabriel Fernandez },\ 1161615f31feSGabriel Fernandez .ops = STM32_RTC_OPS,\ 1162615f31feSGabriel Fernandez } 1163615f31feSGabriel Fernandez 1164615f31feSGabriel Fernandez enum { 1165615f31feSGabriel Fernandez STM32_PLL_OPS = STM32_LAST_OPS, 1166615f31feSGabriel Fernandez STM32_PLL1_OPS, 1167615f31feSGabriel Fernandez STM32_FLEXGEN_OPS, 1168615f31feSGabriel Fernandez STM32_OSC_MSI_OPS, 1169615f31feSGabriel Fernandez STM32_RTC_OPS, 1170615f31feSGabriel Fernandez 1171*088238adSNicolas Le Bayon MP2_LAST_OPS 1172615f31feSGabriel Fernandez }; 1173615f31feSGabriel Fernandez 1174*088238adSNicolas Le Bayon static const struct stm32_clk_ops *ops_array_mp2[MP2_LAST_OPS] = { 1175615f31feSGabriel Fernandez [NO_OPS] = NULL, 1176615f31feSGabriel Fernandez [FIXED_FACTOR_OPS] = &clk_fixed_factor_ops, 1177615f31feSGabriel Fernandez [GATE_OPS] = &clk_gate_ops, 1178615f31feSGabriel Fernandez [STM32_MUX_OPS] = &clk_mux_ops, 1179615f31feSGabriel Fernandez [STM32_DIVIDER_OPS] = &clk_stm32_divider_ops, 1180615f31feSGabriel Fernandez [STM32_GATE_OPS] = &clk_stm32_gate_ops, 1181615f31feSGabriel Fernandez [STM32_TIMER_OPS] = &clk_timer_ops, 1182615f31feSGabriel Fernandez [STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops, 1183615f31feSGabriel Fernandez [STM32_OSC_OPS] = &clk_stm32_osc_ops, 1184615f31feSGabriel Fernandez [STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops, 1185615f31feSGabriel Fernandez 1186615f31feSGabriel Fernandez [STM32_PLL_OPS] = &clk_stm32_pll_ops, 1187615f31feSGabriel Fernandez [STM32_PLL1_OPS] = &clk_stm32_pll1_ops, 1188615f31feSGabriel Fernandez [STM32_FLEXGEN_OPS] = &clk_stm32_flexgen_ops, 1189615f31feSGabriel Fernandez [STM32_OSC_MSI_OPS] = &clk_stm32_osc_msi_ops, 1190615f31feSGabriel Fernandez [STM32_RTC_OPS] = &clk_stm32_rtc_ops 1191615f31feSGabriel Fernandez }; 1192615f31feSGabriel Fernandez 1193*088238adSNicolas Le Bayon static const struct clk_stm32 stm32mp2_clk[CK_LAST] = { 1194615f31feSGabriel Fernandez CLK_FIXED_RATE(_CK_0_MHZ, _NO_ID, RCC_0_MHZ), 1195615f31feSGabriel Fernandez 1196615f31feSGabriel Fernandez /* ROOT CLOCKS */ 1197615f31feSGabriel Fernandez CLK_OSC(_CK_HSE, HSE_CK, CLK_IS_ROOT, OSC_HSE), 1198615f31feSGabriel Fernandez CLK_OSC(_CK_LSE, LSE_CK, CLK_IS_ROOT, OSC_LSE), 1199615f31feSGabriel Fernandez CLK_OSC(_CK_HSI, HSI_CK, CLK_IS_ROOT, OSC_HSI), 1200615f31feSGabriel Fernandez CLK_OSC(_CK_LSI, LSI_CK, CLK_IS_ROOT, OSC_LSI), 1201615f31feSGabriel Fernandez CLK_OSC_MSI(_CK_MSI, MSI_CK, CLK_IS_ROOT, OSC_MSI), 1202615f31feSGabriel Fernandez 1203615f31feSGabriel Fernandez CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN), 1204615f31feSGabriel Fernandez CLK_OSC_FIXED(_SPDIFSYMB, _NO_ID, CLK_IS_ROOT, OSC_SPDIFSYMB), 1205615f31feSGabriel Fernandez 1206615f31feSGabriel Fernandez STM32_DIV(_CK_HSE_RTC, _NO_ID, _CK_HSE, 0, DIV_RTC), 1207615f31feSGabriel Fernandez 1208615f31feSGabriel Fernandez CLK_RTC(_CK_RTCCK, RTC_CK, MUX(MUX_RTC), 0, GATE_RTCCK), 1209615f31feSGabriel Fernandez 1210615f31feSGabriel Fernandez CLK_PLL1(_CK_PLL1, PLL1_CK, MUX(MUX_MUXSEL5), _PLL1, 0), 1211615f31feSGabriel Fernandez 1212615f31feSGabriel Fernandez CLK_PLL(_CK_PLL2, PLL2_CK, MUX(MUX_MUXSEL6), _PLL2, 0), 1213*088238adSNicolas Le Bayon #if !STM32MP21 1214615f31feSGabriel Fernandez CLK_PLL(_CK_PLL3, PLL3_CK, MUX(MUX_MUXSEL7), _PLL3, 0), 1215*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1216615f31feSGabriel Fernandez CLK_PLL(_CK_PLL4, PLL4_CK, MUX(MUX_MUXSEL0), _PLL4, 0), 1217615f31feSGabriel Fernandez CLK_PLL(_CK_PLL5, PLL5_CK, MUX(MUX_MUXSEL1), _PLL5, 0), 1218615f31feSGabriel Fernandez CLK_PLL(_CK_PLL6, PLL6_CK, MUX(MUX_MUXSEL2), _PLL6, 0), 1219615f31feSGabriel Fernandez CLK_PLL(_CK_PLL7, PLL7_CK, MUX(MUX_MUXSEL3), _PLL7, 0), 1220615f31feSGabriel Fernandez CLK_PLL(_CK_PLL8, PLL8_CK, MUX(MUX_MUXSEL4), _PLL8, 0), 1221615f31feSGabriel Fernandez 1222615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_HS_MCU, CK_ICN_HS_MCU, CLK_IS_CRITICAL, 0), 1223615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_SDMMC, CK_ICN_SDMMC, CLK_IS_CRITICAL, 1), 1224615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_DDR, CK_ICN_DDR, CLK_IS_CRITICAL, 2), 1225615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_HSL, CK_ICN_HSL, CLK_IS_CRITICAL, 4), 1226615f31feSGabriel Fernandez FLEXGEN(_CK_ICN_NIC, CK_ICN_NIC, CLK_IS_CRITICAL, 5), 1227615f31feSGabriel Fernandez 1228615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_LS_MCU, CK_ICN_LS_MCU, _CK_ICN_HS_MCU, 0, DIV_LSMCU), 1229615f31feSGabriel Fernandez 1230615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_07, CK_FLEXGEN_07, 0, 7), 1231615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_08, CK_FLEXGEN_08, 0, 8), 1232615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_09, CK_FLEXGEN_09, 0, 9), 1233615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_10, CK_FLEXGEN_10, 0, 10), 1234615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_11, CK_FLEXGEN_11, 0, 11), 1235615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_12, CK_FLEXGEN_12, 0, 12), 1236615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_13, CK_FLEXGEN_13, 0, 13), 1237615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_14, CK_FLEXGEN_14, 0, 14), 1238615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_15, CK_FLEXGEN_15, 0, 15), 1239615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_16, CK_FLEXGEN_16, 0, 16), 1240615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_17, CK_FLEXGEN_17, 0, 17), 1241615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_18, CK_FLEXGEN_18, 0, 18), 1242615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_19, CK_FLEXGEN_19, 0, 19), 1243615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_20, CK_FLEXGEN_20, 0, 20), 1244615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_21, CK_FLEXGEN_21, 0, 21), 1245615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_22, CK_FLEXGEN_22, 0, 22), 1246615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_23, CK_FLEXGEN_23, 0, 23), 1247615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_24, CK_FLEXGEN_24, 0, 24), 1248615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_25, CK_FLEXGEN_25, 0, 25), 1249615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_26, CK_FLEXGEN_26, 0, 26), 1250615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_27, CK_FLEXGEN_27, 0, 27), 1251615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_28, CK_FLEXGEN_28, 0, 28), 1252615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_29, CK_FLEXGEN_29, 0, 29), 1253615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_30, CK_FLEXGEN_30, 0, 30), 1254615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_31, CK_FLEXGEN_31, 0, 31), 1255615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_32, CK_FLEXGEN_32, 0, 32), 1256615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_33, CK_FLEXGEN_33, 0, 33), 1257615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_34, CK_FLEXGEN_34, 0, 34), 1258615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_35, CK_FLEXGEN_35, 0, 35), 1259615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_36, CK_FLEXGEN_36, 0, 36), 1260615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_37, CK_FLEXGEN_37, 0, 37), 1261615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_38, CK_FLEXGEN_38, 0, 38), 1262615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_39, CK_FLEXGEN_39, 0, 39), 1263615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_40, CK_FLEXGEN_40, 0, 40), 1264615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_41, CK_FLEXGEN_41, 0, 41), 1265615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_42, CK_FLEXGEN_42, 0, 42), 1266615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_43, CK_FLEXGEN_43, 0, 43), 1267615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_44, CK_FLEXGEN_44, 0, 44), 1268615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_45, CK_FLEXGEN_45, 0, 45), 1269615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_46, CK_FLEXGEN_46, 0, 46), 1270615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_47, CK_FLEXGEN_47, 0, 47), 1271615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_48, CK_FLEXGEN_48, 0, 48), 1272615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_49, CK_FLEXGEN_49, 0, 49), 1273615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_50, CK_FLEXGEN_50, 0, 50), 1274615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_51, CK_FLEXGEN_51, 0, 51), 1275615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_52, CK_FLEXGEN_52, 0, 52), 1276615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_53, CK_FLEXGEN_53, 0, 53), 1277615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_54, CK_FLEXGEN_54, 0, 54), 1278615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_55, CK_FLEXGEN_55, 0, 55), 1279615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_56, CK_FLEXGEN_56, 0, 56), 1280615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_57, CK_FLEXGEN_57, 0, 57), 1281615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_58, CK_FLEXGEN_58, 0, 58), 1282615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_59, CK_FLEXGEN_59, 0, 59), 1283615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_60, CK_FLEXGEN_60, 0, 60), 1284615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_61, CK_FLEXGEN_61, 0, 61), 1285615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_62, CK_FLEXGEN_62, 0, 62), 1286615f31feSGabriel Fernandez FLEXGEN(_CK_FLEXGEN_63, CK_FLEXGEN_63, 0, 63), 1287615f31feSGabriel Fernandez 1288615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APB1, CK_ICN_APB1, _CK_ICN_LS_MCU, 0, DIV_APB1), 1289615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APB2, CK_ICN_APB2, _CK_ICN_LS_MCU, 0, DIV_APB2), 1290615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APB3, CK_ICN_APB3, _CK_ICN_LS_MCU, 0, DIV_APB3), 1291615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APB4, CK_ICN_APB4, _CK_ICN_LS_MCU, 0, DIV_APB4), 1292*088238adSNicolas Le Bayon #if STM32MP21 1293*088238adSNicolas Le Bayon STM32_DIV(_CK_ICN_APB5, CK_ICN_APB5, _CK_ICN_LS_MCU, 0, DIV_APB5), 1294*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1295615f31feSGabriel Fernandez STM32_DIV(_CK_ICN_APBDBG, CK_ICN_APBDBG, _CK_ICN_LS_MCU, 0, DIV_APBDBG), 1296615f31feSGabriel Fernandez 1297615f31feSGabriel Fernandez /* KERNEL CLOCK */ 1298615f31feSGabriel Fernandez STM32_GATE(_CK_SYSRAM, CK_BUS_SYSRAM, _CK_ICN_HS_MCU, 0, GATE_SYSRAM), 1299615f31feSGabriel Fernandez STM32_GATE(_CK_RETRAM, CK_BUS_RETRAM, _CK_ICN_HS_MCU, 0, GATE_RETRAM), 1300615f31feSGabriel Fernandez STM32_GATE(_CK_SRAM1, CK_BUS_SRAM1, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM1), 1301*088238adSNicolas Le Bayon #if !STM32MP21 1302615f31feSGabriel Fernandez STM32_GATE(_CK_SRAM2, CK_BUS_SRAM2, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM2), 1303*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1304615f31feSGabriel Fernandez 1305615f31feSGabriel Fernandez STM32_GATE(_CK_DDRPHYC, CK_BUS_DDRPHYC, _CK_ICN_LS_MCU, 0, GATE_DDRPHYC), 1306615f31feSGabriel Fernandez STM32_GATE(_CK_SYSCPU1, CK_BUS_SYSCPU1, _CK_ICN_LS_MCU, 0, GATE_SYSCPU1), 1307615f31feSGabriel Fernandez STM32_GATE(_CK_CRC, CK_BUS_CRC, _CK_ICN_LS_MCU, 0, GATE_CRC), 1308*088238adSNicolas Le Bayon #if !STM32MP21 1309615f31feSGabriel Fernandez STM32_GATE(_CK_OSPIIOM, CK_BUS_OSPIIOM, _CK_ICN_LS_MCU, 0, GATE_OSPIIOM), 1310*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1311615f31feSGabriel Fernandez STM32_GATE(_CK_BKPSRAM, CK_BUS_BKPSRAM, _CK_ICN_LS_MCU, 0, GATE_BKPSRAM), 1312*088238adSNicolas Le Bayon #if STM32MP21 1313*088238adSNicolas Le Bayon STM32_GATE(_CK_HASH1, CK_BUS_HASH1, _CK_ICN_LS_MCU, 0, GATE_HASH1), 1314*088238adSNicolas Le Bayon STM32_GATE(_CK_HASH2, CK_BUS_HASH2, _CK_ICN_LS_MCU, 0, GATE_HASH2), 1315*088238adSNicolas Le Bayon STM32_GATE(_CK_RNG1, CK_BUS_RNG1, _CK_ICN_LS_MCU, 0, GATE_RNG1), 1316*088238adSNicolas Le Bayon STM32_GATE(_CK_RNG2, CK_BUS_RNG2, _CK_ICN_LS_MCU, 0, GATE_RNG2), 1317*088238adSNicolas Le Bayon #else /* STM32MP21 */ 1318615f31feSGabriel Fernandez STM32_GATE(_CK_HASH, CK_BUS_HASH, _CK_ICN_LS_MCU, 0, GATE_HASH), 1319615f31feSGabriel Fernandez STM32_GATE(_CK_RNG, CK_BUS_RNG, _CK_ICN_LS_MCU, 0, GATE_RNG), 1320*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1321615f31feSGabriel Fernandez STM32_GATE(_CK_CRYP1, CK_BUS_CRYP1, _CK_ICN_LS_MCU, 0, GATE_CRYP1), 1322615f31feSGabriel Fernandez STM32_GATE(_CK_CRYP2, CK_BUS_CRYP2, _CK_ICN_LS_MCU, 0, GATE_CRYP2), 1323615f31feSGabriel Fernandez STM32_GATE(_CK_SAES, CK_BUS_SAES, _CK_ICN_LS_MCU, 0, GATE_SAES), 1324615f31feSGabriel Fernandez STM32_GATE(_CK_PKA, CK_BUS_PKA, _CK_ICN_LS_MCU, 0, GATE_PKA), 1325615f31feSGabriel Fernandez 1326615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOA, CK_BUS_GPIOA, _CK_ICN_LS_MCU, 0, GATE_GPIOA), 1327615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOB, CK_BUS_GPIOB, _CK_ICN_LS_MCU, 0, GATE_GPIOB), 1328615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOC, CK_BUS_GPIOC, _CK_ICN_LS_MCU, 0, GATE_GPIOC), 1329615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOD, CK_BUS_GPIOD, _CK_ICN_LS_MCU, 0, GATE_GPIOD), 1330615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOE, CK_BUS_GPIOE, _CK_ICN_LS_MCU, 0, GATE_GPIOE), 1331615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOF, CK_BUS_GPIOF, _CK_ICN_LS_MCU, 0, GATE_GPIOF), 1332615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOG, CK_BUS_GPIOG, _CK_ICN_LS_MCU, 0, GATE_GPIOG), 1333615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOH, CK_BUS_GPIOH, _CK_ICN_LS_MCU, 0, GATE_GPIOH), 1334615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOI, CK_BUS_GPIOI, _CK_ICN_LS_MCU, 0, GATE_GPIOI), 1335*088238adSNicolas Le Bayon #if !STM32MP21 1336615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOJ, CK_BUS_GPIOJ, _CK_ICN_LS_MCU, 0, GATE_GPIOJ), 1337615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOK, CK_BUS_GPIOK, _CK_ICN_LS_MCU, 0, GATE_GPIOK), 1338*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1339615f31feSGabriel Fernandez STM32_GATE(_CK_GPIOZ, CK_BUS_GPIOZ, _CK_ICN_LS_MCU, 0, GATE_GPIOZ), 1340615f31feSGabriel Fernandez STM32_GATE(_CK_RTC, CK_BUS_RTC, _CK_ICN_LS_MCU, 0, GATE_RTC), 1341615f31feSGabriel Fernandez 1342615f31feSGabriel Fernandez STM32_GATE(_CK_DDRCP, CK_BUS_DDR, _CK_ICN_DDR, 0, GATE_DDRCP), 1343615f31feSGabriel Fernandez 1344615f31feSGabriel Fernandez /* WARNING 2 CLOCKS FOR ONE GATE */ 1345*088238adSNicolas Le Bayon #if STM32MP21 1346*088238adSNicolas Le Bayon STM32_GATE(_CK_USBHOHCI, CK_BUS_USBHOHCI, _CK_ICN_HSL, 0, GATE_USBHOHCI), 1347*088238adSNicolas Le Bayon STM32_GATE(_CK_USBHEHCI, CK_BUS_USBHEHCI, _CK_ICN_HSL, 0, GATE_USBHEHCI), 1348*088238adSNicolas Le Bayon #else /* STM32MP21 */ 1349615f31feSGabriel Fernandez STM32_GATE(_CK_USB2OHCI, CK_BUS_USB2OHCI, _CK_ICN_HSL, 0, GATE_USB2OHCI), 1350615f31feSGabriel Fernandez STM32_GATE(_CK_USB2EHCI, CK_BUS_USB2EHCI, _CK_ICN_HSL, 0, GATE_USB2EHCI), 1351*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1352615f31feSGabriel Fernandez 1353*088238adSNicolas Le Bayon #if !STM32MP21 1354615f31feSGabriel Fernandez STM32_GATE(_CK_USB3DR, CK_BUS_USB3DR, _CK_ICN_HSL, 0, GATE_USB3DR), 1355*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1356615f31feSGabriel Fernandez 1357615f31feSGabriel Fernandez STM32_GATE(_CK_BSEC, CK_BUS_BSEC, _CK_ICN_APB3, 0, GATE_BSEC), 1358615f31feSGabriel Fernandez STM32_GATE(_CK_IWDG1, CK_BUS_IWDG1, _CK_ICN_APB3, 0, GATE_IWDG1), 1359615f31feSGabriel Fernandez STM32_GATE(_CK_IWDG2, CK_BUS_IWDG2, _CK_ICN_APB3, 0, GATE_IWDG2), 1360615f31feSGabriel Fernandez 1361615f31feSGabriel Fernandez STM32_GATE(_CK_DDRCAPB, CK_BUS_DDRC, _CK_ICN_APB4, 0, GATE_DDRCAPB), 1362615f31feSGabriel Fernandez STM32_GATE(_CK_DDR, CK_BUS_DDRCFG, _CK_ICN_APB4, 0, GATE_DDR), 1363615f31feSGabriel Fernandez 1364615f31feSGabriel Fernandez STM32_GATE(_CK_USART2, CK_KER_USART2, _CK_FLEXGEN_08, 0, GATE_USART2), 1365615f31feSGabriel Fernandez STM32_GATE(_CK_UART4, CK_KER_UART4, _CK_FLEXGEN_08, 0, GATE_UART4), 1366615f31feSGabriel Fernandez STM32_GATE(_CK_USART3, CK_KER_USART3, _CK_FLEXGEN_09, 0, GATE_USART3), 1367615f31feSGabriel Fernandez STM32_GATE(_CK_UART5, CK_KER_UART5, _CK_FLEXGEN_09, 0, GATE_UART5), 1368*088238adSNicolas Le Bayon #if STM32MP21 1369*088238adSNicolas Le Bayon STM32_GATE(_CK_I2C1, CK_KER_I2C1, _CK_FLEXGEN_13, 0, GATE_I2C1), 1370*088238adSNicolas Le Bayon STM32_GATE(_CK_I2C2, CK_KER_I2C2, _CK_FLEXGEN_13, 0, GATE_I2C2), 1371*088238adSNicolas Le Bayon STM32_GATE(_CK_USART1, CK_KER_USART1, _CK_FLEXGEN_18, 0, GATE_USART1), 1372*088238adSNicolas Le Bayon STM32_GATE(_CK_USART6, CK_KER_USART6, _CK_FLEXGEN_19, 0, GATE_USART6), 1373*088238adSNicolas Le Bayon STM32_GATE(_CK_UART7, CK_KER_UART7, _CK_FLEXGEN_20, 0, GATE_UART7), 1374*088238adSNicolas Le Bayon STM32_GATE(_CK_I2C3, CK_KER_I2C3, _CK_FLEXGEN_38, 0, GATE_I2C3), 1375*088238adSNicolas Le Bayon #else /* STM32MP21 */ 1376615f31feSGabriel Fernandez STM32_GATE(_CK_I2C1, CK_KER_I2C1, _CK_FLEXGEN_12, 0, GATE_I2C1), 1377615f31feSGabriel Fernandez STM32_GATE(_CK_I2C2, CK_KER_I2C2, _CK_FLEXGEN_12, 0, GATE_I2C2), 1378*088238adSNicolas Le Bayon #if STM32MP25 1379615f31feSGabriel Fernandez STM32_GATE(_CK_I2C3, CK_KER_I2C3, _CK_FLEXGEN_13, 0, GATE_I2C3), 1380615f31feSGabriel Fernandez STM32_GATE(_CK_I2C5, CK_KER_I2C5, _CK_FLEXGEN_13, 0, GATE_I2C5), 1381615f31feSGabriel Fernandez STM32_GATE(_CK_I2C4, CK_KER_I2C4, _CK_FLEXGEN_14, 0, GATE_I2C4), 1382615f31feSGabriel Fernandez STM32_GATE(_CK_I2C6, CK_KER_I2C6, _CK_FLEXGEN_14, 0, GATE_I2C6), 1383*088238adSNicolas Le Bayon #endif /* STM32MP25 */ 1384615f31feSGabriel Fernandez STM32_GATE(_CK_I2C7, CK_KER_I2C7, _CK_FLEXGEN_15, 0, GATE_I2C7), 1385615f31feSGabriel Fernandez STM32_GATE(_CK_USART1, CK_KER_USART1, _CK_FLEXGEN_19, 0, GATE_USART1), 1386615f31feSGabriel Fernandez STM32_GATE(_CK_USART6, CK_KER_USART6, _CK_FLEXGEN_20, 0, GATE_USART6), 1387615f31feSGabriel Fernandez STM32_GATE(_CK_UART7, CK_KER_UART7, _CK_FLEXGEN_21, 0, GATE_UART7), 1388*088238adSNicolas Le Bayon #if STM32MP25 1389615f31feSGabriel Fernandez STM32_GATE(_CK_UART8, CK_KER_UART8, _CK_FLEXGEN_21, 0, GATE_UART8), 1390615f31feSGabriel Fernandez STM32_GATE(_CK_UART9, CK_KER_UART9, _CK_FLEXGEN_22, 0, GATE_UART9), 1391*088238adSNicolas Le Bayon #endif /* STM32MP25 */ 1392*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 1393615f31feSGabriel Fernandez STM32_GATE(_CK_STGEN, CK_KER_STGEN, _CK_FLEXGEN_33, 0, GATE_STGEN), 1394*088238adSNicolas Le Bayon #if !STM32MP21 1395615f31feSGabriel Fernandez STM32_GATE(_CK_USB3PCIEPHY, CK_KER_USB3PCIEPHY, _CK_FLEXGEN_34, 0, GATE_USB3PCIEPHY), 1396615f31feSGabriel Fernandez STM32_GATE(_CK_USBTC, CK_KER_USBTC, _CK_FLEXGEN_35, 0, GATE_USBTC), 1397615f31feSGabriel Fernandez STM32_GATE(_CK_I2C8, CK_KER_I2C8, _CK_FLEXGEN_38, 0, GATE_I2C8), 1398*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1399615f31feSGabriel Fernandez STM32_GATE(_CK_OSPI1, CK_KER_OSPI1, _CK_FLEXGEN_48, 0, GATE_OSPI1), 1400*088238adSNicolas Le Bayon #if !STM32MP21 1401615f31feSGabriel Fernandez STM32_GATE(_CK_OSPI2, CK_KER_OSPI2, _CK_FLEXGEN_49, 0, GATE_OSPI2), 1402*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1403615f31feSGabriel Fernandez STM32_GATE(_CK_FMC, CK_KER_FMC, _CK_FLEXGEN_50, 0, GATE_FMC), 1404615f31feSGabriel Fernandez STM32_GATE(_CK_SDMMC1, CK_KER_SDMMC1, _CK_FLEXGEN_51, 0, GATE_SDMMC1), 1405615f31feSGabriel Fernandez STM32_GATE(_CK_SDMMC2, CK_KER_SDMMC2, _CK_FLEXGEN_52, 0, GATE_SDMMC2), 1406615f31feSGabriel Fernandez STM32_GATE(_CK_USB2PHY1, CK_KER_USB2PHY1, _CK_FLEXGEN_57, 0, GATE_USB2PHY1), 1407615f31feSGabriel Fernandez STM32_GATE(_CK_USB2PHY2, CK_KER_USB2PHY2, _CK_FLEXGEN_58, 0, GATE_USB2PHY2), 1408615f31feSGabriel Fernandez }; 1409615f31feSGabriel Fernandez 1410615f31feSGabriel Fernandez enum clksrc_id { 1411615f31feSGabriel Fernandez CLKSRC_CA35SS, 1412615f31feSGabriel Fernandez CLKSRC_PLL1, 1413615f31feSGabriel Fernandez CLKSRC_PLL2, 1414*088238adSNicolas Le Bayon #if !STM32MP21 1415615f31feSGabriel Fernandez CLKSRC_PLL3, 1416*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 1417615f31feSGabriel Fernandez CLKSRC_PLL4, 1418615f31feSGabriel Fernandez CLKSRC_PLL5, 1419615f31feSGabriel Fernandez CLKSRC_PLL6, 1420615f31feSGabriel Fernandez CLKSRC_PLL7, 1421615f31feSGabriel Fernandez CLKSRC_PLL8, 1422615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL0, 1423615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL1, 1424615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL2, 1425615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL3, 1426615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL4, 1427615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL5, 1428615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL6, 1429615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL7, 1430615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL8, 1431615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL9, 1432615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL10, 1433615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL11, 1434615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL12, 1435615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL13, 1436615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL14, 1437615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL15, 1438615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL16, 1439615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL17, 1440615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL18, 1441615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL19, 1442615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL20, 1443615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL21, 1444615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL22, 1445615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL23, 1446615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL24, 1447615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL25, 1448615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL26, 1449615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL27, 1450615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL28, 1451615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL29, 1452615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL30, 1453615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL31, 1454615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL32, 1455615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL33, 1456615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL34, 1457615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL35, 1458615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL36, 1459615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL37, 1460615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL38, 1461615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL39, 1462615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL40, 1463615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL41, 1464615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL42, 1465615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL43, 1466615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL44, 1467615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL45, 1468615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL46, 1469615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL47, 1470615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL48, 1471615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL49, 1472615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL50, 1473615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL51, 1474615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL52, 1475615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL53, 1476615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL54, 1477615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL55, 1478615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL56, 1479615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL57, 1480615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL58, 1481615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL59, 1482615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL60, 1483615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL61, 1484615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL62, 1485615f31feSGabriel Fernandez CLKSRC_XBAR_CHANNEL63, 1486615f31feSGabriel Fernandez CLKSRC_RTC, 1487615f31feSGabriel Fernandez CLKSRC_MCO1, 1488615f31feSGabriel Fernandez CLKSRC_MCO2, 1489615f31feSGabriel Fernandez CLKSRC_NB 1490615f31feSGabriel Fernandez }; 1491615f31feSGabriel Fernandez 1492615f31feSGabriel Fernandez static void stm32mp2_a35_ss_on_hsi(void) 1493615f31feSGabriel Fernandez { 1494615f31feSGabriel Fernandez uintptr_t a35_ss_address = A35SSC_BASE; 1495615f31feSGabriel Fernandez uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ; 1496615f31feSGabriel Fernandez uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE; 1497615f31feSGabriel Fernandez uint64_t timeout; 1498615f31feSGabriel Fernandez 1499615f31feSGabriel Fernandez if ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) == 1500615f31feSGabriel Fernandez A35_SS_CHGCLKREQ_ARM_CHGCLKACK) { 1501615f31feSGabriel Fernandez /* Nothing to do, clock source is already set on bypass clock */ 1502615f31feSGabriel Fernandez return; 1503615f31feSGabriel Fernandez } 1504615f31feSGabriel Fernandez 1505615f31feSGabriel Fernandez mmio_setbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ); 1506615f31feSGabriel Fernandez 1507615f31feSGabriel Fernandez timeout = timeout_init_us(CLKSRC_TIMEOUT); 1508615f31feSGabriel Fernandez while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) != 1509615f31feSGabriel Fernandez A35_SS_CHGCLKREQ_ARM_CHGCLKACK) { 1510615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1511615f31feSGabriel Fernandez EARLY_ERROR("Cannot switch A35 to bypass clock\n"); 1512615f31feSGabriel Fernandez panic(); 1513615f31feSGabriel Fernandez } 1514615f31feSGabriel Fernandez } 1515615f31feSGabriel Fernandez 1516615f31feSGabriel Fernandez mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF); 1517615f31feSGabriel Fernandez } 1518615f31feSGabriel Fernandez 1519615f31feSGabriel Fernandez #ifdef IMAGE_BL2 1520615f31feSGabriel Fernandez static void stm32mp2_clk_muxsel_on_hsi(struct stm32_clk_priv *priv) 1521615f31feSGabriel Fernandez { 1522615f31feSGabriel Fernandez mmio_clrbits_32(priv->base + RCC_MUXSELCFGR, 1523615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL0_MASK | 1524615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL1_MASK | 1525615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL2_MASK | 1526615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL3_MASK | 1527615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL4_MASK | 1528615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL5_MASK | 1529615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL6_MASK | 1530615f31feSGabriel Fernandez RCC_MUXSELCFGR_MUXSEL7_MASK); 1531615f31feSGabriel Fernandez } 1532615f31feSGabriel Fernandez 1533615f31feSGabriel Fernandez static void stm32mp2_clk_xbar_on_hsi(struct stm32_clk_priv *priv) 1534615f31feSGabriel Fernandez { 1535615f31feSGabriel Fernandez uintptr_t xbar0cfgr = priv->base + RCC_XBAR0CFGR; 1536615f31feSGabriel Fernandez uint32_t i; 1537615f31feSGabriel Fernandez 1538615f31feSGabriel Fernandez for (i = 0; i < XBAR_CHANNEL_NB; i++) { 1539615f31feSGabriel Fernandez mmio_clrsetbits_32(xbar0cfgr + (0x4 * i), 1540615f31feSGabriel Fernandez RCC_XBAR0CFGR_XBAR0SEL_MASK, 1541615f31feSGabriel Fernandez XBAR_SRC_HSI); 1542615f31feSGabriel Fernandez } 1543615f31feSGabriel Fernandez } 1544615f31feSGabriel Fernandez 1545615f31feSGabriel Fernandez static int stm32mp2_a35_pll1_start(void) 1546615f31feSGabriel Fernandez { 1547615f31feSGabriel Fernandez uintptr_t a35_ss_address = A35SSC_BASE; 1548615f31feSGabriel Fernandez uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE; 1549615f31feSGabriel Fernandez uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ; 1550615f31feSGabriel Fernandez uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT); 1551615f31feSGabriel Fernandez 1552615f31feSGabriel Fernandez mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD); 1553615f31feSGabriel Fernandez 1554615f31feSGabriel Fernandez /* Wait PLL lock */ 1555615f31feSGabriel Fernandez while ((mmio_read_32(pll_enable_reg) & A35_SS_PLL_ENABLE_LOCKP) == 0U) { 1556615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1557615f31feSGabriel Fernandez EARLY_ERROR("PLL1 start failed @ 0x%lx: 0x%x\n", 1558615f31feSGabriel Fernandez pll_enable_reg, mmio_read_32(pll_enable_reg)); 1559615f31feSGabriel Fernandez return -ETIMEDOUT; 1560615f31feSGabriel Fernandez } 1561615f31feSGabriel Fernandez } 1562615f31feSGabriel Fernandez 1563615f31feSGabriel Fernandez /* De-assert reset on PLL output clock path */ 1564615f31feSGabriel Fernandez mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF); 1565615f31feSGabriel Fernandez 1566615f31feSGabriel Fernandez /* Switch CPU clock to PLL clock */ 1567615f31feSGabriel Fernandez mmio_clrbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ); 1568615f31feSGabriel Fernandez 1569615f31feSGabriel Fernandez /* Wait for clock change acknowledge */ 1570615f31feSGabriel Fernandez timeout = timeout_init_us(CLKSRC_TIMEOUT); 1571615f31feSGabriel Fernandez while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) != 0U) { 1572615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1573615f31feSGabriel Fernandez EARLY_ERROR("CA35SS switch to PLL1 failed @ 0x%lx: 0x%x\n", 1574615f31feSGabriel Fernandez chgclkreq_reg, mmio_read_32(chgclkreq_reg)); 1575615f31feSGabriel Fernandez return -ETIMEDOUT; 1576615f31feSGabriel Fernandez } 1577615f31feSGabriel Fernandez } 1578615f31feSGabriel Fernandez 1579615f31feSGabriel Fernandez return 0; 1580615f31feSGabriel Fernandez } 1581615f31feSGabriel Fernandez 1582615f31feSGabriel Fernandez static void stm32mp2_a35_pll1_config(uint32_t fbdiv, uint32_t refdiv, uint32_t postdiv1, 1583615f31feSGabriel Fernandez uint32_t postdiv2) 1584615f31feSGabriel Fernandez { 1585615f31feSGabriel Fernandez uintptr_t a35_ss_address = A35SSC_BASE; 1586615f31feSGabriel Fernandez uintptr_t pll_freq1_reg = a35_ss_address + A35_SS_PLL_FREQ1; 1587615f31feSGabriel Fernandez uintptr_t pll_freq2_reg = a35_ss_address + A35_SS_PLL_FREQ2; 1588615f31feSGabriel Fernandez 1589615f31feSGabriel Fernandez mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_REFDIV_MASK, 1590615f31feSGabriel Fernandez (refdiv << A35_SS_PLL_FREQ1_REFDIV_SHIFT) & 1591615f31feSGabriel Fernandez A35_SS_PLL_FREQ1_REFDIV_MASK); 1592615f31feSGabriel Fernandez 1593615f31feSGabriel Fernandez mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_FBDIV_MASK, 1594615f31feSGabriel Fernandez (fbdiv << A35_SS_PLL_FREQ1_FBDIV_SHIFT) & 1595615f31feSGabriel Fernandez A35_SS_PLL_FREQ1_FBDIV_MASK); 1596615f31feSGabriel Fernandez 1597615f31feSGabriel Fernandez mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV1_MASK, 1598615f31feSGabriel Fernandez (postdiv1 << A35_SS_PLL_FREQ2_POSTDIV1_SHIFT) & 1599615f31feSGabriel Fernandez A35_SS_PLL_FREQ2_POSTDIV1_MASK); 1600615f31feSGabriel Fernandez 1601615f31feSGabriel Fernandez mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV2_MASK, 1602615f31feSGabriel Fernandez (postdiv2 << A35_SS_PLL_FREQ2_POSTDIV2_SHIFT) & 1603615f31feSGabriel Fernandez A35_SS_PLL_FREQ2_POSTDIV2_MASK); 1604615f31feSGabriel Fernandez } 1605615f31feSGabriel Fernandez 1606615f31feSGabriel Fernandez static int clk_stm32_pll_config_output(struct stm32_clk_priv *priv, 1607615f31feSGabriel Fernandez const struct stm32_clk_pll *pll, 1608615f31feSGabriel Fernandez uint32_t *pllcfg, 1609615f31feSGabriel Fernandez uint32_t fracv) 1610615f31feSGabriel Fernandez { 1611615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 1612615f31feSGabriel Fernandez uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2; 1613615f31feSGabriel Fernandez uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3; 1614615f31feSGabriel Fernandez uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4; 1615615f31feSGabriel Fernandez uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6; 1616615f31feSGabriel Fernandez uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7; 1617615f31feSGabriel Fernandez unsigned long refclk; 1618615f31feSGabriel Fernandez 1619615f31feSGabriel Fernandez refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id); 1620615f31feSGabriel Fernandez 1621615f31feSGabriel Fernandez if (fracv == 0U) { 1622615f31feSGabriel Fernandez /* PLL in integer mode */ 1623615f31feSGabriel Fernandez 1624615f31feSGabriel Fernandez /* 1625615f31feSGabriel Fernandez * No need to check max clock, as oscillator reference clocks 1626615f31feSGabriel Fernandez * will always be less than 1.2GHz 1627615f31feSGabriel Fernandez */ 1628615f31feSGabriel Fernandez if (refclk < PLL_REFCLK_MIN) { 1629615f31feSGabriel Fernandez panic(); 1630615f31feSGabriel Fernandez } 1631615f31feSGabriel Fernandez 1632615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK); 1633615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN); 1634615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN); 1635615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS); 1636615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST); 1637615f31feSGabriel Fernandez } else { 1638615f31feSGabriel Fernandez /* PLL in frac mode */ 1639615f31feSGabriel Fernandez 1640615f31feSGabriel Fernandez /* 1641615f31feSGabriel Fernandez * No need to check max clock, as oscillator reference clocks 1642615f31feSGabriel Fernandez * will always be less than 1.2GHz 1643615f31feSGabriel Fernandez */ 1644615f31feSGabriel Fernandez if (refclk < PLL_FRAC_REFCLK_MIN) { 1645615f31feSGabriel Fernandez panic(); 1646615f31feSGabriel Fernandez } 1647615f31feSGabriel Fernandez 1648615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK, 1649615f31feSGabriel Fernandez fracv & RCC_PLLxCFGR3_FRACIN_MASK); 1650615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS); 1651615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN); 1652615f31feSGabriel Fernandez } 1653615f31feSGabriel Fernandez 1654615f31feSGabriel Fernandez assert(pllcfg[REFDIV] != 0U); 1655615f31feSGabriel Fernandez 1656615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FBDIV_MASK, 1657615f31feSGabriel Fernandez (pllcfg[FBDIV] << RCC_PLLxCFGR2_FBDIV_SHIFT) & 1658615f31feSGabriel Fernandez RCC_PLLxCFGR2_FBDIV_MASK); 1659615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FREFDIV_MASK, 1660615f31feSGabriel Fernandez pllcfg[REFDIV] & RCC_PLLxCFGR2_FREFDIV_MASK); 1661615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr6, RCC_PLLxCFGR6_POSTDIV1_MASK, 1662615f31feSGabriel Fernandez pllcfg[POSTDIV1] & RCC_PLLxCFGR6_POSTDIV1_MASK); 1663615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr7, RCC_PLLxCFGR7_POSTDIV2_MASK, 1664615f31feSGabriel Fernandez pllcfg[POSTDIV2] & RCC_PLLxCFGR7_POSTDIV2_MASK); 1665615f31feSGabriel Fernandez 1666615f31feSGabriel Fernandez if ((pllcfg[POSTDIV1] == 0U) || (pllcfg[POSTDIV2] == 0U)) { 1667615f31feSGabriel Fernandez /* Bypass mode */ 1668615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS); 1669615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN); 1670615f31feSGabriel Fernandez } else { 1671615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS); 1672615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN); 1673615f31feSGabriel Fernandez } 1674615f31feSGabriel Fernandez 1675615f31feSGabriel Fernandez return 0; 1676615f31feSGabriel Fernandez } 1677615f31feSGabriel Fernandez 1678615f31feSGabriel Fernandez static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv, 1679615f31feSGabriel Fernandez const struct stm32_clk_pll *pll, 1680615f31feSGabriel Fernandez uint32_t *csg) 1681615f31feSGabriel Fernandez { 1682615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 1683615f31feSGabriel Fernandez uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3; 1684615f31feSGabriel Fernandez uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4; 1685615f31feSGabriel Fernandez uintptr_t pllxcfgr5 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR5; 1686615f31feSGabriel Fernandez 1687615f31feSGabriel Fernandez 1688615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_DIVVAL_MASK, 1689615f31feSGabriel Fernandez csg[DIVVAL] & RCC_PLLxCFGR5_DIVVAL_MASK); 1690615f31feSGabriel Fernandez mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_SPREAD_MASK, 1691615f31feSGabriel Fernandez (csg[SPREAD] << RCC_PLLxCFGR5_SPREAD_SHIFT) & 1692615f31feSGabriel Fernandez RCC_PLLxCFGR5_SPREAD_MASK); 1693615f31feSGabriel Fernandez 1694615f31feSGabriel Fernandez if (csg[DOWNSPREAD] != 0) { 1695615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD); 1696615f31feSGabriel Fernandez } else { 1697615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD); 1698615f31feSGabriel Fernandez } 1699615f31feSGabriel Fernandez 1700615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS); 1701615f31feSGabriel Fernandez 1702615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN); 1703615f31feSGabriel Fernandez udelay(1); 1704615f31feSGabriel Fernandez 1705615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN); 1706615f31feSGabriel Fernandez mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN); 1707615f31feSGabriel Fernandez } 1708615f31feSGabriel Fernandez 1709615f31feSGabriel Fernandez static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data); 1710615f31feSGabriel Fernandez 1711615f31feSGabriel Fernandez static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx) 1712615f31feSGabriel Fernandez { 1713615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1714615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 1715615f31feSGabriel Fernandez 1716615f31feSGabriel Fernandez return &pdata->pll[pll_idx]; 1717615f31feSGabriel Fernandez } 1718615f31feSGabriel Fernandez 1719615f31feSGabriel Fernandez static int _clk_stm32_pll1_init(struct stm32_clk_priv *priv, int pll_idx, 1720615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf) 1721615f31feSGabriel Fernandez { 1722615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx); 1723615f31feSGabriel Fernandez unsigned long refclk; 1724615f31feSGabriel Fernandez int ret = 0; 1725615f31feSGabriel Fernandez 1726615f31feSGabriel Fernandez stm32mp2_a35_ss_on_hsi(); 1727615f31feSGabriel Fernandez 1728615f31feSGabriel Fernandez ret = stm32_clk_configure_mux(priv, pll_conf->src); 1729615f31feSGabriel Fernandez if (ret != 0) { 1730615f31feSGabriel Fernandez panic(); 1731615f31feSGabriel Fernandez } 1732615f31feSGabriel Fernandez 1733615f31feSGabriel Fernandez refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id); 1734615f31feSGabriel Fernandez 1735615f31feSGabriel Fernandez /* 1736615f31feSGabriel Fernandez * No need to check max clock, as oscillator reference clocks will 1737615f31feSGabriel Fernandez * always be less than 1.2 GHz 1738615f31feSGabriel Fernandez */ 1739615f31feSGabriel Fernandez if (refclk < PLL_REFCLK_MIN) { 1740615f31feSGabriel Fernandez EARLY_ERROR("%s: %d\n", __func__, __LINE__); 1741615f31feSGabriel Fernandez panic(); 1742615f31feSGabriel Fernandez } 1743615f31feSGabriel Fernandez 1744615f31feSGabriel Fernandez stm32mp2_a35_pll1_config(pll_conf->cfg[FBDIV], pll_conf->cfg[REFDIV], 1745615f31feSGabriel Fernandez pll_conf->cfg[POSTDIV1], pll_conf->cfg[POSTDIV2]); 1746615f31feSGabriel Fernandez 1747615f31feSGabriel Fernandez ret = stm32mp2_a35_pll1_start(); 1748615f31feSGabriel Fernandez if (ret != 0) { 1749615f31feSGabriel Fernandez panic(); 1750615f31feSGabriel Fernandez } 1751615f31feSGabriel Fernandez 1752615f31feSGabriel Fernandez return 0; 1753615f31feSGabriel Fernandez } 1754615f31feSGabriel Fernandez 1755615f31feSGabriel Fernandez static int clk_stm32_pll_wait_mux_ready(struct stm32_clk_priv *priv, 1756615f31feSGabriel Fernandez const struct stm32_clk_pll *pll) 1757615f31feSGabriel Fernandez { 1758615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 1759615f31feSGabriel Fernandez uint64_t timeout = timeout_init_us(CLKSRC_TIMEOUT); 1760615f31feSGabriel Fernandez 1761615f31feSGabriel Fernandez while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_CKREFST) != 1762615f31feSGabriel Fernandez RCC_PLLxCFGR1_CKREFST) { 1763615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1764615f31feSGabriel Fernandez EARLY_ERROR("PLL%d ref clock not started\n", pll->clk_id - _CK_PLL1 + 1); 1765615f31feSGabriel Fernandez return -ETIMEDOUT; 1766615f31feSGabriel Fernandez } 1767615f31feSGabriel Fernandez } 1768615f31feSGabriel Fernandez 1769615f31feSGabriel Fernandez return 0; 1770615f31feSGabriel Fernandez } 1771615f31feSGabriel Fernandez 1772615f31feSGabriel Fernandez static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx, 1773615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf) 1774615f31feSGabriel Fernandez { 1775615f31feSGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx); 1776615f31feSGabriel Fernandez uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1; 1777615f31feSGabriel Fernandez bool spread_spectrum = false; 1778615f31feSGabriel Fernandez int ret = 0; 1779615f31feSGabriel Fernandez 1780615f31feSGabriel Fernandez _clk_stm32_pll_disable(priv, pll); 1781615f31feSGabriel Fernandez 1782615f31feSGabriel Fernandez ret = stm32_clk_configure_mux(priv, pll_conf->src); 1783615f31feSGabriel Fernandez if (ret != 0) { 1784615f31feSGabriel Fernandez panic(); 1785615f31feSGabriel Fernandez } 1786615f31feSGabriel Fernandez 1787615f31feSGabriel Fernandez ret = clk_stm32_pll_wait_mux_ready(priv, pll); 1788615f31feSGabriel Fernandez if (ret != 0) { 1789615f31feSGabriel Fernandez panic(); 1790615f31feSGabriel Fernandez } 1791615f31feSGabriel Fernandez 1792615f31feSGabriel Fernandez ret = clk_stm32_pll_config_output(priv, pll, pll_conf->cfg, pll_conf->frac); 1793615f31feSGabriel Fernandez if (ret != 0) { 1794615f31feSGabriel Fernandez panic(); 1795615f31feSGabriel Fernandez } 1796615f31feSGabriel Fernandez 1797615f31feSGabriel Fernandez if (pll_conf->csg_enabled) { 1798615f31feSGabriel Fernandez clk_stm32_pll_config_csg(priv, pll, pll_conf->csg); 1799615f31feSGabriel Fernandez spread_spectrum = true; 1800615f31feSGabriel Fernandez } 1801615f31feSGabriel Fernandez 1802615f31feSGabriel Fernandez _clk_stm32_pll_enable(priv, pll); 1803615f31feSGabriel Fernandez 1804615f31feSGabriel Fernandez if (spread_spectrum) { 1805615f31feSGabriel Fernandez mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST); 1806615f31feSGabriel Fernandez } 1807615f31feSGabriel Fernandez 1808615f31feSGabriel Fernandez return 0; 1809615f31feSGabriel Fernandez } 1810615f31feSGabriel Fernandez 1811615f31feSGabriel Fernandez static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx) 1812615f31feSGabriel Fernandez { 1813615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx); 1814615f31feSGabriel Fernandez 1815615f31feSGabriel Fernandez if (pll_conf->enabled) { 1816615f31feSGabriel Fernandez if (pll_idx == _PLL1) { 1817615f31feSGabriel Fernandez return _clk_stm32_pll1_init(priv, pll_idx, pll_conf); 1818615f31feSGabriel Fernandez } else { 1819615f31feSGabriel Fernandez return _clk_stm32_pll_init(priv, pll_idx, pll_conf); 1820615f31feSGabriel Fernandez } 1821615f31feSGabriel Fernandez } 1822615f31feSGabriel Fernandez 1823615f31feSGabriel Fernandez return 0; 1824615f31feSGabriel Fernandez } 1825615f31feSGabriel Fernandez 1826615f31feSGabriel Fernandez static int stm32mp2_clk_pll_configure(struct stm32_clk_priv *priv) 1827615f31feSGabriel Fernandez { 1828615f31feSGabriel Fernandez enum pll_id i; 1829615f31feSGabriel Fernandez int err; 1830615f31feSGabriel Fernandez 1831615f31feSGabriel Fernandez for (i = _PLL1; i < _PLL_NB; i++) { 1832*088238adSNicolas Le Bayon #if STM32MP21 1833*088238adSNicolas Le Bayon if (i == _PLL3) { 1834*088238adSNicolas Le Bayon continue; 1835*088238adSNicolas Le Bayon } 1836*088238adSNicolas Le Bayon #endif 1837615f31feSGabriel Fernandez err = clk_stm32_pll_init(priv, i); 1838615f31feSGabriel Fernandez if (err) { 1839615f31feSGabriel Fernandez return err; 1840615f31feSGabriel Fernandez } 1841615f31feSGabriel Fernandez } 1842615f31feSGabriel Fernandez 1843615f31feSGabriel Fernandez return 0; 1844615f31feSGabriel Fernandez } 1845615f31feSGabriel Fernandez 1846615f31feSGabriel Fernandez static int wait_predivsr(uint16_t channel) 1847615f31feSGabriel Fernandez { 1848615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1849615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1850615f31feSGabriel Fernandez uintptr_t previvsr; 1851615f31feSGabriel Fernandez uint32_t channel_bit; 1852615f31feSGabriel Fernandez uint64_t timeout; 1853615f31feSGabriel Fernandez 1854615f31feSGabriel Fernandez if (channel < __WORD_BIT) { 1855615f31feSGabriel Fernandez previvsr = rcc_base + RCC_PREDIVSR1; 1856615f31feSGabriel Fernandez channel_bit = BIT(channel); 1857615f31feSGabriel Fernandez } else { 1858615f31feSGabriel Fernandez previvsr = rcc_base + RCC_PREDIVSR2; 1859615f31feSGabriel Fernandez channel_bit = BIT(channel - __WORD_BIT); 1860615f31feSGabriel Fernandez } 1861615f31feSGabriel Fernandez 1862615f31feSGabriel Fernandez timeout = timeout_init_us(CLKDIV_TIMEOUT); 1863615f31feSGabriel Fernandez while ((mmio_read_32(previvsr) & channel_bit) != 0U) { 1864615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1865615f31feSGabriel Fernandez EARLY_ERROR("Pre divider status: %x\n", 1866615f31feSGabriel Fernandez mmio_read_32(previvsr)); 1867615f31feSGabriel Fernandez return -ETIMEDOUT; 1868615f31feSGabriel Fernandez } 1869615f31feSGabriel Fernandez } 1870615f31feSGabriel Fernandez 1871615f31feSGabriel Fernandez return 0; 1872615f31feSGabriel Fernandez } 1873615f31feSGabriel Fernandez 1874615f31feSGabriel Fernandez static int wait_findivsr(uint16_t channel) 1875615f31feSGabriel Fernandez { 1876615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1877615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1878615f31feSGabriel Fernandez uintptr_t finvivsr; 1879615f31feSGabriel Fernandez uint32_t channel_bit; 1880615f31feSGabriel Fernandez uint64_t timeout; 1881615f31feSGabriel Fernandez 1882615f31feSGabriel Fernandez if (channel < __WORD_BIT) { 1883615f31feSGabriel Fernandez finvivsr = rcc_base + RCC_FINDIVSR1; 1884615f31feSGabriel Fernandez channel_bit = BIT(channel); 1885615f31feSGabriel Fernandez } else { 1886615f31feSGabriel Fernandez finvivsr = rcc_base + RCC_FINDIVSR2; 1887615f31feSGabriel Fernandez channel_bit = BIT(channel - __WORD_BIT); 1888615f31feSGabriel Fernandez } 1889615f31feSGabriel Fernandez 1890615f31feSGabriel Fernandez timeout = timeout_init_us(CLKDIV_TIMEOUT); 1891615f31feSGabriel Fernandez while ((mmio_read_32(finvivsr) & channel_bit) != 0U) { 1892615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1893615f31feSGabriel Fernandez EARLY_ERROR("Final divider status: %x\n", 1894615f31feSGabriel Fernandez mmio_read_32(finvivsr)); 1895615f31feSGabriel Fernandez return -ETIMEDOUT; 1896615f31feSGabriel Fernandez } 1897615f31feSGabriel Fernandez } 1898615f31feSGabriel Fernandez 1899615f31feSGabriel Fernandez return 0; 1900615f31feSGabriel Fernandez } 1901615f31feSGabriel Fernandez 1902615f31feSGabriel Fernandez static int wait_xbar_sts(uint16_t channel) 1903615f31feSGabriel Fernandez { 1904615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1905615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1906615f31feSGabriel Fernandez uintptr_t xbar_cfgr = rcc_base + RCC_XBAR0CFGR + (0x4U * channel); 1907615f31feSGabriel Fernandez uint64_t timeout; 1908615f31feSGabriel Fernandez 1909615f31feSGabriel Fernandez timeout = timeout_init_us(CLKDIV_TIMEOUT); 1910615f31feSGabriel Fernandez while ((mmio_read_32(xbar_cfgr) & RCC_XBAR0CFGR_XBAR0STS) != 0U) { 1911615f31feSGabriel Fernandez if (timeout_elapsed(timeout)) { 1912615f31feSGabriel Fernandez EARLY_ERROR("XBAR%uCFGR: %x\n", channel, 1913615f31feSGabriel Fernandez mmio_read_32(xbar_cfgr)); 1914615f31feSGabriel Fernandez return -ETIMEDOUT; 1915615f31feSGabriel Fernandez } 1916615f31feSGabriel Fernandez } 1917615f31feSGabriel Fernandez 1918615f31feSGabriel Fernandez return 0; 1919615f31feSGabriel Fernandez } 1920615f31feSGabriel Fernandez 1921615f31feSGabriel Fernandez static void flexclkgen_config_channel(uint16_t channel, unsigned int clk_src, 1922615f31feSGabriel Fernandez unsigned int prediv, unsigned int findiv) 1923615f31feSGabriel Fernandez { 1924615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1925615f31feSGabriel Fernandez uintptr_t rcc_base = priv->base; 1926615f31feSGabriel Fernandez 1927615f31feSGabriel Fernandez if (wait_predivsr(channel) != 0) { 1928615f31feSGabriel Fernandez panic(); 1929615f31feSGabriel Fernandez } 1930615f31feSGabriel Fernandez 1931615f31feSGabriel Fernandez mmio_clrsetbits_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel), 1932615f31feSGabriel Fernandez RCC_PREDIV0CFGR_PREDIV0_MASK, 1933615f31feSGabriel Fernandez prediv); 1934615f31feSGabriel Fernandez 1935615f31feSGabriel Fernandez if (wait_predivsr(channel) != 0) { 1936615f31feSGabriel Fernandez panic(); 1937615f31feSGabriel Fernandez } 1938615f31feSGabriel Fernandez 1939615f31feSGabriel Fernandez if (wait_findivsr(channel) != 0) { 1940615f31feSGabriel Fernandez panic(); 1941615f31feSGabriel Fernandez } 1942615f31feSGabriel Fernandez 1943615f31feSGabriel Fernandez mmio_clrsetbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel), 1944615f31feSGabriel Fernandez RCC_FINDIV0CFGR_FINDIV0_MASK, 1945615f31feSGabriel Fernandez findiv); 1946615f31feSGabriel Fernandez 1947615f31feSGabriel Fernandez if (wait_findivsr(channel) != 0) { 1948615f31feSGabriel Fernandez panic(); 1949615f31feSGabriel Fernandez } 1950615f31feSGabriel Fernandez 1951615f31feSGabriel Fernandez if (wait_xbar_sts(channel) != 0) { 1952615f31feSGabriel Fernandez panic(); 1953615f31feSGabriel Fernandez } 1954615f31feSGabriel Fernandez 1955615f31feSGabriel Fernandez mmio_clrsetbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel), 1956615f31feSGabriel Fernandez RCC_XBARxCFGR_XBARxSEL_MASK, 1957615f31feSGabriel Fernandez clk_src); 1958615f31feSGabriel Fernandez mmio_setbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel), 1959615f31feSGabriel Fernandez RCC_XBARxCFGR_XBARxEN); 1960615f31feSGabriel Fernandez 1961615f31feSGabriel Fernandez if (wait_xbar_sts(channel) != 0) { 1962615f31feSGabriel Fernandez panic(); 1963615f31feSGabriel Fernandez } 1964615f31feSGabriel Fernandez } 1965615f31feSGabriel Fernandez 1966615f31feSGabriel Fernandez static int stm32mp2_clk_flexgen_configure(struct stm32_clk_priv *priv) 1967615f31feSGabriel Fernandez { 1968615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 1969615f31feSGabriel Fernandez uint32_t i; 1970615f31feSGabriel Fernandez 1971615f31feSGabriel Fernandez for (i = 0U; i < pdata->nflexgen; i++) { 1972615f31feSGabriel Fernandez uint32_t val = pdata->flexgen[i]; 1973615f31feSGabriel Fernandez uint32_t cmd, cmd_data; 1974615f31feSGabriel Fernandez unsigned int channel, clk_src, pdiv, fdiv; 1975615f31feSGabriel Fernandez 1976615f31feSGabriel Fernandez cmd = (val & CMD_MASK) >> CMD_SHIFT; 1977615f31feSGabriel Fernandez cmd_data = val & ~CMD_MASK; 1978615f31feSGabriel Fernandez 1979615f31feSGabriel Fernandez if (cmd != CMD_FLEXGEN) { 1980615f31feSGabriel Fernandez continue; 1981615f31feSGabriel Fernandez } 1982615f31feSGabriel Fernandez 1983615f31feSGabriel Fernandez channel = (cmd_data & FLEX_ID_MASK) >> FLEX_ID_SHIFT; 1984615f31feSGabriel Fernandez clk_src = (cmd_data & FLEX_SEL_MASK) >> FLEX_SEL_SHIFT; 1985615f31feSGabriel Fernandez pdiv = (cmd_data & FLEX_PDIV_MASK) >> FLEX_PDIV_SHIFT; 1986615f31feSGabriel Fernandez fdiv = (cmd_data & FLEX_FDIV_MASK) >> FLEX_FDIV_SHIFT; 1987615f31feSGabriel Fernandez 1988615f31feSGabriel Fernandez switch (channel) { 1989615f31feSGabriel Fernandez case 33U: /* STGEN */ 1990615f31feSGabriel Fernandez break; 1991615f31feSGabriel Fernandez 1992615f31feSGabriel Fernandez default: 1993615f31feSGabriel Fernandez flexclkgen_config_channel(channel, clk_src, pdiv, fdiv); 1994615f31feSGabriel Fernandez break; 1995615f31feSGabriel Fernandez } 1996615f31feSGabriel Fernandez } 1997615f31feSGabriel Fernandez 1998615f31feSGabriel Fernandez return 0; 1999615f31feSGabriel Fernandez } 2000615f31feSGabriel Fernandez 2001615f31feSGabriel Fernandez static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv) 2002615f31feSGabriel Fernandez { 2003615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2004615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE]; 2005615f31feSGabriel Fernandez bool digbyp = osci->digbyp; 2006615f31feSGabriel Fernandez bool bypass = osci->bypass; 2007615f31feSGabriel Fernandez bool css = osci->css; 2008615f31feSGabriel Fernandez 2009615f31feSGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) { 2010615f31feSGabriel Fernandez return; 2011615f31feSGabriel Fernandez } 2012615f31feSGabriel Fernandez 2013615f31feSGabriel Fernandez clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass); 2014615f31feSGabriel Fernandez 2015615f31feSGabriel Fernandez _clk_stm32_enable(priv, _CK_HSE); 2016615f31feSGabriel Fernandez 2017615f31feSGabriel Fernandez clk_oscillator_set_css(priv, _CK_HSE, css); 2018615f31feSGabriel Fernandez } 2019615f31feSGabriel Fernandez 2020615f31feSGabriel Fernandez static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv) 2021615f31feSGabriel Fernandez { 2022615f31feSGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE); 2023615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2024615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE]; 2025615f31feSGabriel Fernandez bool digbyp = osci->digbyp; 2026615f31feSGabriel Fernandez bool bypass = osci->bypass; 2027615f31feSGabriel Fernandez uint8_t drive = osci->drive; 2028615f31feSGabriel Fernandez 2029615f31feSGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) { 2030615f31feSGabriel Fernandez return; 2031615f31feSGabriel Fernandez } 2032615f31feSGabriel Fernandez 2033615f31feSGabriel Fernandez /* Do not reconfigure LSE if already enabled */ 2034615f31feSGabriel Fernandez if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) { 2035615f31feSGabriel Fernandez return; 2036615f31feSGabriel Fernandez } 2037615f31feSGabriel Fernandez 2038615f31feSGabriel Fernandez clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass); 2039615f31feSGabriel Fernandez 2040615f31feSGabriel Fernandez clk_oscillator_set_drive(priv, _CK_LSE, drive); 2041615f31feSGabriel Fernandez 2042615f31feSGabriel Fernandez _clk_stm32_gate_enable(priv, osc_data->gate_id); 2043615f31feSGabriel Fernandez } 2044615f31feSGabriel Fernandez 2045615f31feSGabriel Fernandez static int stm32mp2_clk_switch_to_hsi(struct stm32_clk_priv *priv) 2046615f31feSGabriel Fernandez { 2047615f31feSGabriel Fernandez stm32mp2_a35_ss_on_hsi(); 2048615f31feSGabriel Fernandez stm32mp2_clk_muxsel_on_hsi(priv); 2049615f31feSGabriel Fernandez stm32mp2_clk_xbar_on_hsi(priv); 2050615f31feSGabriel Fernandez 2051615f31feSGabriel Fernandez return 0; 2052615f31feSGabriel Fernandez } 2053615f31feSGabriel Fernandez 2054615f31feSGabriel Fernandez static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv) 2055615f31feSGabriel Fernandez { 2056615f31feSGabriel Fernandez int ret = 0; 2057615f31feSGabriel Fernandez 2058615f31feSGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) { 2059615f31feSGabriel Fernandez ret = clk_oscillator_wait_ready_on(priv, _CK_LSE); 2060615f31feSGabriel Fernandez } 2061615f31feSGabriel Fernandez 2062615f31feSGabriel Fernandez return ret; 2063615f31feSGabriel Fernandez } 2064615f31feSGabriel Fernandez 2065615f31feSGabriel Fernandez static void stm32_enable_oscillator_msi(struct stm32_clk_priv *priv) 2066615f31feSGabriel Fernandez { 2067*088238adSNicolas Le Bayon #if !STM32MP21 2068615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2069615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_MSI]; 2070615f31feSGabriel Fernandez int err; 2071615f31feSGabriel Fernandez 2072615f31feSGabriel Fernandez err = clk_stm32_osc_msi_set_rate(priv, _CK_MSI, osci->freq, 0); 2073615f31feSGabriel Fernandez if (err != 0) { 2074615f31feSGabriel Fernandez EARLY_ERROR("Invalid rate %lu MHz for MSI ! (4 or 16 only)\n", 2075615f31feSGabriel Fernandez osci->freq / 1000000U); 2076615f31feSGabriel Fernandez panic(); 2077615f31feSGabriel Fernandez } 2078*088238adSNicolas Le Bayon #endif /* !STM32MP21 */ 2079615f31feSGabriel Fernandez 2080615f31feSGabriel Fernandez _clk_stm32_enable(priv, _CK_MSI); 2081615f31feSGabriel Fernandez } 2082615f31feSGabriel Fernandez 2083615f31feSGabriel Fernandez static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv) 2084615f31feSGabriel Fernandez { 2085615f31feSGabriel Fernandez stm32_enable_oscillator_hse(priv); 2086615f31feSGabriel Fernandez stm32_enable_oscillator_lse(priv); 2087615f31feSGabriel Fernandez stm32_enable_oscillator_msi(priv); 2088615f31feSGabriel Fernandez _clk_stm32_enable(priv, _CK_LSI); 2089615f31feSGabriel Fernandez } 2090615f31feSGabriel Fernandez 2091615f31feSGabriel Fernandez static int stm32_clk_configure_div(struct stm32_clk_priv *priv, uint32_t data) 2092615f31feSGabriel Fernandez { 2093615f31feSGabriel Fernandez int div_id = (data & DIV_ID_MASK) >> DIV_ID_SHIFT; 2094615f31feSGabriel Fernandez int div_n = (data & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT; 2095615f31feSGabriel Fernandez 2096615f31feSGabriel Fernandez return clk_stm32_set_div(priv, div_id, div_n); 2097615f31feSGabriel Fernandez } 2098615f31feSGabriel Fernandez 2099615f31feSGabriel Fernandez static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data) 2100615f31feSGabriel Fernandez { 2101615f31feSGabriel Fernandez int mux_id = (data & MUX_ID_MASK) >> MUX_ID_SHIFT; 2102615f31feSGabriel Fernandez int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT; 2103615f31feSGabriel Fernandez 2104615f31feSGabriel Fernandez return clk_mux_set_parent(priv, mux_id, sel); 2105615f31feSGabriel Fernandez } 2106615f31feSGabriel Fernandez 2107615f31feSGabriel Fernandez static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data) 2108615f31feSGabriel Fernandez { 2109615f31feSGabriel Fernandez unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT; 2110615f31feSGabriel Fernandez 2111615f31feSGabriel Fernandez return clk_get_index(priv, binding_id); 2112615f31feSGabriel Fernandez } 2113615f31feSGabriel Fernandez 2114615f31feSGabriel Fernandez static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data) 2115615f31feSGabriel Fernandez { 2116615f31feSGabriel Fernandez int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT; 2117615f31feSGabriel Fernandez bool enable = ((data & CLK_ON_MASK) >> CLK_ON_SHIFT) != 0U; 2118615f31feSGabriel Fernandez int clk_id = 0; 2119615f31feSGabriel Fernandez int ret = 0; 2120615f31feSGabriel Fernandez 2121615f31feSGabriel Fernandez clk_id = stm32_clk_configure_clk_get_binding_id(priv, data); 2122615f31feSGabriel Fernandez if (clk_id < 0) { 2123615f31feSGabriel Fernandez return clk_id; 2124615f31feSGabriel Fernandez } 2125615f31feSGabriel Fernandez 2126615f31feSGabriel Fernandez if (sel != CLK_NOMUX) { 2127615f31feSGabriel Fernandez ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel); 2128615f31feSGabriel Fernandez if (ret != 0) { 2129615f31feSGabriel Fernandez return ret; 2130615f31feSGabriel Fernandez } 2131615f31feSGabriel Fernandez } 2132615f31feSGabriel Fernandez 2133615f31feSGabriel Fernandez if (enable) { 2134615f31feSGabriel Fernandez clk_stm32_enable_call_ops(priv, clk_id); 2135615f31feSGabriel Fernandez } else { 2136615f31feSGabriel Fernandez clk_stm32_disable_call_ops(priv, clk_id); 2137615f31feSGabriel Fernandez } 2138615f31feSGabriel Fernandez 2139615f31feSGabriel Fernandez return 0; 2140615f31feSGabriel Fernandez } 2141615f31feSGabriel Fernandez 2142615f31feSGabriel Fernandez static int stm32_clk_configure(struct stm32_clk_priv *priv, uint32_t val) 2143615f31feSGabriel Fernandez { 2144615f31feSGabriel Fernandez uint32_t cmd = (val & CMD_MASK) >> CMD_SHIFT; 2145615f31feSGabriel Fernandez uint32_t cmd_data = val & ~CMD_MASK; 2146615f31feSGabriel Fernandez int ret = -1; 2147615f31feSGabriel Fernandez 2148615f31feSGabriel Fernandez switch (cmd) { 2149615f31feSGabriel Fernandez case CMD_DIV: 2150615f31feSGabriel Fernandez ret = stm32_clk_configure_div(priv, cmd_data); 2151615f31feSGabriel Fernandez break; 2152615f31feSGabriel Fernandez 2153615f31feSGabriel Fernandez case CMD_MUX: 2154615f31feSGabriel Fernandez ret = stm32_clk_configure_mux(priv, cmd_data); 2155615f31feSGabriel Fernandez break; 2156615f31feSGabriel Fernandez 2157615f31feSGabriel Fernandez case CMD_CLK: 2158615f31feSGabriel Fernandez ret = stm32_clk_configure_clk(priv, cmd_data); 2159615f31feSGabriel Fernandez break; 2160615f31feSGabriel Fernandez 2161615f31feSGabriel Fernandez default: 2162615f31feSGabriel Fernandez EARLY_ERROR("%s: cmd unknown ! : 0x%x\n", __func__, val); 2163615f31feSGabriel Fernandez break; 2164615f31feSGabriel Fernandez } 2165615f31feSGabriel Fernandez 2166615f31feSGabriel Fernandez return ret; 2167615f31feSGabriel Fernandez } 2168615f31feSGabriel Fernandez 2169615f31feSGabriel Fernandez static int stm32_clk_bus_configure(struct stm32_clk_priv *priv) 2170615f31feSGabriel Fernandez { 2171615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2172615f31feSGabriel Fernandez uint32_t i; 2173615f31feSGabriel Fernandez 2174615f31feSGabriel Fernandez for (i = 0; i < pdata->nbusclk; i++) { 2175615f31feSGabriel Fernandez int ret; 2176615f31feSGabriel Fernandez 2177615f31feSGabriel Fernandez ret = stm32_clk_configure(priv, pdata->busclk[i]); 2178615f31feSGabriel Fernandez if (ret != 0) { 2179615f31feSGabriel Fernandez return ret; 2180615f31feSGabriel Fernandez } 2181615f31feSGabriel Fernandez } 2182615f31feSGabriel Fernandez 2183615f31feSGabriel Fernandez return 0; 2184615f31feSGabriel Fernandez } 2185615f31feSGabriel Fernandez 2186615f31feSGabriel Fernandez static int stm32_clk_kernel_configure(struct stm32_clk_priv *priv) 2187615f31feSGabriel Fernandez { 2188615f31feSGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 2189615f31feSGabriel Fernandez uint32_t i; 2190615f31feSGabriel Fernandez 2191615f31feSGabriel Fernandez for (i = 0U; i < pdata->nkernelclk; i++) { 2192615f31feSGabriel Fernandez int ret; 2193615f31feSGabriel Fernandez 2194615f31feSGabriel Fernandez ret = stm32_clk_configure(priv, pdata->kernelclk[i]); 2195615f31feSGabriel Fernandez if (ret != 0) { 2196615f31feSGabriel Fernandez return ret; 2197615f31feSGabriel Fernandez } 2198615f31feSGabriel Fernandez } 2199615f31feSGabriel Fernandez 2200615f31feSGabriel Fernandez return 0; 2201615f31feSGabriel Fernandez } 2202615f31feSGabriel Fernandez 2203615f31feSGabriel Fernandez static int stm32mp2_init_clock_tree(void) 2204615f31feSGabriel Fernandez { 2205615f31feSGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 2206615f31feSGabriel Fernandez int ret; 2207615f31feSGabriel Fernandez 2208615f31feSGabriel Fernandez /* Set timer with STGEN without changing its clock source */ 2209615f31feSGabriel Fernandez stm32mp_stgen_restore_rate(); 2210615f31feSGabriel Fernandez generic_delay_timer_init(); 2211615f31feSGabriel Fernandez 2212615f31feSGabriel Fernandez stm32_clk_oscillators_enable(priv); 2213615f31feSGabriel Fernandez 2214615f31feSGabriel Fernandez /* Come back to HSI */ 2215615f31feSGabriel Fernandez ret = stm32mp2_clk_switch_to_hsi(priv); 2216615f31feSGabriel Fernandez if (ret != 0) { 2217615f31feSGabriel Fernandez panic(); 2218615f31feSGabriel Fernandez } 2219615f31feSGabriel Fernandez 2220615f31feSGabriel Fernandez ret = stm32mp2_clk_pll_configure(priv); 2221615f31feSGabriel Fernandez if (ret != 0) { 2222615f31feSGabriel Fernandez panic(); 2223615f31feSGabriel Fernandez } 2224615f31feSGabriel Fernandez 2225615f31feSGabriel Fernandez /* Wait LSE ready before to use it */ 2226615f31feSGabriel Fernandez ret = stm32_clk_oscillators_wait_lse_ready(priv); 2227615f31feSGabriel Fernandez if (ret != 0) { 2228615f31feSGabriel Fernandez panic(); 2229615f31feSGabriel Fernandez } 2230615f31feSGabriel Fernandez 2231615f31feSGabriel Fernandez ret = stm32mp2_clk_flexgen_configure(priv); 2232615f31feSGabriel Fernandez if (ret != 0) { 2233615f31feSGabriel Fernandez panic(); 2234615f31feSGabriel Fernandez } 2235615f31feSGabriel Fernandez 2236615f31feSGabriel Fernandez ret = stm32_clk_bus_configure(priv); 2237615f31feSGabriel Fernandez if (ret != 0) { 2238615f31feSGabriel Fernandez panic(); 2239615f31feSGabriel Fernandez } 2240615f31feSGabriel Fernandez 2241615f31feSGabriel Fernandez ret = stm32_clk_kernel_configure(priv); 2242615f31feSGabriel Fernandez if (ret != 0) { 2243615f31feSGabriel Fernandez panic(); 2244615f31feSGabriel Fernandez } 2245615f31feSGabriel Fernandez 2246615f31feSGabriel Fernandez return 0; 2247615f31feSGabriel Fernandez } 2248615f31feSGabriel Fernandez 2249615f31feSGabriel Fernandez static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name, 2250615f31feSGabriel Fernandez struct stm32_osci_dt_cfg *osci) 2251615f31feSGabriel Fernandez { 2252615f31feSGabriel Fernandez int subnode = 0; 2253615f31feSGabriel Fernandez 2254615f31feSGabriel Fernandez /* Default value oscillator not found, freq=0 */ 2255615f31feSGabriel Fernandez osci->freq = 0; 2256615f31feSGabriel Fernandez 2257615f31feSGabriel Fernandez fdt_for_each_subnode(subnode, fdt, node) { 2258615f31feSGabriel Fernandez const char *cchar = NULL; 2259615f31feSGabriel Fernandez const fdt32_t *cuint = NULL; 2260615f31feSGabriel Fernandez int ret = 0; 2261615f31feSGabriel Fernandez 2262615f31feSGabriel Fernandez cchar = fdt_get_name(fdt, subnode, &ret); 2263615f31feSGabriel Fernandez if (cchar == NULL) { 2264615f31feSGabriel Fernandez return ret; 2265615f31feSGabriel Fernandez } 2266615f31feSGabriel Fernandez 2267615f31feSGabriel Fernandez if (strncmp(cchar, name, (size_t)ret) || 2268615f31feSGabriel Fernandez fdt_get_status(subnode) == DT_DISABLED) { 2269615f31feSGabriel Fernandez continue; 2270615f31feSGabriel Fernandez } 2271615f31feSGabriel Fernandez 2272615f31feSGabriel Fernandez cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret); 2273615f31feSGabriel Fernandez if (cuint == NULL) { 2274615f31feSGabriel Fernandez return ret; 2275615f31feSGabriel Fernandez } 2276615f31feSGabriel Fernandez 2277615f31feSGabriel Fernandez osci->freq = fdt32_to_cpu(*cuint); 2278615f31feSGabriel Fernandez 2279615f31feSGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) { 2280615f31feSGabriel Fernandez osci->bypass = true; 2281615f31feSGabriel Fernandez } 2282615f31feSGabriel Fernandez 2283615f31feSGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) { 2284615f31feSGabriel Fernandez osci->digbyp = true; 2285615f31feSGabriel Fernandez } 2286615f31feSGabriel Fernandez 2287615f31feSGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) { 2288615f31feSGabriel Fernandez osci->css = true; 2289615f31feSGabriel Fernandez } 2290615f31feSGabriel Fernandez 2291615f31feSGabriel Fernandez osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH); 2292615f31feSGabriel Fernandez 2293615f31feSGabriel Fernandez return 0; 2294615f31feSGabriel Fernandez } 2295615f31feSGabriel Fernandez 2296615f31feSGabriel Fernandez return 0; 2297615f31feSGabriel Fernandez } 2298615f31feSGabriel Fernandez 2299615f31feSGabriel Fernandez static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata) 2300615f31feSGabriel Fernandez { 2301615f31feSGabriel Fernandez int fdt_err = 0; 2302615f31feSGabriel Fernandez uint32_t i = 0; 2303615f31feSGabriel Fernandez int node = 0; 2304615f31feSGabriel Fernandez 2305615f31feSGabriel Fernandez node = fdt_path_offset(fdt, "/clocks"); 2306615f31feSGabriel Fernandez if (node < 0) { 2307615f31feSGabriel Fernandez return -FDT_ERR_NOTFOUND; 2308615f31feSGabriel Fernandez } 2309615f31feSGabriel Fernandez 2310615f31feSGabriel Fernandez for (i = 0; i < pdata->nosci; i++) { 2311615f31feSGabriel Fernandez const char *name = NULL; 2312615f31feSGabriel Fernandez 2313615f31feSGabriel Fernandez name = clk_stm32_get_oscillator_name((enum stm32_osc)i); 2314615f31feSGabriel Fernandez if (name == NULL) { 2315615f31feSGabriel Fernandez continue; 2316615f31feSGabriel Fernandez } 2317615f31feSGabriel Fernandez 2318615f31feSGabriel Fernandez fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]); 2319615f31feSGabriel Fernandez if (fdt_err < 0) { 2320615f31feSGabriel Fernandez panic(); 2321615f31feSGabriel Fernandez } 2322615f31feSGabriel Fernandez } 2323615f31feSGabriel Fernandez 2324615f31feSGabriel Fernandez return 0; 2325615f31feSGabriel Fernandez } 2326615f31feSGabriel Fernandez 2327615f31feSGabriel Fernandez static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll) 2328615f31feSGabriel Fernandez { 2329615f31feSGabriel Fernandez const fdt32_t *cuint = NULL; 2330615f31feSGabriel Fernandez int subnode_pll = 0; 2331615f31feSGabriel Fernandez uint32_t val = 0; 2332615f31feSGabriel Fernandez int err = 0; 2333615f31feSGabriel Fernandez 2334615f31feSGabriel Fernandez cuint = fdt_getprop(fdt, subnode, "st,pll", NULL); 2335615f31feSGabriel Fernandez if (!cuint) { 2336615f31feSGabriel Fernandez return -FDT_ERR_NOTFOUND; 2337615f31feSGabriel Fernandez } 2338615f31feSGabriel Fernandez 2339615f31feSGabriel Fernandez subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); 2340615f31feSGabriel Fernandez if (subnode_pll < 0) { 2341615f31feSGabriel Fernandez return -FDT_ERR_NOTFOUND; 2342615f31feSGabriel Fernandez } 2343615f31feSGabriel Fernandez 2344615f31feSGabriel Fernandez err = fdt_read_uint32_array(fdt, subnode_pll, "cfg", (int)PLLCFG_NB, pll->cfg); 2345615f31feSGabriel Fernandez if (err != 0) { 2346615f31feSGabriel Fernandez return err; 2347615f31feSGabriel Fernandez } 2348615f31feSGabriel Fernandez 2349615f31feSGabriel Fernandez err = fdt_read_uint32_array(fdt, subnode_pll, "csg", (int)PLLCSG_NB, pll->csg); 2350615f31feSGabriel Fernandez 2351615f31feSGabriel Fernandez pll->csg_enabled = (err == 0); 2352615f31feSGabriel Fernandez 2353615f31feSGabriel Fernandez if (err == -FDT_ERR_NOTFOUND) { 2354615f31feSGabriel Fernandez err = 0; 2355615f31feSGabriel Fernandez } 2356615f31feSGabriel Fernandez 2357615f31feSGabriel Fernandez if (err != 0) { 2358615f31feSGabriel Fernandez return err; 2359615f31feSGabriel Fernandez } 2360615f31feSGabriel Fernandez 2361615f31feSGabriel Fernandez pll->enabled = true; 2362615f31feSGabriel Fernandez 2363615f31feSGabriel Fernandez pll->frac = fdt_read_uint32_default(fdt, subnode_pll, "frac", 0); 2364615f31feSGabriel Fernandez 2365615f31feSGabriel Fernandez pll->src = UINT32_MAX; 2366615f31feSGabriel Fernandez 2367615f31feSGabriel Fernandez err = fdt_read_uint32(fdt, subnode_pll, "src", &val); 2368615f31feSGabriel Fernandez if (err == 0) { 2369615f31feSGabriel Fernandez pll->src = val; 2370615f31feSGabriel Fernandez } 2371615f31feSGabriel Fernandez 2372615f31feSGabriel Fernandez return 0; 2373615f31feSGabriel Fernandez } 2374615f31feSGabriel Fernandez 2375615f31feSGabriel Fernandez #define RCC_PLL_NAME_SIZE 12 2376615f31feSGabriel Fernandez 2377615f31feSGabriel Fernandez static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata) 2378615f31feSGabriel Fernandez { 2379615f31feSGabriel Fernandez unsigned int i = 0; 2380615f31feSGabriel Fernandez 2381615f31feSGabriel Fernandez for (i = _PLL1; i < pdata->npll; i++) { 2382615f31feSGabriel Fernandez struct stm32_pll_dt_cfg *pll = pdata->pll + i; 2383615f31feSGabriel Fernandez char name[RCC_PLL_NAME_SIZE]; 2384615f31feSGabriel Fernandez int subnode = 0; 2385615f31feSGabriel Fernandez int err = 0; 2386615f31feSGabriel Fernandez 2387*088238adSNicolas Le Bayon #if STM32MP21 2388*088238adSNicolas Le Bayon if (i == _PLL3) { 2389*088238adSNicolas Le Bayon continue; 2390*088238adSNicolas Le Bayon } 2391*088238adSNicolas Le Bayon #endif 2392615f31feSGabriel Fernandez snprintf(name, sizeof(name), "st,pll-%u", i + 1); 2393615f31feSGabriel Fernandez 2394615f31feSGabriel Fernandez subnode = fdt_subnode_offset(fdt, node, name); 2395615f31feSGabriel Fernandez if (!fdt_check_node(subnode)) { 2396615f31feSGabriel Fernandez continue; 2397615f31feSGabriel Fernandez } 2398615f31feSGabriel Fernandez 2399615f31feSGabriel Fernandez err = clk_stm32_parse_pll_fdt(fdt, subnode, pll); 2400615f31feSGabriel Fernandez if (err != 0) { 2401615f31feSGabriel Fernandez panic(); 2402615f31feSGabriel Fernandez } 2403615f31feSGabriel Fernandez } 2404615f31feSGabriel Fernandez 2405615f31feSGabriel Fernandez return 0; 2406615f31feSGabriel Fernandez } 2407615f31feSGabriel Fernandez 2408615f31feSGabriel Fernandez static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata) 2409615f31feSGabriel Fernandez { 2410615f31feSGabriel Fernandez void *fdt = NULL; 2411615f31feSGabriel Fernandez int node; 2412615f31feSGabriel Fernandez int err; 2413615f31feSGabriel Fernandez 2414615f31feSGabriel Fernandez if (fdt_get_address(&fdt) == 0) { 2415615f31feSGabriel Fernandez return -ENOENT; 2416615f31feSGabriel Fernandez } 2417615f31feSGabriel Fernandez 2418615f31feSGabriel Fernandez node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); 2419615f31feSGabriel Fernandez if (node < 0) { 2420615f31feSGabriel Fernandez panic(); 2421615f31feSGabriel Fernandez } 2422615f31feSGabriel Fernandez 2423615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata); 2424615f31feSGabriel Fernandez if (err != 0) { 2425615f31feSGabriel Fernandez return err; 2426615f31feSGabriel Fernandez } 2427615f31feSGabriel Fernandez 2428615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata); 2429615f31feSGabriel Fernandez if (err != 0) { 2430615f31feSGabriel Fernandez return err; 2431615f31feSGabriel Fernandez } 2432615f31feSGabriel Fernandez 2433615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_by_name(fdt, node, "st,busclk", pdata->busclk, &pdata->nbusclk); 2434615f31feSGabriel Fernandez if (err != 0) { 2435615f31feSGabriel Fernandez return err; 2436615f31feSGabriel Fernandez } 2437615f31feSGabriel Fernandez 2438615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_by_name(fdt, node, "st,flexgen", pdata->flexgen, 2439615f31feSGabriel Fernandez &pdata->nflexgen); 2440615f31feSGabriel Fernandez if (err != 0) { 2441615f31feSGabriel Fernandez return err; 2442615f31feSGabriel Fernandez } 2443615f31feSGabriel Fernandez 2444615f31feSGabriel Fernandez err = stm32_clk_parse_fdt_by_name(fdt, node, "st,kerclk", pdata->kernelclk, 2445615f31feSGabriel Fernandez &pdata->nkernelclk); 2446615f31feSGabriel Fernandez if (err != 0) { 2447615f31feSGabriel Fernandez return err; 2448615f31feSGabriel Fernandez } 2449615f31feSGabriel Fernandez 2450615f31feSGabriel Fernandez return 0; 2451615f31feSGabriel Fernandez } 2452615f31feSGabriel Fernandez #endif /* IMAGE_BL2 */ 2453615f31feSGabriel Fernandez 2454*088238adSNicolas Le Bayon static struct stm32_osci_dt_cfg mp2_osci[NB_OSCILLATOR]; 2455615f31feSGabriel Fernandez 2456*088238adSNicolas Le Bayon static struct stm32_pll_dt_cfg mp2_pll[_PLL_NB]; 2457615f31feSGabriel Fernandez 2458615f31feSGabriel Fernandez #define DT_FLEXGEN_CLK_MAX 64 2459*088238adSNicolas Le Bayon static uint32_t mp2_flexgen[DT_FLEXGEN_CLK_MAX]; 2460615f31feSGabriel Fernandez 2461*088238adSNicolas Le Bayon #if STM32MP21 2462*088238adSNicolas Le Bayon #define DT_BUS_CLK_MAX 7 2463*088238adSNicolas Le Bayon #else /* STM32MP21 */ 2464615f31feSGabriel Fernandez #define DT_BUS_CLK_MAX 6 2465*088238adSNicolas Le Bayon #endif /* STM32MP21 */ 2466*088238adSNicolas Le Bayon static uint32_t mp2_busclk[DT_BUS_CLK_MAX]; 2467615f31feSGabriel Fernandez 2468615f31feSGabriel Fernandez #define DT_KERNEL_CLK_MAX 20 2469*088238adSNicolas Le Bayon static uint32_t mp2_kernelclk[DT_KERNEL_CLK_MAX]; 2470615f31feSGabriel Fernandez 2471*088238adSNicolas Le Bayon static struct stm32_clk_platdata stm32mp2_pdata = { 2472*088238adSNicolas Le Bayon .osci = mp2_osci, 2473615f31feSGabriel Fernandez .nosci = NB_OSCILLATOR, 2474*088238adSNicolas Le Bayon .pll = mp2_pll, 2475615f31feSGabriel Fernandez .npll = _PLL_NB, 2476*088238adSNicolas Le Bayon .flexgen = mp2_flexgen, 2477615f31feSGabriel Fernandez .nflexgen = DT_FLEXGEN_CLK_MAX, 2478*088238adSNicolas Le Bayon .busclk = mp2_busclk, 2479615f31feSGabriel Fernandez .nbusclk = DT_BUS_CLK_MAX, 2480*088238adSNicolas Le Bayon .kernelclk = mp2_kernelclk, 2481615f31feSGabriel Fernandez .nkernelclk = DT_KERNEL_CLK_MAX, 2482615f31feSGabriel Fernandez }; 2483615f31feSGabriel Fernandez 2484*088238adSNicolas Le Bayon static uint8_t refcounts_mp2[CK_LAST]; 2485615f31feSGabriel Fernandez 2486*088238adSNicolas Le Bayon static struct stm32_clk_priv stm32mp2_clock_data = { 2487615f31feSGabriel Fernandez .base = RCC_BASE, 2488*088238adSNicolas Le Bayon .num = ARRAY_SIZE(stm32mp2_clk), 2489*088238adSNicolas Le Bayon .clks = stm32mp2_clk, 2490*088238adSNicolas Le Bayon .parents = parent_mp2, 2491*088238adSNicolas Le Bayon .nb_parents = ARRAY_SIZE(parent_mp2), 2492*088238adSNicolas Le Bayon .gates = gates_mp2, 2493*088238adSNicolas Le Bayon .nb_gates = ARRAY_SIZE(gates_mp2), 2494*088238adSNicolas Le Bayon .div = dividers_mp2, 2495*088238adSNicolas Le Bayon .nb_div = ARRAY_SIZE(dividers_mp2), 2496*088238adSNicolas Le Bayon .osci_data = stm32mp2_osc_data, 2497*088238adSNicolas Le Bayon .nb_osci_data = ARRAY_SIZE(stm32mp2_osc_data), 2498*088238adSNicolas Le Bayon .gate_refcounts = refcounts_mp2, 2499*088238adSNicolas Le Bayon .pdata = &stm32mp2_pdata, 2500*088238adSNicolas Le Bayon .ops_array = ops_array_mp2, 2501615f31feSGabriel Fernandez }; 2502615f31feSGabriel Fernandez 2503615f31feSGabriel Fernandez int stm32mp2_clk_init(void) 2504615f31feSGabriel Fernandez { 2505615f31feSGabriel Fernandez uintptr_t base = RCC_BASE; 2506615f31feSGabriel Fernandez int ret; 2507615f31feSGabriel Fernandez 2508615f31feSGabriel Fernandez #ifdef IMAGE_BL2 2509*088238adSNicolas Le Bayon ret = stm32_clk_parse_fdt(&stm32mp2_pdata); 2510615f31feSGabriel Fernandez if (ret != 0) { 2511615f31feSGabriel Fernandez return ret; 2512615f31feSGabriel Fernandez } 2513615f31feSGabriel Fernandez #endif 2514615f31feSGabriel Fernandez 2515*088238adSNicolas Le Bayon ret = clk_stm32_init(&stm32mp2_clock_data, base); 2516615f31feSGabriel Fernandez if (ret != 0) { 2517615f31feSGabriel Fernandez return ret; 2518615f31feSGabriel Fernandez } 2519615f31feSGabriel Fernandez 2520615f31feSGabriel Fernandez #ifdef IMAGE_BL2 2521615f31feSGabriel Fernandez ret = stm32mp2_init_clock_tree(); 2522615f31feSGabriel Fernandez if (ret != 0) { 2523615f31feSGabriel Fernandez return ret; 2524615f31feSGabriel Fernandez } 2525615f31feSGabriel Fernandez 2526615f31feSGabriel Fernandez clk_stm32_enable_critical_clocks(); 2527615f31feSGabriel Fernandez #endif 2528615f31feSGabriel Fernandez 2529615f31feSGabriel Fernandez return 0; 2530615f31feSGabriel Fernandez } 2531615f31feSGabriel Fernandez 2532615f31feSGabriel Fernandez int stm32mp2_pll1_disable(void) 2533615f31feSGabriel Fernandez { 2534615f31feSGabriel Fernandez #ifdef IMAGE_BL2 2535615f31feSGabriel Fernandez return -EPERM; 2536615f31feSGabriel Fernandez #else 2537615f31feSGabriel Fernandez uintptr_t a35_ss_address = A35SSC_BASE; 2538615f31feSGabriel Fernandez uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE; 2539615f31feSGabriel Fernandez 2540615f31feSGabriel Fernandez stm32mp2_a35_ss_on_hsi(); 2541615f31feSGabriel Fernandez 2542615f31feSGabriel Fernandez mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD); 2543615f31feSGabriel Fernandez 2544615f31feSGabriel Fernandez return 0; 2545615f31feSGabriel Fernandez #endif 2546615f31feSGabriel Fernandez } 2547