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