1*e5e793a6SGabriel Fernandez // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2*e5e793a6SGabriel Fernandez /* 3*e5e793a6SGabriel Fernandez * Copyright (C) STMicroelectronics 2022 - All Rights Reserved 4*e5e793a6SGabriel Fernandez */ 5*e5e793a6SGabriel Fernandez 6*e5e793a6SGabriel Fernandez #include <assert.h> 7*e5e793a6SGabriel Fernandez #include <drivers/clk.h> 8*e5e793a6SGabriel Fernandez #include <drivers/clk_dt.h> 9*e5e793a6SGabriel Fernandez #include <drivers/stm32mp_dt_bindings.h> 10*e5e793a6SGabriel Fernandez #include <drivers/stm32mp13_rcc.h> 11*e5e793a6SGabriel Fernandez #include <io.h> 12*e5e793a6SGabriel Fernandez #include <kernel/boot.h> 13*e5e793a6SGabriel Fernandez #include <libfdt.h> 14*e5e793a6SGabriel Fernandez #include <stdio.h> 15*e5e793a6SGabriel Fernandez 16*e5e793a6SGabriel Fernandez #include "clk-stm32-core.h" 17*e5e793a6SGabriel Fernandez 18*e5e793a6SGabriel Fernandez #define MAX_HSI_HZ 64000000 19*e5e793a6SGabriel Fernandez #define USB_PHY_48_MHZ 48000000 20*e5e793a6SGabriel Fernandez 21*e5e793a6SGabriel Fernandez #define TIMEOUT_US_200MS U(200000) 22*e5e793a6SGabriel Fernandez #define HSIDIV_TIMEOUT TIMEOUT_US_200MS 23*e5e793a6SGabriel Fernandez 24*e5e793a6SGabriel Fernandez #define MAX_OPP CFG_STM32MP_OPP_COUNT 25*e5e793a6SGabriel Fernandez 26*e5e793a6SGabriel Fernandez #define RCC_PLL_NAME_SIZE 12 27*e5e793a6SGabriel Fernandez 28*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg { 29*e5e793a6SGabriel Fernandez unsigned long freq; 30*e5e793a6SGabriel Fernandez bool bypass; 31*e5e793a6SGabriel Fernandez bool digbyp; 32*e5e793a6SGabriel Fernandez bool css; 33*e5e793a6SGabriel Fernandez uint32_t drive; 34*e5e793a6SGabriel Fernandez }; 35*e5e793a6SGabriel Fernandez 36*e5e793a6SGabriel Fernandez enum pll_mn { 37*e5e793a6SGabriel Fernandez PLL_CFG_M, 38*e5e793a6SGabriel Fernandez PLL_CFG_N, 39*e5e793a6SGabriel Fernandez PLL_DIV_MN_NB 40*e5e793a6SGabriel Fernandez }; 41*e5e793a6SGabriel Fernandez 42*e5e793a6SGabriel Fernandez enum pll_pqr { 43*e5e793a6SGabriel Fernandez PLL_CFG_P, 44*e5e793a6SGabriel Fernandez PLL_CFG_Q, 45*e5e793a6SGabriel Fernandez PLL_CFG_R, 46*e5e793a6SGabriel Fernandez PLL_DIV_PQR_NB 47*e5e793a6SGabriel Fernandez }; 48*e5e793a6SGabriel Fernandez 49*e5e793a6SGabriel Fernandez enum pll_csg { 50*e5e793a6SGabriel Fernandez PLL_CSG_MOD_PER, 51*e5e793a6SGabriel Fernandez PLL_CSG_INC_STEP, 52*e5e793a6SGabriel Fernandez PLL_CSG_SSCG_MODE, 53*e5e793a6SGabriel Fernandez PLL_CSG_NB 54*e5e793a6SGabriel Fernandez }; 55*e5e793a6SGabriel Fernandez 56*e5e793a6SGabriel Fernandez struct stm32_pll_vco { 57*e5e793a6SGabriel Fernandez uint32_t status; 58*e5e793a6SGabriel Fernandez uint32_t src; 59*e5e793a6SGabriel Fernandez uint32_t div_mn[PLL_DIV_MN_NB]; 60*e5e793a6SGabriel Fernandez uint32_t frac; 61*e5e793a6SGabriel Fernandez bool csg_enabled; 62*e5e793a6SGabriel Fernandez uint32_t csg[PLL_CSG_NB]; 63*e5e793a6SGabriel Fernandez }; 64*e5e793a6SGabriel Fernandez 65*e5e793a6SGabriel Fernandez struct stm32_pll_output { 66*e5e793a6SGabriel Fernandez uint32_t output[PLL_DIV_PQR_NB]; 67*e5e793a6SGabriel Fernandez }; 68*e5e793a6SGabriel Fernandez 69*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg { 70*e5e793a6SGabriel Fernandez struct stm32_pll_vco vco; 71*e5e793a6SGabriel Fernandez struct stm32_pll_output output; 72*e5e793a6SGabriel Fernandez }; 73*e5e793a6SGabriel Fernandez 74*e5e793a6SGabriel Fernandez struct stm32_clk_opp_cfg { 75*e5e793a6SGabriel Fernandez uint32_t frq; 76*e5e793a6SGabriel Fernandez uint32_t src; 77*e5e793a6SGabriel Fernandez uint32_t div; 78*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg pll_cfg; 79*e5e793a6SGabriel Fernandez }; 80*e5e793a6SGabriel Fernandez 81*e5e793a6SGabriel Fernandez struct stm32_clk_opp_dt_cfg { 82*e5e793a6SGabriel Fernandez struct stm32_clk_opp_cfg mpu_opp[MAX_OPP]; 83*e5e793a6SGabriel Fernandez struct stm32_clk_opp_cfg axi_opp[MAX_OPP]; 84*e5e793a6SGabriel Fernandez struct stm32_clk_opp_cfg mlahbs_opp[MAX_OPP]; 85*e5e793a6SGabriel Fernandez }; 86*e5e793a6SGabriel Fernandez 87*e5e793a6SGabriel Fernandez struct stm32_clk_platdata { 88*e5e793a6SGabriel Fernandez uintptr_t rcc_base; 89*e5e793a6SGabriel Fernandez uint32_t nosci; 90*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci; 91*e5e793a6SGabriel Fernandez uint32_t npll; 92*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg *pll; 93*e5e793a6SGabriel Fernandez struct stm32_clk_opp_dt_cfg *opp; 94*e5e793a6SGabriel Fernandez uint32_t nclksrc; 95*e5e793a6SGabriel Fernandez uint32_t *clksrc; 96*e5e793a6SGabriel Fernandez uint32_t nclkdiv; 97*e5e793a6SGabriel Fernandez uint32_t *clkdiv; 98*e5e793a6SGabriel Fernandez }; 99*e5e793a6SGabriel Fernandez 100*e5e793a6SGabriel Fernandez /* 101*e5e793a6SGabriel Fernandez * GATE CONFIG 102*e5e793a6SGabriel Fernandez */ 103*e5e793a6SGabriel Fernandez 104*e5e793a6SGabriel Fernandez /* Warning GATE_XXX_RDY must follow GATE_XXX */ 105*e5e793a6SGabriel Fernandez enum enum_gate_cfg { 106*e5e793a6SGabriel Fernandez GATE_LSE, 107*e5e793a6SGabriel Fernandez GATE_LSE_RDY, 108*e5e793a6SGabriel Fernandez GATE_LSI, 109*e5e793a6SGabriel Fernandez GATE_LSI_RDY, 110*e5e793a6SGabriel Fernandez GATE_HSI, 111*e5e793a6SGabriel Fernandez GATE_HSI_RDY, 112*e5e793a6SGabriel Fernandez GATE_CSI, 113*e5e793a6SGabriel Fernandez GATE_CSI_RDY, 114*e5e793a6SGabriel Fernandez GATE_HSE, 115*e5e793a6SGabriel Fernandez GATE_HSE_RDY, 116*e5e793a6SGabriel Fernandez GATE_PLL1, 117*e5e793a6SGabriel Fernandez GATE_PLL1_RDY, 118*e5e793a6SGabriel Fernandez GATE_PLL2, 119*e5e793a6SGabriel Fernandez GATE_PLL2_RDY, 120*e5e793a6SGabriel Fernandez GATE_PLL3, 121*e5e793a6SGabriel Fernandez GATE_PLL3_RDY, 122*e5e793a6SGabriel Fernandez GATE_PLL4, 123*e5e793a6SGabriel Fernandez GATE_PLL4_RDY, 124*e5e793a6SGabriel Fernandez GATE_HSIDIVRDY, 125*e5e793a6SGabriel Fernandez GATE_MPUSRCRDY, 126*e5e793a6SGabriel Fernandez GATE_AXISSRCRDY, 127*e5e793a6SGabriel Fernandez GATE_MCUSSRCRDY, 128*e5e793a6SGabriel Fernandez GATE_PLL12SRCRDY, 129*e5e793a6SGabriel Fernandez GATE_PLL3SRCRDY, 130*e5e793a6SGabriel Fernandez GATE_PLL4SRCRDY, 131*e5e793a6SGabriel Fernandez GATE_MPUDIVRDY, 132*e5e793a6SGabriel Fernandez GATE_AXIDIVRDY, 133*e5e793a6SGabriel Fernandez GATE_MLAHBDIVRDY, 134*e5e793a6SGabriel Fernandez GATE_APB1DIVRDY, 135*e5e793a6SGabriel Fernandez GATE_APB2DIVRDY, 136*e5e793a6SGabriel Fernandez GATE_APB3DIVRDY, 137*e5e793a6SGabriel Fernandez GATE_APB4DIVRDY, 138*e5e793a6SGabriel Fernandez GATE_APB5DIVRDY, 139*e5e793a6SGabriel Fernandez GATE_APB6DIVRDY, 140*e5e793a6SGabriel Fernandez GATE_RTCCK, 141*e5e793a6SGabriel Fernandez GATE_MCO1, 142*e5e793a6SGabriel Fernandez GATE_MCO2, 143*e5e793a6SGabriel Fernandez GATE_DBGCK, 144*e5e793a6SGabriel Fernandez GATE_TRACECK, 145*e5e793a6SGabriel Fernandez GATE_PLL1_DIVP, 146*e5e793a6SGabriel Fernandez GATE_PLL1_DIVQ, 147*e5e793a6SGabriel Fernandez GATE_PLL1_DIVR, 148*e5e793a6SGabriel Fernandez GATE_PLL2_DIVP, 149*e5e793a6SGabriel Fernandez GATE_PLL2_DIVQ, 150*e5e793a6SGabriel Fernandez GATE_PLL2_DIVR, 151*e5e793a6SGabriel Fernandez GATE_PLL3_DIVP, 152*e5e793a6SGabriel Fernandez GATE_PLL3_DIVQ, 153*e5e793a6SGabriel Fernandez GATE_PLL3_DIVR, 154*e5e793a6SGabriel Fernandez GATE_PLL4_DIVP, 155*e5e793a6SGabriel Fernandez GATE_PLL4_DIVQ, 156*e5e793a6SGabriel Fernandez GATE_PLL4_DIVR, 157*e5e793a6SGabriel Fernandez GATE_DDRC1, 158*e5e793a6SGabriel Fernandez GATE_DDRC1LP, 159*e5e793a6SGabriel Fernandez GATE_DDRPHYC, 160*e5e793a6SGabriel Fernandez GATE_DDRPHYCLP, 161*e5e793a6SGabriel Fernandez GATE_DDRCAPB, 162*e5e793a6SGabriel Fernandez GATE_DDRCAPBLP, 163*e5e793a6SGabriel Fernandez GATE_AXIDCG, 164*e5e793a6SGabriel Fernandez GATE_DDRPHYCAPB, 165*e5e793a6SGabriel Fernandez GATE_DDRPHYCAPBLP, 166*e5e793a6SGabriel Fernandez GATE_TIM2, 167*e5e793a6SGabriel Fernandez GATE_TIM3, 168*e5e793a6SGabriel Fernandez GATE_TIM4, 169*e5e793a6SGabriel Fernandez GATE_TIM5, 170*e5e793a6SGabriel Fernandez GATE_TIM6, 171*e5e793a6SGabriel Fernandez GATE_TIM7, 172*e5e793a6SGabriel Fernandez GATE_LPTIM1, 173*e5e793a6SGabriel Fernandez GATE_SPI2, 174*e5e793a6SGabriel Fernandez GATE_SPI3, 175*e5e793a6SGabriel Fernandez GATE_USART3, 176*e5e793a6SGabriel Fernandez GATE_UART4, 177*e5e793a6SGabriel Fernandez GATE_UART5, 178*e5e793a6SGabriel Fernandez GATE_UART7, 179*e5e793a6SGabriel Fernandez GATE_UART8, 180*e5e793a6SGabriel Fernandez GATE_I2C1, 181*e5e793a6SGabriel Fernandez GATE_I2C2, 182*e5e793a6SGabriel Fernandez GATE_SPDIF, 183*e5e793a6SGabriel Fernandez GATE_TIM1, 184*e5e793a6SGabriel Fernandez GATE_TIM8, 185*e5e793a6SGabriel Fernandez GATE_SPI1, 186*e5e793a6SGabriel Fernandez GATE_USART6, 187*e5e793a6SGabriel Fernandez GATE_SAI1, 188*e5e793a6SGabriel Fernandez GATE_SAI2, 189*e5e793a6SGabriel Fernandez GATE_DFSDM, 190*e5e793a6SGabriel Fernandez GATE_ADFSDM, 191*e5e793a6SGabriel Fernandez GATE_FDCAN, 192*e5e793a6SGabriel Fernandez GATE_LPTIM2, 193*e5e793a6SGabriel Fernandez GATE_LPTIM3, 194*e5e793a6SGabriel Fernandez GATE_LPTIM4, 195*e5e793a6SGabriel Fernandez GATE_LPTIM5, 196*e5e793a6SGabriel Fernandez GATE_VREF, 197*e5e793a6SGabriel Fernandez GATE_DTS, 198*e5e793a6SGabriel Fernandez GATE_PMBCTRL, 199*e5e793a6SGabriel Fernandez GATE_HDP, 200*e5e793a6SGabriel Fernandez GATE_SYSCFG, 201*e5e793a6SGabriel Fernandez GATE_DCMIPP, 202*e5e793a6SGabriel Fernandez GATE_DDRPERFM, 203*e5e793a6SGabriel Fernandez GATE_IWDG2APB, 204*e5e793a6SGabriel Fernandez GATE_USBPHY, 205*e5e793a6SGabriel Fernandez GATE_STGENRO, 206*e5e793a6SGabriel Fernandez GATE_LTDC, 207*e5e793a6SGabriel Fernandez GATE_RTCAPB, 208*e5e793a6SGabriel Fernandez GATE_TZC, 209*e5e793a6SGabriel Fernandez GATE_ETZPC, 210*e5e793a6SGabriel Fernandez GATE_IWDG1APB, 211*e5e793a6SGabriel Fernandez GATE_BSEC, 212*e5e793a6SGabriel Fernandez GATE_STGENC, 213*e5e793a6SGabriel Fernandez GATE_USART1, 214*e5e793a6SGabriel Fernandez GATE_USART2, 215*e5e793a6SGabriel Fernandez GATE_SPI4, 216*e5e793a6SGabriel Fernandez GATE_SPI5, 217*e5e793a6SGabriel Fernandez GATE_I2C3, 218*e5e793a6SGabriel Fernandez GATE_I2C4, 219*e5e793a6SGabriel Fernandez GATE_I2C5, 220*e5e793a6SGabriel Fernandez GATE_TIM12, 221*e5e793a6SGabriel Fernandez GATE_TIM13, 222*e5e793a6SGabriel Fernandez GATE_TIM14, 223*e5e793a6SGabriel Fernandez GATE_TIM15, 224*e5e793a6SGabriel Fernandez GATE_TIM16, 225*e5e793a6SGabriel Fernandez GATE_TIM17, 226*e5e793a6SGabriel Fernandez GATE_DMA1, 227*e5e793a6SGabriel Fernandez GATE_DMA2, 228*e5e793a6SGabriel Fernandez GATE_DMAMUX1, 229*e5e793a6SGabriel Fernandez GATE_DMA3, 230*e5e793a6SGabriel Fernandez GATE_DMAMUX2, 231*e5e793a6SGabriel Fernandez GATE_ADC1, 232*e5e793a6SGabriel Fernandez GATE_ADC2, 233*e5e793a6SGabriel Fernandez GATE_USBO, 234*e5e793a6SGabriel Fernandez GATE_TSC, 235*e5e793a6SGabriel Fernandez GATE_GPIOA, 236*e5e793a6SGabriel Fernandez GATE_GPIOB, 237*e5e793a6SGabriel Fernandez GATE_GPIOC, 238*e5e793a6SGabriel Fernandez GATE_GPIOD, 239*e5e793a6SGabriel Fernandez GATE_GPIOE, 240*e5e793a6SGabriel Fernandez GATE_GPIOF, 241*e5e793a6SGabriel Fernandez GATE_GPIOG, 242*e5e793a6SGabriel Fernandez GATE_GPIOH, 243*e5e793a6SGabriel Fernandez GATE_GPIOI, 244*e5e793a6SGabriel Fernandez GATE_PKA, 245*e5e793a6SGabriel Fernandez GATE_SAES, 246*e5e793a6SGabriel Fernandez GATE_CRYP1, 247*e5e793a6SGabriel Fernandez GATE_HASH1, 248*e5e793a6SGabriel Fernandez GATE_RNG1, 249*e5e793a6SGabriel Fernandez GATE_BKPSRAM, 250*e5e793a6SGabriel Fernandez GATE_AXIMC, 251*e5e793a6SGabriel Fernandez GATE_MCE, 252*e5e793a6SGabriel Fernandez GATE_ETH1CK, 253*e5e793a6SGabriel Fernandez GATE_ETH1TX, 254*e5e793a6SGabriel Fernandez GATE_ETH1RX, 255*e5e793a6SGabriel Fernandez GATE_ETH1MAC, 256*e5e793a6SGabriel Fernandez GATE_FMC, 257*e5e793a6SGabriel Fernandez GATE_QSPI, 258*e5e793a6SGabriel Fernandez GATE_SDMMC1, 259*e5e793a6SGabriel Fernandez GATE_SDMMC2, 260*e5e793a6SGabriel Fernandez GATE_CRC1, 261*e5e793a6SGabriel Fernandez GATE_USBH, 262*e5e793a6SGabriel Fernandez GATE_ETH2CK, 263*e5e793a6SGabriel Fernandez GATE_ETH2TX, 264*e5e793a6SGabriel Fernandez GATE_ETH2RX, 265*e5e793a6SGabriel Fernandez GATE_ETH2MAC, 266*e5e793a6SGabriel Fernandez GATE_MDMA, 267*e5e793a6SGabriel Fernandez GATE_NB 268*e5e793a6SGabriel Fernandez }; 269*e5e793a6SGabriel Fernandez 270*e5e793a6SGabriel Fernandez #define GATE_CFG(_id, _offset, _bit_idx, _offset_clr)\ 271*e5e793a6SGabriel Fernandez [(_id)] = {\ 272*e5e793a6SGabriel Fernandez .offset = (_offset),\ 273*e5e793a6SGabriel Fernandez .bit_idx = (_bit_idx),\ 274*e5e793a6SGabriel Fernandez .set_clr = (_offset_clr),\ 275*e5e793a6SGabriel Fernandez } 276*e5e793a6SGabriel Fernandez 277*e5e793a6SGabriel Fernandez static const struct gate_cfg gates_mp13[GATE_NB] = { 278*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LSE, RCC_BDCR, 0, 0), 279*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LSE_RDY, RCC_BDCR, 2, 0), 280*e5e793a6SGabriel Fernandez GATE_CFG(GATE_RTCCK, RCC_BDCR, 20, 0), 281*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LSI, RCC_RDLSICR, 0, 0), 282*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LSI_RDY, RCC_RDLSICR, 1, 0), 283*e5e793a6SGabriel Fernandez GATE_CFG(GATE_HSI, RCC_OCENSETR, 0, 1), 284*e5e793a6SGabriel Fernandez GATE_CFG(GATE_HSI_RDY, RCC_OCRDYR, 0, 0), 285*e5e793a6SGabriel Fernandez GATE_CFG(GATE_CSI, RCC_OCENSETR, 4, 1), 286*e5e793a6SGabriel Fernandez GATE_CFG(GATE_CSI_RDY, RCC_OCRDYR, 4, 0), 287*e5e793a6SGabriel Fernandez GATE_CFG(GATE_HSE, RCC_OCENSETR, 8, 1), 288*e5e793a6SGabriel Fernandez GATE_CFG(GATE_HSE_RDY, RCC_OCRDYR, 8, 0), 289*e5e793a6SGabriel Fernandez GATE_CFG(GATE_HSIDIVRDY, RCC_OCRDYR, 2, 0), 290*e5e793a6SGabriel Fernandez GATE_CFG(GATE_MPUSRCRDY, RCC_MPCKSELR, 31, 0), 291*e5e793a6SGabriel Fernandez GATE_CFG(GATE_AXISSRCRDY, RCC_ASSCKSELR, 31, 0), 292*e5e793a6SGabriel Fernandez GATE_CFG(GATE_MCUSSRCRDY, RCC_MSSCKSELR, 31, 0), 293*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL12SRCRDY, RCC_RCK12SELR, 31, 0), 294*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL3SRCRDY, RCC_RCK3SELR, 31, 0), 295*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL4SRCRDY, RCC_RCK4SELR, 31, 0), 296*e5e793a6SGabriel Fernandez GATE_CFG(GATE_MPUDIVRDY, RCC_MPCKDIVR, 31, 0), 297*e5e793a6SGabriel Fernandez GATE_CFG(GATE_AXIDIVRDY, RCC_AXIDIVR, 31, 0), 298*e5e793a6SGabriel Fernandez GATE_CFG(GATE_MLAHBDIVRDY, RCC_MLAHBDIVR, 31, 0), 299*e5e793a6SGabriel Fernandez GATE_CFG(GATE_APB1DIVRDY, RCC_APB1DIVR, 31, 0), 300*e5e793a6SGabriel Fernandez GATE_CFG(GATE_APB2DIVRDY, RCC_APB2DIVR, 31, 0), 301*e5e793a6SGabriel Fernandez GATE_CFG(GATE_APB3DIVRDY, RCC_APB3DIVR, 31, 0), 302*e5e793a6SGabriel Fernandez GATE_CFG(GATE_APB4DIVRDY, RCC_APB4DIVR, 31, 0), 303*e5e793a6SGabriel Fernandez GATE_CFG(GATE_APB5DIVRDY, RCC_APB5DIVR, 31, 0), 304*e5e793a6SGabriel Fernandez GATE_CFG(GATE_APB6DIVRDY, RCC_APB6DIVR, 31, 0), 305*e5e793a6SGabriel Fernandez GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 12, 0), 306*e5e793a6SGabriel Fernandez GATE_CFG(GATE_MCO2, RCC_MCO2CFGR, 12, 0), 307*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DBGCK, RCC_DBGCFGR, 8, 0), 308*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TRACECK, RCC_DBGCFGR, 9, 0), 309*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL1, RCC_PLL1CR, 0, 0), 310*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL1_RDY, RCC_PLL1CR, 1, 0), 311*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL1_DIVP, RCC_PLL1CR, 4, 0), 312*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL1_DIVQ, RCC_PLL1CR, 5, 0), 313*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL1_DIVR, RCC_PLL1CR, 6, 0), 314*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL2, RCC_PLL2CR, 0, 0), 315*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL2_RDY, RCC_PLL2CR, 1, 0), 316*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL2_DIVP, RCC_PLL2CR, 4, 0), 317*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL2_DIVQ, RCC_PLL2CR, 5, 0), 318*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL2_DIVR, RCC_PLL2CR, 6, 0), 319*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL3, RCC_PLL3CR, 0, 0), 320*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL3_RDY, RCC_PLL3CR, 1, 0), 321*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL3_DIVP, RCC_PLL3CR, 4, 0), 322*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL3_DIVQ, RCC_PLL3CR, 5, 0), 323*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL3_DIVR, RCC_PLL3CR, 6, 0), 324*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL4, RCC_PLL4CR, 0, 0), 325*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL4_RDY, RCC_PLL4CR, 1, 0), 326*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL4_DIVP, RCC_PLL4CR, 4, 0), 327*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL4_DIVQ, RCC_PLL4CR, 5, 0), 328*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PLL4_DIVR, RCC_PLL4CR, 6, 0), 329*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRC1, RCC_DDRITFCR, 0, 0), 330*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRC1LP, RCC_DDRITFCR, 1, 0), 331*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRPHYC, RCC_DDRITFCR, 4, 0), 332*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRPHYCLP, RCC_DDRITFCR, 5, 0), 333*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRCAPB, RCC_DDRITFCR, 6, 0), 334*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRCAPBLP, RCC_DDRITFCR, 7, 0), 335*e5e793a6SGabriel Fernandez GATE_CFG(GATE_AXIDCG, RCC_DDRITFCR, 8, 0), 336*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRPHYCAPB, RCC_DDRITFCR, 9, 0), 337*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRPHYCAPBLP, RCC_DDRITFCR, 10, 0), 338*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM2, RCC_MP_APB1ENSETR, 0, 1), 339*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM3, RCC_MP_APB1ENSETR, 1, 1), 340*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM4, RCC_MP_APB1ENSETR, 2, 1), 341*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM5, RCC_MP_APB1ENSETR, 3, 1), 342*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM6, RCC_MP_APB1ENSETR, 4, 1), 343*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM7, RCC_MP_APB1ENSETR, 5, 1), 344*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LPTIM1, RCC_MP_APB1ENSETR, 9, 1), 345*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SPI2, RCC_MP_APB1ENSETR, 11, 1), 346*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SPI3, RCC_MP_APB1ENSETR, 12, 1), 347*e5e793a6SGabriel Fernandez GATE_CFG(GATE_USART3, RCC_MP_APB1ENSETR, 15, 1), 348*e5e793a6SGabriel Fernandez GATE_CFG(GATE_UART4, RCC_MP_APB1ENSETR, 16, 1), 349*e5e793a6SGabriel Fernandez GATE_CFG(GATE_UART5, RCC_MP_APB1ENSETR, 17, 1), 350*e5e793a6SGabriel Fernandez GATE_CFG(GATE_UART7, RCC_MP_APB1ENSETR, 18, 1), 351*e5e793a6SGabriel Fernandez GATE_CFG(GATE_UART8, RCC_MP_APB1ENSETR, 19, 1), 352*e5e793a6SGabriel Fernandez GATE_CFG(GATE_I2C1, RCC_MP_APB1ENSETR, 21, 1), 353*e5e793a6SGabriel Fernandez GATE_CFG(GATE_I2C2, RCC_MP_APB1ENSETR, 22, 1), 354*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SPDIF, RCC_MP_APB1ENSETR, 26, 1), 355*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM1, RCC_MP_APB2ENSETR, 0, 1), 356*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM8, RCC_MP_APB2ENSETR, 1, 1), 357*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SPI1, RCC_MP_APB2ENSETR, 8, 1), 358*e5e793a6SGabriel Fernandez GATE_CFG(GATE_USART6, RCC_MP_APB2ENSETR, 13, 1), 359*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SAI1, RCC_MP_APB2ENSETR, 16, 1), 360*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SAI2, RCC_MP_APB2ENSETR, 17, 1), 361*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DFSDM, RCC_MP_APB2ENSETR, 20, 1), 362*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ADFSDM, RCC_MP_APB2ENSETR, 21, 1), 363*e5e793a6SGabriel Fernandez GATE_CFG(GATE_FDCAN, RCC_MP_APB2ENSETR, 24, 1), 364*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LPTIM2, RCC_MP_APB3ENSETR, 0, 1), 365*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LPTIM3, RCC_MP_APB3ENSETR, 1, 1), 366*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LPTIM4, RCC_MP_APB3ENSETR, 2, 1), 367*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LPTIM5, RCC_MP_APB3ENSETR, 3, 1), 368*e5e793a6SGabriel Fernandez GATE_CFG(GATE_VREF, RCC_MP_APB3ENSETR, 13, 1), 369*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DTS, RCC_MP_APB3ENSETR, 16, 1), 370*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PMBCTRL, RCC_MP_APB3ENSETR, 17, 1), 371*e5e793a6SGabriel Fernandez GATE_CFG(GATE_HDP, RCC_MP_APB3ENSETR, 20, 1), 372*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SYSCFG, RCC_MP_S_APB3ENSETR, 0, 1), 373*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DCMIPP, RCC_MP_APB4ENSETR, 1, 1), 374*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DDRPERFM, RCC_MP_APB4ENSETR, 8, 1), 375*e5e793a6SGabriel Fernandez GATE_CFG(GATE_IWDG2APB, RCC_MP_APB4ENSETR, 15, 1), 376*e5e793a6SGabriel Fernandez GATE_CFG(GATE_USBPHY, RCC_MP_APB4ENSETR, 16, 1), 377*e5e793a6SGabriel Fernandez GATE_CFG(GATE_STGENRO, RCC_MP_APB4ENSETR, 20, 1), 378*e5e793a6SGabriel Fernandez GATE_CFG(GATE_LTDC, RCC_MP_S_APB4ENSETR, 0, 1), 379*e5e793a6SGabriel Fernandez GATE_CFG(GATE_RTCAPB, RCC_MP_APB5ENSETR, 8, 1), 380*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TZC, RCC_MP_APB5ENSETR, 11, 1), 381*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETZPC, RCC_MP_APB5ENSETR, 13, 1), 382*e5e793a6SGabriel Fernandez GATE_CFG(GATE_IWDG1APB, RCC_MP_APB5ENSETR, 15, 1), 383*e5e793a6SGabriel Fernandez GATE_CFG(GATE_BSEC, RCC_MP_APB5ENSETR, 16, 1), 384*e5e793a6SGabriel Fernandez GATE_CFG(GATE_STGENC, RCC_MP_APB5ENSETR, 20, 1), 385*e5e793a6SGabriel Fernandez GATE_CFG(GATE_USART1, RCC_MP_APB6ENSETR, 0, 1), 386*e5e793a6SGabriel Fernandez GATE_CFG(GATE_USART2, RCC_MP_APB6ENSETR, 1, 1), 387*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SPI4, RCC_MP_APB6ENSETR, 2, 1), 388*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SPI5, RCC_MP_APB6ENSETR, 3, 1), 389*e5e793a6SGabriel Fernandez GATE_CFG(GATE_I2C3, RCC_MP_APB6ENSETR, 4, 1), 390*e5e793a6SGabriel Fernandez GATE_CFG(GATE_I2C4, RCC_MP_APB6ENSETR, 5, 1), 391*e5e793a6SGabriel Fernandez GATE_CFG(GATE_I2C5, RCC_MP_APB6ENSETR, 6, 1), 392*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM12, RCC_MP_APB6ENSETR, 7, 1), 393*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM13, RCC_MP_APB6ENSETR, 8, 1), 394*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM14, RCC_MP_APB6ENSETR, 9, 1), 395*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM15, RCC_MP_APB6ENSETR, 10, 1), 396*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM16, RCC_MP_APB6ENSETR, 11, 1), 397*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TIM17, RCC_MP_APB6ENSETR, 12, 1), 398*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DMA1, RCC_MP_AHB2ENSETR, 0, 1), 399*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DMA2, RCC_MP_AHB2ENSETR, 1, 1), 400*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DMAMUX1, RCC_MP_AHB2ENSETR, 2, 1), 401*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DMA3, RCC_MP_AHB2ENSETR, 3, 1), 402*e5e793a6SGabriel Fernandez GATE_CFG(GATE_DMAMUX2, RCC_MP_AHB2ENSETR, 4, 1), 403*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ADC1, RCC_MP_AHB2ENSETR, 5, 1), 404*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ADC2, RCC_MP_AHB2ENSETR, 6, 1), 405*e5e793a6SGabriel Fernandez GATE_CFG(GATE_USBO, RCC_MP_AHB2ENSETR, 8, 1), 406*e5e793a6SGabriel Fernandez GATE_CFG(GATE_TSC, RCC_MP_AHB4ENSETR, 15, 1), 407*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOA, RCC_MP_S_AHB4ENSETR, 0, 1), 408*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOB, RCC_MP_S_AHB4ENSETR, 1, 1), 409*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOC, RCC_MP_S_AHB4ENSETR, 2, 1), 410*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOD, RCC_MP_S_AHB4ENSETR, 3, 1), 411*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOE, RCC_MP_S_AHB4ENSETR, 4, 1), 412*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOF, RCC_MP_S_AHB4ENSETR, 5, 1), 413*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOG, RCC_MP_S_AHB4ENSETR, 6, 1), 414*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOH, RCC_MP_S_AHB4ENSETR, 7, 1), 415*e5e793a6SGabriel Fernandez GATE_CFG(GATE_GPIOI, RCC_MP_S_AHB4ENSETR, 8, 1), 416*e5e793a6SGabriel Fernandez GATE_CFG(GATE_PKA, RCC_MP_AHB5ENSETR, 2, 1), 417*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SAES, RCC_MP_AHB5ENSETR, 3, 1), 418*e5e793a6SGabriel Fernandez GATE_CFG(GATE_CRYP1, RCC_MP_AHB5ENSETR, 4, 1), 419*e5e793a6SGabriel Fernandez GATE_CFG(GATE_HASH1, RCC_MP_AHB5ENSETR, 5, 1), 420*e5e793a6SGabriel Fernandez GATE_CFG(GATE_RNG1, RCC_MP_AHB5ENSETR, 6, 1), 421*e5e793a6SGabriel Fernandez GATE_CFG(GATE_BKPSRAM, RCC_MP_AHB5ENSETR, 8, 1), 422*e5e793a6SGabriel Fernandez GATE_CFG(GATE_AXIMC, RCC_MP_AHB5ENSETR, 16, 1), 423*e5e793a6SGabriel Fernandez GATE_CFG(GATE_MCE, RCC_MP_AHB6ENSETR, 1, 1), 424*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETH1CK, RCC_MP_AHB6ENSETR, 7, 1), 425*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETH1TX, RCC_MP_AHB6ENSETR, 8, 1), 426*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETH1RX, RCC_MP_AHB6ENSETR, 9, 1), 427*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETH1MAC, RCC_MP_AHB6ENSETR, 10, 1), 428*e5e793a6SGabriel Fernandez GATE_CFG(GATE_FMC, RCC_MP_AHB6ENSETR, 12, 1), 429*e5e793a6SGabriel Fernandez GATE_CFG(GATE_QSPI, RCC_MP_AHB6ENSETR, 14, 1), 430*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SDMMC1, RCC_MP_AHB6ENSETR, 16, 1), 431*e5e793a6SGabriel Fernandez GATE_CFG(GATE_SDMMC2, RCC_MP_AHB6ENSETR, 17, 1), 432*e5e793a6SGabriel Fernandez GATE_CFG(GATE_CRC1, RCC_MP_AHB6ENSETR, 20, 1), 433*e5e793a6SGabriel Fernandez GATE_CFG(GATE_USBH, RCC_MP_AHB6ENSETR, 24, 1), 434*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETH2CK, RCC_MP_AHB6ENSETR, 27, 1), 435*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETH2TX, RCC_MP_AHB6ENSETR, 28, 1), 436*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETH2RX, RCC_MP_AHB6ENSETR, 29, 1), 437*e5e793a6SGabriel Fernandez GATE_CFG(GATE_ETH2MAC, RCC_MP_AHB6ENSETR, 30, 1), 438*e5e793a6SGabriel Fernandez GATE_CFG(GATE_MDMA, RCC_MP_S_AHB6ENSETR, 0, 1), 439*e5e793a6SGabriel Fernandez }; 440*e5e793a6SGabriel Fernandez 441*e5e793a6SGabriel Fernandez /* 442*e5e793a6SGabriel Fernandez * MUX CONFIG 443*e5e793a6SGabriel Fernandez */ 444*e5e793a6SGabriel Fernandez #define MUXRDY_CFG(_id, _offset, _shift, _witdh, _rdy)\ 445*e5e793a6SGabriel Fernandez [(_id)] = {\ 446*e5e793a6SGabriel Fernandez .offset = (_offset),\ 447*e5e793a6SGabriel Fernandez .shift = (_shift),\ 448*e5e793a6SGabriel Fernandez .width = (_witdh),\ 449*e5e793a6SGabriel Fernandez .ready = (_rdy),\ 450*e5e793a6SGabriel Fernandez } 451*e5e793a6SGabriel Fernandez 452*e5e793a6SGabriel Fernandez #define MUX_CFG(_id, _offset, _shift, _witdh)\ 453*e5e793a6SGabriel Fernandez MUXRDY_CFG(_id, _offset, _shift, _witdh, MUX_NO_RDY) 454*e5e793a6SGabriel Fernandez 455*e5e793a6SGabriel Fernandez static const struct mux_cfg parent_mp13[MUX_NB] = { 456*e5e793a6SGabriel Fernandez MUXRDY_CFG(MUX_MPU, RCC_MPCKSELR, 0, 2, GATE_MPUSRCRDY), 457*e5e793a6SGabriel Fernandez MUXRDY_CFG(MUX_AXI, RCC_ASSCKSELR, 0, 3, GATE_AXISSRCRDY), 458*e5e793a6SGabriel Fernandez MUXRDY_CFG(MUX_MLAHB, RCC_MSSCKSELR, 0, 2, GATE_MCUSSRCRDY), 459*e5e793a6SGabriel Fernandez MUXRDY_CFG(MUX_PLL12, RCC_RCK12SELR, 0, 2, GATE_PLL12SRCRDY), 460*e5e793a6SGabriel Fernandez MUXRDY_CFG(MUX_PLL3, RCC_RCK3SELR, 0, 2, GATE_PLL3SRCRDY), 461*e5e793a6SGabriel Fernandez MUXRDY_CFG(MUX_PLL4, RCC_RCK4SELR, 0, 2, GATE_PLL4SRCRDY), 462*e5e793a6SGabriel Fernandez MUX_CFG(MUX_ADC1, RCC_ADC12CKSELR, 0, 2), 463*e5e793a6SGabriel Fernandez MUX_CFG(MUX_ADC2, RCC_ADC12CKSELR, 2, 2), 464*e5e793a6SGabriel Fernandez MUX_CFG(MUX_CKPER, RCC_CPERCKSELR, 0, 2), 465*e5e793a6SGabriel Fernandez MUX_CFG(MUX_DCMIPP, RCC_DCMIPPCKSELR, 0, 2), 466*e5e793a6SGabriel Fernandez MUX_CFG(MUX_ETH1, RCC_ETH12CKSELR, 0, 2), 467*e5e793a6SGabriel Fernandez MUX_CFG(MUX_ETH2, RCC_ETH12CKSELR, 8, 2), 468*e5e793a6SGabriel Fernandez MUX_CFG(MUX_FDCAN, RCC_FDCANCKSELR, 0, 2), 469*e5e793a6SGabriel Fernandez MUX_CFG(MUX_FMC, RCC_FMCCKSELR, 0, 2), 470*e5e793a6SGabriel Fernandez MUX_CFG(MUX_I2C12, RCC_I2C12CKSELR, 0, 3), 471*e5e793a6SGabriel Fernandez MUX_CFG(MUX_I2C3, RCC_I2C345CKSELR, 0, 3), 472*e5e793a6SGabriel Fernandez MUX_CFG(MUX_I2C4, RCC_I2C345CKSELR, 3, 3), 473*e5e793a6SGabriel Fernandez MUX_CFG(MUX_I2C5, RCC_I2C345CKSELR, 6, 3), 474*e5e793a6SGabriel Fernandez MUX_CFG(MUX_LPTIM1, RCC_LPTIM1CKSELR, 0, 3), 475*e5e793a6SGabriel Fernandez MUX_CFG(MUX_LPTIM2, RCC_LPTIM23CKSELR, 0, 3), 476*e5e793a6SGabriel Fernandez MUX_CFG(MUX_LPTIM3, RCC_LPTIM23CKSELR, 3, 3), 477*e5e793a6SGabriel Fernandez MUX_CFG(MUX_LPTIM45, RCC_LPTIM45CKSELR, 0, 3), 478*e5e793a6SGabriel Fernandez MUX_CFG(MUX_MCO1, RCC_MCO1CFGR, 0, 3), 479*e5e793a6SGabriel Fernandez MUX_CFG(MUX_MCO2, RCC_MCO2CFGR, 0, 3), 480*e5e793a6SGabriel Fernandez MUX_CFG(MUX_QSPI, RCC_QSPICKSELR, 0, 2), 481*e5e793a6SGabriel Fernandez MUX_CFG(MUX_RNG1, RCC_RNG1CKSELR, 0, 2), 482*e5e793a6SGabriel Fernandez MUX_CFG(MUX_RTC, RCC_BDCR, 16, 2), 483*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SAES, RCC_SAESCKSELR, 0, 2), 484*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SAI1, RCC_SAI1CKSELR, 0, 3), 485*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SAI2, RCC_SAI2CKSELR, 0, 3), 486*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SDMMC1, RCC_SDMMC12CKSELR, 0, 3), 487*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SDMMC2, RCC_SDMMC12CKSELR, 3, 3), 488*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SPDIF, RCC_SPDIFCKSELR, 0, 2), 489*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SPI1, RCC_SPI2S1CKSELR, 0, 3), 490*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SPI23, RCC_SPI2S23CKSELR, 0, 3), 491*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SPI4, RCC_SPI45CKSELR, 0, 3), 492*e5e793a6SGabriel Fernandez MUX_CFG(MUX_SPI5, RCC_SPI45CKSELR, 3, 3), 493*e5e793a6SGabriel Fernandez MUX_CFG(MUX_STGEN, RCC_STGENCKSELR, 0, 2), 494*e5e793a6SGabriel Fernandez MUX_CFG(MUX_UART1, RCC_UART12CKSELR, 0, 3), 495*e5e793a6SGabriel Fernandez MUX_CFG(MUX_UART2, RCC_UART12CKSELR, 3, 3), 496*e5e793a6SGabriel Fernandez MUX_CFG(MUX_UART35, RCC_UART35CKSELR, 0, 3), 497*e5e793a6SGabriel Fernandez MUX_CFG(MUX_UART4, RCC_UART4CKSELR, 0, 3), 498*e5e793a6SGabriel Fernandez MUX_CFG(MUX_UART6, RCC_UART6CKSELR, 0, 3), 499*e5e793a6SGabriel Fernandez MUX_CFG(MUX_UART78, RCC_UART78CKSELR, 0, 3), 500*e5e793a6SGabriel Fernandez MUX_CFG(MUX_USBO, RCC_USBCKSELR, 4, 1), 501*e5e793a6SGabriel Fernandez MUX_CFG(MUX_USBPHY, RCC_USBCKSELR, 0, 2), 502*e5e793a6SGabriel Fernandez }; 503*e5e793a6SGabriel Fernandez 504*e5e793a6SGabriel Fernandez /* 505*e5e793a6SGabriel Fernandez * DIV CONFIG 506*e5e793a6SGabriel Fernandez */ 507*e5e793a6SGabriel Fernandez static const struct div_table_cfg axi_div_table[] = { 508*e5e793a6SGabriel Fernandez { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, 509*e5e793a6SGabriel Fernandez { 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 }, 510*e5e793a6SGabriel Fernandez { 0 }, 511*e5e793a6SGabriel Fernandez }; 512*e5e793a6SGabriel Fernandez 513*e5e793a6SGabriel Fernandez static const struct div_table_cfg mlahb_div_table[] = { 514*e5e793a6SGabriel Fernandez { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, 515*e5e793a6SGabriel Fernandez { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 }, 516*e5e793a6SGabriel Fernandez { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 }, 517*e5e793a6SGabriel Fernandez { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 }, 518*e5e793a6SGabriel Fernandez { 0 }, 519*e5e793a6SGabriel Fernandez }; 520*e5e793a6SGabriel Fernandez 521*e5e793a6SGabriel Fernandez static const struct div_table_cfg apb_div_table[] = { 522*e5e793a6SGabriel Fernandez { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, 523*e5e793a6SGabriel Fernandez { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 }, 524*e5e793a6SGabriel Fernandez { 0 }, 525*e5e793a6SGabriel Fernandez }; 526*e5e793a6SGabriel Fernandez 527*e5e793a6SGabriel Fernandez #define DIVRDY_CFG(_id, _offset, _shift, _width, _flags, _table, _ready)\ 528*e5e793a6SGabriel Fernandez [(_id)] = {\ 529*e5e793a6SGabriel Fernandez .offset = (_offset),\ 530*e5e793a6SGabriel Fernandez .shift = (_shift),\ 531*e5e793a6SGabriel Fernandez .width = (_width),\ 532*e5e793a6SGabriel Fernandez .flags = (_flags),\ 533*e5e793a6SGabriel Fernandez .table = (_table),\ 534*e5e793a6SGabriel Fernandez .ready = (_ready),\ 535*e5e793a6SGabriel Fernandez } 536*e5e793a6SGabriel Fernandez 537*e5e793a6SGabriel Fernandez #define DIV_CFG(_id, _offset, _shift, _width, _flags, _table)\ 538*e5e793a6SGabriel Fernandez DIVRDY_CFG(_id, _offset, _shift, _width, _flags, _table, DIV_NO_RDY) 539*e5e793a6SGabriel Fernandez 540*e5e793a6SGabriel Fernandez static const struct div_cfg dividers_mp13[] = { 541*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 0, NULL, 542*e5e793a6SGabriel Fernandez GATE_MPUDIVRDY), 543*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 0, axi_div_table, 544*e5e793a6SGabriel Fernandez GATE_AXIDIVRDY), 545*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_MLAHB, RCC_MLAHBDIVR, 0, 4, 0, mlahb_div_table, 546*e5e793a6SGabriel Fernandez GATE_MLAHBDIVRDY), 547*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 548*e5e793a6SGabriel Fernandez GATE_APB1DIVRDY), 549*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 550*e5e793a6SGabriel Fernandez GATE_APB2DIVRDY), 551*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 552*e5e793a6SGabriel Fernandez GATE_APB3DIVRDY), 553*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 554*e5e793a6SGabriel Fernandez GATE_APB4DIVRDY), 555*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, 556*e5e793a6SGabriel Fernandez GATE_APB5DIVRDY), 557*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_APB6, RCC_APB6DIVR, 0, 3, 0, apb_div_table, 558*e5e793a6SGabriel Fernandez GATE_APB6DIVRDY), 559*e5e793a6SGabriel Fernandez DIVRDY_CFG(DIV_HSI, RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL, 560*e5e793a6SGabriel Fernandez GATE_HSIDIVRDY), 561*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL), 562*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL), 563*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL), 564*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL2DIVR, RCC_PLL2CFGR2, 16, 7, 0, NULL), 565*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL3DIVP, RCC_PLL3CFGR2, 0, 7, 0, NULL), 566*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL3DIVQ, RCC_PLL3CFGR2, 8, 7, 0, NULL), 567*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL3DIVR, RCC_PLL3CFGR2, 16, 7, 0, NULL), 568*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL4DIVP, RCC_PLL4CFGR2, 0, 7, 0, NULL), 569*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL4DIVQ, RCC_PLL4CFGR2, 8, 7, 0, NULL), 570*e5e793a6SGabriel Fernandez DIV_CFG(DIV_PLL4DIVR, RCC_PLL4CFGR2, 16, 7, 0, NULL), 571*e5e793a6SGabriel Fernandez DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL), 572*e5e793a6SGabriel Fernandez DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL), 573*e5e793a6SGabriel Fernandez DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL), 574*e5e793a6SGabriel Fernandez DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, CLK_DIVIDER_POWER_OF_TWO, NULL), 575*e5e793a6SGabriel Fernandez DIV_CFG(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL), 576*e5e793a6SGabriel Fernandez DIV_CFG(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL), 577*e5e793a6SGabriel Fernandez }; 578*e5e793a6SGabriel Fernandez 579*e5e793a6SGabriel Fernandez enum stm32_osc { 580*e5e793a6SGabriel Fernandez OSC_HSI, 581*e5e793a6SGabriel Fernandez OSC_HSE, 582*e5e793a6SGabriel Fernandez OSC_CSI, 583*e5e793a6SGabriel Fernandez OSC_LSI, 584*e5e793a6SGabriel Fernandez OSC_LSE, 585*e5e793a6SGabriel Fernandez NB_OSCILLATOR 586*e5e793a6SGabriel Fernandez }; 587*e5e793a6SGabriel Fernandez 588*e5e793a6SGabriel Fernandez struct stm32_osc_cfg { 589*e5e793a6SGabriel Fernandez int osc_id; 590*e5e793a6SGabriel Fernandez }; 591*e5e793a6SGabriel Fernandez 592*e5e793a6SGabriel Fernandez struct clk_stm32_bypass { 593*e5e793a6SGabriel Fernandez uint16_t offset; 594*e5e793a6SGabriel Fernandez uint8_t bit_byp; 595*e5e793a6SGabriel Fernandez uint8_t bit_digbyp; 596*e5e793a6SGabriel Fernandez }; 597*e5e793a6SGabriel Fernandez 598*e5e793a6SGabriel Fernandez struct clk_stm32_css { 599*e5e793a6SGabriel Fernandez uint16_t offset; 600*e5e793a6SGabriel Fernandez uint8_t bit_css; 601*e5e793a6SGabriel Fernandez }; 602*e5e793a6SGabriel Fernandez 603*e5e793a6SGabriel Fernandez struct clk_stm32_drive { 604*e5e793a6SGabriel Fernandez uint16_t offset; 605*e5e793a6SGabriel Fernandez uint8_t drv_shift; 606*e5e793a6SGabriel Fernandez uint8_t drv_width; 607*e5e793a6SGabriel Fernandez uint8_t drv_default; 608*e5e793a6SGabriel Fernandez }; 609*e5e793a6SGabriel Fernandez 610*e5e793a6SGabriel Fernandez struct clk_oscillator_data { 611*e5e793a6SGabriel Fernandez const char *name; 612*e5e793a6SGabriel Fernandez unsigned long frequency; 613*e5e793a6SGabriel Fernandez uint16_t gate_id; 614*e5e793a6SGabriel Fernandez struct clk_stm32_bypass *bypass; 615*e5e793a6SGabriel Fernandez struct clk_stm32_css *css; 616*e5e793a6SGabriel Fernandez struct clk_stm32_drive *drive; 617*e5e793a6SGabriel Fernandez }; 618*e5e793a6SGabriel Fernandez 619*e5e793a6SGabriel Fernandez #define BYPASS(_offset, _bit_byp, _bit_digbyp) (&(struct clk_stm32_bypass){\ 620*e5e793a6SGabriel Fernandez .offset = (_offset),\ 621*e5e793a6SGabriel Fernandez .bit_byp = (_bit_byp),\ 622*e5e793a6SGabriel Fernandez .bit_digbyp = (_bit_digbyp),\ 623*e5e793a6SGabriel Fernandez }) 624*e5e793a6SGabriel Fernandez 625*e5e793a6SGabriel Fernandez #define CSS(_offset, _bit_css) (&(struct clk_stm32_css){\ 626*e5e793a6SGabriel Fernandez .offset = (_offset),\ 627*e5e793a6SGabriel Fernandez .bit_css = (_bit_css),\ 628*e5e793a6SGabriel Fernandez }) 629*e5e793a6SGabriel Fernandez 630*e5e793a6SGabriel Fernandez #define DRIVE(_offset, _shift, _width, _default) (&(struct clk_stm32_drive){\ 631*e5e793a6SGabriel Fernandez .offset = (_offset),\ 632*e5e793a6SGabriel Fernandez .drv_shift = (_shift),\ 633*e5e793a6SGabriel Fernandez .drv_width = (_width),\ 634*e5e793a6SGabriel Fernandez .drv_default = (_default),\ 635*e5e793a6SGabriel Fernandez }) 636*e5e793a6SGabriel Fernandez 637*e5e793a6SGabriel Fernandez #define OSCILLATOR(idx_osc, _name, _gate_id, _bypass, _css, _drive) \ 638*e5e793a6SGabriel Fernandez [(idx_osc)] = (struct clk_oscillator_data){\ 639*e5e793a6SGabriel Fernandez .name = (_name),\ 640*e5e793a6SGabriel Fernandez .gate_id = (_gate_id),\ 641*e5e793a6SGabriel Fernandez .bypass = (_bypass),\ 642*e5e793a6SGabriel Fernandez .css = (_css),\ 643*e5e793a6SGabriel Fernandez .drive = (_drive),\ 644*e5e793a6SGabriel Fernandez } 645*e5e793a6SGabriel Fernandez 646*e5e793a6SGabriel Fernandez static struct clk_oscillator_data stm32mp13_osc_data[NB_OSCILLATOR] = { 647*e5e793a6SGabriel Fernandez OSCILLATOR(OSC_HSI, "clk-hsi", GATE_HSI, 648*e5e793a6SGabriel Fernandez NULL, NULL, NULL), 649*e5e793a6SGabriel Fernandez 650*e5e793a6SGabriel Fernandez OSCILLATOR(OSC_LSI, "clk-lsi", GATE_LSI, 651*e5e793a6SGabriel Fernandez NULL, NULL, NULL), 652*e5e793a6SGabriel Fernandez 653*e5e793a6SGabriel Fernandez OSCILLATOR(OSC_CSI, "clk-csi", GATE_CSI, 654*e5e793a6SGabriel Fernandez NULL, NULL, NULL), 655*e5e793a6SGabriel Fernandez 656*e5e793a6SGabriel Fernandez OSCILLATOR(OSC_LSE, "clk-lse", GATE_LSE, 657*e5e793a6SGabriel Fernandez BYPASS(RCC_BDCR, 1, 3), 658*e5e793a6SGabriel Fernandez CSS(RCC_BDCR, 8), 659*e5e793a6SGabriel Fernandez DRIVE(RCC_BDCR, 4, 2, 2)), 660*e5e793a6SGabriel Fernandez 661*e5e793a6SGabriel Fernandez OSCILLATOR(OSC_HSE, "clk-hse", GATE_HSE, 662*e5e793a6SGabriel Fernandez BYPASS(RCC_OCENSETR, 10, 7), 663*e5e793a6SGabriel Fernandez CSS(RCC_OCENSETR, 11), 664*e5e793a6SGabriel Fernandez NULL), 665*e5e793a6SGabriel Fernandez }; 666*e5e793a6SGabriel Fernandez 667*e5e793a6SGabriel Fernandez static struct clk_oscillator_data *clk_oscillator_get_data(int osc_id) 668*e5e793a6SGabriel Fernandez { 669*e5e793a6SGabriel Fernandez assert(osc_id >= 0 && osc_id < (int)ARRAY_SIZE(stm32mp13_osc_data)); 670*e5e793a6SGabriel Fernandez 671*e5e793a6SGabriel Fernandez return &stm32mp13_osc_data[osc_id]; 672*e5e793a6SGabriel Fernandez } 673*e5e793a6SGabriel Fernandez 674*e5e793a6SGabriel Fernandez static unsigned long clk_stm32_get_rate_oscillateur(int osc_id) 675*e5e793a6SGabriel Fernandez { 676*e5e793a6SGabriel Fernandez struct clk_stm32_priv *priv = clk_stm32_get_priv(); 677*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 678*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[osc_id]; 679*e5e793a6SGabriel Fernandez 680*e5e793a6SGabriel Fernandez return osci->freq; 681*e5e793a6SGabriel Fernandez } 682*e5e793a6SGabriel Fernandez 683*e5e793a6SGabriel Fernandez static void clk_oscillator_set_bypass(struct clk_stm32_priv *priv, 684*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data, 685*e5e793a6SGabriel Fernandez bool digbyp, bool bypass) 686*e5e793a6SGabriel Fernandez { 687*e5e793a6SGabriel Fernandez struct clk_stm32_bypass *bypass_data = osc_data->bypass; 688*e5e793a6SGabriel Fernandez uintptr_t address = 0; 689*e5e793a6SGabriel Fernandez 690*e5e793a6SGabriel Fernandez if (!bypass_data) 691*e5e793a6SGabriel Fernandez return; 692*e5e793a6SGabriel Fernandez 693*e5e793a6SGabriel Fernandez address = priv->base + bypass_data->offset; 694*e5e793a6SGabriel Fernandez 695*e5e793a6SGabriel Fernandez if (digbyp) 696*e5e793a6SGabriel Fernandez io_setbits32(address, BIT(bypass_data->bit_digbyp)); 697*e5e793a6SGabriel Fernandez 698*e5e793a6SGabriel Fernandez if (bypass || digbyp) 699*e5e793a6SGabriel Fernandez io_setbits32(address, BIT(bypass_data->bit_byp)); 700*e5e793a6SGabriel Fernandez } 701*e5e793a6SGabriel Fernandez 702*e5e793a6SGabriel Fernandez static void clk_oscillator_set_css(struct clk_stm32_priv *priv, 703*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data, 704*e5e793a6SGabriel Fernandez bool css) 705*e5e793a6SGabriel Fernandez { 706*e5e793a6SGabriel Fernandez struct clk_stm32_css *css_data = osc_data->css; 707*e5e793a6SGabriel Fernandez uintptr_t address = 0; 708*e5e793a6SGabriel Fernandez 709*e5e793a6SGabriel Fernandez if (!css_data) 710*e5e793a6SGabriel Fernandez return; 711*e5e793a6SGabriel Fernandez 712*e5e793a6SGabriel Fernandez address = priv->base + css_data->offset; 713*e5e793a6SGabriel Fernandez 714*e5e793a6SGabriel Fernandez if (css) 715*e5e793a6SGabriel Fernandez io_setbits32(address, BIT(css_data->bit_css)); 716*e5e793a6SGabriel Fernandez } 717*e5e793a6SGabriel Fernandez 718*e5e793a6SGabriel Fernandez static void clk_oscillator_set_drive(struct clk_stm32_priv *priv, 719*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data, 720*e5e793a6SGabriel Fernandez uint8_t lsedrv) 721*e5e793a6SGabriel Fernandez { 722*e5e793a6SGabriel Fernandez struct clk_stm32_drive *drive_data = osc_data->drive; 723*e5e793a6SGabriel Fernandez uintptr_t address = 0; 724*e5e793a6SGabriel Fernandez uint32_t mask = 0; 725*e5e793a6SGabriel Fernandez uint32_t value = 0; 726*e5e793a6SGabriel Fernandez 727*e5e793a6SGabriel Fernandez if (!drive_data) 728*e5e793a6SGabriel Fernandez return; 729*e5e793a6SGabriel Fernandez 730*e5e793a6SGabriel Fernandez address = priv->base + drive_data->offset; 731*e5e793a6SGabriel Fernandez 732*e5e793a6SGabriel Fernandez mask = (BIT(drive_data->drv_width) - 1U) << drive_data->drv_shift; 733*e5e793a6SGabriel Fernandez 734*e5e793a6SGabriel Fernandez /* 735*e5e793a6SGabriel Fernandez * Warning: not recommended to switch directly from "high drive" 736*e5e793a6SGabriel Fernandez * to "medium low drive", and vice-versa. 737*e5e793a6SGabriel Fernandez */ 738*e5e793a6SGabriel Fernandez value = (io_read32(address) & mask) >> drive_data->drv_shift; 739*e5e793a6SGabriel Fernandez 740*e5e793a6SGabriel Fernandez while (value != lsedrv) { 741*e5e793a6SGabriel Fernandez if (value > lsedrv) 742*e5e793a6SGabriel Fernandez value--; 743*e5e793a6SGabriel Fernandez else 744*e5e793a6SGabriel Fernandez value++; 745*e5e793a6SGabriel Fernandez 746*e5e793a6SGabriel Fernandez io_clrsetbits32(address, mask, value << drive_data->drv_shift); 747*e5e793a6SGabriel Fernandez } 748*e5e793a6SGabriel Fernandez } 749*e5e793a6SGabriel Fernandez 750*e5e793a6SGabriel Fernandez static void stm32_enable_oscillator_hse(struct clk_stm32_priv *priv, 751*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 752*e5e793a6SGabriel Fernandez { 753*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_HSE); 754*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE]; 755*e5e793a6SGabriel Fernandez 756*e5e793a6SGabriel Fernandez if (osci->freq == 0U) 757*e5e793a6SGabriel Fernandez return; 758*e5e793a6SGabriel Fernandez 759*e5e793a6SGabriel Fernandez clk_oscillator_set_bypass(priv, osc_data, osci->digbyp, osci->bypass); 760*e5e793a6SGabriel Fernandez 761*e5e793a6SGabriel Fernandez /* Enable clock and wait ready bit */ 762*e5e793a6SGabriel Fernandez if (stm32_gate_rdy_enable(osc_data->gate_id)) { 763*e5e793a6SGabriel Fernandez EMSG("timeout to enable hse clock"); 764*e5e793a6SGabriel Fernandez panic(); 765*e5e793a6SGabriel Fernandez } 766*e5e793a6SGabriel Fernandez 767*e5e793a6SGabriel Fernandez clk_oscillator_set_css(priv, osc_data, osci->css); 768*e5e793a6SGabriel Fernandez } 769*e5e793a6SGabriel Fernandez 770*e5e793a6SGabriel Fernandez static void stm32_enable_oscillator_lse(struct clk_stm32_priv *priv, 771*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 772*e5e793a6SGabriel Fernandez { 773*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_LSE); 774*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE]; 775*e5e793a6SGabriel Fernandez 776*e5e793a6SGabriel Fernandez if (osci->freq == 0U) 777*e5e793a6SGabriel Fernandez return; 778*e5e793a6SGabriel Fernandez 779*e5e793a6SGabriel Fernandez clk_oscillator_set_bypass(priv, osc_data, osci->digbyp, osci->bypass); 780*e5e793a6SGabriel Fernandez 781*e5e793a6SGabriel Fernandez clk_oscillator_set_drive(priv, osc_data, osci->drive); 782*e5e793a6SGabriel Fernandez 783*e5e793a6SGabriel Fernandez /* Enable lse clock, but don't wait ready bit */ 784*e5e793a6SGabriel Fernandez stm32_gate_enable(osc_data->gate_id); 785*e5e793a6SGabriel Fernandez } 786*e5e793a6SGabriel Fernandez 787*e5e793a6SGabriel Fernandez static void 788*e5e793a6SGabriel Fernandez stm32_enable_oscillator_lsi(struct clk_stm32_priv *priv __maybe_unused, 789*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 790*e5e793a6SGabriel Fernandez { 791*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_LSI); 792*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSI]; 793*e5e793a6SGabriel Fernandez 794*e5e793a6SGabriel Fernandez if (osci->freq == 0U) 795*e5e793a6SGabriel Fernandez return; 796*e5e793a6SGabriel Fernandez 797*e5e793a6SGabriel Fernandez /* Enable clock and wait ready bit */ 798*e5e793a6SGabriel Fernandez if (stm32_gate_rdy_enable(osc_data->gate_id)) { 799*e5e793a6SGabriel Fernandez EMSG("timeout to enable lsi clock"); 800*e5e793a6SGabriel Fernandez panic(); 801*e5e793a6SGabriel Fernandez } 802*e5e793a6SGabriel Fernandez } 803*e5e793a6SGabriel Fernandez 804*e5e793a6SGabriel Fernandez static void 805*e5e793a6SGabriel Fernandez stm32_enable_oscillator_csi(struct clk_stm32_priv *priv __maybe_unused, 806*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 807*e5e793a6SGabriel Fernandez { 808*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_CSI); 809*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_CSI]; 810*e5e793a6SGabriel Fernandez 811*e5e793a6SGabriel Fernandez if (osci->freq == 0U) 812*e5e793a6SGabriel Fernandez return; 813*e5e793a6SGabriel Fernandez 814*e5e793a6SGabriel Fernandez /* Enable clock and wait ready bit */ 815*e5e793a6SGabriel Fernandez if (stm32_gate_rdy_enable(osc_data->gate_id)) { 816*e5e793a6SGabriel Fernandez EMSG("timeout to enable csi clock"); 817*e5e793a6SGabriel Fernandez panic(); 818*e5e793a6SGabriel Fernandez } 819*e5e793a6SGabriel Fernandez } 820*e5e793a6SGabriel Fernandez 821*e5e793a6SGabriel Fernandez static int stm32_clk_oscillators_lse_set_css(struct clk_stm32_priv *priv, 822*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 823*e5e793a6SGabriel Fernandez 824*e5e793a6SGabriel Fernandez { 825*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_LSE); 826*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE]; 827*e5e793a6SGabriel Fernandez 828*e5e793a6SGabriel Fernandez clk_oscillator_set_css(priv, osc_data, osci->css); 829*e5e793a6SGabriel Fernandez 830*e5e793a6SGabriel Fernandez return 0; 831*e5e793a6SGabriel Fernandez } 832*e5e793a6SGabriel Fernandez 833*e5e793a6SGabriel Fernandez static int 834*e5e793a6SGabriel Fernandez stm32_clk_oscillators_wait_lse_ready(struct clk_stm32_priv *priv __maybe_unused, 835*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 836*e5e793a6SGabriel Fernandez { 837*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(OSC_LSE); 838*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE]; 839*e5e793a6SGabriel Fernandez 840*e5e793a6SGabriel Fernandez if (osci->freq == 0U) 841*e5e793a6SGabriel Fernandez return 0; 842*e5e793a6SGabriel Fernandez 843*e5e793a6SGabriel Fernandez if (stm32_gate_wait_ready(osc_data->gate_id, true)) 844*e5e793a6SGabriel Fernandez return -1; 845*e5e793a6SGabriel Fernandez 846*e5e793a6SGabriel Fernandez return 0; 847*e5e793a6SGabriel Fernandez } 848*e5e793a6SGabriel Fernandez 849*e5e793a6SGabriel Fernandez static void stm32_clk_oscillators_enable(struct clk_stm32_priv *priv, 850*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 851*e5e793a6SGabriel Fernandez { 852*e5e793a6SGabriel Fernandez stm32_enable_oscillator_hse(priv, pdata); 853*e5e793a6SGabriel Fernandez stm32_enable_oscillator_lse(priv, pdata); 854*e5e793a6SGabriel Fernandez stm32_enable_oscillator_lsi(priv, pdata); 855*e5e793a6SGabriel Fernandez stm32_enable_oscillator_csi(priv, pdata); 856*e5e793a6SGabriel Fernandez } 857*e5e793a6SGabriel Fernandez 858*e5e793a6SGabriel Fernandez enum stm32_pll_id { 859*e5e793a6SGabriel Fernandez PLL1_ID, 860*e5e793a6SGabriel Fernandez PLL2_ID, 861*e5e793a6SGabriel Fernandez PLL3_ID, 862*e5e793a6SGabriel Fernandez PLL4_ID, 863*e5e793a6SGabriel Fernandez PLL_NB 864*e5e793a6SGabriel Fernandez }; 865*e5e793a6SGabriel Fernandez 866*e5e793a6SGabriel Fernandez enum stm32mp1_plltype { 867*e5e793a6SGabriel Fernandez PLL_800, 868*e5e793a6SGabriel Fernandez PLL_1600, 869*e5e793a6SGabriel Fernandez PLL_2000, 870*e5e793a6SGabriel Fernandez PLL_TYPE_NB 871*e5e793a6SGabriel Fernandez }; 872*e5e793a6SGabriel Fernandez 873*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXCR 0 874*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXCFGR1 4 875*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXCFGR2 8 876*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXFRACR 12 877*e5e793a6SGabriel Fernandez #define RCC_OFFSET_PLLXCSGR 16 878*e5e793a6SGabriel Fernandez 879*e5e793a6SGabriel Fernandez struct stm32_clk_pll { 880*e5e793a6SGabriel Fernandez enum stm32mp1_plltype plltype; 881*e5e793a6SGabriel Fernandez uint16_t gate_id; 882*e5e793a6SGabriel Fernandez uint16_t mux_id; 883*e5e793a6SGabriel Fernandez uint16_t reg_pllxcr; 884*e5e793a6SGabriel Fernandez }; 885*e5e793a6SGabriel Fernandez 886*e5e793a6SGabriel Fernandez struct stm32mp1_pll { 887*e5e793a6SGabriel Fernandez uint8_t refclk_min; 888*e5e793a6SGabriel Fernandez uint8_t refclk_max; 889*e5e793a6SGabriel Fernandez }; 890*e5e793a6SGabriel Fernandez 891*e5e793a6SGabriel Fernandez /* Define characteristic of PLL according type */ 892*e5e793a6SGabriel Fernandez static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = { 893*e5e793a6SGabriel Fernandez [PLL_800] = { 894*e5e793a6SGabriel Fernandez .refclk_min = 4, 895*e5e793a6SGabriel Fernandez .refclk_max = 16, 896*e5e793a6SGabriel Fernandez }, 897*e5e793a6SGabriel Fernandez [PLL_1600] = { 898*e5e793a6SGabriel Fernandez .refclk_min = 8, 899*e5e793a6SGabriel Fernandez .refclk_max = 16, 900*e5e793a6SGabriel Fernandez }, 901*e5e793a6SGabriel Fernandez [PLL_2000] = { 902*e5e793a6SGabriel Fernandez .refclk_min = 8, 903*e5e793a6SGabriel Fernandez .refclk_max = 16, 904*e5e793a6SGabriel Fernandez } 905*e5e793a6SGabriel Fernandez }; 906*e5e793a6SGabriel Fernandez 907*e5e793a6SGabriel Fernandez #define CLK_PLL_CFG(_idx, _type, _gate_id, _mux_id, _reg)\ 908*e5e793a6SGabriel Fernandez [(_idx)] = {\ 909*e5e793a6SGabriel Fernandez .gate_id = (_gate_id),\ 910*e5e793a6SGabriel Fernandez .mux_id = (_mux_id),\ 911*e5e793a6SGabriel Fernandez .plltype = (_type),\ 912*e5e793a6SGabriel Fernandez .reg_pllxcr = (_reg),\ 913*e5e793a6SGabriel Fernandez } 914*e5e793a6SGabriel Fernandez 915*e5e793a6SGabriel Fernandez static const struct stm32_clk_pll stm32_mp13_clk_pll[PLL_NB] = { 916*e5e793a6SGabriel Fernandez CLK_PLL_CFG(PLL1_ID, PLL_2000, GATE_PLL1, MUX_PLL12, RCC_PLL1CR), 917*e5e793a6SGabriel Fernandez CLK_PLL_CFG(PLL2_ID, PLL_1600, GATE_PLL2, MUX_PLL12, RCC_PLL2CR), 918*e5e793a6SGabriel Fernandez CLK_PLL_CFG(PLL3_ID, PLL_800, GATE_PLL3, MUX_PLL3, RCC_PLL3CR), 919*e5e793a6SGabriel Fernandez CLK_PLL_CFG(PLL4_ID, PLL_800, GATE_PLL4, MUX_PLL4, RCC_PLL4CR), 920*e5e793a6SGabriel Fernandez }; 921*e5e793a6SGabriel Fernandez 922*e5e793a6SGabriel Fernandez static const struct stm32_clk_pll *clk_stm32_pll_data(unsigned int idx) 923*e5e793a6SGabriel Fernandez { 924*e5e793a6SGabriel Fernandez return &stm32_mp13_clk_pll[idx]; 925*e5e793a6SGabriel Fernandez } 926*e5e793a6SGabriel Fernandez 927*e5e793a6SGabriel Fernandez /* Clock TREE configuration */ 928*e5e793a6SGabriel Fernandez 929*e5e793a6SGabriel Fernandez static unsigned int stm32_clk_configure_clk_get_binding_id(uint32_t data) 930*e5e793a6SGabriel Fernandez { 931*e5e793a6SGabriel Fernandez return (data & CLK_ID_MASK) >> CLK_ID_SHIFT; 932*e5e793a6SGabriel Fernandez } 933*e5e793a6SGabriel Fernandez 934*e5e793a6SGabriel Fernandez static int stm32_clk_configure_clk(struct clk_stm32_priv *priv __maybe_unused, 935*e5e793a6SGabriel Fernandez uint32_t data) 936*e5e793a6SGabriel Fernandez { 937*e5e793a6SGabriel Fernandez int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT; 938*e5e793a6SGabriel Fernandez int enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT; 939*e5e793a6SGabriel Fernandez int clk_id = 0; 940*e5e793a6SGabriel Fernandez int ret = 0; 941*e5e793a6SGabriel Fernandez int mux = -1; 942*e5e793a6SGabriel Fernandez int gate = -1; 943*e5e793a6SGabriel Fernandez 944*e5e793a6SGabriel Fernandez clk_id = stm32_clk_configure_clk_get_binding_id(data); 945*e5e793a6SGabriel Fernandez 946*e5e793a6SGabriel Fernandez switch (clk_id) { 947*e5e793a6SGabriel Fernandez case CK_MCO1: 948*e5e793a6SGabriel Fernandez mux = MUX_MCO1; 949*e5e793a6SGabriel Fernandez gate = GATE_MCO1; 950*e5e793a6SGabriel Fernandez break; 951*e5e793a6SGabriel Fernandez 952*e5e793a6SGabriel Fernandez case CK_MCO2: 953*e5e793a6SGabriel Fernandez mux = MUX_MCO2; 954*e5e793a6SGabriel Fernandez gate = GATE_MCO2; 955*e5e793a6SGabriel Fernandez break; 956*e5e793a6SGabriel Fernandez default: 957*e5e793a6SGabriel Fernandez ret = -1; 958*e5e793a6SGabriel Fernandez break; 959*e5e793a6SGabriel Fernandez } 960*e5e793a6SGabriel Fernandez 961*e5e793a6SGabriel Fernandez if (ret != 0) 962*e5e793a6SGabriel Fernandez return ret; 963*e5e793a6SGabriel Fernandez 964*e5e793a6SGabriel Fernandez if (stm32_mux_set_parent(mux, sel)) 965*e5e793a6SGabriel Fernandez return -1; 966*e5e793a6SGabriel Fernandez 967*e5e793a6SGabriel Fernandez if (enable) 968*e5e793a6SGabriel Fernandez stm32_gate_enable(gate); 969*e5e793a6SGabriel Fernandez else 970*e5e793a6SGabriel Fernandez stm32_gate_disable(gate); 971*e5e793a6SGabriel Fernandez 972*e5e793a6SGabriel Fernandez return 0; 973*e5e793a6SGabriel Fernandez } 974*e5e793a6SGabriel Fernandez 975*e5e793a6SGabriel Fernandez static int stm32_clk_configure_mux(__unused struct clk_stm32_priv *priv, 976*e5e793a6SGabriel Fernandez uint32_t data) 977*e5e793a6SGabriel Fernandez { 978*e5e793a6SGabriel Fernandez int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT; 979*e5e793a6SGabriel Fernandez int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT; 980*e5e793a6SGabriel Fernandez 981*e5e793a6SGabriel Fernandez if (mux == MUX_RTC) { 982*e5e793a6SGabriel Fernandez /* Mux RTC clock only is selector is valid and RTC not yet 983*e5e793a6SGabriel Fernandez * enabled 984*e5e793a6SGabriel Fernandez */ 985*e5e793a6SGabriel Fernandez if (sel == 0) 986*e5e793a6SGabriel Fernandez return 0; 987*e5e793a6SGabriel Fernandez 988*e5e793a6SGabriel Fernandez if (stm32_gate_is_enabled(GATE_RTCCK)) 989*e5e793a6SGabriel Fernandez return 0; 990*e5e793a6SGabriel Fernandez } 991*e5e793a6SGabriel Fernandez 992*e5e793a6SGabriel Fernandez if (stm32_mux_set_parent(mux, sel)) 993*e5e793a6SGabriel Fernandez return -1; 994*e5e793a6SGabriel Fernandez 995*e5e793a6SGabriel Fernandez return 0; 996*e5e793a6SGabriel Fernandez } 997*e5e793a6SGabriel Fernandez 998*e5e793a6SGabriel Fernandez static TEE_Result 999*e5e793a6SGabriel Fernandez stm32_clk_configure_div(struct clk_stm32_priv *priv __maybe_unused, 1000*e5e793a6SGabriel Fernandez uint32_t data) 1001*e5e793a6SGabriel Fernandez { 1002*e5e793a6SGabriel Fernandez int div_id = (data & DIV_ID_MASK) >> DIV_ID_SHIFT; 1003*e5e793a6SGabriel Fernandez int div_n = (data & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT; 1004*e5e793a6SGabriel Fernandez 1005*e5e793a6SGabriel Fernandez return stm32_div_set_value(div_id, div_n); 1006*e5e793a6SGabriel Fernandez } 1007*e5e793a6SGabriel Fernandez 1008*e5e793a6SGabriel Fernandez static int stm32_clk_dividers_configure(struct clk_stm32_priv *priv) 1009*e5e793a6SGabriel Fernandez { 1010*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 1011*e5e793a6SGabriel Fernandez unsigned int i = 0; 1012*e5e793a6SGabriel Fernandez 1013*e5e793a6SGabriel Fernandez for (i = 0; i < pdata->nclkdiv; i++) { 1014*e5e793a6SGabriel Fernandez if (stm32_clk_configure_div(priv, pdata->clkdiv[i])) 1015*e5e793a6SGabriel Fernandez return -1; 1016*e5e793a6SGabriel Fernandez } 1017*e5e793a6SGabriel Fernandez 1018*e5e793a6SGabriel Fernandez return 0; 1019*e5e793a6SGabriel Fernandez } 1020*e5e793a6SGabriel Fernandez 1021*e5e793a6SGabriel Fernandez static int stm32_clk_source_configure(struct clk_stm32_priv *priv) 1022*e5e793a6SGabriel Fernandez { 1023*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 1024*e5e793a6SGabriel Fernandez bool ckper_disabled = false; 1025*e5e793a6SGabriel Fernandez int ret = 0; 1026*e5e793a6SGabriel Fernandez size_t i = 0; 1027*e5e793a6SGabriel Fernandez 1028*e5e793a6SGabriel Fernandez for (i = 0; i < pdata->nclksrc; i++) { 1029*e5e793a6SGabriel Fernandez uint32_t val = pdata->clksrc[i]; 1030*e5e793a6SGabriel Fernandez uint32_t cmd = 0; 1031*e5e793a6SGabriel Fernandez uint32_t cmd_data = 0; 1032*e5e793a6SGabriel Fernandez 1033*e5e793a6SGabriel Fernandez if (val == (uint32_t)CLK_CKPER_DISABLED) { 1034*e5e793a6SGabriel Fernandez ckper_disabled = true; 1035*e5e793a6SGabriel Fernandez continue; 1036*e5e793a6SGabriel Fernandez } 1037*e5e793a6SGabriel Fernandez 1038*e5e793a6SGabriel Fernandez cmd = (val & CMD_MASK) >> CMD_SHIFT; 1039*e5e793a6SGabriel Fernandez cmd_data = val & ~CMD_MASK; 1040*e5e793a6SGabriel Fernandez 1041*e5e793a6SGabriel Fernandez switch (cmd) { 1042*e5e793a6SGabriel Fernandez case CMD_MUX: 1043*e5e793a6SGabriel Fernandez ret = stm32_clk_configure_mux(priv, cmd_data); 1044*e5e793a6SGabriel Fernandez break; 1045*e5e793a6SGabriel Fernandez 1046*e5e793a6SGabriel Fernandez case CMD_CLK: 1047*e5e793a6SGabriel Fernandez ret = stm32_clk_configure_clk(priv, cmd_data); 1048*e5e793a6SGabriel Fernandez break; 1049*e5e793a6SGabriel Fernandez default: 1050*e5e793a6SGabriel Fernandez ret = -1; 1051*e5e793a6SGabriel Fernandez break; 1052*e5e793a6SGabriel Fernandez } 1053*e5e793a6SGabriel Fernandez 1054*e5e793a6SGabriel Fernandez if (ret != 0) 1055*e5e793a6SGabriel Fernandez return ret; 1056*e5e793a6SGabriel Fernandez } 1057*e5e793a6SGabriel Fernandez 1058*e5e793a6SGabriel Fernandez /* 1059*e5e793a6SGabriel Fernandez * CKPER is source for some peripheral clocks 1060*e5e793a6SGabriel Fernandez * (FMC-NAND / QPSI-NOR) and switching source is allowed 1061*e5e793a6SGabriel Fernandez * only if previous clock is still ON 1062*e5e793a6SGabriel Fernandez * => deactivate CKPER only after switching clock 1063*e5e793a6SGabriel Fernandez */ 1064*e5e793a6SGabriel Fernandez if (ckper_disabled) { 1065*e5e793a6SGabriel Fernandez ret = stm32_clk_configure_mux(priv, 1066*e5e793a6SGabriel Fernandez CLK_CKPER_DISABLED & CMD_MASK); 1067*e5e793a6SGabriel Fernandez if (ret != 0) 1068*e5e793a6SGabriel Fernandez return ret; 1069*e5e793a6SGabriel Fernandez } 1070*e5e793a6SGabriel Fernandez 1071*e5e793a6SGabriel Fernandez return 0; 1072*e5e793a6SGabriel Fernandez } 1073*e5e793a6SGabriel Fernandez 1074*e5e793a6SGabriel Fernandez static unsigned long clk_stm32_pll_get_oscillator_rate(int sel) 1075*e5e793a6SGabriel Fernandez { 1076*e5e793a6SGabriel Fernandez const int osc[] = { OSC_HSI, OSC_HSE, OSC_CSI }; 1077*e5e793a6SGabriel Fernandez 1078*e5e793a6SGabriel Fernandez assert(sel >= 0 && sel < (int)ARRAY_SIZE(osc)); 1079*e5e793a6SGabriel Fernandez 1080*e5e793a6SGabriel Fernandez return clk_stm32_get_rate_oscillateur(osc[sel]); 1081*e5e793a6SGabriel Fernandez } 1082*e5e793a6SGabriel Fernandez 1083*e5e793a6SGabriel Fernandez static int clk_stm32_pll_compute_cfgr1(const struct stm32_clk_pll *pll, 1084*e5e793a6SGabriel Fernandez struct stm32_pll_vco *vco, 1085*e5e793a6SGabriel Fernandez uint32_t *value) 1086*e5e793a6SGabriel Fernandez { 1087*e5e793a6SGabriel Fernandez int sel = (vco->src & MUX_SEL_MASK) >> MUX_SEL_SHIFT; 1088*e5e793a6SGabriel Fernandez uint32_t divm = vco->div_mn[PLL_CFG_M]; 1089*e5e793a6SGabriel Fernandez uint32_t divn = vco->div_mn[PLL_CFG_N]; 1090*e5e793a6SGabriel Fernandez unsigned long refclk = 0UL; 1091*e5e793a6SGabriel Fernandez 1092*e5e793a6SGabriel Fernandez refclk = clk_stm32_pll_get_oscillator_rate(sel) / (divm + 1U); 1093*e5e793a6SGabriel Fernandez 1094*e5e793a6SGabriel Fernandez if ((refclk < (stm32mp1_pll[pll->plltype].refclk_min * 1000000U)) || 1095*e5e793a6SGabriel Fernandez (refclk > (stm32mp1_pll[pll->plltype].refclk_max * 1000000U))) 1096*e5e793a6SGabriel Fernandez return -1; 1097*e5e793a6SGabriel Fernandez 1098*e5e793a6SGabriel Fernandez *value = 0; 1099*e5e793a6SGabriel Fernandez 1100*e5e793a6SGabriel Fernandez if (pll->plltype == PLL_800 && refclk >= 8000000U) 1101*e5e793a6SGabriel Fernandez *value = 1U << RCC_PLLNCFGR1_IFRGE_SHIFT; 1102*e5e793a6SGabriel Fernandez 1103*e5e793a6SGabriel Fernandez *value |= (divn << RCC_PLLNCFGR1_DIVN_SHIFT) & RCC_PLLNCFGR1_DIVN_MASK; 1104*e5e793a6SGabriel Fernandez *value |= (divm << RCC_PLLNCFGR1_DIVM_SHIFT) & RCC_PLLNCFGR1_DIVM_MASK; 1105*e5e793a6SGabriel Fernandez 1106*e5e793a6SGabriel Fernandez return 0; 1107*e5e793a6SGabriel Fernandez } 1108*e5e793a6SGabriel Fernandez 1109*e5e793a6SGabriel Fernandez static uint32_t clk_stm32_pll_compute_cfgr2(struct stm32_pll_output *out) 1110*e5e793a6SGabriel Fernandez { 1111*e5e793a6SGabriel Fernandez uint32_t value = 0; 1112*e5e793a6SGabriel Fernandez 1113*e5e793a6SGabriel Fernandez value |= (out->output[PLL_CFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) & 1114*e5e793a6SGabriel Fernandez RCC_PLLNCFGR2_DIVP_MASK; 1115*e5e793a6SGabriel Fernandez value |= (out->output[PLL_CFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) & 1116*e5e793a6SGabriel Fernandez RCC_PLLNCFGR2_DIVQ_MASK; 1117*e5e793a6SGabriel Fernandez value |= (out->output[PLL_CFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) & 1118*e5e793a6SGabriel Fernandez RCC_PLLNCFGR2_DIVR_MASK; 1119*e5e793a6SGabriel Fernandez 1120*e5e793a6SGabriel Fernandez return value; 1121*e5e793a6SGabriel Fernandez } 1122*e5e793a6SGabriel Fernandez 1123*e5e793a6SGabriel Fernandez /* 1124*e5e793a6SGabriel Fernandez * Check if PLL1 can be configured on the fly. 1125*e5e793a6SGabriel Fernandez * @result (-1) => config on the fly is not possible. 1126*e5e793a6SGabriel Fernandez * (0) => config on the fly is possible. 1127*e5e793a6SGabriel Fernandez * (+1) => same parameters, no need to reconfigure. 1128*e5e793a6SGabriel Fernandez * Return value is 0 if no error. 1129*e5e793a6SGabriel Fernandez */ 1130*e5e793a6SGabriel Fernandez static int clk_stm32_is_pll_config_on_the_fly(struct clk_stm32_priv *priv, 1131*e5e793a6SGabriel Fernandez const struct stm32_clk_pll *pll, 1132*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf, 1133*e5e793a6SGabriel Fernandez int *result) 1134*e5e793a6SGabriel Fernandez { 1135*e5e793a6SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 1136*e5e793a6SGabriel Fernandez struct stm32_pll_vco *vco = &pll_conf->vco; 1137*e5e793a6SGabriel Fernandez struct stm32_pll_output *out = &pll_conf->output; 1138*e5e793a6SGabriel Fernandez uint32_t fracr = 0; 1139*e5e793a6SGabriel Fernandez uint32_t value = 0; 1140*e5e793a6SGabriel Fernandez int ret = 0; 1141*e5e793a6SGabriel Fernandez size_t sel = 0; 1142*e5e793a6SGabriel Fernandez 1143*e5e793a6SGabriel Fernandez ret = clk_stm32_pll_compute_cfgr1(pll, vco, &value); 1144*e5e793a6SGabriel Fernandez if (ret != 0) 1145*e5e793a6SGabriel Fernandez return ret; 1146*e5e793a6SGabriel Fernandez 1147*e5e793a6SGabriel Fernandez sel = (vco->src & MUX_SEL_MASK) >> MUX_SEL_SHIFT; 1148*e5e793a6SGabriel Fernandez if (sel != stm32_mux_get_parent(pll->mux_id)) { 1149*e5e793a6SGabriel Fernandez /* Clock source of the PLL is different */ 1150*e5e793a6SGabriel Fernandez *result = -1; 1151*e5e793a6SGabriel Fernandez return 0; 1152*e5e793a6SGabriel Fernandez } 1153*e5e793a6SGabriel Fernandez 1154*e5e793a6SGabriel Fernandez if (io_read32(pll_base + RCC_OFFSET_PLLXCFGR1) != value) { 1155*e5e793a6SGabriel Fernandez /* Different DIVN/DIVM, can't config on the fly */ 1156*e5e793a6SGabriel Fernandez *result = -1; 1157*e5e793a6SGabriel Fernandez return 0; 1158*e5e793a6SGabriel Fernandez } 1159*e5e793a6SGabriel Fernandez 1160*e5e793a6SGabriel Fernandez *result = 1; 1161*e5e793a6SGabriel Fernandez 1162*e5e793a6SGabriel Fernandez fracr = vco->frac << RCC_PLLNFRACR_FRACV_SHIFT; 1163*e5e793a6SGabriel Fernandez fracr |= RCC_PLLNCFGR1_DIVM_MASK; 1164*e5e793a6SGabriel Fernandez value = clk_stm32_pll_compute_cfgr2(out); 1165*e5e793a6SGabriel Fernandez 1166*e5e793a6SGabriel Fernandez if ((io_read32(pll_base + RCC_OFFSET_PLLXFRACR) == fracr) && 1167*e5e793a6SGabriel Fernandez (io_read32(pll_base + RCC_OFFSET_PLLXCFGR2) == value)) { 1168*e5e793a6SGabriel Fernandez /* Same parameters, no need to config */ 1169*e5e793a6SGabriel Fernandez *result = 1; 1170*e5e793a6SGabriel Fernandez } else { 1171*e5e793a6SGabriel Fernandez *result = 0; 1172*e5e793a6SGabriel Fernandez } 1173*e5e793a6SGabriel Fernandez 1174*e5e793a6SGabriel Fernandez return 0; 1175*e5e793a6SGabriel Fernandez } 1176*e5e793a6SGabriel Fernandez 1177*e5e793a6SGabriel Fernandez static int stm32_clk_hsidiv_configure(struct clk_stm32_priv *priv) 1178*e5e793a6SGabriel Fernandez { 1179*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 1180*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSI]; 1181*e5e793a6SGabriel Fernandez 1182*e5e793a6SGabriel Fernandez return stm32_div_set_rate(DIV_HSI, osci->freq, MAX_HSI_HZ); 1183*e5e793a6SGabriel Fernandez } 1184*e5e793a6SGabriel Fernandez 1185*e5e793a6SGabriel Fernandez static void clk_stm32_pll_config_vco(struct clk_stm32_priv *priv, 1186*e5e793a6SGabriel Fernandez const struct stm32_clk_pll *pll, 1187*e5e793a6SGabriel Fernandez struct stm32_pll_vco *vco) 1188*e5e793a6SGabriel Fernandez { 1189*e5e793a6SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 1190*e5e793a6SGabriel Fernandez uint32_t value = 0; 1191*e5e793a6SGabriel Fernandez 1192*e5e793a6SGabriel Fernandez if (clk_stm32_pll_compute_cfgr1(pll, vco, &value) != 0) { 1193*e5e793a6SGabriel Fernandez EMSG("Invalid Vref clock"); 1194*e5e793a6SGabriel Fernandez panic(); 1195*e5e793a6SGabriel Fernandez } 1196*e5e793a6SGabriel Fernandez 1197*e5e793a6SGabriel Fernandez /* Write N / M / IFREGE fields */ 1198*e5e793a6SGabriel Fernandez io_write32(pll_base + RCC_OFFSET_PLLXCFGR1, value); 1199*e5e793a6SGabriel Fernandez 1200*e5e793a6SGabriel Fernandez /* Fractional configuration */ 1201*e5e793a6SGabriel Fernandez io_write32(pll_base + RCC_OFFSET_PLLXFRACR, 0); 1202*e5e793a6SGabriel Fernandez 1203*e5e793a6SGabriel Fernandez /* Frac must be enabled only once its configuration is loaded */ 1204*e5e793a6SGabriel Fernandez io_write32(pll_base + RCC_OFFSET_PLLXFRACR, 1205*e5e793a6SGabriel Fernandez vco->frac << RCC_PLLNFRACR_FRACV_SHIFT); 1206*e5e793a6SGabriel Fernandez 1207*e5e793a6SGabriel Fernandez io_setbits32(pll_base + RCC_OFFSET_PLLXFRACR, RCC_PLLNFRACR_FRACLE); 1208*e5e793a6SGabriel Fernandez } 1209*e5e793a6SGabriel Fernandez 1210*e5e793a6SGabriel Fernandez static void clk_stm32_pll_config_csg(struct clk_stm32_priv *priv, 1211*e5e793a6SGabriel Fernandez const struct stm32_clk_pll *pll, 1212*e5e793a6SGabriel Fernandez struct stm32_pll_vco *vco) 1213*e5e793a6SGabriel Fernandez { 1214*e5e793a6SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 1215*e5e793a6SGabriel Fernandez uint32_t mod_per = 0; 1216*e5e793a6SGabriel Fernandez uint32_t inc_step = 0; 1217*e5e793a6SGabriel Fernandez uint32_t sscg_mode = 0; 1218*e5e793a6SGabriel Fernandez uint32_t value = 0; 1219*e5e793a6SGabriel Fernandez 1220*e5e793a6SGabriel Fernandez if (!vco->csg_enabled) 1221*e5e793a6SGabriel Fernandez return; 1222*e5e793a6SGabriel Fernandez 1223*e5e793a6SGabriel Fernandez mod_per = vco->csg[PLL_CSG_MOD_PER]; 1224*e5e793a6SGabriel Fernandez inc_step = vco->csg[PLL_CSG_INC_STEP]; 1225*e5e793a6SGabriel Fernandez sscg_mode = vco->csg[PLL_CSG_SSCG_MODE]; 1226*e5e793a6SGabriel Fernandez 1227*e5e793a6SGabriel Fernandez value |= (mod_per << RCC_PLLNCSGR_MOD_PER_SHIFT) & 1228*e5e793a6SGabriel Fernandez RCC_PLLNCSGR_MOD_PER_MASK; 1229*e5e793a6SGabriel Fernandez value |= (inc_step << RCC_PLLNCSGR_INC_STEP_SHIFT) & 1230*e5e793a6SGabriel Fernandez RCC_PLLNCSGR_INC_STEP_MASK; 1231*e5e793a6SGabriel Fernandez value |= (sscg_mode << RCC_PLLNCSGR_SSCG_MODE_SHIFT) & 1232*e5e793a6SGabriel Fernandez RCC_PLLNCSGR_SSCG_MODE_MASK; 1233*e5e793a6SGabriel Fernandez 1234*e5e793a6SGabriel Fernandez io_write32(pll_base + RCC_OFFSET_PLLXCSGR, value); 1235*e5e793a6SGabriel Fernandez io_setbits32(pll_base + RCC_OFFSET_PLLXCR, RCC_PLLNCR_SSCG_CTRL); 1236*e5e793a6SGabriel Fernandez } 1237*e5e793a6SGabriel Fernandez 1238*e5e793a6SGabriel Fernandez static void clk_stm32_pll_config_out(struct clk_stm32_priv *priv, 1239*e5e793a6SGabriel Fernandez const struct stm32_clk_pll *pll, 1240*e5e793a6SGabriel Fernandez struct stm32_pll_output *out) 1241*e5e793a6SGabriel Fernandez { 1242*e5e793a6SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 1243*e5e793a6SGabriel Fernandez uint32_t value = 0; 1244*e5e793a6SGabriel Fernandez 1245*e5e793a6SGabriel Fernandez value = clk_stm32_pll_compute_cfgr2(out); 1246*e5e793a6SGabriel Fernandez 1247*e5e793a6SGabriel Fernandez io_write32(pll_base + RCC_OFFSET_PLLXCFGR2, value); 1248*e5e793a6SGabriel Fernandez } 1249*e5e793a6SGabriel Fernandez 1250*e5e793a6SGabriel Fernandez static struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx) 1251*e5e793a6SGabriel Fernandez { 1252*e5e793a6SGabriel Fernandez struct clk_stm32_priv *priv = clk_stm32_get_priv(); 1253*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 1254*e5e793a6SGabriel Fernandez 1255*e5e793a6SGabriel Fernandez return &pdata->pll[pll_idx]; 1256*e5e793a6SGabriel Fernandez } 1257*e5e793a6SGabriel Fernandez 1258*e5e793a6SGabriel Fernandez static int clk_stm32_pll_init_switch_to_hsi_clk_system(int mux_sys) 1259*e5e793a6SGabriel Fernandez { 1260*e5e793a6SGabriel Fernandez int sel = 0; 1261*e5e793a6SGabriel Fernandez 1262*e5e793a6SGabriel Fernandez if (mux_sys == -1) 1263*e5e793a6SGabriel Fernandez return -1; 1264*e5e793a6SGabriel Fernandez 1265*e5e793a6SGabriel Fernandez /* Make a backup to the current parent */ 1266*e5e793a6SGabriel Fernandez sel = stm32_mux_get_parent(mux_sys); 1267*e5e793a6SGabriel Fernandez 1268*e5e793a6SGabriel Fernandez /* Switch to HSI */ 1269*e5e793a6SGabriel Fernandez if (stm32_mux_set_parent(mux_sys, 0)) 1270*e5e793a6SGabriel Fernandez return -1; 1271*e5e793a6SGabriel Fernandez 1272*e5e793a6SGabriel Fernandez return sel; 1273*e5e793a6SGabriel Fernandez } 1274*e5e793a6SGabriel Fernandez 1275*e5e793a6SGabriel Fernandez static uint32_t 1276*e5e793a6SGabriel Fernandez clk_stm32_pll_backup_output_diven(const struct stm32_clk_pll *pll) 1277*e5e793a6SGabriel Fernandez { 1278*e5e793a6SGabriel Fernandez struct clk_stm32_priv *priv = clk_stm32_get_priv(); 1279*e5e793a6SGabriel Fernandez uintptr_t addr = priv->base + pll->reg_pllxcr; 1280*e5e793a6SGabriel Fernandez 1281*e5e793a6SGabriel Fernandez return io_read32(addr + RCC_OFFSET_PLLXCR) & 1282*e5e793a6SGabriel Fernandez (RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | 1283*e5e793a6SGabriel Fernandez RCC_PLLNCR_DIVREN); 1284*e5e793a6SGabriel Fernandez } 1285*e5e793a6SGabriel Fernandez 1286*e5e793a6SGabriel Fernandez static void clk_stm32_pll_restore_output_diven(const struct stm32_clk_pll *pll, 1287*e5e793a6SGabriel Fernandez uint32_t value) 1288*e5e793a6SGabriel Fernandez { 1289*e5e793a6SGabriel Fernandez struct clk_stm32_priv *priv = clk_stm32_get_priv(); 1290*e5e793a6SGabriel Fernandez uintptr_t addr = priv->base + pll->reg_pllxcr; 1291*e5e793a6SGabriel Fernandez const uint32_t mask = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | 1292*e5e793a6SGabriel Fernandez RCC_PLLNCR_DIVREN; 1293*e5e793a6SGabriel Fernandez 1294*e5e793a6SGabriel Fernandez io_clrsetbits32(addr, mask, value & mask); 1295*e5e793a6SGabriel Fernandez } 1296*e5e793a6SGabriel Fernandez 1297*e5e793a6SGabriel Fernandez static int clk_stm32_pll_init(struct clk_stm32_priv *priv, int pll_idx, 1298*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf) 1299*e5e793a6SGabriel Fernandez { 1300*e5e793a6SGabriel Fernandez const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx); 1301*e5e793a6SGabriel Fernandez int config_on_the_fly = -1; 1302*e5e793a6SGabriel Fernandez int ret = 0; 1303*e5e793a6SGabriel Fernandez uint8_t sel = 0; 1304*e5e793a6SGabriel Fernandez uint32_t save_div_pqr_en = 0; 1305*e5e793a6SGabriel Fernandez int mux_system[] = { MUX_MPU, MUX_AXI, MUX_MLAHB, -1 }; 1306*e5e793a6SGabriel Fernandez int mux_sys = mux_system[pll_idx]; 1307*e5e793a6SGabriel Fernandez 1308*e5e793a6SGabriel Fernandez ret = clk_stm32_is_pll_config_on_the_fly(priv, pll, pll_conf, 1309*e5e793a6SGabriel Fernandez &config_on_the_fly); 1310*e5e793a6SGabriel Fernandez if (ret != 0) 1311*e5e793a6SGabriel Fernandez return ret; 1312*e5e793a6SGabriel Fernandez 1313*e5e793a6SGabriel Fernandez /* Backup status of DIV DIVPEN / DIVQEN / DIVREN */ 1314*e5e793a6SGabriel Fernandez save_div_pqr_en = clk_stm32_pll_backup_output_diven(pll); 1315*e5e793a6SGabriel Fernandez 1316*e5e793a6SGabriel Fernandez if (config_on_the_fly == -1) { 1317*e5e793a6SGabriel Fernandez /* Make a backup to the current parent and switch to HSI */ 1318*e5e793a6SGabriel Fernandez sel = clk_stm32_pll_init_switch_to_hsi_clk_system(mux_sys); 1319*e5e793a6SGabriel Fernandez 1320*e5e793a6SGabriel Fernandez /* Stop the PLL before */ 1321*e5e793a6SGabriel Fernandez if (stm32_gate_is_enabled(pll->gate_id)) { 1322*e5e793a6SGabriel Fernandez io_clrbits32(priv->base + pll->reg_pllxcr, 1323*e5e793a6SGabriel Fernandez RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | 1324*e5e793a6SGabriel Fernandez RCC_PLLNCR_DIVREN); 1325*e5e793a6SGabriel Fernandez 1326*e5e793a6SGabriel Fernandez if (stm32_gate_rdy_disable(pll->gate_id)) 1327*e5e793a6SGabriel Fernandez return -1; 1328*e5e793a6SGabriel Fernandez } 1329*e5e793a6SGabriel Fernandez 1330*e5e793a6SGabriel Fernandez /* Configure PLLs source */ 1331*e5e793a6SGabriel Fernandez ret = stm32_clk_configure_mux(priv, pll_conf->vco.src); 1332*e5e793a6SGabriel Fernandez if (ret) 1333*e5e793a6SGabriel Fernandez return ret; 1334*e5e793a6SGabriel Fernandez 1335*e5e793a6SGabriel Fernandez clk_stm32_pll_config_vco(priv, pll, &pll_conf->vco); 1336*e5e793a6SGabriel Fernandez } 1337*e5e793a6SGabriel Fernandez 1338*e5e793a6SGabriel Fernandez if (config_on_the_fly != 1) { 1339*e5e793a6SGabriel Fernandez clk_stm32_pll_config_out(priv, pll, &pll_conf->output); 1340*e5e793a6SGabriel Fernandez clk_stm32_pll_config_csg(priv, pll, &pll_conf->vco); 1341*e5e793a6SGabriel Fernandez } 1342*e5e793a6SGabriel Fernandez 1343*e5e793a6SGabriel Fernandez if (!stm32_gate_is_enabled(pll->gate_id)) { 1344*e5e793a6SGabriel Fernandez if (stm32_gate_rdy_enable(pll->gate_id)) 1345*e5e793a6SGabriel Fernandez return -1; 1346*e5e793a6SGabriel Fernandez 1347*e5e793a6SGabriel Fernandez clk_stm32_pll_restore_output_diven(pll, save_div_pqr_en); 1348*e5e793a6SGabriel Fernandez } 1349*e5e793a6SGabriel Fernandez 1350*e5e793a6SGabriel Fernandez if ((config_on_the_fly == -1) && (mux_sys != -1)) { 1351*e5e793a6SGabriel Fernandez /* Restore to backup parent */ 1352*e5e793a6SGabriel Fernandez if (stm32_mux_set_parent(mux_sys, sel)) 1353*e5e793a6SGabriel Fernandez return -1; 1354*e5e793a6SGabriel Fernandez } 1355*e5e793a6SGabriel Fernandez 1356*e5e793a6SGabriel Fernandez return 0; 1357*e5e793a6SGabriel Fernandez } 1358*e5e793a6SGabriel Fernandez 1359*e5e793a6SGabriel Fernandez static int stm32_clk_pll_configure(struct clk_stm32_priv *priv) 1360*e5e793a6SGabriel Fernandez { 1361*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf = NULL; 1362*e5e793a6SGabriel Fernandez size_t i = 0; 1363*e5e793a6SGabriel Fernandez const int plls[] = { PLL1_ID, PLL3_ID, PLL4_ID }; 1364*e5e793a6SGabriel Fernandez 1365*e5e793a6SGabriel Fernandez for (i = 0; i < ARRAY_SIZE(plls); i++) { 1366*e5e793a6SGabriel Fernandez pll_conf = clk_stm32_pll_get_pdata(plls[i]); 1367*e5e793a6SGabriel Fernandez 1368*e5e793a6SGabriel Fernandez if (pll_conf->vco.status) { 1369*e5e793a6SGabriel Fernandez int err = 0; 1370*e5e793a6SGabriel Fernandez 1371*e5e793a6SGabriel Fernandez err = clk_stm32_pll_init(priv, plls[i], pll_conf); 1372*e5e793a6SGabriel Fernandez if (err) 1373*e5e793a6SGabriel Fernandez return err; 1374*e5e793a6SGabriel Fernandez } 1375*e5e793a6SGabriel Fernandez } 1376*e5e793a6SGabriel Fernandez 1377*e5e793a6SGabriel Fernandez return 0; 1378*e5e793a6SGabriel Fernandez } 1379*e5e793a6SGabriel Fernandez 1380*e5e793a6SGabriel Fernandez static int stm32mp1_init_clock_tree(struct clk_stm32_priv *priv, 1381*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 1382*e5e793a6SGabriel Fernandez { 1383*e5e793a6SGabriel Fernandez int ret = 0; 1384*e5e793a6SGabriel Fernandez 1385*e5e793a6SGabriel Fernandez /* 1386*e5e793a6SGabriel Fernandez * Switch ON oscillators found in device-tree. 1387*e5e793a6SGabriel Fernandez * Note: HSI already ON after BootROM stage. 1388*e5e793a6SGabriel Fernandez */ 1389*e5e793a6SGabriel Fernandez stm32_clk_oscillators_enable(priv, pdata); 1390*e5e793a6SGabriel Fernandez 1391*e5e793a6SGabriel Fernandez ret = stm32_clk_hsidiv_configure(priv); 1392*e5e793a6SGabriel Fernandez if (ret != 0) 1393*e5e793a6SGabriel Fernandez return ret; 1394*e5e793a6SGabriel Fernandez 1395*e5e793a6SGabriel Fernandez ret = stm32_clk_dividers_configure(priv); 1396*e5e793a6SGabriel Fernandez if (ret != 0) 1397*e5e793a6SGabriel Fernandez panic(); 1398*e5e793a6SGabriel Fernandez 1399*e5e793a6SGabriel Fernandez ret = stm32_clk_pll_configure(priv); 1400*e5e793a6SGabriel Fernandez if (ret != 0) 1401*e5e793a6SGabriel Fernandez panic(); 1402*e5e793a6SGabriel Fernandez 1403*e5e793a6SGabriel Fernandez /* Wait LSE ready before to use it */ 1404*e5e793a6SGabriel Fernandez ret = stm32_clk_oscillators_wait_lse_ready(priv, pdata); 1405*e5e793a6SGabriel Fernandez if (ret != 0) 1406*e5e793a6SGabriel Fernandez panic(); 1407*e5e793a6SGabriel Fernandez 1408*e5e793a6SGabriel Fernandez /* Configure with expected clock source */ 1409*e5e793a6SGabriel Fernandez ret = stm32_clk_source_configure(priv); 1410*e5e793a6SGabriel Fernandez if (ret != 0) 1411*e5e793a6SGabriel Fernandez panic(); 1412*e5e793a6SGabriel Fernandez 1413*e5e793a6SGabriel Fernandez /* Configure LSE CSS after RTC source configuration */ 1414*e5e793a6SGabriel Fernandez ret = stm32_clk_oscillators_lse_set_css(priv, pdata); 1415*e5e793a6SGabriel Fernandez if (ret != 0) 1416*e5e793a6SGabriel Fernandez panic(); 1417*e5e793a6SGabriel Fernandez 1418*e5e793a6SGabriel Fernandez /* Software Self-Refresh mode (SSR) during DDR initilialization */ 1419*e5e793a6SGabriel Fernandez io_clrsetbits32(priv->base + RCC_DDRITFCR, RCC_DDRITFCR_DDRCKMOD_MASK, 1420*e5e793a6SGabriel Fernandez RCC_DDRITFCR_DDRCKMOD_SSR << 1421*e5e793a6SGabriel Fernandez RCC_DDRITFCR_DDRCKMOD_SHIFT); 1422*e5e793a6SGabriel Fernandez 1423*e5e793a6SGabriel Fernandez return 0; 1424*e5e793a6SGabriel Fernandez } 1425*e5e793a6SGabriel Fernandez 1426*e5e793a6SGabriel Fernandez static int clk_stm32_parse_oscillator_fdt(const void *fdt, int node, 1427*e5e793a6SGabriel Fernandez const char *name, 1428*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci) 1429*e5e793a6SGabriel Fernandez { 1430*e5e793a6SGabriel Fernandez int subnode = 0; 1431*e5e793a6SGabriel Fernandez 1432*e5e793a6SGabriel Fernandez fdt_for_each_subnode(subnode, fdt, node) { 1433*e5e793a6SGabriel Fernandez const char *cchar = NULL; 1434*e5e793a6SGabriel Fernandez const fdt32_t *cuint = NULL; 1435*e5e793a6SGabriel Fernandez int ret = 0; 1436*e5e793a6SGabriel Fernandez 1437*e5e793a6SGabriel Fernandez cchar = fdt_get_name(fdt, subnode, &ret); 1438*e5e793a6SGabriel Fernandez if (!cchar) 1439*e5e793a6SGabriel Fernandez return ret; 1440*e5e793a6SGabriel Fernandez 1441*e5e793a6SGabriel Fernandez if (strncmp(cchar, name, (size_t)ret) || 1442*e5e793a6SGabriel Fernandez _fdt_get_status(fdt, subnode) == DT_STATUS_DISABLED) 1443*e5e793a6SGabriel Fernandez continue; 1444*e5e793a6SGabriel Fernandez 1445*e5e793a6SGabriel Fernandez cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret); 1446*e5e793a6SGabriel Fernandez if (!cuint) 1447*e5e793a6SGabriel Fernandez panic(); 1448*e5e793a6SGabriel Fernandez 1449*e5e793a6SGabriel Fernandez osci->freq = fdt32_to_cpu(*cuint); 1450*e5e793a6SGabriel Fernandez 1451*e5e793a6SGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,bypass", NULL)) 1452*e5e793a6SGabriel Fernandez osci->bypass = true; 1453*e5e793a6SGabriel Fernandez 1454*e5e793a6SGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,digbypass", NULL)) 1455*e5e793a6SGabriel Fernandez osci->digbyp = true; 1456*e5e793a6SGabriel Fernandez 1457*e5e793a6SGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,css", NULL)) 1458*e5e793a6SGabriel Fernandez osci->css = true; 1459*e5e793a6SGabriel Fernandez 1460*e5e793a6SGabriel Fernandez osci->drive = _fdt_read_uint32_default(fdt, subnode, "st,drive", 1461*e5e793a6SGabriel Fernandez LSEDRV_MEDIUM_HIGH); 1462*e5e793a6SGabriel Fernandez 1463*e5e793a6SGabriel Fernandez return 0; 1464*e5e793a6SGabriel Fernandez } 1465*e5e793a6SGabriel Fernandez 1466*e5e793a6SGabriel Fernandez return -FDT_ERR_NOTFOUND; 1467*e5e793a6SGabriel Fernandez } 1468*e5e793a6SGabriel Fernandez 1469*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt_all_oscillator(const void *fdt, 1470*e5e793a6SGabriel Fernandez int node __maybe_unused, 1471*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 1472*e5e793a6SGabriel Fernandez { 1473*e5e793a6SGabriel Fernandez int fdt_err = 0; 1474*e5e793a6SGabriel Fernandez size_t i = 0; 1475*e5e793a6SGabriel Fernandez int osc_node = 0; 1476*e5e793a6SGabriel Fernandez 1477*e5e793a6SGabriel Fernandez osc_node = fdt_path_offset(fdt, "/clocks"); 1478*e5e793a6SGabriel Fernandez if (osc_node < 0) 1479*e5e793a6SGabriel Fernandez return -FDT_ERR_NOTFOUND; 1480*e5e793a6SGabriel Fernandez 1481*e5e793a6SGabriel Fernandez for (i = 0; i < NB_OSCILLATOR; i++) { 1482*e5e793a6SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[i]; 1483*e5e793a6SGabriel Fernandez struct clk_oscillator_data *osc_data = NULL; 1484*e5e793a6SGabriel Fernandez 1485*e5e793a6SGabriel Fernandez osc_data = clk_oscillator_get_data(i); 1486*e5e793a6SGabriel Fernandez 1487*e5e793a6SGabriel Fernandez fdt_err = clk_stm32_parse_oscillator_fdt(fdt, osc_node, 1488*e5e793a6SGabriel Fernandez osc_data->name, osci); 1489*e5e793a6SGabriel Fernandez if (fdt_err < 0) 1490*e5e793a6SGabriel Fernandez panic(); 1491*e5e793a6SGabriel Fernandez } 1492*e5e793a6SGabriel Fernandez 1493*e5e793a6SGabriel Fernandez return 0; 1494*e5e793a6SGabriel Fernandez } 1495*e5e793a6SGabriel Fernandez 1496*e5e793a6SGabriel Fernandez static int clk_stm32_load_vco_config_fdt(const void *fdt, int subnode, 1497*e5e793a6SGabriel Fernandez struct stm32_pll_vco *vco) 1498*e5e793a6SGabriel Fernandez { 1499*e5e793a6SGabriel Fernandez int ret = 0; 1500*e5e793a6SGabriel Fernandez 1501*e5e793a6SGabriel Fernandez ret = _fdt_read_uint32_array(fdt, subnode, "divmn", vco->div_mn, 1502*e5e793a6SGabriel Fernandez PLL_DIV_MN_NB); 1503*e5e793a6SGabriel Fernandez if (ret != 0) 1504*e5e793a6SGabriel Fernandez return ret; 1505*e5e793a6SGabriel Fernandez 1506*e5e793a6SGabriel Fernandez ret = _fdt_read_uint32_array(fdt, subnode, "csg", vco->csg, 1507*e5e793a6SGabriel Fernandez PLL_CSG_NB); 1508*e5e793a6SGabriel Fernandez 1509*e5e793a6SGabriel Fernandez vco->csg_enabled = (ret == 0); 1510*e5e793a6SGabriel Fernandez 1511*e5e793a6SGabriel Fernandez if (ret == -FDT_ERR_NOTFOUND) 1512*e5e793a6SGabriel Fernandez ret = 0; 1513*e5e793a6SGabriel Fernandez 1514*e5e793a6SGabriel Fernandez if (ret != 0) 1515*e5e793a6SGabriel Fernandez return ret; 1516*e5e793a6SGabriel Fernandez 1517*e5e793a6SGabriel Fernandez vco->status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | 1518*e5e793a6SGabriel Fernandez RCC_PLLNCR_DIVREN | RCC_PLLNCR_PLLON; 1519*e5e793a6SGabriel Fernandez 1520*e5e793a6SGabriel Fernandez vco->frac = _fdt_read_uint32_default(fdt, subnode, "frac", 0); 1521*e5e793a6SGabriel Fernandez 1522*e5e793a6SGabriel Fernandez vco->src = _fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX); 1523*e5e793a6SGabriel Fernandez 1524*e5e793a6SGabriel Fernandez return 0; 1525*e5e793a6SGabriel Fernandez } 1526*e5e793a6SGabriel Fernandez 1527*e5e793a6SGabriel Fernandez static int clk_stm32_load_output_config_fdt(const void *fdt, int subnode, 1528*e5e793a6SGabriel Fernandez struct stm32_pll_output *output) 1529*e5e793a6SGabriel Fernandez { 1530*e5e793a6SGabriel Fernandez return _fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr", 1531*e5e793a6SGabriel Fernandez output->output, (int)PLL_DIV_PQR_NB); 1532*e5e793a6SGabriel Fernandez } 1533*e5e793a6SGabriel Fernandez 1534*e5e793a6SGabriel Fernandez static int clk_stm32_parse_pll_fdt(const void *fdt, int subnode, 1535*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg *pll) 1536*e5e793a6SGabriel Fernandez { 1537*e5e793a6SGabriel Fernandez const fdt32_t *cuint = NULL; 1538*e5e793a6SGabriel Fernandez int subnode_pll = 0; 1539*e5e793a6SGabriel Fernandez int subnode_vco = 0; 1540*e5e793a6SGabriel Fernandez int err = 0; 1541*e5e793a6SGabriel Fernandez 1542*e5e793a6SGabriel Fernandez cuint = fdt_getprop(fdt, subnode, "st,pll", NULL); 1543*e5e793a6SGabriel Fernandez if (!cuint) 1544*e5e793a6SGabriel Fernandez return -FDT_ERR_NOTFOUND; 1545*e5e793a6SGabriel Fernandez 1546*e5e793a6SGabriel Fernandez subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); 1547*e5e793a6SGabriel Fernandez if (subnode_pll < 0) 1548*e5e793a6SGabriel Fernandez return -FDT_ERR_NOTFOUND; 1549*e5e793a6SGabriel Fernandez 1550*e5e793a6SGabriel Fernandez cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL); 1551*e5e793a6SGabriel Fernandez if (!cuint) 1552*e5e793a6SGabriel Fernandez return -FDT_ERR_NOTFOUND; 1553*e5e793a6SGabriel Fernandez 1554*e5e793a6SGabriel Fernandez subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); 1555*e5e793a6SGabriel Fernandez if (subnode_vco < 0) 1556*e5e793a6SGabriel Fernandez return -FDT_ERR_NOTFOUND; 1557*e5e793a6SGabriel Fernandez 1558*e5e793a6SGabriel Fernandez err = clk_stm32_load_vco_config_fdt(fdt, subnode_vco, &pll->vco); 1559*e5e793a6SGabriel Fernandez if (err != 0) 1560*e5e793a6SGabriel Fernandez return err; 1561*e5e793a6SGabriel Fernandez 1562*e5e793a6SGabriel Fernandez err = clk_stm32_load_output_config_fdt(fdt, subnode_pll, &pll->output); 1563*e5e793a6SGabriel Fernandez if (err != 0) 1564*e5e793a6SGabriel Fernandez return err; 1565*e5e793a6SGabriel Fernandez 1566*e5e793a6SGabriel Fernandez return 0; 1567*e5e793a6SGabriel Fernandez } 1568*e5e793a6SGabriel Fernandez 1569*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt_all_pll(const void *fdt, int node, 1570*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 1571*e5e793a6SGabriel Fernandez { 1572*e5e793a6SGabriel Fernandez size_t i = 0; 1573*e5e793a6SGabriel Fernandez 1574*e5e793a6SGabriel Fernandez for (i = PLL1_ID; i < pdata->npll; i++) { 1575*e5e793a6SGabriel Fernandez struct stm32_pll_dt_cfg *pll = pdata->pll + i; 1576*e5e793a6SGabriel Fernandez char name[RCC_PLL_NAME_SIZE] = { 0 }; 1577*e5e793a6SGabriel Fernandez int subnode = 0; 1578*e5e793a6SGabriel Fernandez int err = 0; 1579*e5e793a6SGabriel Fernandez 1580*e5e793a6SGabriel Fernandez snprintf(name, sizeof(name), "st,pll@%d", i); 1581*e5e793a6SGabriel Fernandez 1582*e5e793a6SGabriel Fernandez subnode = fdt_subnode_offset(fdt, node, name); 1583*e5e793a6SGabriel Fernandez if (subnode < 0) 1584*e5e793a6SGabriel Fernandez continue; 1585*e5e793a6SGabriel Fernandez 1586*e5e793a6SGabriel Fernandez err = clk_stm32_parse_pll_fdt(fdt, subnode, pll); 1587*e5e793a6SGabriel Fernandez if (err != 0) 1588*e5e793a6SGabriel Fernandez panic(); 1589*e5e793a6SGabriel Fernandez } 1590*e5e793a6SGabriel Fernandez 1591*e5e793a6SGabriel Fernandez return 0; 1592*e5e793a6SGabriel Fernandez } 1593*e5e793a6SGabriel Fernandez 1594*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt_opp(const void *fdt, int node, 1595*e5e793a6SGabriel Fernandez const char *opp_name, 1596*e5e793a6SGabriel Fernandez struct stm32_clk_opp_cfg *opp_cfg) 1597*e5e793a6SGabriel Fernandez { 1598*e5e793a6SGabriel Fernandez int subnode = 0; 1599*e5e793a6SGabriel Fernandez int nb_opp = 0; 1600*e5e793a6SGabriel Fernandez int ret = 0; 1601*e5e793a6SGabriel Fernandez 1602*e5e793a6SGabriel Fernandez node = fdt_subnode_offset(fdt, node, opp_name); 1603*e5e793a6SGabriel Fernandez if (node == -FDT_ERR_NOTFOUND) 1604*e5e793a6SGabriel Fernandez return 0; 1605*e5e793a6SGabriel Fernandez if (node < 0) 1606*e5e793a6SGabriel Fernandez return node; 1607*e5e793a6SGabriel Fernandez 1608*e5e793a6SGabriel Fernandez fdt_for_each_subnode(subnode, fdt, node) { 1609*e5e793a6SGabriel Fernandez if (nb_opp >= MAX_OPP) { 1610*e5e793a6SGabriel Fernandez EMSG("%d MAX opp in %s", MAX_OPP, opp_name); 1611*e5e793a6SGabriel Fernandez panic(); 1612*e5e793a6SGabriel Fernandez } 1613*e5e793a6SGabriel Fernandez 1614*e5e793a6SGabriel Fernandez opp_cfg->frq = _fdt_read_uint32_default(fdt, subnode, 1615*e5e793a6SGabriel Fernandez "hz", 1616*e5e793a6SGabriel Fernandez UINT32_MAX); 1617*e5e793a6SGabriel Fernandez 1618*e5e793a6SGabriel Fernandez opp_cfg->src = _fdt_read_uint32_default(fdt, subnode, 1619*e5e793a6SGabriel Fernandez "st,clksrc", 1620*e5e793a6SGabriel Fernandez UINT32_MAX); 1621*e5e793a6SGabriel Fernandez 1622*e5e793a6SGabriel Fernandez opp_cfg->div = _fdt_read_uint32_default(fdt, subnode, 1623*e5e793a6SGabriel Fernandez "st,clkdiv", 1624*e5e793a6SGabriel Fernandez UINT32_MAX); 1625*e5e793a6SGabriel Fernandez 1626*e5e793a6SGabriel Fernandez ret = clk_stm32_parse_pll_fdt(fdt, subnode, &opp_cfg->pll_cfg); 1627*e5e793a6SGabriel Fernandez if (ret) 1628*e5e793a6SGabriel Fernandez return ret; 1629*e5e793a6SGabriel Fernandez 1630*e5e793a6SGabriel Fernandez opp_cfg++; 1631*e5e793a6SGabriel Fernandez nb_opp++; 1632*e5e793a6SGabriel Fernandez } 1633*e5e793a6SGabriel Fernandez 1634*e5e793a6SGabriel Fernandez return 0; 1635*e5e793a6SGabriel Fernandez } 1636*e5e793a6SGabriel Fernandez 1637*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt_all_opp(const void *fdt, int node, 1638*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 1639*e5e793a6SGabriel Fernandez { 1640*e5e793a6SGabriel Fernandez struct stm32_clk_opp_dt_cfg *opp = pdata->opp; 1641*e5e793a6SGabriel Fernandez int ret = 0; 1642*e5e793a6SGabriel Fernandez 1643*e5e793a6SGabriel Fernandez node = fdt_subnode_offset(fdt, node, "st,clk_opp"); 1644*e5e793a6SGabriel Fernandez /* No opp are defined */ 1645*e5e793a6SGabriel Fernandez if (node == -FDT_ERR_NOTFOUND) 1646*e5e793a6SGabriel Fernandez return 0; 1647*e5e793a6SGabriel Fernandez if (node < 0) 1648*e5e793a6SGabriel Fernandez return node; 1649*e5e793a6SGabriel Fernandez 1650*e5e793a6SGabriel Fernandez ret = stm32_clk_parse_fdt_opp(fdt, node, "st,ck_mpu", opp->mpu_opp); 1651*e5e793a6SGabriel Fernandez if (ret) 1652*e5e793a6SGabriel Fernandez return ret; 1653*e5e793a6SGabriel Fernandez 1654*e5e793a6SGabriel Fernandez ret = stm32_clk_parse_fdt_opp(fdt, node, "st,ck_axi", opp->axi_opp); 1655*e5e793a6SGabriel Fernandez if (ret) 1656*e5e793a6SGabriel Fernandez return ret; 1657*e5e793a6SGabriel Fernandez 1658*e5e793a6SGabriel Fernandez ret = stm32_clk_parse_fdt_opp(fdt, node, "st,ck_mlahbs", 1659*e5e793a6SGabriel Fernandez opp->mlahbs_opp); 1660*e5e793a6SGabriel Fernandez if (ret) 1661*e5e793a6SGabriel Fernandez return ret; 1662*e5e793a6SGabriel Fernandez 1663*e5e793a6SGabriel Fernandez return 0; 1664*e5e793a6SGabriel Fernandez } 1665*e5e793a6SGabriel Fernandez 1666*e5e793a6SGabriel Fernandez static int stm32_clk_parse_fdt(const void *fdt, int node, 1667*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata) 1668*e5e793a6SGabriel Fernandez { 1669*e5e793a6SGabriel Fernandez int err = 0; 1670*e5e793a6SGabriel Fernandez 1671*e5e793a6SGabriel Fernandez err = stm32_clk_parse_fdt_all_oscillator(fdt, node, pdata); 1672*e5e793a6SGabriel Fernandez if (err != 0) 1673*e5e793a6SGabriel Fernandez return err; 1674*e5e793a6SGabriel Fernandez 1675*e5e793a6SGabriel Fernandez err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata); 1676*e5e793a6SGabriel Fernandez if (err != 0) 1677*e5e793a6SGabriel Fernandez return err; 1678*e5e793a6SGabriel Fernandez 1679*e5e793a6SGabriel Fernandez err = stm32_clk_parse_fdt_all_opp(fdt, node, pdata); 1680*e5e793a6SGabriel Fernandez if (err != 0) 1681*e5e793a6SGabriel Fernandez return err; 1682*e5e793a6SGabriel Fernandez 1683*e5e793a6SGabriel Fernandez err = clk_stm32_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv, 1684*e5e793a6SGabriel Fernandez &pdata->nclkdiv); 1685*e5e793a6SGabriel Fernandez if (err != 0) 1686*e5e793a6SGabriel Fernandez return err; 1687*e5e793a6SGabriel Fernandez 1688*e5e793a6SGabriel Fernandez err = clk_stm32_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc, 1689*e5e793a6SGabriel Fernandez &pdata->nclksrc); 1690*e5e793a6SGabriel Fernandez if (err != 0) 1691*e5e793a6SGabriel Fernandez return err; 1692*e5e793a6SGabriel Fernandez 1693*e5e793a6SGabriel Fernandez return 0; 1694*e5e793a6SGabriel Fernandez } 1695*e5e793a6SGabriel Fernandez 1696*e5e793a6SGabriel Fernandez static struct stm32_pll_dt_cfg mp13_pll[PLL_NB]; 1697*e5e793a6SGabriel Fernandez static struct stm32_clk_opp_dt_cfg mp13_clk_opp; 1698*e5e793a6SGabriel Fernandez static struct stm32_osci_dt_cfg mp13_osci[NB_OSCILLATOR]; 1699*e5e793a6SGabriel Fernandez static uint32_t mp13_clksrc[MUX_NB]; 1700*e5e793a6SGabriel Fernandez static uint32_t mp13_clkdiv[DIV_NB]; 1701*e5e793a6SGabriel Fernandez 1702*e5e793a6SGabriel Fernandez static struct stm32_clk_platdata stm32mp13_clock_pdata = { 1703*e5e793a6SGabriel Fernandez .osci = mp13_osci, 1704*e5e793a6SGabriel Fernandez .nosci = NB_OSCILLATOR, 1705*e5e793a6SGabriel Fernandez .pll = mp13_pll, 1706*e5e793a6SGabriel Fernandez .opp = &mp13_clk_opp, 1707*e5e793a6SGabriel Fernandez .npll = PLL_NB, 1708*e5e793a6SGabriel Fernandez .clksrc = mp13_clksrc, 1709*e5e793a6SGabriel Fernandez .nclksrc = MUX_NB, 1710*e5e793a6SGabriel Fernandez .clkdiv = mp13_clkdiv, 1711*e5e793a6SGabriel Fernandez .nclkdiv = DIV_NB, 1712*e5e793a6SGabriel Fernandez }; 1713*e5e793a6SGabriel Fernandez 1714*e5e793a6SGabriel Fernandez static struct clk_stm32_priv stm32mp13_clock_data = { 1715*e5e793a6SGabriel Fernandez .muxes = parent_mp13, 1716*e5e793a6SGabriel Fernandez .nb_muxes = ARRAY_SIZE(parent_mp13), 1717*e5e793a6SGabriel Fernandez .gates = gates_mp13, 1718*e5e793a6SGabriel Fernandez .nb_gates = ARRAY_SIZE(gates_mp13), 1719*e5e793a6SGabriel Fernandez .div = dividers_mp13, 1720*e5e793a6SGabriel Fernandez .nb_div = ARRAY_SIZE(dividers_mp13), 1721*e5e793a6SGabriel Fernandez .pdata = &stm32mp13_clock_pdata, 1722*e5e793a6SGabriel Fernandez }; 1723*e5e793a6SGabriel Fernandez 1724*e5e793a6SGabriel Fernandez static TEE_Result stm32mp13_clk_probe(const void *fdt, int node, 1725*e5e793a6SGabriel Fernandez const void *compat_data __unused) 1726*e5e793a6SGabriel Fernandez { 1727*e5e793a6SGabriel Fernandez TEE_Result res = TEE_ERROR_GENERIC; 1728*e5e793a6SGabriel Fernandez int fdt_rc = 0; 1729*e5e793a6SGabriel Fernandez int rc = 0; 1730*e5e793a6SGabriel Fernandez struct clk_stm32_priv *priv = &stm32mp13_clock_data; 1731*e5e793a6SGabriel Fernandez struct stm32_clk_platdata *pdata = &stm32mp13_clock_pdata; 1732*e5e793a6SGabriel Fernandez 1733*e5e793a6SGabriel Fernandez fdt_rc = stm32_clk_parse_fdt(fdt, node, pdata); 1734*e5e793a6SGabriel Fernandez if (fdt_rc) { 1735*e5e793a6SGabriel Fernandez EMSG("Failed to parse clock node: %d", fdt_rc); 1736*e5e793a6SGabriel Fernandez return TEE_ERROR_GENERIC; 1737*e5e793a6SGabriel Fernandez } 1738*e5e793a6SGabriel Fernandez 1739*e5e793a6SGabriel Fernandez res = clk_stm32_init(priv, stm32_rcc_base()); 1740*e5e793a6SGabriel Fernandez if (res) 1741*e5e793a6SGabriel Fernandez return res; 1742*e5e793a6SGabriel Fernandez 1743*e5e793a6SGabriel Fernandez rc = stm32mp1_init_clock_tree(priv, pdata); 1744*e5e793a6SGabriel Fernandez if (rc) 1745*e5e793a6SGabriel Fernandez return TEE_ERROR_GENERIC; 1746*e5e793a6SGabriel Fernandez 1747*e5e793a6SGabriel Fernandez return TEE_SUCCESS; 1748*e5e793a6SGabriel Fernandez } 1749*e5e793a6SGabriel Fernandez 1750*e5e793a6SGabriel Fernandez CLK_DT_DECLARE(stm32mp13_clk, "st,stm32mp13-rcc", stm32mp13_clk_probe); 1751