19be88e75SGabriel Fernandez /* 2f4a2bb98SYann Gautier * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved 39be88e75SGabriel Fernandez * 49be88e75SGabriel Fernandez * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 59be88e75SGabriel Fernandez */ 69be88e75SGabriel Fernandez 79be88e75SGabriel Fernandez #include <assert.h> 89be88e75SGabriel Fernandez #include <errno.h> 99be88e75SGabriel Fernandez #include <limits.h> 109be88e75SGabriel Fernandez #include <stdint.h> 119be88e75SGabriel Fernandez #include <stdio.h> 129be88e75SGabriel Fernandez 139be88e75SGabriel Fernandez #include <arch.h> 149be88e75SGabriel Fernandez #include <arch_helpers.h> 159be88e75SGabriel Fernandez #include "clk-stm32-core.h" 169be88e75SGabriel Fernandez #include <common/debug.h> 179be88e75SGabriel Fernandez #include <common/fdt_wrappers.h> 189be88e75SGabriel Fernandez #include <drivers/clk.h> 199be88e75SGabriel Fernandez #include <drivers/delay_timer.h> 209be88e75SGabriel Fernandez #include <drivers/st/stm32mp13_rcc.h> 219be88e75SGabriel Fernandez #include <drivers/st/stm32mp1_clk.h> 229be88e75SGabriel Fernandez #include <drivers/st/stm32mp_clkfunc.h> 239be88e75SGabriel Fernandez #include <dt-bindings/clock/stm32mp13-clksrc.h> 249be88e75SGabriel Fernandez #include <lib/mmio.h> 259be88e75SGabriel Fernandez #include <lib/spinlock.h> 269be88e75SGabriel Fernandez #include <lib/utils_def.h> 279be88e75SGabriel Fernandez #include <libfdt.h> 289be88e75SGabriel Fernandez #include <plat/common/platform.h> 299be88e75SGabriel Fernandez 309be88e75SGabriel Fernandez #include <platform_def.h> 319be88e75SGabriel Fernandez 329be88e75SGabriel Fernandez struct stm32_osci_dt_cfg { 339be88e75SGabriel Fernandez unsigned long freq; 349be88e75SGabriel Fernandez bool bypass; 359be88e75SGabriel Fernandez bool digbyp; 369be88e75SGabriel Fernandez bool css; 379be88e75SGabriel Fernandez uint32_t drive; 389be88e75SGabriel Fernandez }; 399be88e75SGabriel Fernandez 409be88e75SGabriel Fernandez enum pll_mn { 419be88e75SGabriel Fernandez PLL_CFG_M, 429be88e75SGabriel Fernandez PLL_CFG_N, 439be88e75SGabriel Fernandez PLL_DIV_MN_NB 449be88e75SGabriel Fernandez }; 459be88e75SGabriel Fernandez 469be88e75SGabriel Fernandez enum pll_pqr { 479be88e75SGabriel Fernandez PLL_CFG_P, 489be88e75SGabriel Fernandez PLL_CFG_Q, 499be88e75SGabriel Fernandez PLL_CFG_R, 509be88e75SGabriel Fernandez PLL_DIV_PQR_NB 519be88e75SGabriel Fernandez }; 529be88e75SGabriel Fernandez 539be88e75SGabriel Fernandez enum pll_csg { 549be88e75SGabriel Fernandez PLL_CSG_MOD_PER, 559be88e75SGabriel Fernandez PLL_CSG_INC_STEP, 569be88e75SGabriel Fernandez PLL_CSG_SSCG_MODE, 579be88e75SGabriel Fernandez PLL_CSG_NB 589be88e75SGabriel Fernandez }; 599be88e75SGabriel Fernandez 609be88e75SGabriel Fernandez struct stm32_pll_vco { 619be88e75SGabriel Fernandez uint32_t status; 629be88e75SGabriel Fernandez uint32_t src; 639be88e75SGabriel Fernandez uint32_t div_mn[PLL_DIV_MN_NB]; 649be88e75SGabriel Fernandez uint32_t frac; 659be88e75SGabriel Fernandez bool csg_enabled; 669be88e75SGabriel Fernandez uint32_t csg[PLL_CSG_NB]; 679be88e75SGabriel Fernandez }; 689be88e75SGabriel Fernandez 699be88e75SGabriel Fernandez struct stm32_pll_output { 709be88e75SGabriel Fernandez uint32_t output[PLL_DIV_PQR_NB]; 719be88e75SGabriel Fernandez }; 729be88e75SGabriel Fernandez 739be88e75SGabriel Fernandez struct stm32_pll_dt_cfg { 749be88e75SGabriel Fernandez struct stm32_pll_vco vco; 759be88e75SGabriel Fernandez struct stm32_pll_output output; 769be88e75SGabriel Fernandez }; 779be88e75SGabriel Fernandez 789be88e75SGabriel Fernandez struct stm32_clk_platdata { 799be88e75SGabriel Fernandez uint32_t nosci; 809be88e75SGabriel Fernandez struct stm32_osci_dt_cfg *osci; 819be88e75SGabriel Fernandez uint32_t npll; 829be88e75SGabriel Fernandez struct stm32_pll_dt_cfg *pll; 839be88e75SGabriel Fernandez uint32_t nclksrc; 849be88e75SGabriel Fernandez uint32_t *clksrc; 859be88e75SGabriel Fernandez uint32_t nclkdiv; 869be88e75SGabriel Fernandez uint32_t *clkdiv; 879be88e75SGabriel Fernandez }; 889be88e75SGabriel Fernandez 899be88e75SGabriel Fernandez enum stm32_clock { 909be88e75SGabriel Fernandez /* ROOT CLOCKS */ 919be88e75SGabriel Fernandez _CK_OFF, 929be88e75SGabriel Fernandez _CK_HSI, 939be88e75SGabriel Fernandez _CK_HSE, 949be88e75SGabriel Fernandez _CK_CSI, 959be88e75SGabriel Fernandez _CK_LSI, 969be88e75SGabriel Fernandez _CK_LSE, 979be88e75SGabriel Fernandez _I2SCKIN, 989be88e75SGabriel Fernandez _CSI_DIV122, 999be88e75SGabriel Fernandez _HSE_DIV, 1009be88e75SGabriel Fernandez _HSE_DIV2, 1019be88e75SGabriel Fernandez _CK_PLL1, 1029be88e75SGabriel Fernandez _CK_PLL2, 1039be88e75SGabriel Fernandez _CK_PLL3, 1049be88e75SGabriel Fernandez _CK_PLL4, 1059be88e75SGabriel Fernandez _PLL1P, 1069be88e75SGabriel Fernandez _PLL1P_DIV, 1079be88e75SGabriel Fernandez _PLL2P, 1089be88e75SGabriel Fernandez _PLL2Q, 1099be88e75SGabriel Fernandez _PLL2R, 1109be88e75SGabriel Fernandez _PLL3P, 1119be88e75SGabriel Fernandez _PLL3Q, 1129be88e75SGabriel Fernandez _PLL3R, 1139be88e75SGabriel Fernandez _PLL4P, 1149be88e75SGabriel Fernandez _PLL4Q, 1159be88e75SGabriel Fernandez _PLL4R, 1169be88e75SGabriel Fernandez _PCLK1, 1179be88e75SGabriel Fernandez _PCLK2, 1189be88e75SGabriel Fernandez _PCLK3, 1199be88e75SGabriel Fernandez _PCLK4, 1209be88e75SGabriel Fernandez _PCLK5, 1219be88e75SGabriel Fernandez _PCLK6, 1229be88e75SGabriel Fernandez _CKMPU, 1239be88e75SGabriel Fernandez _CKAXI, 1249be88e75SGabriel Fernandez _CKMLAHB, 1259be88e75SGabriel Fernandez _CKPER, 1269be88e75SGabriel Fernandez _CKTIMG1, 1279be88e75SGabriel Fernandez _CKTIMG2, 1289be88e75SGabriel Fernandez _CKTIMG3, 1299be88e75SGabriel Fernandez _USB_PHY_48, 1309be88e75SGabriel Fernandez _MCO1_K, 1319be88e75SGabriel Fernandez _MCO2_K, 1329be88e75SGabriel Fernandez _TRACECK, 1339be88e75SGabriel Fernandez /* BUS and KERNEL CLOCKS */ 1349be88e75SGabriel Fernandez _DDRC1, 1359be88e75SGabriel Fernandez _DDRC1LP, 1369be88e75SGabriel Fernandez _DDRPHYC, 1379be88e75SGabriel Fernandez _DDRPHYCLP, 1389be88e75SGabriel Fernandez _DDRCAPB, 1399be88e75SGabriel Fernandez _DDRCAPBLP, 1409be88e75SGabriel Fernandez _AXIDCG, 1419be88e75SGabriel Fernandez _DDRPHYCAPB, 1429be88e75SGabriel Fernandez _DDRPHYCAPBLP, 1439be88e75SGabriel Fernandez _SYSCFG, 1449be88e75SGabriel Fernandez _DDRPERFM, 1459be88e75SGabriel Fernandez _IWDG2APB, 1469be88e75SGabriel Fernandez _USBPHY_K, 1479be88e75SGabriel Fernandez _USBO_K, 1489be88e75SGabriel Fernandez _RTCAPB, 1499be88e75SGabriel Fernandez _TZC, 1509be88e75SGabriel Fernandez _ETZPC, 1519be88e75SGabriel Fernandez _IWDG1APB, 1529be88e75SGabriel Fernandez _BSEC, 1539be88e75SGabriel Fernandez _STGENC, 1549be88e75SGabriel Fernandez _USART1_K, 1559be88e75SGabriel Fernandez _USART2_K, 1569be88e75SGabriel Fernandez _I2C3_K, 1579be88e75SGabriel Fernandez _I2C4_K, 1589be88e75SGabriel Fernandez _I2C5_K, 1599be88e75SGabriel Fernandez _TIM12, 1609be88e75SGabriel Fernandez _TIM15, 1619be88e75SGabriel Fernandez _RTCCK, 1629be88e75SGabriel Fernandez _GPIOA, 1639be88e75SGabriel Fernandez _GPIOB, 1649be88e75SGabriel Fernandez _GPIOC, 1659be88e75SGabriel Fernandez _GPIOD, 1669be88e75SGabriel Fernandez _GPIOE, 1679be88e75SGabriel Fernandez _GPIOF, 1689be88e75SGabriel Fernandez _GPIOG, 1699be88e75SGabriel Fernandez _GPIOH, 1709be88e75SGabriel Fernandez _GPIOI, 1719be88e75SGabriel Fernandez _PKA, 1729be88e75SGabriel Fernandez _SAES_K, 1739be88e75SGabriel Fernandez _CRYP1, 1749be88e75SGabriel Fernandez _HASH1, 1759be88e75SGabriel Fernandez _RNG1_K, 1769be88e75SGabriel Fernandez _BKPSRAM, 1779be88e75SGabriel Fernandez _SDMMC1_K, 1789be88e75SGabriel Fernandez _SDMMC2_K, 1799be88e75SGabriel Fernandez _DBGCK, 1809be88e75SGabriel Fernandez _USART3_K, 1819be88e75SGabriel Fernandez _UART4_K, 1829be88e75SGabriel Fernandez _UART5_K, 1839be88e75SGabriel Fernandez _UART7_K, 1849be88e75SGabriel Fernandez _UART8_K, 1859be88e75SGabriel Fernandez _USART6_K, 1869be88e75SGabriel Fernandez _MCE, 1879be88e75SGabriel Fernandez _FMC_K, 1889be88e75SGabriel Fernandez _QSPI_K, 189*698bba5eSYann Gautier 1909be88e75SGabriel Fernandez CK_LAST 1919be88e75SGabriel Fernandez }; 1929be88e75SGabriel Fernandez 1939be88e75SGabriel Fernandez /* PARENT CONFIG */ 1949be88e75SGabriel Fernandez static const uint16_t RTC_src[] = { 1959be88e75SGabriel Fernandez _CK_OFF, _CK_LSE, _CK_LSI, _CK_HSE 1969be88e75SGabriel Fernandez }; 1979be88e75SGabriel Fernandez 1989be88e75SGabriel Fernandez static const uint16_t MCO1_src[] = { 1999be88e75SGabriel Fernandez _CK_HSI, _CK_HSE, _CK_CSI, _CK_LSI, _CK_LSE 2009be88e75SGabriel Fernandez }; 2019be88e75SGabriel Fernandez 2029be88e75SGabriel Fernandez static const uint16_t MCO2_src[] = { 2039be88e75SGabriel Fernandez _CKMPU, _CKAXI, _CKMLAHB, _PLL4P, _CK_HSE, _CK_HSI 2049be88e75SGabriel Fernandez }; 2059be88e75SGabriel Fernandez 2069be88e75SGabriel Fernandez static const uint16_t PLL12_src[] = { 2079be88e75SGabriel Fernandez _CK_HSI, _CK_HSE 2089be88e75SGabriel Fernandez }; 2099be88e75SGabriel Fernandez 2109be88e75SGabriel Fernandez static const uint16_t PLL3_src[] = { 2119be88e75SGabriel Fernandez _CK_HSI, _CK_HSE, _CK_CSI 2129be88e75SGabriel Fernandez }; 2139be88e75SGabriel Fernandez 2149be88e75SGabriel Fernandez static const uint16_t PLL4_src[] = { 2159be88e75SGabriel Fernandez _CK_HSI, _CK_HSE, _CK_CSI, _I2SCKIN 2169be88e75SGabriel Fernandez }; 2179be88e75SGabriel Fernandez 2189be88e75SGabriel Fernandez static const uint16_t MPU_src[] = { 2199be88e75SGabriel Fernandez _CK_HSI, _CK_HSE, _PLL1P, _PLL1P_DIV 2209be88e75SGabriel Fernandez }; 2219be88e75SGabriel Fernandez 2229be88e75SGabriel Fernandez static const uint16_t AXI_src[] = { 2239be88e75SGabriel Fernandez _CK_HSI, _CK_HSE, _PLL2P 2249be88e75SGabriel Fernandez }; 2259be88e75SGabriel Fernandez 2269be88e75SGabriel Fernandez static const uint16_t MLAHBS_src[] = { 2279be88e75SGabriel Fernandez _CK_HSI, _CK_HSE, _CK_CSI, _PLL3P 2289be88e75SGabriel Fernandez }; 2299be88e75SGabriel Fernandez 2309be88e75SGabriel Fernandez static const uint16_t CKPER_src[] = { 2319be88e75SGabriel Fernandez _CK_HSI, _CK_CSI, _CK_HSE, _CK_OFF 2329be88e75SGabriel Fernandez }; 2339be88e75SGabriel Fernandez 2349be88e75SGabriel Fernandez static const uint16_t I2C12_src[] = { 2359be88e75SGabriel Fernandez _PCLK1, _PLL4R, _CK_HSI, _CK_CSI 2369be88e75SGabriel Fernandez }; 2379be88e75SGabriel Fernandez 2389be88e75SGabriel Fernandez static const uint16_t I2C3_src[] = { 2399be88e75SGabriel Fernandez _PCLK6, _PLL4R, _CK_HSI, _CK_CSI 2409be88e75SGabriel Fernandez }; 2419be88e75SGabriel Fernandez 2429be88e75SGabriel Fernandez static const uint16_t I2C4_src[] = { 2439be88e75SGabriel Fernandez _PCLK6, _PLL4R, _CK_HSI, _CK_CSI 2449be88e75SGabriel Fernandez }; 2459be88e75SGabriel Fernandez 2469be88e75SGabriel Fernandez static const uint16_t I2C5_src[] = { 2479be88e75SGabriel Fernandez _PCLK6, _PLL4R, _CK_HSI, _CK_CSI 2489be88e75SGabriel Fernandez }; 2499be88e75SGabriel Fernandez 2509be88e75SGabriel Fernandez static const uint16_t SPI1_src[] = { 2519be88e75SGabriel Fernandez _PLL4P, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R 2529be88e75SGabriel Fernandez }; 2539be88e75SGabriel Fernandez 2549be88e75SGabriel Fernandez static const uint16_t SPI23_src[] = { 2559be88e75SGabriel Fernandez _PLL4P, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R 2569be88e75SGabriel Fernandez }; 2579be88e75SGabriel Fernandez 2589be88e75SGabriel Fernandez static const uint16_t SPI4_src[] = { 2599be88e75SGabriel Fernandez _PCLK6, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE, _I2SCKIN 2609be88e75SGabriel Fernandez }; 2619be88e75SGabriel Fernandez 2629be88e75SGabriel Fernandez static const uint16_t SPI5_src[] = { 2639be88e75SGabriel Fernandez _PCLK6, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE 2649be88e75SGabriel Fernandez }; 2659be88e75SGabriel Fernandez 2669be88e75SGabriel Fernandez static const uint16_t UART1_src[] = { 2679be88e75SGabriel Fernandez _PCLK6, _PLL3Q, _CK_HSI, _CK_CSI, _PLL4Q, _CK_HSE 2689be88e75SGabriel Fernandez }; 2699be88e75SGabriel Fernandez 2709be88e75SGabriel Fernandez static const uint16_t UART2_src[] = { 2719be88e75SGabriel Fernandez _PCLK6, _PLL3Q, _CK_HSI, _CK_CSI, _PLL4Q, _CK_HSE 2729be88e75SGabriel Fernandez }; 2739be88e75SGabriel Fernandez 2749be88e75SGabriel Fernandez static const uint16_t UART35_src[] = { 2759be88e75SGabriel Fernandez _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE 2769be88e75SGabriel Fernandez }; 2779be88e75SGabriel Fernandez 2789be88e75SGabriel Fernandez static const uint16_t UART4_src[] = { 2799be88e75SGabriel Fernandez _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE 2809be88e75SGabriel Fernandez }; 2819be88e75SGabriel Fernandez 2829be88e75SGabriel Fernandez static const uint16_t UART6_src[] = { 2839be88e75SGabriel Fernandez _PCLK2, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE 2849be88e75SGabriel Fernandez }; 2859be88e75SGabriel Fernandez 2869be88e75SGabriel Fernandez static const uint16_t UART78_src[] = { 2879be88e75SGabriel Fernandez _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE 2889be88e75SGabriel Fernandez }; 2899be88e75SGabriel Fernandez 2909be88e75SGabriel Fernandez static const uint16_t LPTIM1_src[] = { 2919be88e75SGabriel Fernandez _PCLK1, _PLL4P, _PLL3Q, _CK_LSE, _CK_LSI, _CKPER 2929be88e75SGabriel Fernandez }; 2939be88e75SGabriel Fernandez 2949be88e75SGabriel Fernandez static const uint16_t LPTIM2_src[] = { 2959be88e75SGabriel Fernandez _PCLK3, _PLL4Q, _CKPER, _CK_LSE, _CK_LSI 2969be88e75SGabriel Fernandez }; 2979be88e75SGabriel Fernandez 2989be88e75SGabriel Fernandez static const uint16_t LPTIM3_src[] = { 2999be88e75SGabriel Fernandez _PCLK3, _PLL4Q, _CKPER, _CK_LSE, _CK_LSI 3009be88e75SGabriel Fernandez }; 3019be88e75SGabriel Fernandez 3029be88e75SGabriel Fernandez static const uint16_t LPTIM45_src[] = { 3039be88e75SGabriel Fernandez _PCLK3, _PLL4P, _PLL3Q, _CK_LSE, _CK_LSI, _CKPER 3049be88e75SGabriel Fernandez }; 3059be88e75SGabriel Fernandez 3069be88e75SGabriel Fernandez static const uint16_t SAI1_src[] = { 3079be88e75SGabriel Fernandez _PLL4Q, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R 3089be88e75SGabriel Fernandez }; 3099be88e75SGabriel Fernandez 3109be88e75SGabriel Fernandez static const uint16_t SAI2_src[] = { 3119be88e75SGabriel Fernandez _PLL4Q, _PLL3Q, _I2SCKIN, _CKPER, _NO_ID, _PLL3R 3129be88e75SGabriel Fernandez }; 3139be88e75SGabriel Fernandez 3149be88e75SGabriel Fernandez static const uint16_t FDCAN_src[] = { 3159be88e75SGabriel Fernandez _CK_HSE, _PLL3Q, _PLL4Q, _PLL4R 3169be88e75SGabriel Fernandez }; 3179be88e75SGabriel Fernandez 3189be88e75SGabriel Fernandez static const uint16_t SPDIF_src[] = { 3199be88e75SGabriel Fernandez _PLL4P, _PLL3Q, _CK_HSI 3209be88e75SGabriel Fernandez }; 3219be88e75SGabriel Fernandez 3229be88e75SGabriel Fernandez static const uint16_t ADC1_src[] = { 3239be88e75SGabriel Fernandez _PLL4R, _CKPER, _PLL3Q 3249be88e75SGabriel Fernandez }; 3259be88e75SGabriel Fernandez 3269be88e75SGabriel Fernandez static const uint16_t ADC2_src[] = { 3279be88e75SGabriel Fernandez _PLL4R, _CKPER, _PLL3Q 3289be88e75SGabriel Fernandez }; 3299be88e75SGabriel Fernandez 3309be88e75SGabriel Fernandez static const uint16_t SDMMC1_src[] = { 3319be88e75SGabriel Fernandez _CKAXI, _PLL3R, _PLL4P, _CK_HSI 3329be88e75SGabriel Fernandez }; 3339be88e75SGabriel Fernandez 3349be88e75SGabriel Fernandez static const uint16_t SDMMC2_src[] = { 3359be88e75SGabriel Fernandez _CKAXI, _PLL3R, _PLL4P, _CK_HSI 3369be88e75SGabriel Fernandez }; 3379be88e75SGabriel Fernandez 3389be88e75SGabriel Fernandez static const uint16_t ETH1_src[] = { 3399be88e75SGabriel Fernandez _PLL4P, _PLL3Q 3409be88e75SGabriel Fernandez }; 3419be88e75SGabriel Fernandez 3429be88e75SGabriel Fernandez static const uint16_t ETH2_src[] = { 3439be88e75SGabriel Fernandez _PLL4P, _PLL3Q 3449be88e75SGabriel Fernandez }; 3459be88e75SGabriel Fernandez 3469be88e75SGabriel Fernandez static const uint16_t USBPHY_src[] = { 3479be88e75SGabriel Fernandez _CK_HSE, _PLL4R, _HSE_DIV2 3489be88e75SGabriel Fernandez }; 3499be88e75SGabriel Fernandez 3509be88e75SGabriel Fernandez static const uint16_t USBO_src[] = { 3519be88e75SGabriel Fernandez _PLL4R, _USB_PHY_48 3529be88e75SGabriel Fernandez }; 3539be88e75SGabriel Fernandez 3549be88e75SGabriel Fernandez static const uint16_t QSPI_src[] = { 3559be88e75SGabriel Fernandez _CKAXI, _PLL3R, _PLL4P, _CKPER 3569be88e75SGabriel Fernandez }; 3579be88e75SGabriel Fernandez 3589be88e75SGabriel Fernandez static const uint16_t FMC_src[] = { 3599be88e75SGabriel Fernandez _CKAXI, _PLL3R, _PLL4P, _CKPER 3609be88e75SGabriel Fernandez }; 3619be88e75SGabriel Fernandez 3629be88e75SGabriel Fernandez /* Position 2 of RNG1 mux is reserved */ 3639be88e75SGabriel Fernandez static const uint16_t RNG1_src[] = { 3649be88e75SGabriel Fernandez _CK_CSI, _PLL4R, _CK_OFF, _CK_LSI 3659be88e75SGabriel Fernandez }; 3669be88e75SGabriel Fernandez 3679be88e75SGabriel Fernandez static const uint16_t STGEN_src[] = { 3689be88e75SGabriel Fernandez _CK_HSI, _CK_HSE 3699be88e75SGabriel Fernandez }; 3709be88e75SGabriel Fernandez 3719be88e75SGabriel Fernandez static const uint16_t DCMIPP_src[] = { 3729be88e75SGabriel Fernandez _CKAXI, _PLL2Q, _PLL4P, _CKPER 3739be88e75SGabriel Fernandez }; 3749be88e75SGabriel Fernandez 3759be88e75SGabriel Fernandez static const uint16_t SAES_src[] = { 3769be88e75SGabriel Fernandez _CKAXI, _CKPER, _PLL4R, _CK_LSI 3779be88e75SGabriel Fernandez }; 3789be88e75SGabriel Fernandez 3799be88e75SGabriel Fernandez #define MUX_CFG(id, src, _offset, _shift, _witdh)[id] = {\ 3809be88e75SGabriel Fernandez .id_parents = src,\ 3819be88e75SGabriel Fernandez .num_parents = ARRAY_SIZE(src),\ 3829be88e75SGabriel Fernandez .mux = &(struct mux_cfg) {\ 3839be88e75SGabriel Fernandez .offset = (_offset),\ 3849be88e75SGabriel Fernandez .shift = (_shift),\ 3859be88e75SGabriel Fernandez .width = (_witdh),\ 3869be88e75SGabriel Fernandez .bitrdy = MUX_NO_BIT_RDY,\ 3879be88e75SGabriel Fernandez },\ 3889be88e75SGabriel Fernandez } 3899be88e75SGabriel Fernandez 3909be88e75SGabriel Fernandez #define MUX_RDY_CFG(id, src, _offset, _shift, _witdh)[id] = {\ 3919be88e75SGabriel Fernandez .id_parents = src,\ 3929be88e75SGabriel Fernandez .num_parents = ARRAY_SIZE(src),\ 3939be88e75SGabriel Fernandez .mux = &(struct mux_cfg) {\ 3949be88e75SGabriel Fernandez .offset = (_offset),\ 3959be88e75SGabriel Fernandez .shift = (_shift),\ 3969be88e75SGabriel Fernandez .width = (_witdh),\ 3979be88e75SGabriel Fernandez .bitrdy = 31,\ 3989be88e75SGabriel Fernandez },\ 3999be88e75SGabriel Fernandez } 4009be88e75SGabriel Fernandez 401ee21709eSYann Gautier static const struct parent_cfg parent_mp13[MUX_MAX] = { 4029be88e75SGabriel Fernandez MUX_CFG(MUX_ADC1, ADC1_src, RCC_ADC12CKSELR, 0, 2), 4039be88e75SGabriel Fernandez MUX_CFG(MUX_ADC2, ADC2_src, RCC_ADC12CKSELR, 2, 2), 4049be88e75SGabriel Fernandez MUX_RDY_CFG(MUX_AXI, AXI_src, RCC_ASSCKSELR, 0, 3), 4059be88e75SGabriel Fernandez MUX_CFG(MUX_CKPER, CKPER_src, RCC_CPERCKSELR, 0, 2), 4069be88e75SGabriel Fernandez MUX_CFG(MUX_DCMIPP, DCMIPP_src, RCC_DCMIPPCKSELR, 0, 2), 4079be88e75SGabriel Fernandez MUX_CFG(MUX_ETH1, ETH1_src, RCC_ETH12CKSELR, 0, 2), 4089be88e75SGabriel Fernandez MUX_CFG(MUX_ETH2, ETH2_src, RCC_ETH12CKSELR, 8, 2), 4099be88e75SGabriel Fernandez MUX_CFG(MUX_FDCAN, FDCAN_src, RCC_FDCANCKSELR, 0, 2), 4109be88e75SGabriel Fernandez MUX_CFG(MUX_FMC, FMC_src, RCC_FMCCKSELR, 0, 2), 4119be88e75SGabriel Fernandez MUX_CFG(MUX_I2C12, I2C12_src, RCC_I2C12CKSELR, 0, 3), 4129be88e75SGabriel Fernandez MUX_CFG(MUX_I2C3, I2C3_src, RCC_I2C345CKSELR, 0, 3), 4139be88e75SGabriel Fernandez MUX_CFG(MUX_I2C4, I2C4_src, RCC_I2C345CKSELR, 3, 3), 4149be88e75SGabriel Fernandez MUX_CFG(MUX_I2C5, I2C5_src, RCC_I2C345CKSELR, 6, 3), 4159be88e75SGabriel Fernandez MUX_CFG(MUX_LPTIM1, LPTIM1_src, RCC_LPTIM1CKSELR, 0, 3), 4169be88e75SGabriel Fernandez MUX_CFG(MUX_LPTIM2, LPTIM2_src, RCC_LPTIM23CKSELR, 0, 3), 4179be88e75SGabriel Fernandez MUX_CFG(MUX_LPTIM3, LPTIM3_src, RCC_LPTIM23CKSELR, 3, 3), 4189be88e75SGabriel Fernandez MUX_CFG(MUX_LPTIM45, LPTIM45_src, RCC_LPTIM45CKSELR, 0, 3), 4199be88e75SGabriel Fernandez MUX_CFG(MUX_MCO1, MCO1_src, RCC_MCO1CFGR, 0, 3), 4209be88e75SGabriel Fernandez MUX_CFG(MUX_MCO2, MCO2_src, RCC_MCO2CFGR, 0, 3), 4219be88e75SGabriel Fernandez MUX_RDY_CFG(MUX_MLAHB, MLAHBS_src, RCC_MSSCKSELR, 0, 2), 4229be88e75SGabriel Fernandez MUX_RDY_CFG(MUX_MPU, MPU_src, RCC_MPCKSELR, 0, 2), 4239be88e75SGabriel Fernandez MUX_RDY_CFG(MUX_PLL12, PLL12_src, RCC_RCK12SELR, 0, 2), 4249be88e75SGabriel Fernandez MUX_RDY_CFG(MUX_PLL3, PLL3_src, RCC_RCK3SELR, 0, 2), 4259be88e75SGabriel Fernandez MUX_RDY_CFG(MUX_PLL4, PLL4_src, RCC_RCK4SELR, 0, 2), 4269be88e75SGabriel Fernandez MUX_CFG(MUX_QSPI, QSPI_src, RCC_QSPICKSELR, 0, 2), 4279be88e75SGabriel Fernandez MUX_CFG(MUX_RNG1, RNG1_src, RCC_RNG1CKSELR, 0, 2), 4289be88e75SGabriel Fernandez MUX_CFG(MUX_RTC, RTC_src, RCC_BDCR, 16, 2), 4299be88e75SGabriel Fernandez MUX_CFG(MUX_SAES, SAES_src, RCC_SAESCKSELR, 0, 2), 4309be88e75SGabriel Fernandez MUX_CFG(MUX_SAI1, SAI1_src, RCC_SAI1CKSELR, 0, 3), 4319be88e75SGabriel Fernandez MUX_CFG(MUX_SAI2, SAI2_src, RCC_SAI2CKSELR, 0, 3), 4329be88e75SGabriel Fernandez MUX_CFG(MUX_SDMMC1, SDMMC1_src, RCC_SDMMC12CKSELR, 0, 3), 4339be88e75SGabriel Fernandez MUX_CFG(MUX_SDMMC2, SDMMC2_src, RCC_SDMMC12CKSELR, 3, 3), 4349be88e75SGabriel Fernandez MUX_CFG(MUX_SPDIF, SPDIF_src, RCC_SPDIFCKSELR, 0, 2), 4359be88e75SGabriel Fernandez MUX_CFG(MUX_SPI1, SPI1_src, RCC_SPI2S1CKSELR, 0, 3), 4369be88e75SGabriel Fernandez MUX_CFG(MUX_SPI23, SPI23_src, RCC_SPI2S23CKSELR, 0, 3), 4379be88e75SGabriel Fernandez MUX_CFG(MUX_SPI4, SPI4_src, RCC_SPI45CKSELR, 0, 3), 4389be88e75SGabriel Fernandez MUX_CFG(MUX_SPI5, SPI5_src, RCC_SPI45CKSELR, 3, 3), 4399be88e75SGabriel Fernandez MUX_CFG(MUX_STGEN, STGEN_src, RCC_STGENCKSELR, 0, 2), 4409be88e75SGabriel Fernandez MUX_CFG(MUX_UART1, UART1_src, RCC_UART12CKSELR, 0, 3), 4419be88e75SGabriel Fernandez MUX_CFG(MUX_UART2, UART2_src, RCC_UART12CKSELR, 3, 3), 4429be88e75SGabriel Fernandez MUX_CFG(MUX_UART35, UART35_src, RCC_UART35CKSELR, 0, 3), 4439be88e75SGabriel Fernandez MUX_CFG(MUX_UART4, UART4_src, RCC_UART4CKSELR, 0, 3), 4449be88e75SGabriel Fernandez MUX_CFG(MUX_UART6, UART6_src, RCC_UART6CKSELR, 0, 3), 4459be88e75SGabriel Fernandez MUX_CFG(MUX_UART78, UART78_src, RCC_UART78CKSELR, 0, 3), 4469be88e75SGabriel Fernandez MUX_CFG(MUX_USBO, USBO_src, RCC_USBCKSELR, 4, 1), 4479be88e75SGabriel Fernandez MUX_CFG(MUX_USBPHY, USBPHY_src, RCC_USBCKSELR, 0, 2), 4489be88e75SGabriel Fernandez }; 4499be88e75SGabriel Fernandez 4509be88e75SGabriel Fernandez /* 4519be88e75SGabriel Fernandez * GATE CONFIG 4529be88e75SGabriel Fernandez */ 4539be88e75SGabriel Fernandez 4549be88e75SGabriel Fernandez enum enum_gate_cfg { 4559be88e75SGabriel Fernandez GATE_ZERO, /* reserved for no gate */ 4569be88e75SGabriel Fernandez GATE_LSE, 4579be88e75SGabriel Fernandez GATE_RTCCK, 4589be88e75SGabriel Fernandez GATE_LSI, 4599be88e75SGabriel Fernandez GATE_HSI, 4609be88e75SGabriel Fernandez GATE_CSI, 4619be88e75SGabriel Fernandez GATE_HSE, 4629be88e75SGabriel Fernandez GATE_LSI_RDY, 4639be88e75SGabriel Fernandez GATE_CSI_RDY, 4649be88e75SGabriel Fernandez GATE_LSE_RDY, 4659be88e75SGabriel Fernandez GATE_HSE_RDY, 4669be88e75SGabriel Fernandez GATE_HSI_RDY, 4679be88e75SGabriel Fernandez GATE_MCO1, 4689be88e75SGabriel Fernandez GATE_MCO2, 4699be88e75SGabriel Fernandez GATE_DBGCK, 4709be88e75SGabriel Fernandez GATE_TRACECK, 4719be88e75SGabriel Fernandez GATE_PLL1, 4729be88e75SGabriel Fernandez GATE_PLL1_DIVP, 4739be88e75SGabriel Fernandez GATE_PLL1_DIVQ, 4749be88e75SGabriel Fernandez GATE_PLL1_DIVR, 4759be88e75SGabriel Fernandez GATE_PLL2, 4769be88e75SGabriel Fernandez GATE_PLL2_DIVP, 4779be88e75SGabriel Fernandez GATE_PLL2_DIVQ, 4789be88e75SGabriel Fernandez GATE_PLL2_DIVR, 4799be88e75SGabriel Fernandez GATE_PLL3, 4809be88e75SGabriel Fernandez GATE_PLL3_DIVP, 4819be88e75SGabriel Fernandez GATE_PLL3_DIVQ, 4829be88e75SGabriel Fernandez GATE_PLL3_DIVR, 4839be88e75SGabriel Fernandez GATE_PLL4, 4849be88e75SGabriel Fernandez GATE_PLL4_DIVP, 4859be88e75SGabriel Fernandez GATE_PLL4_DIVQ, 4869be88e75SGabriel Fernandez GATE_PLL4_DIVR, 4879be88e75SGabriel Fernandez GATE_DDRC1, 4889be88e75SGabriel Fernandez GATE_DDRC1LP, 4899be88e75SGabriel Fernandez GATE_DDRPHYC, 4909be88e75SGabriel Fernandez GATE_DDRPHYCLP, 4919be88e75SGabriel Fernandez GATE_DDRCAPB, 4929be88e75SGabriel Fernandez GATE_DDRCAPBLP, 4939be88e75SGabriel Fernandez GATE_AXIDCG, 4949be88e75SGabriel Fernandez GATE_DDRPHYCAPB, 4959be88e75SGabriel Fernandez GATE_DDRPHYCAPBLP, 4969be88e75SGabriel Fernandez GATE_TIM2, 4979be88e75SGabriel Fernandez GATE_TIM3, 4989be88e75SGabriel Fernandez GATE_TIM4, 4999be88e75SGabriel Fernandez GATE_TIM5, 5009be88e75SGabriel Fernandez GATE_TIM6, 5019be88e75SGabriel Fernandez GATE_TIM7, 5029be88e75SGabriel Fernandez GATE_LPTIM1, 5039be88e75SGabriel Fernandez GATE_SPI2, 5049be88e75SGabriel Fernandez GATE_SPI3, 5059be88e75SGabriel Fernandez GATE_USART3, 5069be88e75SGabriel Fernandez GATE_UART4, 5079be88e75SGabriel Fernandez GATE_UART5, 5089be88e75SGabriel Fernandez GATE_UART7, 5099be88e75SGabriel Fernandez GATE_UART8, 5109be88e75SGabriel Fernandez GATE_I2C1, 5119be88e75SGabriel Fernandez GATE_I2C2, 5129be88e75SGabriel Fernandez GATE_SPDIF, 5139be88e75SGabriel Fernandez GATE_TIM1, 5149be88e75SGabriel Fernandez GATE_TIM8, 5159be88e75SGabriel Fernandez GATE_SPI1, 5169be88e75SGabriel Fernandez GATE_USART6, 5179be88e75SGabriel Fernandez GATE_SAI1, 5189be88e75SGabriel Fernandez GATE_SAI2, 5199be88e75SGabriel Fernandez GATE_DFSDM, 5209be88e75SGabriel Fernandez GATE_ADFSDM, 5219be88e75SGabriel Fernandez GATE_FDCAN, 5229be88e75SGabriel Fernandez GATE_LPTIM2, 5239be88e75SGabriel Fernandez GATE_LPTIM3, 5249be88e75SGabriel Fernandez GATE_LPTIM4, 5259be88e75SGabriel Fernandez GATE_LPTIM5, 5269be88e75SGabriel Fernandez GATE_VREF, 5279be88e75SGabriel Fernandez GATE_DTS, 5289be88e75SGabriel Fernandez GATE_PMBCTRL, 5299be88e75SGabriel Fernandez GATE_HDP, 5309be88e75SGabriel Fernandez GATE_SYSCFG, 5319be88e75SGabriel Fernandez GATE_DCMIPP, 5329be88e75SGabriel Fernandez GATE_DDRPERFM, 5339be88e75SGabriel Fernandez GATE_IWDG2APB, 5349be88e75SGabriel Fernandez GATE_USBPHY, 5359be88e75SGabriel Fernandez GATE_STGENRO, 5369be88e75SGabriel Fernandez GATE_LTDC, 5379be88e75SGabriel Fernandez GATE_RTCAPB, 5389be88e75SGabriel Fernandez GATE_TZC, 5399be88e75SGabriel Fernandez GATE_ETZPC, 5409be88e75SGabriel Fernandez GATE_IWDG1APB, 5419be88e75SGabriel Fernandez GATE_BSEC, 5429be88e75SGabriel Fernandez GATE_STGENC, 5439be88e75SGabriel Fernandez GATE_USART1, 5449be88e75SGabriel Fernandez GATE_USART2, 5459be88e75SGabriel Fernandez GATE_SPI4, 5469be88e75SGabriel Fernandez GATE_SPI5, 5479be88e75SGabriel Fernandez GATE_I2C3, 5489be88e75SGabriel Fernandez GATE_I2C4, 5499be88e75SGabriel Fernandez GATE_I2C5, 5509be88e75SGabriel Fernandez GATE_TIM12, 5519be88e75SGabriel Fernandez GATE_TIM13, 5529be88e75SGabriel Fernandez GATE_TIM14, 5539be88e75SGabriel Fernandez GATE_TIM15, 5549be88e75SGabriel Fernandez GATE_TIM16, 5559be88e75SGabriel Fernandez GATE_TIM17, 5569be88e75SGabriel Fernandez GATE_DMA1, 5579be88e75SGabriel Fernandez GATE_DMA2, 5589be88e75SGabriel Fernandez GATE_DMAMUX1, 5599be88e75SGabriel Fernandez GATE_DMA3, 5609be88e75SGabriel Fernandez GATE_DMAMUX2, 5619be88e75SGabriel Fernandez GATE_ADC1, 5629be88e75SGabriel Fernandez GATE_ADC2, 5639be88e75SGabriel Fernandez GATE_USBO, 5649be88e75SGabriel Fernandez GATE_TSC, 5659be88e75SGabriel Fernandez GATE_GPIOA, 5669be88e75SGabriel Fernandez GATE_GPIOB, 5679be88e75SGabriel Fernandez GATE_GPIOC, 5689be88e75SGabriel Fernandez GATE_GPIOD, 5699be88e75SGabriel Fernandez GATE_GPIOE, 5709be88e75SGabriel Fernandez GATE_GPIOF, 5719be88e75SGabriel Fernandez GATE_GPIOG, 5729be88e75SGabriel Fernandez GATE_GPIOH, 5739be88e75SGabriel Fernandez GATE_GPIOI, 5749be88e75SGabriel Fernandez GATE_PKA, 5759be88e75SGabriel Fernandez GATE_SAES, 5769be88e75SGabriel Fernandez GATE_CRYP1, 5779be88e75SGabriel Fernandez GATE_HASH1, 5789be88e75SGabriel Fernandez GATE_RNG1, 5799be88e75SGabriel Fernandez GATE_BKPSRAM, 5809be88e75SGabriel Fernandez GATE_AXIMC, 5819be88e75SGabriel Fernandez GATE_MCE, 5829be88e75SGabriel Fernandez GATE_ETH1CK, 5839be88e75SGabriel Fernandez GATE_ETH1TX, 5849be88e75SGabriel Fernandez GATE_ETH1RX, 5859be88e75SGabriel Fernandez GATE_ETH1MAC, 5869be88e75SGabriel Fernandez GATE_FMC, 5879be88e75SGabriel Fernandez GATE_QSPI, 5889be88e75SGabriel Fernandez GATE_SDMMC1, 5899be88e75SGabriel Fernandez GATE_SDMMC2, 5909be88e75SGabriel Fernandez GATE_CRC1, 5919be88e75SGabriel Fernandez GATE_USBH, 5929be88e75SGabriel Fernandez GATE_ETH2CK, 5939be88e75SGabriel Fernandez GATE_ETH2TX, 5949be88e75SGabriel Fernandez GATE_ETH2RX, 5959be88e75SGabriel Fernandez GATE_ETH2MAC, 5969be88e75SGabriel Fernandez GATE_MDMA, 5979be88e75SGabriel Fernandez 5989be88e75SGabriel Fernandez LAST_GATE 5999be88e75SGabriel Fernandez }; 6009be88e75SGabriel Fernandez 6019be88e75SGabriel Fernandez #define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\ 6029be88e75SGabriel Fernandez .offset = (_offset),\ 6039be88e75SGabriel Fernandez .bit_idx = (_bit_idx),\ 6049be88e75SGabriel Fernandez .set_clr = (_offset_clr),\ 6059be88e75SGabriel Fernandez } 6069be88e75SGabriel Fernandez 6079be88e75SGabriel Fernandez static const struct gate_cfg gates_mp13[LAST_GATE] = { 6089be88e75SGabriel Fernandez GATE_CFG(GATE_LSE, RCC_BDCR, 0, 0), 6099be88e75SGabriel Fernandez GATE_CFG(GATE_RTCCK, RCC_BDCR, 20, 0), 6109be88e75SGabriel Fernandez GATE_CFG(GATE_LSI, RCC_RDLSICR, 0, 0), 6119be88e75SGabriel Fernandez GATE_CFG(GATE_HSI, RCC_OCENSETR, 0, 1), 6129be88e75SGabriel Fernandez GATE_CFG(GATE_CSI, RCC_OCENSETR, 4, 1), 6139be88e75SGabriel Fernandez GATE_CFG(GATE_HSE, RCC_OCENSETR, 8, 1), 6149be88e75SGabriel Fernandez GATE_CFG(GATE_LSI_RDY, RCC_RDLSICR, 1, 0), 6159be88e75SGabriel Fernandez GATE_CFG(GATE_CSI_RDY, RCC_OCRDYR, 4, 0), 6169be88e75SGabriel Fernandez GATE_CFG(GATE_LSE_RDY, RCC_BDCR, 2, 0), 6179be88e75SGabriel Fernandez GATE_CFG(GATE_HSE_RDY, RCC_OCRDYR, 8, 0), 6189be88e75SGabriel Fernandez GATE_CFG(GATE_HSI_RDY, RCC_OCRDYR, 0, 0), 6199be88e75SGabriel Fernandez GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 12, 0), 6209be88e75SGabriel Fernandez GATE_CFG(GATE_MCO2, RCC_MCO2CFGR, 12, 0), 6219be88e75SGabriel Fernandez GATE_CFG(GATE_DBGCK, RCC_DBGCFGR, 8, 0), 6229be88e75SGabriel Fernandez GATE_CFG(GATE_TRACECK, RCC_DBGCFGR, 9, 0), 6239be88e75SGabriel Fernandez GATE_CFG(GATE_PLL1, RCC_PLL1CR, 0, 0), 6249be88e75SGabriel Fernandez GATE_CFG(GATE_PLL1_DIVP, RCC_PLL1CR, 4, 0), 6259be88e75SGabriel Fernandez GATE_CFG(GATE_PLL1_DIVQ, RCC_PLL1CR, 5, 0), 6269be88e75SGabriel Fernandez GATE_CFG(GATE_PLL1_DIVR, RCC_PLL1CR, 6, 0), 6279be88e75SGabriel Fernandez GATE_CFG(GATE_PLL2, RCC_PLL2CR, 0, 0), 6289be88e75SGabriel Fernandez GATE_CFG(GATE_PLL2_DIVP, RCC_PLL2CR, 4, 0), 6299be88e75SGabriel Fernandez GATE_CFG(GATE_PLL2_DIVQ, RCC_PLL2CR, 5, 0), 6309be88e75SGabriel Fernandez GATE_CFG(GATE_PLL2_DIVR, RCC_PLL2CR, 6, 0), 6319be88e75SGabriel Fernandez GATE_CFG(GATE_PLL3, RCC_PLL3CR, 0, 0), 6329be88e75SGabriel Fernandez GATE_CFG(GATE_PLL3_DIVP, RCC_PLL3CR, 4, 0), 6339be88e75SGabriel Fernandez GATE_CFG(GATE_PLL3_DIVQ, RCC_PLL3CR, 5, 0), 6349be88e75SGabriel Fernandez GATE_CFG(GATE_PLL3_DIVR, RCC_PLL3CR, 6, 0), 6359be88e75SGabriel Fernandez GATE_CFG(GATE_PLL4, RCC_PLL4CR, 0, 0), 6369be88e75SGabriel Fernandez GATE_CFG(GATE_PLL4_DIVP, RCC_PLL4CR, 4, 0), 6379be88e75SGabriel Fernandez GATE_CFG(GATE_PLL4_DIVQ, RCC_PLL4CR, 5, 0), 6389be88e75SGabriel Fernandez GATE_CFG(GATE_PLL4_DIVR, RCC_PLL4CR, 6, 0), 6399be88e75SGabriel Fernandez GATE_CFG(GATE_DDRC1, RCC_DDRITFCR, 0, 0), 6409be88e75SGabriel Fernandez GATE_CFG(GATE_DDRC1LP, RCC_DDRITFCR, 1, 0), 6419be88e75SGabriel Fernandez GATE_CFG(GATE_DDRPHYC, RCC_DDRITFCR, 4, 0), 6429be88e75SGabriel Fernandez GATE_CFG(GATE_DDRPHYCLP, RCC_DDRITFCR, 5, 0), 6439be88e75SGabriel Fernandez GATE_CFG(GATE_DDRCAPB, RCC_DDRITFCR, 6, 0), 6449be88e75SGabriel Fernandez GATE_CFG(GATE_DDRCAPBLP, RCC_DDRITFCR, 7, 0), 6459be88e75SGabriel Fernandez GATE_CFG(GATE_AXIDCG, RCC_DDRITFCR, 8, 0), 6469be88e75SGabriel Fernandez GATE_CFG(GATE_DDRPHYCAPB, RCC_DDRITFCR, 9, 0), 6479be88e75SGabriel Fernandez GATE_CFG(GATE_DDRPHYCAPBLP, RCC_DDRITFCR, 10, 0), 6489be88e75SGabriel Fernandez GATE_CFG(GATE_TIM2, RCC_MP_APB1ENSETR, 0, 1), 6499be88e75SGabriel Fernandez GATE_CFG(GATE_TIM3, RCC_MP_APB1ENSETR, 1, 1), 6509be88e75SGabriel Fernandez GATE_CFG(GATE_TIM4, RCC_MP_APB1ENSETR, 2, 1), 6519be88e75SGabriel Fernandez GATE_CFG(GATE_TIM5, RCC_MP_APB1ENSETR, 3, 1), 6529be88e75SGabriel Fernandez GATE_CFG(GATE_TIM6, RCC_MP_APB1ENSETR, 4, 1), 6539be88e75SGabriel Fernandez GATE_CFG(GATE_TIM7, RCC_MP_APB1ENSETR, 5, 1), 6549be88e75SGabriel Fernandez GATE_CFG(GATE_LPTIM1, RCC_MP_APB1ENSETR, 9, 1), 6559be88e75SGabriel Fernandez GATE_CFG(GATE_SPI2, RCC_MP_APB1ENSETR, 11, 1), 6569be88e75SGabriel Fernandez GATE_CFG(GATE_SPI3, RCC_MP_APB1ENSETR, 12, 1), 6579be88e75SGabriel Fernandez GATE_CFG(GATE_USART3, RCC_MP_APB1ENSETR, 15, 1), 6589be88e75SGabriel Fernandez GATE_CFG(GATE_UART4, RCC_MP_APB1ENSETR, 16, 1), 6599be88e75SGabriel Fernandez GATE_CFG(GATE_UART5, RCC_MP_APB1ENSETR, 17, 1), 6609be88e75SGabriel Fernandez GATE_CFG(GATE_UART7, RCC_MP_APB1ENSETR, 18, 1), 6619be88e75SGabriel Fernandez GATE_CFG(GATE_UART8, RCC_MP_APB1ENSETR, 19, 1), 6629be88e75SGabriel Fernandez GATE_CFG(GATE_I2C1, RCC_MP_APB1ENSETR, 21, 1), 6639be88e75SGabriel Fernandez GATE_CFG(GATE_I2C2, RCC_MP_APB1ENSETR, 22, 1), 6649be88e75SGabriel Fernandez GATE_CFG(GATE_SPDIF, RCC_MP_APB1ENSETR, 26, 1), 6659be88e75SGabriel Fernandez GATE_CFG(GATE_TIM1, RCC_MP_APB2ENSETR, 0, 1), 6669be88e75SGabriel Fernandez GATE_CFG(GATE_TIM8, RCC_MP_APB2ENSETR, 1, 1), 6679be88e75SGabriel Fernandez GATE_CFG(GATE_SPI1, RCC_MP_APB2ENSETR, 8, 1), 6689be88e75SGabriel Fernandez GATE_CFG(GATE_USART6, RCC_MP_APB2ENSETR, 13, 1), 6699be88e75SGabriel Fernandez GATE_CFG(GATE_SAI1, RCC_MP_APB2ENSETR, 16, 1), 6709be88e75SGabriel Fernandez GATE_CFG(GATE_SAI2, RCC_MP_APB2ENSETR, 17, 1), 6719be88e75SGabriel Fernandez GATE_CFG(GATE_DFSDM, RCC_MP_APB2ENSETR, 20, 1), 6729be88e75SGabriel Fernandez GATE_CFG(GATE_ADFSDM, RCC_MP_APB2ENSETR, 21, 1), 6739be88e75SGabriel Fernandez GATE_CFG(GATE_FDCAN, RCC_MP_APB2ENSETR, 24, 1), 6749be88e75SGabriel Fernandez GATE_CFG(GATE_LPTIM2, RCC_MP_APB3ENSETR, 0, 1), 6759be88e75SGabriel Fernandez GATE_CFG(GATE_LPTIM3, RCC_MP_APB3ENSETR, 1, 1), 6769be88e75SGabriel Fernandez GATE_CFG(GATE_LPTIM4, RCC_MP_APB3ENSETR, 2, 1), 6779be88e75SGabriel Fernandez GATE_CFG(GATE_LPTIM5, RCC_MP_APB3ENSETR, 3, 1), 6789be88e75SGabriel Fernandez GATE_CFG(GATE_VREF, RCC_MP_APB3ENSETR, 13, 1), 6799be88e75SGabriel Fernandez GATE_CFG(GATE_DTS, RCC_MP_APB3ENSETR, 16, 1), 6809be88e75SGabriel Fernandez GATE_CFG(GATE_PMBCTRL, RCC_MP_APB3ENSETR, 17, 1), 6819be88e75SGabriel Fernandez GATE_CFG(GATE_HDP, RCC_MP_APB3ENSETR, 20, 1), 6829be88e75SGabriel Fernandez GATE_CFG(GATE_SYSCFG, RCC_MP_S_APB3ENSETR, 0, 1), 6839be88e75SGabriel Fernandez GATE_CFG(GATE_DCMIPP, RCC_MP_APB4ENSETR, 1, 1), 6849be88e75SGabriel Fernandez GATE_CFG(GATE_DDRPERFM, RCC_MP_APB4ENSETR, 8, 1), 6859be88e75SGabriel Fernandez GATE_CFG(GATE_IWDG2APB, RCC_MP_APB4ENSETR, 15, 1), 6869be88e75SGabriel Fernandez GATE_CFG(GATE_USBPHY, RCC_MP_APB4ENSETR, 16, 1), 6879be88e75SGabriel Fernandez GATE_CFG(GATE_STGENRO, RCC_MP_APB4ENSETR, 20, 1), 6889be88e75SGabriel Fernandez GATE_CFG(GATE_LTDC, RCC_MP_S_APB4ENSETR, 0, 1), 6899be88e75SGabriel Fernandez GATE_CFG(GATE_RTCAPB, RCC_MP_APB5ENSETR, 8, 1), 6909be88e75SGabriel Fernandez GATE_CFG(GATE_TZC, RCC_MP_APB5ENSETR, 11, 1), 6919be88e75SGabriel Fernandez GATE_CFG(GATE_ETZPC, RCC_MP_APB5ENSETR, 13, 1), 6929be88e75SGabriel Fernandez GATE_CFG(GATE_IWDG1APB, RCC_MP_APB5ENSETR, 15, 1), 6939be88e75SGabriel Fernandez GATE_CFG(GATE_BSEC, RCC_MP_APB5ENSETR, 16, 1), 6949be88e75SGabriel Fernandez GATE_CFG(GATE_STGENC, RCC_MP_APB5ENSETR, 20, 1), 6959be88e75SGabriel Fernandez GATE_CFG(GATE_USART1, RCC_MP_APB6ENSETR, 0, 1), 6969be88e75SGabriel Fernandez GATE_CFG(GATE_USART2, RCC_MP_APB6ENSETR, 1, 1), 6979be88e75SGabriel Fernandez GATE_CFG(GATE_SPI4, RCC_MP_APB6ENSETR, 2, 1), 6989be88e75SGabriel Fernandez GATE_CFG(GATE_SPI5, RCC_MP_APB6ENSETR, 3, 1), 6999be88e75SGabriel Fernandez GATE_CFG(GATE_I2C3, RCC_MP_APB6ENSETR, 4, 1), 7009be88e75SGabriel Fernandez GATE_CFG(GATE_I2C4, RCC_MP_APB6ENSETR, 5, 1), 7019be88e75SGabriel Fernandez GATE_CFG(GATE_I2C5, RCC_MP_APB6ENSETR, 6, 1), 7029be88e75SGabriel Fernandez GATE_CFG(GATE_TIM12, RCC_MP_APB6ENSETR, 7, 1), 7039be88e75SGabriel Fernandez GATE_CFG(GATE_TIM13, RCC_MP_APB6ENSETR, 8, 1), 7049be88e75SGabriel Fernandez GATE_CFG(GATE_TIM14, RCC_MP_APB6ENSETR, 9, 1), 7059be88e75SGabriel Fernandez GATE_CFG(GATE_TIM15, RCC_MP_APB6ENSETR, 10, 1), 7069be88e75SGabriel Fernandez GATE_CFG(GATE_TIM16, RCC_MP_APB6ENSETR, 11, 1), 7079be88e75SGabriel Fernandez GATE_CFG(GATE_TIM17, RCC_MP_APB6ENSETR, 12, 1), 7089be88e75SGabriel Fernandez GATE_CFG(GATE_DMA1, RCC_MP_AHB2ENSETR, 0, 1), 7099be88e75SGabriel Fernandez GATE_CFG(GATE_DMA2, RCC_MP_AHB2ENSETR, 1, 1), 7109be88e75SGabriel Fernandez GATE_CFG(GATE_DMAMUX1, RCC_MP_AHB2ENSETR, 2, 1), 7119be88e75SGabriel Fernandez GATE_CFG(GATE_DMA3, RCC_MP_AHB2ENSETR, 3, 1), 7129be88e75SGabriel Fernandez GATE_CFG(GATE_DMAMUX2, RCC_MP_AHB2ENSETR, 4, 1), 7139be88e75SGabriel Fernandez GATE_CFG(GATE_ADC1, RCC_MP_AHB2ENSETR, 5, 1), 7149be88e75SGabriel Fernandez GATE_CFG(GATE_ADC2, RCC_MP_AHB2ENSETR, 6, 1), 7159be88e75SGabriel Fernandez GATE_CFG(GATE_USBO, RCC_MP_AHB2ENSETR, 8, 1), 7169be88e75SGabriel Fernandez GATE_CFG(GATE_TSC, RCC_MP_AHB4ENSETR, 15, 1), 7179be88e75SGabriel Fernandez 7189be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOA, RCC_MP_S_AHB4ENSETR, 0, 1), 7199be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOB, RCC_MP_S_AHB4ENSETR, 1, 1), 7209be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOC, RCC_MP_S_AHB4ENSETR, 2, 1), 7219be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOD, RCC_MP_S_AHB4ENSETR, 3, 1), 7229be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOE, RCC_MP_S_AHB4ENSETR, 4, 1), 7239be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOF, RCC_MP_S_AHB4ENSETR, 5, 1), 7249be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOG, RCC_MP_S_AHB4ENSETR, 6, 1), 7259be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOH, RCC_MP_S_AHB4ENSETR, 7, 1), 7269be88e75SGabriel Fernandez GATE_CFG(GATE_GPIOI, RCC_MP_S_AHB4ENSETR, 8, 1), 7279be88e75SGabriel Fernandez 7289be88e75SGabriel Fernandez GATE_CFG(GATE_PKA, RCC_MP_AHB5ENSETR, 2, 1), 7299be88e75SGabriel Fernandez GATE_CFG(GATE_SAES, RCC_MP_AHB5ENSETR, 3, 1), 7309be88e75SGabriel Fernandez GATE_CFG(GATE_CRYP1, RCC_MP_AHB5ENSETR, 4, 1), 7319be88e75SGabriel Fernandez GATE_CFG(GATE_HASH1, RCC_MP_AHB5ENSETR, 5, 1), 7329be88e75SGabriel Fernandez GATE_CFG(GATE_RNG1, RCC_MP_AHB5ENSETR, 6, 1), 7339be88e75SGabriel Fernandez GATE_CFG(GATE_BKPSRAM, RCC_MP_AHB5ENSETR, 8, 1), 7349be88e75SGabriel Fernandez GATE_CFG(GATE_AXIMC, RCC_MP_AHB5ENSETR, 16, 1), 7359be88e75SGabriel Fernandez GATE_CFG(GATE_MCE, RCC_MP_AHB6ENSETR, 1, 1), 7369be88e75SGabriel Fernandez GATE_CFG(GATE_ETH1CK, RCC_MP_AHB6ENSETR, 7, 1), 7379be88e75SGabriel Fernandez GATE_CFG(GATE_ETH1TX, RCC_MP_AHB6ENSETR, 8, 1), 7389be88e75SGabriel Fernandez GATE_CFG(GATE_ETH1RX, RCC_MP_AHB6ENSETR, 9, 1), 7399be88e75SGabriel Fernandez GATE_CFG(GATE_ETH1MAC, RCC_MP_AHB6ENSETR, 10, 1), 7409be88e75SGabriel Fernandez GATE_CFG(GATE_FMC, RCC_MP_AHB6ENSETR, 12, 1), 7419be88e75SGabriel Fernandez GATE_CFG(GATE_QSPI, RCC_MP_AHB6ENSETR, 14, 1), 7429be88e75SGabriel Fernandez GATE_CFG(GATE_SDMMC1, RCC_MP_AHB6ENSETR, 16, 1), 7439be88e75SGabriel Fernandez GATE_CFG(GATE_SDMMC2, RCC_MP_AHB6ENSETR, 17, 1), 7449be88e75SGabriel Fernandez GATE_CFG(GATE_CRC1, RCC_MP_AHB6ENSETR, 20, 1), 7459be88e75SGabriel Fernandez GATE_CFG(GATE_USBH, RCC_MP_AHB6ENSETR, 24, 1), 7469be88e75SGabriel Fernandez GATE_CFG(GATE_ETH2CK, RCC_MP_AHB6ENSETR, 27, 1), 7479be88e75SGabriel Fernandez GATE_CFG(GATE_ETH2TX, RCC_MP_AHB6ENSETR, 28, 1), 7489be88e75SGabriel Fernandez GATE_CFG(GATE_ETH2RX, RCC_MP_AHB6ENSETR, 29, 1), 7499be88e75SGabriel Fernandez GATE_CFG(GATE_ETH2MAC, RCC_MP_AHB6ENSETR, 30, 1), 7509be88e75SGabriel Fernandez GATE_CFG(GATE_MDMA, RCC_MP_S_AHB6ENSETR, 0, 1), 7519be88e75SGabriel Fernandez }; 7529be88e75SGabriel Fernandez 7539be88e75SGabriel Fernandez /* 7549be88e75SGabriel Fernandez * DIV CONFIG 7559be88e75SGabriel Fernandez */ 7569be88e75SGabriel Fernandez 7579be88e75SGabriel Fernandez static const struct clk_div_table axi_div_table[] = { 7589be88e75SGabriel Fernandez { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, 7599be88e75SGabriel Fernandez { 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 }, 7609be88e75SGabriel Fernandez { 0 }, 7619be88e75SGabriel Fernandez }; 7629be88e75SGabriel Fernandez 7639be88e75SGabriel Fernandez static const struct clk_div_table mlahb_div_table[] = { 7649be88e75SGabriel Fernandez { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, 7659be88e75SGabriel Fernandez { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 }, 7669be88e75SGabriel Fernandez { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 }, 7679be88e75SGabriel Fernandez { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 }, 7689be88e75SGabriel Fernandez { 0 }, 7699be88e75SGabriel Fernandez }; 7709be88e75SGabriel Fernandez 7719be88e75SGabriel Fernandez static const struct clk_div_table apb_div_table[] = { 7729be88e75SGabriel Fernandez { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, 7739be88e75SGabriel Fernandez { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 }, 7749be88e75SGabriel Fernandez { 0 }, 7759be88e75SGabriel Fernandez }; 7769be88e75SGabriel Fernandez 7779be88e75SGabriel Fernandez #define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\ 7789be88e75SGabriel Fernandez .offset = _offset,\ 7799be88e75SGabriel Fernandez .shift = _shift,\ 7809be88e75SGabriel Fernandez .width = _width,\ 7819be88e75SGabriel Fernandez .flags = _flags,\ 7829be88e75SGabriel Fernandez .table = _table,\ 7839be88e75SGabriel Fernandez .bitrdy = _bitrdy,\ 7849be88e75SGabriel Fernandez } 7859be88e75SGabriel Fernandez 786ee21709eSYann Gautier static const struct div_cfg dividers_mp13[DIV_MAX] = { 7879be88e75SGabriel Fernandez DIV_CFG(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY), 7889be88e75SGabriel Fernandez DIV_CFG(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY), 7899be88e75SGabriel Fernandez DIV_CFG(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY), 7909be88e75SGabriel Fernandez DIV_CFG(DIV_PLL2DIVR, RCC_PLL2CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY), 7919be88e75SGabriel Fernandez DIV_CFG(DIV_PLL3DIVP, RCC_PLL3CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY), 7929be88e75SGabriel Fernandez DIV_CFG(DIV_PLL3DIVQ, RCC_PLL3CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY), 7939be88e75SGabriel Fernandez DIV_CFG(DIV_PLL3DIVR, RCC_PLL3CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY), 7949be88e75SGabriel Fernandez DIV_CFG(DIV_PLL4DIVP, RCC_PLL4CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY), 7959be88e75SGabriel Fernandez DIV_CFG(DIV_PLL4DIVQ, RCC_PLL4CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY), 7969be88e75SGabriel Fernandez DIV_CFG(DIV_PLL4DIVR, RCC_PLL4CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY), 7979be88e75SGabriel Fernandez DIV_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 0, NULL, DIV_NO_BIT_RDY), 7989be88e75SGabriel Fernandez DIV_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 0, axi_div_table, 31), 7999be88e75SGabriel Fernandez DIV_CFG(DIV_MLAHB, RCC_MLAHBDIVR, 0, 4, 0, mlahb_div_table, 31), 8009be88e75SGabriel Fernandez DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31), 8019be88e75SGabriel Fernandez DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31), 8029be88e75SGabriel Fernandez DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31), 8039be88e75SGabriel Fernandez DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31), 8049be88e75SGabriel Fernandez DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, 31), 8059be88e75SGabriel Fernandez DIV_CFG(DIV_APB6, RCC_APB6DIVR, 0, 3, 0, apb_div_table, 31), 8069be88e75SGabriel Fernandez DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, DIV_NO_BIT_RDY), 8079be88e75SGabriel Fernandez DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL, DIV_NO_BIT_RDY), 8089be88e75SGabriel Fernandez DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL, DIV_NO_BIT_RDY), 8099be88e75SGabriel Fernandez 8109be88e75SGabriel Fernandez DIV_CFG(DIV_HSI, RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_BIT_RDY), 8119be88e75SGabriel Fernandez DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_BIT_RDY), 8129be88e75SGabriel Fernandez 8139be88e75SGabriel Fernandez DIV_CFG(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL, DIV_NO_BIT_RDY), 8149be88e75SGabriel Fernandez DIV_CFG(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL, DIV_NO_BIT_RDY), 8159be88e75SGabriel Fernandez }; 8169be88e75SGabriel Fernandez 8179be88e75SGabriel Fernandez #define MAX_HSI_HZ 64000000 8189be88e75SGabriel Fernandez #define USB_PHY_48_MHZ 48000000 8199be88e75SGabriel Fernandez 8209be88e75SGabriel Fernandez #define TIMEOUT_US_200MS U(200000) 8219be88e75SGabriel Fernandez #define TIMEOUT_US_1S U(1000000) 8229be88e75SGabriel Fernandez 8239be88e75SGabriel Fernandez #define PLLRDY_TIMEOUT TIMEOUT_US_200MS 8249be88e75SGabriel Fernandez #define CLKSRC_TIMEOUT TIMEOUT_US_200MS 8259be88e75SGabriel Fernandez #define CLKDIV_TIMEOUT TIMEOUT_US_200MS 8269be88e75SGabriel Fernandez #define HSIDIV_TIMEOUT TIMEOUT_US_200MS 8279be88e75SGabriel Fernandez #define OSCRDY_TIMEOUT TIMEOUT_US_1S 8289be88e75SGabriel Fernandez 8299be88e75SGabriel Fernandez enum stm32_osc { 8309be88e75SGabriel Fernandez OSC_HSI, 8319be88e75SGabriel Fernandez OSC_HSE, 8329be88e75SGabriel Fernandez OSC_CSI, 8339be88e75SGabriel Fernandez OSC_LSI, 8349be88e75SGabriel Fernandez OSC_LSE, 8359be88e75SGabriel Fernandez OSC_I2SCKIN, 8369be88e75SGabriel Fernandez NB_OSCILLATOR 8379be88e75SGabriel Fernandez }; 8389be88e75SGabriel Fernandez 8399be88e75SGabriel Fernandez enum stm32mp1_pll_id { 8409be88e75SGabriel Fernandez _PLL1, 8419be88e75SGabriel Fernandez _PLL2, 8429be88e75SGabriel Fernandez _PLL3, 8439be88e75SGabriel Fernandez _PLL4, 8449be88e75SGabriel Fernandez _PLL_NB 8459be88e75SGabriel Fernandez }; 8469be88e75SGabriel Fernandez 8479be88e75SGabriel Fernandez enum stm32mp1_plltype { 8489be88e75SGabriel Fernandez PLL_800, 8499be88e75SGabriel Fernandez PLL_1600, 8509be88e75SGabriel Fernandez PLL_2000, 8519be88e75SGabriel Fernandez PLL_TYPE_NB 8529be88e75SGabriel Fernandez }; 8539be88e75SGabriel Fernandez 8549be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXCR 0 8559be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXCFGR1 4 8569be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXCFGR2 8 8579be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXFRACR 12 8589be88e75SGabriel Fernandez #define RCC_OFFSET_PLLXCSGR 16 8599be88e75SGabriel Fernandez 8609be88e75SGabriel Fernandez struct stm32_clk_pll { 8619be88e75SGabriel Fernandez enum stm32mp1_plltype plltype; 8629be88e75SGabriel Fernandez uint16_t clk_id; 8639be88e75SGabriel Fernandez uint16_t reg_pllxcr; 8649be88e75SGabriel Fernandez }; 8659be88e75SGabriel Fernandez 8669be88e75SGabriel Fernandez struct stm32mp1_pll { 8679be88e75SGabriel Fernandez uint8_t refclk_min; 8689be88e75SGabriel Fernandez uint8_t refclk_max; 8699be88e75SGabriel Fernandez }; 8709be88e75SGabriel Fernandez 8719be88e75SGabriel Fernandez /* Define characteristic of PLL according type */ 8729be88e75SGabriel Fernandez static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = { 8739be88e75SGabriel Fernandez [PLL_800] = { 8749be88e75SGabriel Fernandez .refclk_min = 4, 8759be88e75SGabriel Fernandez .refclk_max = 16, 8769be88e75SGabriel Fernandez }, 8779be88e75SGabriel Fernandez [PLL_1600] = { 8789be88e75SGabriel Fernandez .refclk_min = 8, 8799be88e75SGabriel Fernandez .refclk_max = 16, 8809be88e75SGabriel Fernandez }, 8819be88e75SGabriel Fernandez [PLL_2000] = { 8829be88e75SGabriel Fernandez .refclk_min = 8, 8839be88e75SGabriel Fernandez .refclk_max = 16, 8849be88e75SGabriel Fernandez }, 8859be88e75SGabriel Fernandez }; 8869be88e75SGabriel Fernandez 8879be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER 8889be88e75SGabriel Fernandez static bool pll4_bootrom; 8899be88e75SGabriel Fernandez #endif 8909be88e75SGabriel Fernandez 8919be88e75SGabriel Fernandez /* RCC clock device driver private */ 8929be88e75SGabriel Fernandez static unsigned int refcounts_mp13[CK_LAST]; 8939be88e75SGabriel Fernandez 8949be88e75SGabriel Fernandez static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx); 8959be88e75SGabriel Fernandez 8969be88e75SGabriel Fernandez #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 8979be88e75SGabriel Fernandez static void clk_oscillator_check_bypass(struct stm32_clk_priv *priv, int idx, 8989be88e75SGabriel Fernandez bool digbyp, bool bypass) 8999be88e75SGabriel Fernandez { 9009be88e75SGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, idx); 9019be88e75SGabriel Fernandez struct stm32_clk_bypass *bypass_data = osc_data->bypass; 9029be88e75SGabriel Fernandez uintptr_t address; 9039be88e75SGabriel Fernandez 9049be88e75SGabriel Fernandez if (bypass_data == NULL) { 9059be88e75SGabriel Fernandez return; 9069be88e75SGabriel Fernandez } 9079be88e75SGabriel Fernandez 9089be88e75SGabriel Fernandez address = priv->base + bypass_data->offset; 9099be88e75SGabriel Fernandez if ((mmio_read_32(address) & RCC_OCENR_HSEBYP) && 9109be88e75SGabriel Fernandez (!(digbyp || bypass))) { 9119be88e75SGabriel Fernandez panic(); 9129be88e75SGabriel Fernandez } 9139be88e75SGabriel Fernandez } 9149be88e75SGabriel Fernandez #endif 9159be88e75SGabriel Fernandez 9169be88e75SGabriel Fernandez static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv) 9179be88e75SGabriel Fernandez { 9189be88e75SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 9199be88e75SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE]; 9209be88e75SGabriel Fernandez bool digbyp = osci->digbyp; 9219be88e75SGabriel Fernandez bool bypass = osci->bypass; 9229be88e75SGabriel Fernandez bool css = osci->css; 9239be88e75SGabriel Fernandez 9249be88e75SGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) { 9259be88e75SGabriel Fernandez return; 9269be88e75SGabriel Fernandez } 9279be88e75SGabriel Fernandez 9289be88e75SGabriel Fernandez clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass); 9299be88e75SGabriel Fernandez 9309be88e75SGabriel Fernandez _clk_stm32_enable(priv, _CK_HSE); 9319be88e75SGabriel Fernandez 9329be88e75SGabriel Fernandez #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 9339be88e75SGabriel Fernandez clk_oscillator_check_bypass(priv, _CK_HSE, digbyp, bypass); 9349be88e75SGabriel Fernandez #endif 9359be88e75SGabriel Fernandez 9369be88e75SGabriel Fernandez clk_oscillator_set_css(priv, _CK_HSE, css); 9379be88e75SGabriel Fernandez } 9389be88e75SGabriel Fernandez 9399be88e75SGabriel Fernandez static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv) 9409be88e75SGabriel Fernandez { 9419be88e75SGabriel Fernandez struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE); 9429be88e75SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 9439be88e75SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE]; 9449be88e75SGabriel Fernandez bool digbyp = osci->digbyp; 9459be88e75SGabriel Fernandez bool bypass = osci->bypass; 9469be88e75SGabriel Fernandez uint8_t drive = osci->drive; 9479be88e75SGabriel Fernandez 9489be88e75SGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) { 9499be88e75SGabriel Fernandez return; 9509be88e75SGabriel Fernandez } 9519be88e75SGabriel Fernandez 952f4a2bb98SYann Gautier /* Do not reconfigure LSE if already enabled */ 953f4a2bb98SYann Gautier if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) { 954f4a2bb98SYann Gautier return; 955f4a2bb98SYann Gautier } 956f4a2bb98SYann Gautier 9579be88e75SGabriel Fernandez clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass); 9589be88e75SGabriel Fernandez 9599be88e75SGabriel Fernandez clk_oscillator_set_drive(priv, _CK_LSE, drive); 9609be88e75SGabriel Fernandez 9619be88e75SGabriel Fernandez _clk_stm32_gate_enable(priv, osc_data->gate_id); 9629be88e75SGabriel Fernandez } 9639be88e75SGabriel Fernandez 9649be88e75SGabriel Fernandez static int stm32mp1_set_hsidiv(uint8_t hsidiv) 9659be88e75SGabriel Fernandez { 9669be88e75SGabriel Fernandez uint64_t timeout; 9679be88e75SGabriel Fernandez uintptr_t rcc_base = stm32mp_rcc_base(); 9689be88e75SGabriel Fernandez uintptr_t address = rcc_base + RCC_OCRDYR; 9699be88e75SGabriel Fernandez 9709be88e75SGabriel Fernandez mmio_clrsetbits_32(rcc_base + RCC_HSICFGR, 9719be88e75SGabriel Fernandez RCC_HSICFGR_HSIDIV_MASK, 9729be88e75SGabriel Fernandez RCC_HSICFGR_HSIDIV_MASK & (uint32_t)hsidiv); 9739be88e75SGabriel Fernandez 9749be88e75SGabriel Fernandez timeout = timeout_init_us(HSIDIV_TIMEOUT); 9759be88e75SGabriel Fernandez while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) { 9769be88e75SGabriel Fernandez if (timeout_elapsed(timeout)) { 9779be88e75SGabriel Fernandez ERROR("HSIDIV failed @ 0x%lx: 0x%x\n", 9789be88e75SGabriel Fernandez address, mmio_read_32(address)); 9799be88e75SGabriel Fernandez return -ETIMEDOUT; 9809be88e75SGabriel Fernandez } 9819be88e75SGabriel Fernandez } 9829be88e75SGabriel Fernandez 9839be88e75SGabriel Fernandez return 0; 9849be88e75SGabriel Fernandez } 9859be88e75SGabriel Fernandez 9869be88e75SGabriel Fernandez static int stm32mp1_hsidiv(unsigned long hsifreq) 9879be88e75SGabriel Fernandez { 9889be88e75SGabriel Fernandez uint8_t hsidiv; 9899be88e75SGabriel Fernandez uint32_t hsidivfreq = MAX_HSI_HZ; 9909be88e75SGabriel Fernandez 9919be88e75SGabriel Fernandez for (hsidiv = 0; hsidiv < 4U; hsidiv++) { 9929be88e75SGabriel Fernandez if (hsidivfreq == hsifreq) { 9939be88e75SGabriel Fernandez break; 9949be88e75SGabriel Fernandez } 9959be88e75SGabriel Fernandez 9969be88e75SGabriel Fernandez hsidivfreq /= 2U; 9979be88e75SGabriel Fernandez } 9989be88e75SGabriel Fernandez 9999be88e75SGabriel Fernandez if (hsidiv == 4U) { 10009be88e75SGabriel Fernandez ERROR("Invalid clk-hsi frequency\n"); 10019be88e75SGabriel Fernandez return -EINVAL; 10029be88e75SGabriel Fernandez } 10039be88e75SGabriel Fernandez 10049be88e75SGabriel Fernandez if (hsidiv != 0U) { 10059be88e75SGabriel Fernandez return stm32mp1_set_hsidiv(hsidiv); 10069be88e75SGabriel Fernandez } 10079be88e75SGabriel Fernandez 10089be88e75SGabriel Fernandez return 0; 10099be88e75SGabriel Fernandez } 10109be88e75SGabriel Fernandez 10119be88e75SGabriel Fernandez static int stm32_clk_oscillators_lse_set_css(struct stm32_clk_priv *priv) 10129be88e75SGabriel Fernandez { 10139be88e75SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 10149be88e75SGabriel Fernandez struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE]; 10159be88e75SGabriel Fernandez 10169be88e75SGabriel Fernandez clk_oscillator_set_css(priv, _CK_LSE, osci->css); 10179be88e75SGabriel Fernandez 10189be88e75SGabriel Fernandez return 0; 10199be88e75SGabriel Fernandez } 10209be88e75SGabriel Fernandez 10219be88e75SGabriel Fernandez static int stm32mp1_come_back_to_hsi(void) 10229be88e75SGabriel Fernandez { 10239be88e75SGabriel Fernandez int ret; 10249be88e75SGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 10259be88e75SGabriel Fernandez 10269be88e75SGabriel Fernandez /* Come back to HSI */ 10279be88e75SGabriel Fernandez ret = _clk_stm32_set_parent(priv, _CKMPU, _CK_HSI); 10289be88e75SGabriel Fernandez if (ret != 0) { 10299be88e75SGabriel Fernandez return ret; 10309be88e75SGabriel Fernandez } 10319be88e75SGabriel Fernandez 10329be88e75SGabriel Fernandez ret = _clk_stm32_set_parent(priv, _CKAXI, _CK_HSI); 10339be88e75SGabriel Fernandez if (ret != 0) { 10349be88e75SGabriel Fernandez return ret; 10359be88e75SGabriel Fernandez } 10369be88e75SGabriel Fernandez 10379be88e75SGabriel Fernandez ret = _clk_stm32_set_parent(priv, _CKMLAHB, _CK_HSI); 10389be88e75SGabriel Fernandez if (ret != 0) { 10399be88e75SGabriel Fernandez return ret; 10409be88e75SGabriel Fernandez } 10419be88e75SGabriel Fernandez 10429be88e75SGabriel Fernandez return 0; 10439be88e75SGabriel Fernandez } 10449be88e75SGabriel Fernandez 10459be88e75SGabriel Fernandez static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data) 10469be88e75SGabriel Fernandez { 10479be88e75SGabriel Fernandez unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT; 10489be88e75SGabriel Fernandez 10499be88e75SGabriel Fernandez return clk_get_index(priv, binding_id); 10509be88e75SGabriel Fernandez } 10519be88e75SGabriel Fernandez 10529be88e75SGabriel Fernandez static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data) 10539be88e75SGabriel Fernandez { 10549be88e75SGabriel Fernandez int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT; 10559be88e75SGabriel Fernandez int enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT; 10569be88e75SGabriel Fernandez int clk_id; 10579be88e75SGabriel Fernandez int ret; 10589be88e75SGabriel Fernandez 10599be88e75SGabriel Fernandez clk_id = stm32_clk_configure_clk_get_binding_id(priv, data); 10609be88e75SGabriel Fernandez if (clk_id < 0) { 10619be88e75SGabriel Fernandez return clk_id; 10629be88e75SGabriel Fernandez } 10639be88e75SGabriel Fernandez 10649be88e75SGabriel Fernandez ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel); 10659be88e75SGabriel Fernandez if (ret != 0) { 10669be88e75SGabriel Fernandez return ret; 10679be88e75SGabriel Fernandez } 10689be88e75SGabriel Fernandez 1069c3ae7da0SYann Gautier if (enable != 0) { 10709be88e75SGabriel Fernandez clk_stm32_enable_call_ops(priv, clk_id); 10719be88e75SGabriel Fernandez } else { 10729be88e75SGabriel Fernandez clk_stm32_disable_call_ops(priv, clk_id); 10739be88e75SGabriel Fernandez } 10749be88e75SGabriel Fernandez 10759be88e75SGabriel Fernandez return 0; 10769be88e75SGabriel Fernandez } 10779be88e75SGabriel Fernandez 10789be88e75SGabriel Fernandez static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data) 10799be88e75SGabriel Fernandez { 10809be88e75SGabriel Fernandez int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT; 10819be88e75SGabriel Fernandez int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT; 10829be88e75SGabriel Fernandez 10839be88e75SGabriel Fernandez return clk_mux_set_parent(priv, mux, sel); 10849be88e75SGabriel Fernandez } 10859be88e75SGabriel Fernandez 10869be88e75SGabriel Fernandez static int stm32_clk_dividers_configure(struct stm32_clk_priv *priv) 10879be88e75SGabriel Fernandez { 10889be88e75SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 10899be88e75SGabriel Fernandez uint32_t i; 10909be88e75SGabriel Fernandez 10919be88e75SGabriel Fernandez for (i = 0; i < pdata->nclkdiv; i++) { 10929be88e75SGabriel Fernandez int div_id, div_n; 10939be88e75SGabriel Fernandez int val; 10949be88e75SGabriel Fernandez int ret; 10959be88e75SGabriel Fernandez 10969be88e75SGabriel Fernandez val = pdata->clkdiv[i] & CMD_DATA_MASK; 10979be88e75SGabriel Fernandez div_id = (val & DIV_ID_MASK) >> DIV_ID_SHIFT; 10989be88e75SGabriel Fernandez div_n = (val & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT; 10999be88e75SGabriel Fernandez 11009be88e75SGabriel Fernandez ret = clk_stm32_set_div(priv, div_id, div_n); 11019be88e75SGabriel Fernandez if (ret != 0) { 11029be88e75SGabriel Fernandez return ret; 11039be88e75SGabriel Fernandez } 11049be88e75SGabriel Fernandez } 11059be88e75SGabriel Fernandez 11069be88e75SGabriel Fernandez return 0; 11079be88e75SGabriel Fernandez } 11089be88e75SGabriel Fernandez 11099be88e75SGabriel Fernandez static int stm32_clk_source_configure(struct stm32_clk_priv *priv) 11109be88e75SGabriel Fernandez { 11119be88e75SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 11129be88e75SGabriel Fernandez bool ckper_disabled = false; 11139be88e75SGabriel Fernandez int clk_id; 11149be88e75SGabriel Fernandez int ret; 11159be88e75SGabriel Fernandez uint32_t i; 11169be88e75SGabriel Fernandez 11179be88e75SGabriel Fernandez for (i = 0; i < pdata->nclksrc; i++) { 11189be88e75SGabriel Fernandez uint32_t val = pdata->clksrc[i]; 11199be88e75SGabriel Fernandez uint32_t cmd, cmd_data; 11209be88e75SGabriel Fernandez 11219be88e75SGabriel Fernandez if (val == (uint32_t)CLK_CKPER_DISABLED) { 11229be88e75SGabriel Fernandez ckper_disabled = true; 11239be88e75SGabriel Fernandez continue; 11249be88e75SGabriel Fernandez } 11259be88e75SGabriel Fernandez 11269be88e75SGabriel Fernandez if (val == (uint32_t)CLK_RTC_DISABLED) { 11279be88e75SGabriel Fernandez continue; 11289be88e75SGabriel Fernandez } 11299be88e75SGabriel Fernandez 11309be88e75SGabriel Fernandez cmd = (val & CMD_MASK) >> CMD_SHIFT; 11319be88e75SGabriel Fernandez cmd_data = val & ~CMD_MASK; 11329be88e75SGabriel Fernandez 11339be88e75SGabriel Fernandez switch (cmd) { 11349be88e75SGabriel Fernandez case CMD_MUX: 11359be88e75SGabriel Fernandez ret = stm32_clk_configure_mux(priv, cmd_data); 11369be88e75SGabriel Fernandez break; 11379be88e75SGabriel Fernandez 11389be88e75SGabriel Fernandez case CMD_CLK: 11399be88e75SGabriel Fernandez clk_id = stm32_clk_configure_clk_get_binding_id(priv, cmd_data); 11409be88e75SGabriel Fernandez 11419be88e75SGabriel Fernandez if (clk_id == _RTCCK) { 11429be88e75SGabriel Fernandez if ((_clk_stm32_is_enabled(priv, _RTCCK) == true)) { 11439be88e75SGabriel Fernandez continue; 11449be88e75SGabriel Fernandez } 11459be88e75SGabriel Fernandez } 11469be88e75SGabriel Fernandez 11479be88e75SGabriel Fernandez ret = stm32_clk_configure_clk(priv, cmd_data); 11489be88e75SGabriel Fernandez break; 11499be88e75SGabriel Fernandez default: 11509be88e75SGabriel Fernandez ret = -EINVAL; 11519be88e75SGabriel Fernandez break; 11529be88e75SGabriel Fernandez } 11539be88e75SGabriel Fernandez 11549be88e75SGabriel Fernandez if (ret != 0) { 11559be88e75SGabriel Fernandez return ret; 11569be88e75SGabriel Fernandez } 11579be88e75SGabriel Fernandez } 11589be88e75SGabriel Fernandez 11599be88e75SGabriel Fernandez /* 11609be88e75SGabriel Fernandez * CKPER is source for some peripheral clocks 11619be88e75SGabriel Fernandez * (FMC-NAND / QPSI-NOR) and switching source is allowed 11629be88e75SGabriel Fernandez * only if previous clock is still ON 11639be88e75SGabriel Fernandez * => deactivate CKPER only after switching clock 11649be88e75SGabriel Fernandez */ 11659be88e75SGabriel Fernandez if (ckper_disabled) { 11661bbcb58aSGabriel Fernandez ret = stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED); 11679be88e75SGabriel Fernandez if (ret != 0) { 11689be88e75SGabriel Fernandez return ret; 11699be88e75SGabriel Fernandez } 11709be88e75SGabriel Fernandez } 11719be88e75SGabriel Fernandez 11729be88e75SGabriel Fernandez return 0; 11739be88e75SGabriel Fernandez } 11749be88e75SGabriel Fernandez 11759be88e75SGabriel Fernandez static int stm32_clk_stgen_configure(struct stm32_clk_priv *priv, int id) 11769be88e75SGabriel Fernandez { 11779be88e75SGabriel Fernandez unsigned long stgen_freq; 11789be88e75SGabriel Fernandez 11799be88e75SGabriel Fernandez stgen_freq = _clk_stm32_get_rate(priv, id); 11809be88e75SGabriel Fernandez 11819be88e75SGabriel Fernandez stm32mp_stgen_config(stgen_freq); 11829be88e75SGabriel Fernandez 11839be88e75SGabriel Fernandez return 0; 11849be88e75SGabriel Fernandez } 11859be88e75SGabriel Fernandez 11869be88e75SGabriel Fernandez #define CLK_PLL_CFG(_idx, _clk_id, _type, _reg)\ 11879be88e75SGabriel Fernandez [(_idx)] = {\ 11889be88e75SGabriel Fernandez .clk_id = (_clk_id),\ 11899be88e75SGabriel Fernandez .plltype = (_type),\ 11909be88e75SGabriel Fernandez .reg_pllxcr = (_reg),\ 11919be88e75SGabriel Fernandez } 11929be88e75SGabriel Fernandez 11939be88e75SGabriel Fernandez static int clk_stm32_pll_compute_cfgr1(struct stm32_clk_priv *priv, 11949be88e75SGabriel Fernandez const struct stm32_clk_pll *pll, 11959be88e75SGabriel Fernandez struct stm32_pll_vco *vco, 11969be88e75SGabriel Fernandez uint32_t *value) 11979be88e75SGabriel Fernandez { 11989be88e75SGabriel Fernandez uint32_t divm = vco->div_mn[PLL_CFG_M]; 11999be88e75SGabriel Fernandez uint32_t divn = vco->div_mn[PLL_CFG_N]; 12009be88e75SGabriel Fernandez unsigned long prate = 0UL; 12019be88e75SGabriel Fernandez unsigned long refclk = 0UL; 12029be88e75SGabriel Fernandez 12039be88e75SGabriel Fernandez prate = _clk_stm32_get_parent_rate(priv, pll->clk_id); 12049be88e75SGabriel Fernandez refclk = prate / (divm + 1U); 12059be88e75SGabriel Fernandez 12069be88e75SGabriel Fernandez if ((refclk < (stm32mp1_pll[pll->plltype].refclk_min * 1000000U)) || 12079be88e75SGabriel Fernandez (refclk > (stm32mp1_pll[pll->plltype].refclk_max * 1000000U))) { 12089be88e75SGabriel Fernandez return -EINVAL; 12099be88e75SGabriel Fernandez } 12109be88e75SGabriel Fernandez 12119be88e75SGabriel Fernandez *value = 0; 12129be88e75SGabriel Fernandez 12139be88e75SGabriel Fernandez if ((pll->plltype == PLL_800) && (refclk >= 8000000U)) { 12149be88e75SGabriel Fernandez *value = 1U << RCC_PLLNCFGR1_IFRGE_SHIFT; 12159be88e75SGabriel Fernandez } 12169be88e75SGabriel Fernandez 12179be88e75SGabriel Fernandez *value |= (divn << RCC_PLLNCFGR1_DIVN_SHIFT) & RCC_PLLNCFGR1_DIVN_MASK; 12189be88e75SGabriel Fernandez *value |= (divm << RCC_PLLNCFGR1_DIVM_SHIFT) & RCC_PLLNCFGR1_DIVM_MASK; 12199be88e75SGabriel Fernandez 12209be88e75SGabriel Fernandez return 0; 12219be88e75SGabriel Fernandez } 12229be88e75SGabriel Fernandez 12239be88e75SGabriel Fernandez static uint32_t clk_stm32_pll_compute_cfgr2(struct stm32_pll_output *out) 12249be88e75SGabriel Fernandez { 12259be88e75SGabriel Fernandez uint32_t value = 0; 12269be88e75SGabriel Fernandez 12279be88e75SGabriel Fernandez value |= (out->output[PLL_CFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) & RCC_PLLNCFGR2_DIVP_MASK; 12289be88e75SGabriel Fernandez value |= (out->output[PLL_CFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) & RCC_PLLNCFGR2_DIVQ_MASK; 12299be88e75SGabriel Fernandez value |= (out->output[PLL_CFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) & RCC_PLLNCFGR2_DIVR_MASK; 12309be88e75SGabriel Fernandez 12319be88e75SGabriel Fernandez return value; 12329be88e75SGabriel Fernandez } 12339be88e75SGabriel Fernandez 12349be88e75SGabriel Fernandez static void clk_stm32_pll_config_vco(struct stm32_clk_priv *priv, 12359be88e75SGabriel Fernandez const struct stm32_clk_pll *pll, 12369be88e75SGabriel Fernandez struct stm32_pll_vco *vco) 12379be88e75SGabriel Fernandez { 12389be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 12399be88e75SGabriel Fernandez uint32_t value = 0; 12409be88e75SGabriel Fernandez 12419be88e75SGabriel Fernandez if (clk_stm32_pll_compute_cfgr1(priv, pll, vco, &value) != 0) { 12429be88e75SGabriel Fernandez ERROR("Invalid Vref clock !\n"); 12439be88e75SGabriel Fernandez panic(); 12449be88e75SGabriel Fernandez } 12459be88e75SGabriel Fernandez 12469be88e75SGabriel Fernandez /* Write N / M / IFREGE fields */ 12479be88e75SGabriel Fernandez mmio_write_32(pll_base + RCC_OFFSET_PLLXCFGR1, value); 12489be88e75SGabriel Fernandez 12499be88e75SGabriel Fernandez /* Fractional configuration */ 12509be88e75SGabriel Fernandez mmio_write_32(pll_base + RCC_OFFSET_PLLXFRACR, 0); 12519be88e75SGabriel Fernandez 12529be88e75SGabriel Fernandez /* Frac must be enabled only once its configuration is loaded */ 12539be88e75SGabriel Fernandez mmio_write_32(pll_base + RCC_OFFSET_PLLXFRACR, vco->frac << RCC_PLLNFRACR_FRACV_SHIFT); 12549be88e75SGabriel Fernandez mmio_setbits_32(pll_base + RCC_OFFSET_PLLXFRACR, RCC_PLLNFRACR_FRACLE); 12559be88e75SGabriel Fernandez } 12569be88e75SGabriel Fernandez 12579be88e75SGabriel Fernandez static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv, 12589be88e75SGabriel Fernandez const struct stm32_clk_pll *pll, 12599be88e75SGabriel Fernandez struct stm32_pll_vco *vco) 12609be88e75SGabriel Fernandez { 12619be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 12629be88e75SGabriel Fernandez uint32_t mod_per = 0; 12639be88e75SGabriel Fernandez uint32_t inc_step = 0; 12649be88e75SGabriel Fernandez uint32_t sscg_mode = 0; 12659be88e75SGabriel Fernandez uint32_t value = 0; 12669be88e75SGabriel Fernandez 12679be88e75SGabriel Fernandez if (!vco->csg_enabled) { 12689be88e75SGabriel Fernandez return; 12699be88e75SGabriel Fernandez } 12709be88e75SGabriel Fernandez 12719be88e75SGabriel Fernandez mod_per = vco->csg[PLL_CSG_MOD_PER]; 12729be88e75SGabriel Fernandez inc_step = vco->csg[PLL_CSG_INC_STEP]; 12739be88e75SGabriel Fernandez sscg_mode = vco->csg[PLL_CSG_SSCG_MODE]; 12749be88e75SGabriel Fernandez 12759be88e75SGabriel Fernandez value |= (mod_per << RCC_PLLNCSGR_MOD_PER_SHIFT) & RCC_PLLNCSGR_MOD_PER_MASK; 12769be88e75SGabriel Fernandez value |= (inc_step << RCC_PLLNCSGR_INC_STEP_SHIFT) & RCC_PLLNCSGR_INC_STEP_MASK; 12779be88e75SGabriel Fernandez value |= (sscg_mode << RCC_PLLNCSGR_SSCG_MODE_SHIFT) & RCC_PLLNCSGR_SSCG_MODE_MASK; 12789be88e75SGabriel Fernandez 12799be88e75SGabriel Fernandez mmio_write_32(pll_base + RCC_OFFSET_PLLXCSGR, value); 12809be88e75SGabriel Fernandez mmio_setbits_32(pll_base + RCC_OFFSET_PLLXCR, RCC_PLLNCR_SSCG_CTRL); 12819be88e75SGabriel Fernandez } 12829be88e75SGabriel Fernandez 12839be88e75SGabriel Fernandez static void clk_stm32_pll_config_out(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll, 12849be88e75SGabriel Fernandez struct stm32_pll_output *out) 12859be88e75SGabriel Fernandez { 12869be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 12879be88e75SGabriel Fernandez uint32_t value = 0; 12889be88e75SGabriel Fernandez 12899be88e75SGabriel Fernandez value = clk_stm32_pll_compute_cfgr2(out); 12909be88e75SGabriel Fernandez 12919be88e75SGabriel Fernandez mmio_write_32(pll_base + RCC_OFFSET_PLLXCFGR2, value); 12929be88e75SGabriel Fernandez } 12939be88e75SGabriel Fernandez 12949be88e75SGabriel Fernandez static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx) 12959be88e75SGabriel Fernandez { 12969be88e75SGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 12979be88e75SGabriel Fernandez struct stm32_clk_platdata *pdata = priv->pdata; 12989be88e75SGabriel Fernandez 12999be88e75SGabriel Fernandez return &pdata->pll[pll_idx]; 13009be88e75SGabriel Fernandez } 13019be88e75SGabriel Fernandez 1302f6559227SYann Gautier /* Define characteristic for PLL1 : PLL_2000 */ 1303f6559227SYann Gautier #define POST_DIVM_MIN 8000000U 1304f6559227SYann Gautier #define POST_DIVM_MAX 16000000U 1305f6559227SYann Gautier #define DIVM_MIN 0U 1306f6559227SYann Gautier #define DIVM_MAX 63U 1307f6559227SYann Gautier #define DIVN_MIN 24U 1308f6559227SYann Gautier #define DIVN_MAX 99U 1309f6559227SYann Gautier #define DIVP_MIN 0U 1310f6559227SYann Gautier #define DIVP_MAX 127U 1311f6559227SYann Gautier #define FRAC_MAX 8192U 1312f6559227SYann Gautier #define VCO_MIN 992000000U 1313f6559227SYann Gautier #define VCO_MAX 2000000000U 1314f6559227SYann Gautier 1315f6559227SYann Gautier static int clk_compute_pll1_settings(uint32_t freq_khz) 1316f6559227SYann Gautier { 1317f6559227SYann Gautier struct stm32_clk_priv *priv = clk_stm32_get_priv(); 1318f6559227SYann Gautier struct stm32_pll_dt_cfg *pll1 = clk_stm32_pll_get_pdata(_PLL1); 1319f6559227SYann Gautier struct stm32_pll_dt_cfg *pll2 = clk_stm32_pll_get_pdata(_PLL2); 1320f6559227SYann Gautier unsigned long long best_diff = ULLONG_MAX; 1321f6559227SYann Gautier unsigned int divm; 1322f6559227SYann Gautier unsigned long input_freq = 0UL; 1323f6559227SYann Gautier uint32_t src = pll2->vco.src; 1324f6559227SYann Gautier 1325f6559227SYann Gautier /* PLL1 share the same clock source than PLL2 */ 1326f6559227SYann Gautier switch (src) { 1327f6559227SYann Gautier case CLK_PLL12_HSI: 1328f6559227SYann Gautier input_freq = _clk_stm32_get_rate(priv, _CK_HSI); 1329f6559227SYann Gautier break; 1330f6559227SYann Gautier case CLK_PLL12_HSE: 1331f6559227SYann Gautier input_freq = _clk_stm32_get_rate(priv, _CK_HSE); 1332f6559227SYann Gautier break; 1333f6559227SYann Gautier default: 1334f6559227SYann Gautier break; 1335f6559227SYann Gautier } 1336f6559227SYann Gautier 1337f6559227SYann Gautier if (input_freq == 0UL) { 1338f6559227SYann Gautier panic(); 1339f6559227SYann Gautier } 1340f6559227SYann Gautier 1341f6559227SYann Gautier /* Following parameters have always the same value */ 1342f6559227SYann Gautier pll1->output.output[PLL_CFG_Q] = 0U; 1343f6559227SYann Gautier pll1->output.output[PLL_CFG_R] = 0U; 1344f6559227SYann Gautier 1345f6559227SYann Gautier for (divm = (DIVM_MAX + 1U); divm != DIVM_MIN; divm--) { 1346f6559227SYann Gautier unsigned long post_divm = input_freq / divm; 1347f6559227SYann Gautier unsigned int divp; 1348f6559227SYann Gautier 1349f6559227SYann Gautier if ((post_divm < POST_DIVM_MIN) || (post_divm > POST_DIVM_MAX)) { 1350f6559227SYann Gautier continue; 1351f6559227SYann Gautier } 1352f6559227SYann Gautier 1353f6559227SYann Gautier for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) { 1354f6559227SYann Gautier unsigned long long output_freq = freq_khz * 1000ULL; 1355f6559227SYann Gautier unsigned long long freq; 1356f6559227SYann Gautier unsigned long long divn; 1357f6559227SYann Gautier unsigned long long frac; 1358f6559227SYann Gautier unsigned int i; 1359f6559227SYann Gautier 1360f6559227SYann Gautier freq = output_freq * divm * (divp + 1U); 1361f6559227SYann Gautier 1362f6559227SYann Gautier divn = (freq / input_freq) - 1U; 1363f6559227SYann Gautier if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) { 1364f6559227SYann Gautier continue; 1365f6559227SYann Gautier } 1366f6559227SYann Gautier 1367f6559227SYann Gautier frac = ((freq * FRAC_MAX) / input_freq) - ((divn + 1U) * FRAC_MAX); 1368f6559227SYann Gautier 1369f6559227SYann Gautier /* 2 loops to refine the fractional part */ 1370f6559227SYann Gautier for (i = 2U; i != 0U; i--) { 1371f6559227SYann Gautier unsigned long long diff; 1372f6559227SYann Gautier unsigned long long vco; 1373f6559227SYann Gautier 1374f6559227SYann Gautier if (frac > FRAC_MAX) { 1375f6559227SYann Gautier break; 1376f6559227SYann Gautier } 1377f6559227SYann Gautier 1378f6559227SYann Gautier vco = (post_divm * (divn + 1U)) + ((post_divm * frac) / FRAC_MAX); 1379f6559227SYann Gautier 1380f6559227SYann Gautier if ((vco < (VCO_MIN / 2U)) || (vco > (VCO_MAX / 2U))) { 1381f6559227SYann Gautier frac++; 1382f6559227SYann Gautier continue; 1383f6559227SYann Gautier } 1384f6559227SYann Gautier 1385f6559227SYann Gautier freq = vco / (divp + 1U); 1386f6559227SYann Gautier if (output_freq < freq) { 1387f6559227SYann Gautier diff = freq - output_freq; 1388f6559227SYann Gautier } else { 1389f6559227SYann Gautier diff = output_freq - freq; 1390f6559227SYann Gautier } 1391f6559227SYann Gautier 1392f6559227SYann Gautier if (diff < best_diff) { 1393f6559227SYann Gautier pll1->vco.src = src; 1394f6559227SYann Gautier pll1->vco.status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_PLLON; 1395f6559227SYann Gautier pll1->vco.div_mn[PLL_CFG_M] = divm - 1U; 1396f6559227SYann Gautier pll1->vco.div_mn[PLL_CFG_N] = (uint32_t)divn; 1397f6559227SYann Gautier pll1->vco.frac = (uint32_t)frac; 1398f6559227SYann Gautier pll1->output.output[PLL_CFG_P] = divp; 1399f6559227SYann Gautier 1400f6559227SYann Gautier if (diff == 0U) { 1401f6559227SYann Gautier return 0; 1402f6559227SYann Gautier } 1403f6559227SYann Gautier 1404f6559227SYann Gautier best_diff = diff; 1405f6559227SYann Gautier } 1406f6559227SYann Gautier 1407f6559227SYann Gautier frac++; 1408f6559227SYann Gautier } 1409f6559227SYann Gautier } 1410f6559227SYann Gautier } 1411f6559227SYann Gautier 1412f6559227SYann Gautier if (best_diff == ULLONG_MAX) { 1413f6559227SYann Gautier return -EINVAL; 1414f6559227SYann Gautier } 1415f6559227SYann Gautier 1416f6559227SYann Gautier return 0; 1417f6559227SYann Gautier } 1418f6559227SYann Gautier 14199be88e75SGabriel Fernandez static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 14209be88e75SGabriel Fernandez { 14219be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 14229be88e75SGabriel Fernandez 14239be88e75SGabriel Fernandez return ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLON) != 0U); 14249be88e75SGabriel Fernandez } 14259be88e75SGabriel Fernandez 14269be88e75SGabriel Fernandez static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 14279be88e75SGabriel Fernandez { 14289be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 14299be88e75SGabriel Fernandez 14309be88e75SGabriel Fernandez /* Preserve RCC_PLLNCR_SSCG_CTRL value */ 14319be88e75SGabriel Fernandez mmio_clrsetbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN, 14329be88e75SGabriel Fernandez RCC_PLLNCR_PLLON); 14339be88e75SGabriel Fernandez } 14349be88e75SGabriel Fernandez 14359be88e75SGabriel Fernandez static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 14369be88e75SGabriel Fernandez { 14379be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 14389be88e75SGabriel Fernandez 14399be88e75SGabriel Fernandez /* Stop all output */ 14409be88e75SGabriel Fernandez mmio_clrbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN); 14419be88e75SGabriel Fernandez 14429be88e75SGabriel Fernandez /* Stop PLL */ 14439be88e75SGabriel Fernandez mmio_clrbits_32(pll_base, RCC_PLLNCR_PLLON); 14449be88e75SGabriel Fernandez } 14459be88e75SGabriel Fernandez 14469be88e75SGabriel Fernandez static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv, 14479be88e75SGabriel Fernandez const struct stm32_clk_pll *pll) 14489be88e75SGabriel Fernandez { 14499be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 14509be88e75SGabriel Fernandez uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT); 14519be88e75SGabriel Fernandez 14529be88e75SGabriel Fernandez /* Wait PLL lock */ 14539be88e75SGabriel Fernandez while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) == 0U) { 14549be88e75SGabriel Fernandez if (timeout_elapsed(timeout)) { 1455039b7d46SPatrick Delaunay ERROR("PLL%d start failed @ 0x%x: 0x%x\n", 1456039b7d46SPatrick Delaunay pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base)); 14579be88e75SGabriel Fernandez return -EINVAL; 14589be88e75SGabriel Fernandez } 14599be88e75SGabriel Fernandez } 14609be88e75SGabriel Fernandez 14619be88e75SGabriel Fernandez return 0; 14629be88e75SGabriel Fernandez } 14639be88e75SGabriel Fernandez 14649be88e75SGabriel Fernandez static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv, 14659be88e75SGabriel Fernandez const struct stm32_clk_pll *pll) 14669be88e75SGabriel Fernandez { 14679be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 14689be88e75SGabriel Fernandez uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT); 14699be88e75SGabriel Fernandez 14709be88e75SGabriel Fernandez /* Wait PLL lock */ 14719be88e75SGabriel Fernandez while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) != 0U) { 14729be88e75SGabriel Fernandez if (timeout_elapsed(timeout)) { 1473039b7d46SPatrick Delaunay ERROR("PLL%d stop failed @ 0x%x: 0x%x\n", 1474039b7d46SPatrick Delaunay pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base)); 14759be88e75SGabriel Fernandez return -EINVAL; 14769be88e75SGabriel Fernandez } 14779be88e75SGabriel Fernandez } 14789be88e75SGabriel Fernandez 14799be88e75SGabriel Fernandez return 0; 14809be88e75SGabriel Fernandez } 14819be88e75SGabriel Fernandez 14829be88e75SGabriel Fernandez static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 14839be88e75SGabriel Fernandez { 14849be88e75SGabriel Fernandez if (_clk_stm32_pll_is_enabled(priv, pll)) { 14859be88e75SGabriel Fernandez return 0; 14869be88e75SGabriel Fernandez } 14879be88e75SGabriel Fernandez 14889be88e75SGabriel Fernandez /* Preserve RCC_PLLNCR_SSCG_CTRL value */ 14899be88e75SGabriel Fernandez _clk_stm32_pll_set_on(priv, pll); 14909be88e75SGabriel Fernandez 14919be88e75SGabriel Fernandez /* Wait PLL lock */ 14929be88e75SGabriel Fernandez return _clk_stm32_pll_wait_ready_on(priv, pll); 14939be88e75SGabriel Fernandez } 14949be88e75SGabriel Fernandez 14959be88e75SGabriel Fernandez static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll) 14969be88e75SGabriel Fernandez { 14979be88e75SGabriel Fernandez if (!_clk_stm32_pll_is_enabled(priv, pll)) { 14989be88e75SGabriel Fernandez return; 14999be88e75SGabriel Fernandez } 15009be88e75SGabriel Fernandez 15019be88e75SGabriel Fernandez /* Stop all outputs and the PLL */ 15029be88e75SGabriel Fernandez _clk_stm32_pll_set_off(priv, pll); 15039be88e75SGabriel Fernandez 15049be88e75SGabriel Fernandez /* Wait PLL stopped */ 15059be88e75SGabriel Fernandez _clk_stm32_pll_wait_ready_off(priv, pll); 15069be88e75SGabriel Fernandez } 15079be88e75SGabriel Fernandez 15089be88e75SGabriel Fernandez static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx, 15099be88e75SGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf) 15109be88e75SGabriel Fernandez { 15119be88e75SGabriel Fernandez const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_idx); 15129be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 15139be88e75SGabriel Fernandez int ret = 0; 15149be88e75SGabriel Fernandez 15159be88e75SGabriel Fernandez /* Configure PLLs source */ 15169be88e75SGabriel Fernandez ret = stm32_clk_configure_mux(priv, pll_conf->vco.src); 1517c3ae7da0SYann Gautier if (ret != 0) { 15189be88e75SGabriel Fernandez return ret; 15199be88e75SGabriel Fernandez } 15209be88e75SGabriel Fernandez 15219be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER 15229be88e75SGabriel Fernandez if ((pll_idx == _PLL4) && pll4_bootrom) { 15239be88e75SGabriel Fernandez clk_stm32_pll_config_out(priv, pll, &pll_conf->output); 15249be88e75SGabriel Fernandez 15259be88e75SGabriel Fernandez mmio_setbits_32(pll_base, 15269be88e75SGabriel Fernandez RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN); 15279be88e75SGabriel Fernandez 15289be88e75SGabriel Fernandez return 0; 15299be88e75SGabriel Fernandez } 15309be88e75SGabriel Fernandez #endif 15319be88e75SGabriel Fernandez /* Stop the PLL before */ 15329be88e75SGabriel Fernandez _clk_stm32_pll_disable(priv, pll); 15339be88e75SGabriel Fernandez 15349be88e75SGabriel Fernandez clk_stm32_pll_config_vco(priv, pll, &pll_conf->vco); 15359be88e75SGabriel Fernandez clk_stm32_pll_config_out(priv, pll, &pll_conf->output); 15369be88e75SGabriel Fernandez clk_stm32_pll_config_csg(priv, pll, &pll_conf->vco); 15379be88e75SGabriel Fernandez 15389be88e75SGabriel Fernandez ret = _clk_stm32_pll_enable(priv, pll); 15399be88e75SGabriel Fernandez if (ret != 0) { 15409be88e75SGabriel Fernandez return ret; 15419be88e75SGabriel Fernandez } 15429be88e75SGabriel Fernandez 15439be88e75SGabriel Fernandez mmio_setbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN); 15449be88e75SGabriel Fernandez 15459be88e75SGabriel Fernandez return 0; 15469be88e75SGabriel Fernandez } 15479be88e75SGabriel Fernandez 15489be88e75SGabriel Fernandez static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx) 15499be88e75SGabriel Fernandez { 15509be88e75SGabriel Fernandez struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx); 15519be88e75SGabriel Fernandez 1552c3ae7da0SYann Gautier if (pll_conf->vco.status != 0U) { 15539be88e75SGabriel Fernandez return _clk_stm32_pll_init(priv, pll_idx, pll_conf); 15549be88e75SGabriel Fernandez } 15559be88e75SGabriel Fernandez 15569be88e75SGabriel Fernandez return 0; 15579be88e75SGabriel Fernandez } 15589be88e75SGabriel Fernandez 15599be88e75SGabriel Fernandez static int stm32_clk_pll_configure(struct stm32_clk_priv *priv) 15609be88e75SGabriel Fernandez { 15619be88e75SGabriel Fernandez int err = 0; 15629be88e75SGabriel Fernandez 15639be88e75SGabriel Fernandez err = clk_stm32_pll_init(priv, _PLL1); 1564c3ae7da0SYann Gautier if (err != 0) { 15659be88e75SGabriel Fernandez return err; 15669be88e75SGabriel Fernandez } 15679be88e75SGabriel Fernandez 15689be88e75SGabriel Fernandez err = clk_stm32_pll_init(priv, _PLL2); 1569c3ae7da0SYann Gautier if (err != 0) { 15709be88e75SGabriel Fernandez return err; 15719be88e75SGabriel Fernandez } 15729be88e75SGabriel Fernandez 15739be88e75SGabriel Fernandez err = clk_stm32_pll_init(priv, _PLL3); 1574c3ae7da0SYann Gautier if (err != 0) { 15759be88e75SGabriel Fernandez return err; 15769be88e75SGabriel Fernandez } 15779be88e75SGabriel Fernandez 15789be88e75SGabriel Fernandez err = clk_stm32_pll_init(priv, _PLL4); 1579c3ae7da0SYann Gautier if (err != 0) { 15809be88e75SGabriel Fernandez return err; 15819be88e75SGabriel Fernandez } 15829be88e75SGabriel Fernandez 15839be88e75SGabriel Fernandez return 0; 15849be88e75SGabriel Fernandez } 15859be88e75SGabriel Fernandez 15869be88e75SGabriel Fernandez static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv) 15879be88e75SGabriel Fernandez { 15889be88e75SGabriel Fernandez int ret = 0; 15899be88e75SGabriel Fernandez 15909be88e75SGabriel Fernandez if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) { 15919be88e75SGabriel Fernandez ret = clk_oscillator_wait_ready_on(priv, _CK_LSE); 15929be88e75SGabriel Fernandez } 15939be88e75SGabriel Fernandez 15949be88e75SGabriel Fernandez return ret; 15959be88e75SGabriel Fernandez } 15969be88e75SGabriel Fernandez 15979be88e75SGabriel Fernandez static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv) 15989be88e75SGabriel Fernandez { 15999be88e75SGabriel Fernandez stm32_enable_oscillator_hse(priv); 16009be88e75SGabriel Fernandez stm32_enable_oscillator_lse(priv); 16019be88e75SGabriel Fernandez _clk_stm32_enable(priv, _CK_LSI); 16029be88e75SGabriel Fernandez _clk_stm32_enable(priv, _CK_CSI); 16039be88e75SGabriel Fernandez } 16049be88e75SGabriel Fernandez 16059be88e75SGabriel Fernandez static int stm32_clk_hsidiv_configure(struct stm32_clk_priv *priv) 16069be88e75SGabriel Fernandez { 16079be88e75SGabriel Fernandez return stm32mp1_hsidiv(_clk_stm32_get_rate(priv, _CK_HSI)); 16089be88e75SGabriel Fernandez } 16099be88e75SGabriel Fernandez 16109be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER 16119be88e75SGabriel Fernandez static bool stm32mp1_clk_is_pll4_used_by_bootrom(struct stm32_clk_priv *priv, int usbphy_p) 16129be88e75SGabriel Fernandez { 16139be88e75SGabriel Fernandez /* Don't initialize PLL4, when used by BOOTROM */ 16149be88e75SGabriel Fernandez if ((stm32mp_get_boot_itf_selected() == 16159be88e75SGabriel Fernandez BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB) && 16169be88e75SGabriel Fernandez (usbphy_p == _PLL4R)) { 16179be88e75SGabriel Fernandez return true; 16189be88e75SGabriel Fernandez } 16199be88e75SGabriel Fernandez 16209be88e75SGabriel Fernandez return false; 16219be88e75SGabriel Fernandez } 16229be88e75SGabriel Fernandez 16239be88e75SGabriel Fernandez static int stm32mp1_clk_check_usb_conflict(struct stm32_clk_priv *priv, int usbphy_p, int usbo_p) 16249be88e75SGabriel Fernandez { 16259be88e75SGabriel Fernandez int _usbo_p; 16269be88e75SGabriel Fernandez int _usbphy_p; 16279be88e75SGabriel Fernandez 16289be88e75SGabriel Fernandez if (!pll4_bootrom) { 16299be88e75SGabriel Fernandez return 0; 16309be88e75SGabriel Fernandez } 16319be88e75SGabriel Fernandez 16329be88e75SGabriel Fernandez _usbo_p = _clk_stm32_get_parent(priv, _USBO_K); 16339be88e75SGabriel Fernandez _usbphy_p = _clk_stm32_get_parent(priv, _USBPHY_K); 16349be88e75SGabriel Fernandez 16359be88e75SGabriel Fernandez if ((_usbo_p != usbo_p) || (_usbphy_p != usbphy_p)) { 16369be88e75SGabriel Fernandez return -FDT_ERR_BADVALUE; 16379be88e75SGabriel Fernandez } 16389be88e75SGabriel Fernandez 16399be88e75SGabriel Fernandez return 0; 16409be88e75SGabriel Fernandez } 16419be88e75SGabriel Fernandez #endif 16429be88e75SGabriel Fernandez 16439be88e75SGabriel Fernandez static struct clk_oscillator_data stm32mp13_osc_data[NB_OSCILLATOR] = { 16449be88e75SGabriel Fernandez OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY, 16459be88e75SGabriel Fernandez NULL, NULL, NULL), 16469be88e75SGabriel Fernandez 16479be88e75SGabriel Fernandez OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY, 16489be88e75SGabriel Fernandez NULL, NULL, NULL), 16499be88e75SGabriel Fernandez 16509be88e75SGabriel Fernandez OSCILLATOR(OSC_CSI, _CK_CSI, "clk-csi", GATE_CSI, GATE_CSI_RDY, 16519be88e75SGabriel Fernandez NULL, NULL, NULL), 16529be88e75SGabriel Fernandez 16539be88e75SGabriel Fernandez OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY, 16549be88e75SGabriel Fernandez BYPASS(RCC_BDCR, 1, 3), 16559be88e75SGabriel Fernandez CSS(RCC_BDCR, 8), 16569be88e75SGabriel Fernandez DRIVE(RCC_BDCR, 4, 2, 2)), 16579be88e75SGabriel Fernandez 16589be88e75SGabriel Fernandez OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY, 16599be88e75SGabriel Fernandez BYPASS(RCC_OCENSETR, 10, 7), 16609be88e75SGabriel Fernandez CSS(RCC_OCENSETR, 11), 16619be88e75SGabriel Fernandez NULL), 16629be88e75SGabriel Fernandez 16639be88e75SGabriel Fernandez OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE, 16649be88e75SGabriel Fernandez NULL, NULL, NULL), 16659be88e75SGabriel Fernandez }; 16669be88e75SGabriel Fernandez 16679be88e75SGabriel Fernandez static const char *clk_stm32_get_oscillator_name(enum stm32_osc id) 16689be88e75SGabriel Fernandez { 16699be88e75SGabriel Fernandez if (id < NB_OSCILLATOR) { 16709be88e75SGabriel Fernandez return stm32mp13_osc_data[id].name; 16719be88e75SGabriel Fernandez } 16729be88e75SGabriel Fernandez 16739be88e75SGabriel Fernandez return NULL; 16749be88e75SGabriel Fernandez } 16759be88e75SGabriel Fernandez 16769be88e75SGabriel Fernandez #define CLK_PLL_CFG(_idx, _clk_id, _type, _reg)\ 16779be88e75SGabriel Fernandez [(_idx)] = {\ 16789be88e75SGabriel Fernandez .clk_id = (_clk_id),\ 16799be88e75SGabriel Fernandez .plltype = (_type),\ 16809be88e75SGabriel Fernandez .reg_pllxcr = (_reg),\ 16819be88e75SGabriel Fernandez } 16829be88e75SGabriel Fernandez 16839be88e75SGabriel Fernandez static const struct stm32_clk_pll stm32_mp13_clk_pll[_PLL_NB] = { 16849be88e75SGabriel Fernandez CLK_PLL_CFG(_PLL1, _CK_PLL1, PLL_2000, RCC_PLL1CR), 16859be88e75SGabriel Fernandez CLK_PLL_CFG(_PLL2, _CK_PLL2, PLL_1600, RCC_PLL2CR), 16869be88e75SGabriel Fernandez CLK_PLL_CFG(_PLL3, _CK_PLL3, PLL_800, RCC_PLL3CR), 16879be88e75SGabriel Fernandez CLK_PLL_CFG(_PLL4, _CK_PLL4, PLL_800, RCC_PLL4CR), 16889be88e75SGabriel Fernandez }; 16899be88e75SGabriel Fernandez 16909be88e75SGabriel Fernandez static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx) 16919be88e75SGabriel Fernandez { 16929be88e75SGabriel Fernandez return &stm32_mp13_clk_pll[idx]; 16939be88e75SGabriel Fernandez } 16949be88e75SGabriel Fernandez 16959be88e75SGabriel Fernandez struct stm32_pll_cfg { 16969be88e75SGabriel Fernandez int pll_id; 16979be88e75SGabriel Fernandez }; 16989be88e75SGabriel Fernandez 16999be88e75SGabriel Fernandez static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id, 17009be88e75SGabriel Fernandez unsigned long prate) 17019be88e75SGabriel Fernandez { 17029be88e75SGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 17039be88e75SGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 17049be88e75SGabriel Fernandez const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id); 17059be88e75SGabriel Fernandez uintptr_t pll_base = priv->base + pll->reg_pllxcr; 17069be88e75SGabriel Fernandez uint32_t cfgr1, fracr, divm, divn; 17079be88e75SGabriel Fernandez unsigned long fvco; 17089be88e75SGabriel Fernandez 17099be88e75SGabriel Fernandez cfgr1 = mmio_read_32(pll_base + RCC_OFFSET_PLLXCFGR1); 17109be88e75SGabriel Fernandez fracr = mmio_read_32(pll_base + RCC_OFFSET_PLLXFRACR); 17119be88e75SGabriel Fernandez 17129be88e75SGabriel Fernandez divm = (cfgr1 & (RCC_PLLNCFGR1_DIVM_MASK)) >> RCC_PLLNCFGR1_DIVM_SHIFT; 17139be88e75SGabriel Fernandez divn = cfgr1 & RCC_PLLNCFGR1_DIVN_MASK; 17149be88e75SGabriel Fernandez 17159be88e75SGabriel Fernandez /* 17169be88e75SGabriel Fernandez * With FRACV : 17179be88e75SGabriel Fernandez * Fvco = Fck_ref * ((DIVN + 1) + FRACV / 2^13) / (DIVM + 1) 17189be88e75SGabriel Fernandez * Without FRACV 17199be88e75SGabriel Fernandez * Fvco = Fck_ref * ((DIVN + 1) / (DIVM + 1) 17209be88e75SGabriel Fernandez */ 17219be88e75SGabriel Fernandez if ((fracr & RCC_PLLNFRACR_FRACLE) != 0U) { 17229be88e75SGabriel Fernandez uint32_t fracv = (fracr & RCC_PLLNFRACR_FRACV_MASK) >> 17239be88e75SGabriel Fernandez RCC_PLLNFRACR_FRACV_SHIFT; 17249be88e75SGabriel Fernandez unsigned long long numerator, denominator; 17259be88e75SGabriel Fernandez 17269be88e75SGabriel Fernandez numerator = (((unsigned long long)divn + 1U) << 13) + fracv; 17279be88e75SGabriel Fernandez numerator = prate * numerator; 17289be88e75SGabriel Fernandez denominator = ((unsigned long long)divm + 1U) << 13; 17299be88e75SGabriel Fernandez fvco = (unsigned long)(numerator / denominator); 17309be88e75SGabriel Fernandez } else { 17319be88e75SGabriel Fernandez fvco = (unsigned long)(prate * (divn + 1U) / (divm + 1U)); 17329be88e75SGabriel Fernandez } 17339be88e75SGabriel Fernandez 17349be88e75SGabriel Fernandez return fvco; 17359be88e75SGabriel Fernandez }; 17369be88e75SGabriel Fernandez 17379be88e75SGabriel Fernandez static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id) 17389be88e75SGabriel Fernandez { 17399be88e75SGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 17409be88e75SGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 17419be88e75SGabriel Fernandez const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id); 17429be88e75SGabriel Fernandez 17439be88e75SGabriel Fernandez return _clk_stm32_pll_is_enabled(priv, pll); 17449be88e75SGabriel Fernandez } 17459be88e75SGabriel Fernandez 17469be88e75SGabriel Fernandez static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id) 17479be88e75SGabriel Fernandez { 17489be88e75SGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 17499be88e75SGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 17509be88e75SGabriel Fernandez const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id); 17519be88e75SGabriel Fernandez 17529be88e75SGabriel Fernandez return _clk_stm32_pll_enable(priv, pll); 17539be88e75SGabriel Fernandez } 17549be88e75SGabriel Fernandez 17559be88e75SGabriel Fernandez static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id) 17569be88e75SGabriel Fernandez { 17579be88e75SGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, id); 17589be88e75SGabriel Fernandez struct stm32_pll_cfg *pll_cfg = clk->clock_cfg; 17599be88e75SGabriel Fernandez const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id); 17609be88e75SGabriel Fernandez 17619be88e75SGabriel Fernandez _clk_stm32_pll_disable(priv, pll); 17629be88e75SGabriel Fernandez } 17639be88e75SGabriel Fernandez 17649be88e75SGabriel Fernandez static const struct stm32_clk_ops clk_stm32_pll_ops = { 17659be88e75SGabriel Fernandez .recalc_rate = clk_stm32_pll_recalc_rate, 17669be88e75SGabriel Fernandez .enable = clk_stm32_pll_enable, 17679be88e75SGabriel Fernandez .disable = clk_stm32_pll_disable, 17689be88e75SGabriel Fernandez .is_enabled = clk_stm32_pll_is_enabled, 17699be88e75SGabriel Fernandez }; 17709be88e75SGabriel Fernandez 17719be88e75SGabriel Fernandez #define CLK_PLL(idx, _idx, _parent, _gate, _pll_id, _flags)[idx] = {\ 17729be88e75SGabriel Fernandez .binding = _idx,\ 17739be88e75SGabriel Fernandez .parent = _parent,\ 17749be88e75SGabriel Fernandez .flags = (_flags),\ 17759be88e75SGabriel Fernandez .clock_cfg = &(struct stm32_pll_cfg) {\ 17769be88e75SGabriel Fernandez .pll_id = _pll_id,\ 17779be88e75SGabriel Fernandez },\ 17789be88e75SGabriel Fernandez .ops = &clk_stm32_pll_ops,\ 17799be88e75SGabriel Fernandez } 17809be88e75SGabriel Fernandez 17819be88e75SGabriel Fernandez struct clk_stm32_composite_cfg { 17829be88e75SGabriel Fernandez int gate_id; 17839be88e75SGabriel Fernandez int div_id; 17849be88e75SGabriel Fernandez }; 17859be88e75SGabriel Fernandez 17869be88e75SGabriel Fernandez static unsigned long clk_stm32_composite_recalc_rate(struct stm32_clk_priv *priv, 17879be88e75SGabriel Fernandez int idx, unsigned long prate) 17889be88e75SGabriel Fernandez { 17899be88e75SGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 17909be88e75SGabriel Fernandez struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg; 17919be88e75SGabriel Fernandez 17929be88e75SGabriel Fernandez return _clk_stm32_divider_recalc(priv, composite_cfg->div_id, prate); 17939be88e75SGabriel Fernandez }; 17949be88e75SGabriel Fernandez 17959be88e75SGabriel Fernandez static bool clk_stm32_composite_gate_is_enabled(struct stm32_clk_priv *priv, int idx) 17969be88e75SGabriel Fernandez { 17979be88e75SGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 17989be88e75SGabriel Fernandez struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg; 17999be88e75SGabriel Fernandez 18009be88e75SGabriel Fernandez return _clk_stm32_gate_is_enabled(priv, composite_cfg->gate_id); 18019be88e75SGabriel Fernandez } 18029be88e75SGabriel Fernandez 18039be88e75SGabriel Fernandez static int clk_stm32_composite_gate_enable(struct stm32_clk_priv *priv, int idx) 18049be88e75SGabriel Fernandez { 18059be88e75SGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 18069be88e75SGabriel Fernandez struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg; 18079be88e75SGabriel Fernandez 18089be88e75SGabriel Fernandez return _clk_stm32_gate_enable(priv, composite_cfg->gate_id); 18099be88e75SGabriel Fernandez } 18109be88e75SGabriel Fernandez 18119be88e75SGabriel Fernandez static void clk_stm32_composite_gate_disable(struct stm32_clk_priv *priv, int idx) 18129be88e75SGabriel Fernandez { 18139be88e75SGabriel Fernandez const struct clk_stm32 *clk = _clk_get(priv, idx); 18149be88e75SGabriel Fernandez struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg; 18159be88e75SGabriel Fernandez 18169be88e75SGabriel Fernandez _clk_stm32_gate_disable(priv, composite_cfg->gate_id); 18179be88e75SGabriel Fernandez } 18189be88e75SGabriel Fernandez 18199be88e75SGabriel Fernandez static const struct stm32_clk_ops clk_stm32_composite_ops = { 18209be88e75SGabriel Fernandez .recalc_rate = clk_stm32_composite_recalc_rate, 18219be88e75SGabriel Fernandez .is_enabled = clk_stm32_composite_gate_is_enabled, 18229be88e75SGabriel Fernandez .enable = clk_stm32_composite_gate_enable, 18239be88e75SGabriel Fernandez .disable = clk_stm32_composite_gate_disable, 18249be88e75SGabriel Fernandez }; 18259be88e75SGabriel Fernandez 18269be88e75SGabriel Fernandez #define STM32_COMPOSITE(idx, _binding, _parent, _flags, _gate_id,\ 18279be88e75SGabriel Fernandez _div_id)[idx] = {\ 18289be88e75SGabriel Fernandez .binding = (_binding),\ 18299be88e75SGabriel Fernandez .parent = (_parent),\ 18309be88e75SGabriel Fernandez .flags = (_flags),\ 18319be88e75SGabriel Fernandez .clock_cfg = &(struct clk_stm32_composite_cfg) {\ 18329be88e75SGabriel Fernandez .gate_id = (_gate_id),\ 18339be88e75SGabriel Fernandez .div_id = (_div_id),\ 18349be88e75SGabriel Fernandez },\ 18359be88e75SGabriel Fernandez .ops = &clk_stm32_composite_ops,\ 18369be88e75SGabriel Fernandez } 18379be88e75SGabriel Fernandez 18389be88e75SGabriel Fernandez static const struct clk_stm32 stm32mp13_clk[CK_LAST] = { 18399be88e75SGabriel Fernandez /* ROOT CLOCKS */ 18409be88e75SGabriel Fernandez CLK_FIXED_RATE(_CK_OFF, _NO_ID, 0), 18419be88e75SGabriel Fernandez CLK_OSC(_CK_HSE, CK_HSE, CLK_IS_ROOT, OSC_HSE), 18429be88e75SGabriel Fernandez CLK_OSC(_CK_HSI, CK_HSI, CLK_IS_ROOT, OSC_HSI), 18439be88e75SGabriel Fernandez CLK_OSC(_CK_CSI, CK_CSI, CLK_IS_ROOT, OSC_CSI), 18449be88e75SGabriel Fernandez CLK_OSC(_CK_LSI, CK_LSI, CLK_IS_ROOT, OSC_LSI), 18459be88e75SGabriel Fernandez CLK_OSC(_CK_LSE, CK_LSE, CLK_IS_ROOT, OSC_LSE), 18469be88e75SGabriel Fernandez 18479be88e75SGabriel Fernandez CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN), 18489be88e75SGabriel Fernandez 18499be88e75SGabriel Fernandez CLK_FIXED_RATE(_USB_PHY_48, _NO_ID, USB_PHY_48_MHZ), 18509be88e75SGabriel Fernandez 18519be88e75SGabriel Fernandez STM32_DIV(_HSE_DIV, _NO_ID, _CK_HSE, 0, DIV_RTC), 18529be88e75SGabriel Fernandez 18539be88e75SGabriel Fernandez FIXED_FACTOR(_HSE_DIV2, CK_HSE_DIV2, _CK_HSE, 1, 2), 18549be88e75SGabriel Fernandez FIXED_FACTOR(_CSI_DIV122, _NO_ID, _CK_CSI, 1, 122), 18559be88e75SGabriel Fernandez 18569be88e75SGabriel Fernandez CLK_PLL(_CK_PLL1, PLL1, MUX(MUX_PLL12), GATE_PLL1, _PLL1, 0), 18579be88e75SGabriel Fernandez CLK_PLL(_CK_PLL2, PLL2, MUX(MUX_PLL12), GATE_PLL2, _PLL2, 0), 18589be88e75SGabriel Fernandez CLK_PLL(_CK_PLL3, PLL3, MUX(MUX_PLL3), GATE_PLL3, _PLL3, 0), 18599be88e75SGabriel Fernandez CLK_PLL(_CK_PLL4, PLL4, MUX(MUX_PLL4), GATE_PLL4, _PLL4, 0), 18609be88e75SGabriel Fernandez 18619be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL1P, PLL1_P, _CK_PLL1, CLK_IS_CRITICAL, GATE_PLL1_DIVP, DIV_PLL1DIVP), 18629be88e75SGabriel Fernandez STM32_DIV(_PLL1P_DIV, _NO_ID, _CK_PLL1, 0, DIV_MPU), 18639be88e75SGabriel Fernandez 18649be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL2P, PLL2_P, _CK_PLL2, CLK_IS_CRITICAL, GATE_PLL2_DIVP, DIV_PLL2DIVP), 18659be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL2Q, PLL2_Q, _CK_PLL2, 0, GATE_PLL2_DIVQ, DIV_PLL2DIVQ), 18669be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL2R, PLL2_R, _CK_PLL2, CLK_IS_CRITICAL, GATE_PLL2_DIVR, DIV_PLL2DIVR), 18679be88e75SGabriel Fernandez 18689be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL3P, PLL3_P, _CK_PLL3, 0, GATE_PLL3_DIVP, DIV_PLL3DIVP), 18699be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL3Q, PLL3_Q, _CK_PLL3, 0, GATE_PLL3_DIVQ, DIV_PLL3DIVQ), 18709be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL3R, PLL3_R, _CK_PLL3, 0, GATE_PLL3_DIVR, DIV_PLL3DIVR), 18719be88e75SGabriel Fernandez 18729be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL4P, PLL4_P, _CK_PLL4, 0, GATE_PLL4_DIVP, DIV_PLL4DIVP), 18739be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL4Q, PLL4_Q, _CK_PLL4, 0, GATE_PLL4_DIVQ, DIV_PLL4DIVQ), 18749be88e75SGabriel Fernandez STM32_COMPOSITE(_PLL4R, PLL4_R, _CK_PLL4, 0, GATE_PLL4_DIVR, DIV_PLL4DIVR), 18759be88e75SGabriel Fernandez 18769be88e75SGabriel Fernandez STM32_MUX(_CKMPU, CK_MPU, MUX_MPU, 0), 18779be88e75SGabriel Fernandez STM32_DIV(_CKAXI, CK_AXI, MUX(MUX_AXI), 0, DIV_AXI), 18789be88e75SGabriel Fernandez STM32_DIV(_CKMLAHB, CK_MLAHB, MUX(MUX_MLAHB), CLK_IS_CRITICAL, DIV_MLAHB), 18799be88e75SGabriel Fernandez STM32_MUX(_CKPER, CK_PER, MUX(MUX_CKPER), 0), 18809be88e75SGabriel Fernandez 18819be88e75SGabriel Fernandez STM32_DIV(_PCLK1, PCLK1, _CKMLAHB, 0, DIV_APB1), 18829be88e75SGabriel Fernandez STM32_DIV(_PCLK2, PCLK2, _CKMLAHB, 0, DIV_APB2), 18839be88e75SGabriel Fernandez STM32_DIV(_PCLK3, PCLK3, _CKMLAHB, 0, DIV_APB3), 18849be88e75SGabriel Fernandez STM32_DIV(_PCLK4, PCLK4, _CKAXI, 0, DIV_APB4), 18859be88e75SGabriel Fernandez STM32_DIV(_PCLK5, PCLK5, _CKAXI, 0, DIV_APB5), 18869be88e75SGabriel Fernandez STM32_DIV(_PCLK6, PCLK6, _CKMLAHB, 0, DIV_APB6), 18879be88e75SGabriel Fernandez 18889be88e75SGabriel Fernandez CK_TIMER(_CKTIMG1, CK_TIMG1, _PCLK1, 0, RCC_APB1DIVR, RCC_TIMG1PRER), 18899be88e75SGabriel Fernandez CK_TIMER(_CKTIMG2, CK_TIMG2, _PCLK2, 0, RCC_APB2DIVR, RCC_TIMG2PRER), 18909be88e75SGabriel Fernandez CK_TIMER(_CKTIMG3, CK_TIMG3, _PCLK6, 0, RCC_APB6DIVR, RCC_TIMG3PRER), 18919be88e75SGabriel Fernandez 18929be88e75SGabriel Fernandez /* END ROOT CLOCKS */ 18939be88e75SGabriel Fernandez 18949be88e75SGabriel Fernandez STM32_GATE(_DDRC1, DDRC1, _CKAXI, CLK_IS_CRITICAL, GATE_DDRC1), 18959be88e75SGabriel Fernandez STM32_GATE(_DDRC1LP, DDRC1LP, _CKAXI, CLK_IS_CRITICAL, GATE_DDRC1LP), 18969be88e75SGabriel Fernandez STM32_GATE(_DDRPHYC, DDRPHYC, _PLL2R, CLK_IS_CRITICAL, GATE_DDRPHYC), 18979be88e75SGabriel Fernandez STM32_GATE(_DDRPHYCLP, DDRPHYCLP, _PLL2R, CLK_IS_CRITICAL, GATE_DDRPHYCLP), 18989be88e75SGabriel Fernandez STM32_GATE(_DDRCAPB, DDRCAPB, _PCLK4, CLK_IS_CRITICAL, GATE_DDRCAPB), 18999be88e75SGabriel Fernandez STM32_GATE(_DDRCAPBLP, DDRCAPBLP, _PCLK4, CLK_IS_CRITICAL, GATE_DDRCAPBLP), 19009be88e75SGabriel Fernandez STM32_GATE(_AXIDCG, AXIDCG, _CKAXI, CLK_IS_CRITICAL, GATE_AXIDCG), 19019be88e75SGabriel Fernandez STM32_GATE(_DDRPHYCAPB, DDRPHYCAPB, _PCLK4, CLK_IS_CRITICAL, GATE_DDRPHYCAPB), 19029be88e75SGabriel Fernandez STM32_GATE(_DDRPHYCAPBLP, DDRPHYCAPBLP, _PCLK4, CLK_IS_CRITICAL, GATE_DDRPHYCAPBLP), 19039be88e75SGabriel Fernandez 19049be88e75SGabriel Fernandez STM32_GATE(_SYSCFG, SYSCFG, _PCLK3, 0, GATE_SYSCFG), 19059be88e75SGabriel Fernandez STM32_GATE(_DDRPERFM, DDRPERFM, _PCLK4, 0, GATE_DDRPERFM), 19069be88e75SGabriel Fernandez STM32_GATE(_IWDG2APB, IWDG2, _PCLK4, 0, GATE_IWDG2APB), 19079be88e75SGabriel Fernandez STM32_GATE(_USBPHY_K, USBPHY_K, MUX(MUX_USBPHY), 0, GATE_USBPHY), 19089be88e75SGabriel Fernandez STM32_GATE(_USBO_K, USBO_K, MUX(MUX_USBO), 0, GATE_USBO), 19099be88e75SGabriel Fernandez 19109be88e75SGabriel Fernandez STM32_GATE(_RTCAPB, RTCAPB, _PCLK5, CLK_IS_CRITICAL, GATE_RTCAPB), 19119be88e75SGabriel Fernandez STM32_GATE(_TZC, TZC, _PCLK5, CLK_IS_CRITICAL, GATE_TZC), 19129be88e75SGabriel Fernandez STM32_GATE(_ETZPC, TZPC, _PCLK5, CLK_IS_CRITICAL, GATE_ETZPC), 19139be88e75SGabriel Fernandez STM32_GATE(_IWDG1APB, IWDG1, _PCLK5, 0, GATE_IWDG1APB), 19149be88e75SGabriel Fernandez STM32_GATE(_BSEC, BSEC, _PCLK5, CLK_IS_CRITICAL, GATE_BSEC), 19159be88e75SGabriel Fernandez STM32_GATE(_STGENC, STGEN_K, MUX(MUX_STGEN), CLK_IS_CRITICAL, GATE_STGENC), 19169be88e75SGabriel Fernandez 19179be88e75SGabriel Fernandez STM32_GATE(_USART1_K, USART1_K, MUX(MUX_UART1), 0, GATE_USART1), 19189be88e75SGabriel Fernandez STM32_GATE(_USART2_K, USART2_K, MUX(MUX_UART2), 0, GATE_USART2), 19199be88e75SGabriel Fernandez STM32_GATE(_I2C3_K, I2C3_K, MUX(MUX_I2C3), 0, GATE_I2C3), 19209be88e75SGabriel Fernandez STM32_GATE(_I2C4_K, I2C4_K, MUX(MUX_I2C4), 0, GATE_I2C4), 19219be88e75SGabriel Fernandez STM32_GATE(_I2C5_K, I2C5_K, MUX(MUX_I2C5), 0, GATE_I2C5), 19229be88e75SGabriel Fernandez STM32_GATE(_TIM12, TIM12_K, _CKTIMG3, 0, GATE_TIM12), 19239be88e75SGabriel Fernandez STM32_GATE(_TIM15, TIM15_K, _CKTIMG3, 0, GATE_TIM15), 19249be88e75SGabriel Fernandez 19259be88e75SGabriel Fernandez STM32_GATE(_RTCCK, RTC, MUX(MUX_RTC), 0, GATE_RTCCK), 19269be88e75SGabriel Fernandez 19279be88e75SGabriel Fernandez STM32_GATE(_GPIOA, GPIOA, _CKMLAHB, 0, GATE_GPIOA), 19289be88e75SGabriel Fernandez STM32_GATE(_GPIOB, GPIOB, _CKMLAHB, 0, GATE_GPIOB), 19299be88e75SGabriel Fernandez STM32_GATE(_GPIOC, GPIOC, _CKMLAHB, 0, GATE_GPIOC), 19309be88e75SGabriel Fernandez STM32_GATE(_GPIOD, GPIOD, _CKMLAHB, 0, GATE_GPIOD), 19319be88e75SGabriel Fernandez STM32_GATE(_GPIOE, GPIOE, _CKMLAHB, 0, GATE_GPIOE), 19329be88e75SGabriel Fernandez STM32_GATE(_GPIOF, GPIOF, _CKMLAHB, 0, GATE_GPIOF), 19339be88e75SGabriel Fernandez STM32_GATE(_GPIOG, GPIOG, _CKMLAHB, 0, GATE_GPIOG), 19349be88e75SGabriel Fernandez STM32_GATE(_GPIOH, GPIOH, _CKMLAHB, 0, GATE_GPIOH), 19359be88e75SGabriel Fernandez STM32_GATE(_GPIOI, GPIOI, _CKMLAHB, 0, GATE_GPIOI), 19369be88e75SGabriel Fernandez 19379be88e75SGabriel Fernandez STM32_GATE(_PKA, PKA, _CKAXI, 0, GATE_PKA), 19389be88e75SGabriel Fernandez STM32_GATE(_SAES_K, SAES_K, MUX(MUX_SAES), 0, GATE_SAES), 19399be88e75SGabriel Fernandez STM32_GATE(_CRYP1, CRYP1, _PCLK5, 0, GATE_CRYP1), 19409be88e75SGabriel Fernandez STM32_GATE(_HASH1, HASH1, _PCLK5, 0, GATE_HASH1), 19419be88e75SGabriel Fernandez 19429be88e75SGabriel Fernandez STM32_GATE(_RNG1_K, RNG1_K, MUX(MUX_RNG1), 0, GATE_RNG1), 19439be88e75SGabriel Fernandez STM32_GATE(_BKPSRAM, BKPSRAM, _PCLK5, CLK_IS_CRITICAL, GATE_BKPSRAM), 19449be88e75SGabriel Fernandez 19459be88e75SGabriel Fernandez STM32_GATE(_SDMMC1_K, SDMMC1_K, MUX(MUX_SDMMC1), 0, GATE_SDMMC1), 19469be88e75SGabriel Fernandez STM32_GATE(_SDMMC2_K, SDMMC2_K, MUX(MUX_SDMMC2), 0, GATE_SDMMC2), 19479be88e75SGabriel Fernandez STM32_GATE(_DBGCK, CK_DBG, _CKAXI, 0, GATE_DBGCK), 19489be88e75SGabriel Fernandez 19499be88e75SGabriel Fernandez STM32_GATE(_USART3_K, USART3_K, MUX(MUX_UART35), 0, GATE_USART3), 19509be88e75SGabriel Fernandez STM32_GATE(_UART4_K, UART4_K, MUX(MUX_UART4), 0, GATE_UART4), 19519be88e75SGabriel Fernandez STM32_GATE(_UART5_K, UART5_K, MUX(MUX_UART35), 0, GATE_UART5), 19529be88e75SGabriel Fernandez STM32_GATE(_UART7_K, UART7_K, MUX(MUX_UART78), 0, GATE_UART7), 19539be88e75SGabriel Fernandez STM32_GATE(_UART8_K, UART8_K, MUX(MUX_UART78), 0, GATE_UART8), 19549be88e75SGabriel Fernandez STM32_GATE(_USART6_K, USART6_K, MUX(MUX_UART6), 0, GATE_USART6), 19559be88e75SGabriel Fernandez STM32_GATE(_MCE, MCE, _CKAXI, CLK_IS_CRITICAL, GATE_MCE), 19569be88e75SGabriel Fernandez STM32_GATE(_FMC_K, FMC_K, MUX(MUX_FMC), 0, GATE_FMC), 19579be88e75SGabriel Fernandez STM32_GATE(_QSPI_K, QSPI_K, MUX(MUX_QSPI), 0, GATE_QSPI), 19589be88e75SGabriel Fernandez 19599be88e75SGabriel Fernandez STM32_COMPOSITE(_MCO1_K, CK_MCO1, MUX(MUX_MCO1), 0, GATE_MCO1, DIV_MCO1), 19609be88e75SGabriel Fernandez STM32_COMPOSITE(_MCO2_K, CK_MCO2, MUX(MUX_MCO2), 0, GATE_MCO2, DIV_MCO2), 19619be88e75SGabriel Fernandez STM32_COMPOSITE(_TRACECK, CK_TRACE, _CKAXI, 0, GATE_TRACECK, DIV_TRACE), 19629be88e75SGabriel Fernandez }; 19639be88e75SGabriel Fernandez 19649be88e75SGabriel Fernandez static struct stm32_pll_dt_cfg mp13_pll[_PLL_NB]; 19659be88e75SGabriel Fernandez 19669be88e75SGabriel Fernandez static struct stm32_osci_dt_cfg mp13_osci[NB_OSCILLATOR]; 19679be88e75SGabriel Fernandez 19689be88e75SGabriel Fernandez static uint32_t mp13_clksrc[MUX_MAX]; 19699be88e75SGabriel Fernandez 19709be88e75SGabriel Fernandez static uint32_t mp13_clkdiv[DIV_MAX]; 19719be88e75SGabriel Fernandez 19729be88e75SGabriel Fernandez static struct stm32_clk_platdata stm32mp13_clock_pdata = { 19739be88e75SGabriel Fernandez .osci = mp13_osci, 19749be88e75SGabriel Fernandez .nosci = NB_OSCILLATOR, 19759be88e75SGabriel Fernandez .pll = mp13_pll, 19769be88e75SGabriel Fernandez .npll = _PLL_NB, 19779be88e75SGabriel Fernandez .clksrc = mp13_clksrc, 19789be88e75SGabriel Fernandez .nclksrc = MUX_MAX, 19799be88e75SGabriel Fernandez .clkdiv = mp13_clkdiv, 19809be88e75SGabriel Fernandez .nclkdiv = DIV_MAX, 19819be88e75SGabriel Fernandez }; 19829be88e75SGabriel Fernandez 19839be88e75SGabriel Fernandez static struct stm32_clk_priv stm32mp13_clock_data = { 19849be88e75SGabriel Fernandez .base = RCC_BASE, 19859be88e75SGabriel Fernandez .num = ARRAY_SIZE(stm32mp13_clk), 19869be88e75SGabriel Fernandez .clks = stm32mp13_clk, 19879be88e75SGabriel Fernandez .parents = parent_mp13, 19889be88e75SGabriel Fernandez .nb_parents = ARRAY_SIZE(parent_mp13), 19899be88e75SGabriel Fernandez .gates = gates_mp13, 19909be88e75SGabriel Fernandez .nb_gates = ARRAY_SIZE(gates_mp13), 19919be88e75SGabriel Fernandez .div = dividers_mp13, 19929be88e75SGabriel Fernandez .nb_div = ARRAY_SIZE(dividers_mp13), 19939be88e75SGabriel Fernandez .osci_data = stm32mp13_osc_data, 19949be88e75SGabriel Fernandez .nb_osci_data = ARRAY_SIZE(stm32mp13_osc_data), 19959be88e75SGabriel Fernandez .gate_refcounts = refcounts_mp13, 19969be88e75SGabriel Fernandez .pdata = &stm32mp13_clock_pdata, 19979be88e75SGabriel Fernandez }; 19989be88e75SGabriel Fernandez 19999be88e75SGabriel Fernandez static int stm32mp1_init_clock_tree(void) 20009be88e75SGabriel Fernandez { 20019be88e75SGabriel Fernandez struct stm32_clk_priv *priv = clk_stm32_get_priv(); 20029be88e75SGabriel Fernandez int ret; 20039be88e75SGabriel Fernandez 20049be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER 20059be88e75SGabriel Fernandez int usbphy_p = _clk_stm32_get_parent(priv, _USBPHY_K); 20069be88e75SGabriel Fernandez int usbo_p = _clk_stm32_get_parent(priv, _USBO_K); 20079be88e75SGabriel Fernandez 20089be88e75SGabriel Fernandez /* Don't initialize PLL4, when used by BOOTROM */ 20099be88e75SGabriel Fernandez pll4_bootrom = stm32mp1_clk_is_pll4_used_by_bootrom(priv, usbphy_p); 20109be88e75SGabriel Fernandez #endif 20119be88e75SGabriel Fernandez 20129be88e75SGabriel Fernandez /* 20139be88e75SGabriel Fernandez * Switch ON oscillators found in device-tree. 20149be88e75SGabriel Fernandez * Note: HSI already ON after BootROM stage. 20159be88e75SGabriel Fernandez */ 20169be88e75SGabriel Fernandez stm32_clk_oscillators_enable(priv); 20179be88e75SGabriel Fernandez 20189be88e75SGabriel Fernandez /* Come back to HSI */ 20199be88e75SGabriel Fernandez ret = stm32mp1_come_back_to_hsi(); 20209be88e75SGabriel Fernandez if (ret != 0) { 20219be88e75SGabriel Fernandez return ret; 20229be88e75SGabriel Fernandez } 20239be88e75SGabriel Fernandez 20249be88e75SGabriel Fernandez ret = stm32_clk_hsidiv_configure(priv); 20259be88e75SGabriel Fernandez if (ret != 0) { 20269be88e75SGabriel Fernandez return ret; 20279be88e75SGabriel Fernandez } 20289be88e75SGabriel Fernandez 20299be88e75SGabriel Fernandez ret = stm32_clk_stgen_configure(priv, _STGENC); 20309be88e75SGabriel Fernandez if (ret != 0) { 20319be88e75SGabriel Fernandez panic(); 20329be88e75SGabriel Fernandez } 20339be88e75SGabriel Fernandez 20349be88e75SGabriel Fernandez ret = stm32_clk_dividers_configure(priv); 20359be88e75SGabriel Fernandez if (ret != 0) { 20369be88e75SGabriel Fernandez panic(); 20379be88e75SGabriel Fernandez } 20389be88e75SGabriel Fernandez 20399be88e75SGabriel Fernandez ret = stm32_clk_pll_configure(priv); 20409be88e75SGabriel Fernandez if (ret != 0) { 20419be88e75SGabriel Fernandez panic(); 20429be88e75SGabriel Fernandez } 20439be88e75SGabriel Fernandez 20449be88e75SGabriel Fernandez /* Wait LSE ready before to use it */ 20459be88e75SGabriel Fernandez ret = stm32_clk_oscillators_wait_lse_ready(priv); 20469be88e75SGabriel Fernandez if (ret != 0) { 20479be88e75SGabriel Fernandez panic(); 20489be88e75SGabriel Fernandez } 20499be88e75SGabriel Fernandez 20509be88e75SGabriel Fernandez /* Configure with expected clock source */ 20519be88e75SGabriel Fernandez ret = stm32_clk_source_configure(priv); 20529be88e75SGabriel Fernandez if (ret != 0) { 20539be88e75SGabriel Fernandez panic(); 20549be88e75SGabriel Fernandez } 20559be88e75SGabriel Fernandez 20569be88e75SGabriel Fernandez /* Configure LSE css after RTC source configuration */ 20579be88e75SGabriel Fernandez ret = stm32_clk_oscillators_lse_set_css(priv); 20589be88e75SGabriel Fernandez if (ret != 0) { 20599be88e75SGabriel Fernandez panic(); 20609be88e75SGabriel Fernandez } 20619be88e75SGabriel Fernandez 20629be88e75SGabriel Fernandez #if STM32MP_USB_PROGRAMMER 20639be88e75SGabriel Fernandez ret = stm32mp1_clk_check_usb_conflict(priv, usbphy_p, usbo_p); 20649be88e75SGabriel Fernandez if (ret != 0) { 20659be88e75SGabriel Fernandez return ret; 20669be88e75SGabriel Fernandez } 20679be88e75SGabriel Fernandez #endif 20689be88e75SGabriel Fernandez /* reconfigure STGEN with DT config */ 20699be88e75SGabriel Fernandez ret = stm32_clk_stgen_configure(priv, _STGENC); 20709be88e75SGabriel Fernandez if (ret != 0) { 20719be88e75SGabriel Fernandez panic(); 20729be88e75SGabriel Fernandez } 20739be88e75SGabriel Fernandez 20749be88e75SGabriel Fernandez /* Software Self-Refresh mode (SSR) during DDR initilialization */ 20759be88e75SGabriel Fernandez mmio_clrsetbits_32(priv->base + RCC_DDRITFCR, 20769be88e75SGabriel Fernandez RCC_DDRITFCR_DDRCKMOD_MASK, 20779be88e75SGabriel Fernandez RCC_DDRITFCR_DDRCKMOD_SSR << 20789be88e75SGabriel Fernandez RCC_DDRITFCR_DDRCKMOD_SHIFT); 20799be88e75SGabriel Fernandez 20809be88e75SGabriel Fernandez return 0; 20819be88e75SGabriel Fernandez } 20829be88e75SGabriel Fernandez 20839be88e75SGabriel Fernandez static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name, 20849be88e75SGabriel Fernandez struct stm32_osci_dt_cfg *osci) 20859be88e75SGabriel Fernandez { 20869be88e75SGabriel Fernandez int subnode = 0; 20879be88e75SGabriel Fernandez 20889be88e75SGabriel Fernandez /* default value oscillator not found, freq=0 */ 20899be88e75SGabriel Fernandez osci->freq = 0; 20909be88e75SGabriel Fernandez 20919be88e75SGabriel Fernandez fdt_for_each_subnode(subnode, fdt, node) { 20929be88e75SGabriel Fernandez const char *cchar = NULL; 20939be88e75SGabriel Fernandez const fdt32_t *cuint = NULL; 20949be88e75SGabriel Fernandez int ret = 0; 20959be88e75SGabriel Fernandez 20969be88e75SGabriel Fernandez cchar = fdt_get_name(fdt, subnode, &ret); 20979be88e75SGabriel Fernandez if (cchar == NULL) { 20989be88e75SGabriel Fernandez return ret; 20999be88e75SGabriel Fernandez } 21009be88e75SGabriel Fernandez 21019be88e75SGabriel Fernandez if (strncmp(cchar, name, (size_t)ret) || 21029be88e75SGabriel Fernandez fdt_get_status(subnode) == DT_DISABLED) { 21039be88e75SGabriel Fernandez continue; 21049be88e75SGabriel Fernandez } 21059be88e75SGabriel Fernandez 21069be88e75SGabriel Fernandez cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret); 21079be88e75SGabriel Fernandez if (cuint == NULL) { 21089be88e75SGabriel Fernandez return ret; 21099be88e75SGabriel Fernandez } 21109be88e75SGabriel Fernandez 21119be88e75SGabriel Fernandez osci->freq = fdt32_to_cpu(*cuint); 21129be88e75SGabriel Fernandez 21139be88e75SGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) { 21149be88e75SGabriel Fernandez osci->bypass = true; 21159be88e75SGabriel Fernandez } 21169be88e75SGabriel Fernandez 21179be88e75SGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) { 21189be88e75SGabriel Fernandez osci->digbyp = true; 21199be88e75SGabriel Fernandez } 21209be88e75SGabriel Fernandez 21219be88e75SGabriel Fernandez if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) { 21229be88e75SGabriel Fernandez osci->css = true; 21239be88e75SGabriel Fernandez } 21249be88e75SGabriel Fernandez 21259be88e75SGabriel Fernandez osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH); 21269be88e75SGabriel Fernandez 21279be88e75SGabriel Fernandez return 0; 21289be88e75SGabriel Fernandez } 21299be88e75SGabriel Fernandez 21309be88e75SGabriel Fernandez return 0; 21319be88e75SGabriel Fernandez } 21329be88e75SGabriel Fernandez 21339be88e75SGabriel Fernandez static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata) 21349be88e75SGabriel Fernandez { 21359be88e75SGabriel Fernandez int fdt_err = 0; 21369be88e75SGabriel Fernandez uint32_t i = 0; 21379be88e75SGabriel Fernandez int node = 0; 21389be88e75SGabriel Fernandez 21399be88e75SGabriel Fernandez node = fdt_path_offset(fdt, "/clocks"); 21409be88e75SGabriel Fernandez if (node < 0) { 21419be88e75SGabriel Fernandez return -FDT_ERR_NOTFOUND; 21429be88e75SGabriel Fernandez } 21439be88e75SGabriel Fernandez 21449be88e75SGabriel Fernandez for (i = 0; i < pdata->nosci; i++) { 21459be88e75SGabriel Fernandez const char *name = NULL; 21469be88e75SGabriel Fernandez 21479be88e75SGabriel Fernandez name = clk_stm32_get_oscillator_name((enum stm32_osc)i); 21489be88e75SGabriel Fernandez if (name == NULL) { 21499be88e75SGabriel Fernandez continue; 21509be88e75SGabriel Fernandez } 21519be88e75SGabriel Fernandez 21529be88e75SGabriel Fernandez fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]); 21539be88e75SGabriel Fernandez if (fdt_err < 0) { 21549be88e75SGabriel Fernandez panic(); 21559be88e75SGabriel Fernandez } 21569be88e75SGabriel Fernandez } 21579be88e75SGabriel Fernandez 21589be88e75SGabriel Fernandez return 0; 21599be88e75SGabriel Fernandez } 21609be88e75SGabriel Fernandez 21619be88e75SGabriel Fernandez #define RCC_PLL_NAME_SIZE 12 21629be88e75SGabriel Fernandez 21639be88e75SGabriel Fernandez static int clk_stm32_load_vco_config(void *fdt, int subnode, struct stm32_pll_vco *vco) 21649be88e75SGabriel Fernandez { 21659be88e75SGabriel Fernandez int err = 0; 21669be88e75SGabriel Fernandez 21679be88e75SGabriel Fernandez err = fdt_read_uint32_array(fdt, subnode, "divmn", (int)PLL_DIV_MN_NB, vco->div_mn); 21689be88e75SGabriel Fernandez if (err != 0) { 21699be88e75SGabriel Fernandez return err; 21709be88e75SGabriel Fernandez } 21719be88e75SGabriel Fernandez 21729be88e75SGabriel Fernandez err = fdt_read_uint32_array(fdt, subnode, "csg", (int)PLL_CSG_NB, vco->csg); 21739be88e75SGabriel Fernandez 21749be88e75SGabriel Fernandez vco->csg_enabled = (err == 0); 21759be88e75SGabriel Fernandez 21769be88e75SGabriel Fernandez if (err == -FDT_ERR_NOTFOUND) { 21779be88e75SGabriel Fernandez err = 0; 21789be88e75SGabriel Fernandez } 21799be88e75SGabriel Fernandez 21809be88e75SGabriel Fernandez if (err != 0) { 21819be88e75SGabriel Fernandez return err; 21829be88e75SGabriel Fernandez } 21839be88e75SGabriel Fernandez 21849be88e75SGabriel Fernandez vco->status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN | RCC_PLLNCR_PLLON; 21859be88e75SGabriel Fernandez 21869be88e75SGabriel Fernandez vco->frac = fdt_read_uint32_default(fdt, subnode, "frac", 0); 21879be88e75SGabriel Fernandez 21889be88e75SGabriel Fernandez vco->src = fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX); 21899be88e75SGabriel Fernandez 21909be88e75SGabriel Fernandez return 0; 21919be88e75SGabriel Fernandez } 21929be88e75SGabriel Fernandez 21939be88e75SGabriel Fernandez static int clk_stm32_load_output_config(void *fdt, int subnode, struct stm32_pll_output *output) 21949be88e75SGabriel Fernandez { 21959be88e75SGabriel Fernandez int err = 0; 21969be88e75SGabriel Fernandez 21979be88e75SGabriel Fernandez err = fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr", (int)PLL_DIV_PQR_NB, 21989be88e75SGabriel Fernandez output->output); 21999be88e75SGabriel Fernandez if (err != 0) { 22009be88e75SGabriel Fernandez return err; 22019be88e75SGabriel Fernandez } 22029be88e75SGabriel Fernandez 22039be88e75SGabriel Fernandez return 0; 22049be88e75SGabriel Fernandez } 22059be88e75SGabriel Fernandez 22069be88e75SGabriel Fernandez static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll) 22079be88e75SGabriel Fernandez { 22089be88e75SGabriel Fernandez const fdt32_t *cuint = NULL; 22099be88e75SGabriel Fernandez int subnode_pll = 0; 22109be88e75SGabriel Fernandez int subnode_vco = 0; 22119be88e75SGabriel Fernandez int err = 0; 22129be88e75SGabriel Fernandez 22139be88e75SGabriel Fernandez cuint = fdt_getprop(fdt, subnode, "st,pll", NULL); 22149be88e75SGabriel Fernandez if (!cuint) { 22159be88e75SGabriel Fernandez return -FDT_ERR_NOTFOUND; 22169be88e75SGabriel Fernandez } 22179be88e75SGabriel Fernandez 22189be88e75SGabriel Fernandez subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); 22199be88e75SGabriel Fernandez if (subnode_pll < 0) { 22209be88e75SGabriel Fernandez return -FDT_ERR_NOTFOUND; 22219be88e75SGabriel Fernandez } 22229be88e75SGabriel Fernandez 22239be88e75SGabriel Fernandez cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL); 22249be88e75SGabriel Fernandez if (!cuint) { 22259be88e75SGabriel Fernandez return -FDT_ERR_NOTFOUND; 22269be88e75SGabriel Fernandez } 22279be88e75SGabriel Fernandez 22289be88e75SGabriel Fernandez subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); 22299be88e75SGabriel Fernandez if (subnode_vco < 0) { 22309be88e75SGabriel Fernandez return -FDT_ERR_NOTFOUND; 22319be88e75SGabriel Fernandez } 22329be88e75SGabriel Fernandez 22339be88e75SGabriel Fernandez err = clk_stm32_load_vco_config(fdt, subnode_vco, &pll->vco); 22349be88e75SGabriel Fernandez if (err != 0) { 22359be88e75SGabriel Fernandez return err; 22369be88e75SGabriel Fernandez } 22379be88e75SGabriel Fernandez 22389be88e75SGabriel Fernandez err = clk_stm32_load_output_config(fdt, subnode_pll, &pll->output); 22399be88e75SGabriel Fernandez if (err != 0) { 22409be88e75SGabriel Fernandez return err; 22419be88e75SGabriel Fernandez } 22429be88e75SGabriel Fernandez 22439be88e75SGabriel Fernandez return 0; 22449be88e75SGabriel Fernandez } 22459be88e75SGabriel Fernandez 22469be88e75SGabriel Fernandez static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata) 22479be88e75SGabriel Fernandez { 22489be88e75SGabriel Fernandez size_t i = 0U; 22499be88e75SGabriel Fernandez 2250f6559227SYann Gautier /* PLL1 is not configurable with device tree */ 2251f6559227SYann Gautier for (i = _PLL2; i < pdata->npll; i++) { 22524198fa1dSYann Gautier struct stm32_pll_dt_cfg *pll = &pdata->pll[i]; 22539be88e75SGabriel Fernandez char name[RCC_PLL_NAME_SIZE]; 22549be88e75SGabriel Fernandez int subnode = 0; 22559be88e75SGabriel Fernandez int err = 0; 22569be88e75SGabriel Fernandez 22579be88e75SGabriel Fernandez snprintf(name, sizeof(name), "st,pll@%u", i); 22589be88e75SGabriel Fernandez 22599be88e75SGabriel Fernandez subnode = fdt_subnode_offset(fdt, node, name); 22609be88e75SGabriel Fernandez if (!fdt_check_node(subnode)) { 22619be88e75SGabriel Fernandez continue; 22629be88e75SGabriel Fernandez } 22639be88e75SGabriel Fernandez 22649be88e75SGabriel Fernandez err = clk_stm32_parse_pll_fdt(fdt, subnode, pll); 22659be88e75SGabriel Fernandez if (err != 0) { 22669be88e75SGabriel Fernandez panic(); 22679be88e75SGabriel Fernandez } 22689be88e75SGabriel Fernandez } 22699be88e75SGabriel Fernandez 22709be88e75SGabriel Fernandez return 0; 22719be88e75SGabriel Fernandez } 22729be88e75SGabriel Fernandez 22739be88e75SGabriel Fernandez static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata) 22749be88e75SGabriel Fernandez { 22759be88e75SGabriel Fernandez void *fdt = NULL; 22769be88e75SGabriel Fernandez int node; 22779be88e75SGabriel Fernandez uint32_t err; 22789be88e75SGabriel Fernandez 22799be88e75SGabriel Fernandez if (fdt_get_address(&fdt) == 0) { 22809be88e75SGabriel Fernandez return -ENOENT; 22819be88e75SGabriel Fernandez } 22829be88e75SGabriel Fernandez 22839be88e75SGabriel Fernandez node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); 22849be88e75SGabriel Fernandez if (node < 0) { 22859be88e75SGabriel Fernandez panic(); 22869be88e75SGabriel Fernandez } 22879be88e75SGabriel Fernandez 22889be88e75SGabriel Fernandez err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata); 22899be88e75SGabriel Fernandez if (err != 0) { 22909be88e75SGabriel Fernandez return err; 22919be88e75SGabriel Fernandez } 22929be88e75SGabriel Fernandez 22939be88e75SGabriel Fernandez err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata); 22949be88e75SGabriel Fernandez if (err != 0) { 22959be88e75SGabriel Fernandez return err; 22969be88e75SGabriel Fernandez } 22979be88e75SGabriel Fernandez 22989be88e75SGabriel Fernandez err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv, &pdata->nclkdiv); 22999be88e75SGabriel Fernandez if (err != 0) { 23009be88e75SGabriel Fernandez return err; 23019be88e75SGabriel Fernandez } 23029be88e75SGabriel Fernandez 23039be88e75SGabriel Fernandez err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc, &pdata->nclksrc); 23049be88e75SGabriel Fernandez if (err != 0) { 23059be88e75SGabriel Fernandez return err; 23069be88e75SGabriel Fernandez } 23079be88e75SGabriel Fernandez 23089be88e75SGabriel Fernandez return 0; 23099be88e75SGabriel Fernandez } 23109be88e75SGabriel Fernandez 23119be88e75SGabriel Fernandez int stm32mp1_clk_init(void) 23129be88e75SGabriel Fernandez { 2313f6559227SYann Gautier int ret; 2314f6559227SYann Gautier 2315f6559227SYann Gautier /* compute the PLL1 settings, not read in device tree */ 2316f6559227SYann Gautier ret = clk_compute_pll1_settings(PLL1_NOMINAL_FREQ_IN_KHZ); 2317f6559227SYann Gautier if (ret != 0) { 2318f6559227SYann Gautier return ret; 2319f6559227SYann Gautier } 2320f6559227SYann Gautier 2321f6559227SYann Gautier ret = stm32mp1_init_clock_tree(); 2322f6559227SYann Gautier if (ret != 0) { 2323f6559227SYann Gautier return ret; 2324f6559227SYann Gautier } 2325f6559227SYann Gautier 2326f6559227SYann Gautier clk_stm32_enable_critical_clocks(); 2327f6559227SYann Gautier 23289be88e75SGabriel Fernandez return 0; 23299be88e75SGabriel Fernandez } 23309be88e75SGabriel Fernandez 23319be88e75SGabriel Fernandez int stm32mp1_clk_probe(void) 23329be88e75SGabriel Fernandez { 23339be88e75SGabriel Fernandez uintptr_t base = RCC_BASE; 23349be88e75SGabriel Fernandez int ret; 23359be88e75SGabriel Fernandez 23369be88e75SGabriel Fernandez ret = stm32_clk_parse_fdt(&stm32mp13_clock_pdata); 23379be88e75SGabriel Fernandez if (ret != 0) { 23389be88e75SGabriel Fernandez return ret; 23399be88e75SGabriel Fernandez } 23409be88e75SGabriel Fernandez 23419be88e75SGabriel Fernandez ret = clk_stm32_init(&stm32mp13_clock_data, base); 2342f6559227SYann Gautier 23439be88e75SGabriel Fernandez return ret; 23449be88e75SGabriel Fernandez } 2345