xref: /openbmc/linux/drivers/clk/clk-stm32mp1.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
19bee94e7SGabriel Fernandez // SPDX-License-Identifier: GPL-2.0
29bee94e7SGabriel Fernandez /*
39bee94e7SGabriel Fernandez  * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
49bee94e7SGabriel Fernandez  * Author: Olivier Bideau <olivier.bideau@st.com> for STMicroelectronics.
59bee94e7SGabriel Fernandez  * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
69bee94e7SGabriel Fernandez  */
79bee94e7SGabriel Fernandez 
89bee94e7SGabriel Fernandez #include <linux/clk.h>
99bee94e7SGabriel Fernandez #include <linux/clk-provider.h>
10c6cf4d32SGabriel Fernandez #include <linux/delay.h>
119bee94e7SGabriel Fernandez #include <linux/err.h>
129bee94e7SGabriel Fernandez #include <linux/io.h>
1395272370SGabriel Fernandez #include <linux/module.h>
149bee94e7SGabriel Fernandez #include <linux/of.h>
159bee94e7SGabriel Fernandez #include <linux/of_address.h>
1695272370SGabriel Fernandez #include <linux/platform_device.h>
17c392df19SGabriel Fernandez #include <linux/reset-controller.h>
189bee94e7SGabriel Fernandez #include <linux/slab.h>
199bee94e7SGabriel Fernandez #include <linux/spinlock.h>
209bee94e7SGabriel Fernandez 
219bee94e7SGabriel Fernandez #include <dt-bindings/clock/stm32mp1-clks.h>
229bee94e7SGabriel Fernandez 
239bee94e7SGabriel Fernandez static DEFINE_SPINLOCK(rlock);
249bee94e7SGabriel Fernandez 
259bee94e7SGabriel Fernandez #define RCC_OCENSETR		0x0C
269bee94e7SGabriel Fernandez #define RCC_HSICFGR		0x18
279bee94e7SGabriel Fernandez #define RCC_RDLSICR		0x144
289bee94e7SGabriel Fernandez #define RCC_PLL1CR		0x80
299bee94e7SGabriel Fernandez #define RCC_PLL1CFGR1		0x84
309bee94e7SGabriel Fernandez #define RCC_PLL1CFGR2		0x88
319bee94e7SGabriel Fernandez #define RCC_PLL2CR		0x94
329bee94e7SGabriel Fernandez #define RCC_PLL2CFGR1		0x98
339bee94e7SGabriel Fernandez #define RCC_PLL2CFGR2		0x9C
349bee94e7SGabriel Fernandez #define RCC_PLL3CR		0x880
359bee94e7SGabriel Fernandez #define RCC_PLL3CFGR1		0x884
369bee94e7SGabriel Fernandez #define RCC_PLL3CFGR2		0x888
379bee94e7SGabriel Fernandez #define RCC_PLL4CR		0x894
389bee94e7SGabriel Fernandez #define RCC_PLL4CFGR1		0x898
399bee94e7SGabriel Fernandez #define RCC_PLL4CFGR2		0x89C
409bee94e7SGabriel Fernandez #define RCC_APB1ENSETR		0xA00
419bee94e7SGabriel Fernandez #define RCC_APB2ENSETR		0xA08
429bee94e7SGabriel Fernandez #define RCC_APB3ENSETR		0xA10
439bee94e7SGabriel Fernandez #define RCC_APB4ENSETR		0x200
449bee94e7SGabriel Fernandez #define RCC_APB5ENSETR		0x208
459bee94e7SGabriel Fernandez #define RCC_AHB2ENSETR		0xA18
469bee94e7SGabriel Fernandez #define RCC_AHB3ENSETR		0xA20
479bee94e7SGabriel Fernandez #define RCC_AHB4ENSETR		0xA28
489bee94e7SGabriel Fernandez #define RCC_AHB5ENSETR		0x210
499bee94e7SGabriel Fernandez #define RCC_AHB6ENSETR		0x218
509bee94e7SGabriel Fernandez #define RCC_AHB6LPENSETR	0x318
519bee94e7SGabriel Fernandez #define RCC_RCK12SELR		0x28
529bee94e7SGabriel Fernandez #define RCC_RCK3SELR		0x820
539bee94e7SGabriel Fernandez #define RCC_RCK4SELR		0x824
549bee94e7SGabriel Fernandez #define RCC_MPCKSELR		0x20
559bee94e7SGabriel Fernandez #define RCC_ASSCKSELR		0x24
569bee94e7SGabriel Fernandez #define RCC_MSSCKSELR		0x48
579bee94e7SGabriel Fernandez #define RCC_SPI6CKSELR		0xC4
589bee94e7SGabriel Fernandez #define RCC_SDMMC12CKSELR	0x8F4
599bee94e7SGabriel Fernandez #define RCC_SDMMC3CKSELR	0x8F8
609bee94e7SGabriel Fernandez #define RCC_FMCCKSELR		0x904
619bee94e7SGabriel Fernandez #define RCC_I2C46CKSELR		0xC0
629bee94e7SGabriel Fernandez #define RCC_I2C12CKSELR		0x8C0
639bee94e7SGabriel Fernandez #define RCC_I2C35CKSELR		0x8C4
649bee94e7SGabriel Fernandez #define RCC_UART1CKSELR		0xC8
659bee94e7SGabriel Fernandez #define RCC_QSPICKSELR		0x900
669bee94e7SGabriel Fernandez #define RCC_ETHCKSELR		0x8FC
679bee94e7SGabriel Fernandez #define RCC_RNG1CKSELR		0xCC
689bee94e7SGabriel Fernandez #define RCC_RNG2CKSELR		0x920
699bee94e7SGabriel Fernandez #define RCC_GPUCKSELR		0x938
709bee94e7SGabriel Fernandez #define RCC_USBCKSELR		0x91C
719bee94e7SGabriel Fernandez #define RCC_STGENCKSELR		0xD4
729bee94e7SGabriel Fernandez #define RCC_SPDIFCKSELR		0x914
739bee94e7SGabriel Fernandez #define RCC_SPI2S1CKSELR	0x8D8
749bee94e7SGabriel Fernandez #define RCC_SPI2S23CKSELR	0x8DC
759bee94e7SGabriel Fernandez #define RCC_SPI2S45CKSELR	0x8E0
769bee94e7SGabriel Fernandez #define RCC_CECCKSELR		0x918
779bee94e7SGabriel Fernandez #define RCC_LPTIM1CKSELR	0x934
789bee94e7SGabriel Fernandez #define RCC_LPTIM23CKSELR	0x930
799bee94e7SGabriel Fernandez #define RCC_LPTIM45CKSELR	0x92C
809bee94e7SGabriel Fernandez #define RCC_UART24CKSELR	0x8E8
819bee94e7SGabriel Fernandez #define RCC_UART35CKSELR	0x8EC
829bee94e7SGabriel Fernandez #define RCC_UART6CKSELR		0x8E4
839bee94e7SGabriel Fernandez #define RCC_UART78CKSELR	0x8F0
849bee94e7SGabriel Fernandez #define RCC_FDCANCKSELR		0x90C
859bee94e7SGabriel Fernandez #define RCC_SAI1CKSELR		0x8C8
869bee94e7SGabriel Fernandez #define RCC_SAI2CKSELR		0x8CC
879bee94e7SGabriel Fernandez #define RCC_SAI3CKSELR		0x8D0
889bee94e7SGabriel Fernandez #define RCC_SAI4CKSELR		0x8D4
899bee94e7SGabriel Fernandez #define RCC_ADCCKSELR		0x928
909bee94e7SGabriel Fernandez #define RCC_MPCKDIVR		0x2C
919bee94e7SGabriel Fernandez #define RCC_DSICKSELR		0x924
929bee94e7SGabriel Fernandez #define RCC_CPERCKSELR		0xD0
939bee94e7SGabriel Fernandez #define RCC_MCO1CFGR		0x800
949bee94e7SGabriel Fernandez #define RCC_MCO2CFGR		0x804
959bee94e7SGabriel Fernandez #define RCC_BDCR		0x140
969bee94e7SGabriel Fernandez #define RCC_AXIDIVR		0x30
979bee94e7SGabriel Fernandez #define RCC_MCUDIVR		0x830
989bee94e7SGabriel Fernandez #define RCC_APB1DIVR		0x834
999bee94e7SGabriel Fernandez #define RCC_APB2DIVR		0x838
1009bee94e7SGabriel Fernandez #define RCC_APB3DIVR		0x83C
1019bee94e7SGabriel Fernandez #define RCC_APB4DIVR		0x3C
1029bee94e7SGabriel Fernandez #define RCC_APB5DIVR		0x40
1039bee94e7SGabriel Fernandez #define RCC_TIMG1PRER		0x828
1049bee94e7SGabriel Fernandez #define RCC_TIMG2PRER		0x82C
1059bee94e7SGabriel Fernandez #define RCC_RTCDIVR		0x44
1069bee94e7SGabriel Fernandez #define RCC_DBGCFGR		0x80C
1079bee94e7SGabriel Fernandez 
1089bee94e7SGabriel Fernandez #define RCC_CLR	0x4
1099bee94e7SGabriel Fernandez 
110dc32eaacSGabriel Fernandez static const char * const ref12_parents[] = {
111dc32eaacSGabriel Fernandez 	"ck_hsi", "ck_hse"
112dc32eaacSGabriel Fernandez };
113dc32eaacSGabriel Fernandez 
114dc32eaacSGabriel Fernandez static const char * const ref3_parents[] = {
115dc32eaacSGabriel Fernandez 	"ck_hsi", "ck_hse", "ck_csi"
116dc32eaacSGabriel Fernandez };
117dc32eaacSGabriel Fernandez 
118dc32eaacSGabriel Fernandez static const char * const ref4_parents[] = {
119dc32eaacSGabriel Fernandez 	"ck_hsi", "ck_hse", "ck_csi"
120dc32eaacSGabriel Fernandez };
121dc32eaacSGabriel Fernandez 
122e51d297eSGabriel Fernandez static const char * const cpu_src[] = {
123e51d297eSGabriel Fernandez 	"ck_hsi", "ck_hse", "pll1_p"
124e51d297eSGabriel Fernandez };
125e51d297eSGabriel Fernandez 
126e51d297eSGabriel Fernandez static const char * const axi_src[] = {
127749c9e55SGabriel Fernandez 	"ck_hsi", "ck_hse", "pll2_p"
128e51d297eSGabriel Fernandez };
129e51d297eSGabriel Fernandez 
130e51d297eSGabriel Fernandez static const char * const per_src[] = {
131e51d297eSGabriel Fernandez 	"ck_hsi", "ck_csi", "ck_hse"
132e51d297eSGabriel Fernandez };
133e51d297eSGabriel Fernandez 
134e51d297eSGabriel Fernandez static const char * const mcu_src[] = {
135e51d297eSGabriel Fernandez 	"ck_hsi", "ck_hse", "ck_csi", "pll3_p"
136e51d297eSGabriel Fernandez };
137e51d297eSGabriel Fernandez 
1381f80590bSGabriel Fernandez static const char * const sdmmc12_src[] = {
1391f80590bSGabriel Fernandez 	"ck_axi", "pll3_r", "pll4_p", "ck_hsi"
1401f80590bSGabriel Fernandez };
1411f80590bSGabriel Fernandez 
1421f80590bSGabriel Fernandez static const char * const sdmmc3_src[] = {
1431f80590bSGabriel Fernandez 	"ck_mcu", "pll3_r", "pll4_p", "ck_hsi"
1441f80590bSGabriel Fernandez };
1451f80590bSGabriel Fernandez 
1461f80590bSGabriel Fernandez static const char * const fmc_src[] = {
1471f80590bSGabriel Fernandez 	"ck_axi", "pll3_r", "pll4_p", "ck_per"
1481f80590bSGabriel Fernandez };
1491f80590bSGabriel Fernandez 
1501f80590bSGabriel Fernandez static const char * const qspi_src[] = {
1511f80590bSGabriel Fernandez 	"ck_axi", "pll3_r", "pll4_p", "ck_per"
1521f80590bSGabriel Fernandez };
1531f80590bSGabriel Fernandez 
1541f80590bSGabriel Fernandez static const char * const eth_src[] = {
1551f80590bSGabriel Fernandez 	"pll4_p", "pll3_q"
1561f80590bSGabriel Fernandez };
1571f80590bSGabriel Fernandez 
158e79d0a43SMarek Vasut static const struct clk_parent_data ethrx_src[] = {
159e9ed1ef1SMarek Vasut 	{ .name = "ethck_k", .fw_name = "ETH_RX_CLK/ETH_REF_CLK" },
160e9ed1ef1SMarek Vasut };
161e9ed1ef1SMarek Vasut 
1621f80590bSGabriel Fernandez static const char * const rng_src[] = {
1631f80590bSGabriel Fernandez 	"ck_csi", "pll4_r", "ck_lse", "ck_lsi"
1641f80590bSGabriel Fernandez };
1651f80590bSGabriel Fernandez 
1661f80590bSGabriel Fernandez static const char * const usbphy_src[] = {
1671f80590bSGabriel Fernandez 	"ck_hse", "pll4_r", "clk-hse-div2"
1681f80590bSGabriel Fernandez };
1691f80590bSGabriel Fernandez 
1701f80590bSGabriel Fernandez static const char * const usbo_src[] = {
1711f80590bSGabriel Fernandez 	"pll4_r", "ck_usbo_48m"
1721f80590bSGabriel Fernandez };
1731f80590bSGabriel Fernandez 
1741f80590bSGabriel Fernandez static const char * const stgen_src[] = {
1751f80590bSGabriel Fernandez 	"ck_hsi", "ck_hse"
1761f80590bSGabriel Fernandez };
1771f80590bSGabriel Fernandez 
1781f80590bSGabriel Fernandez static const char * const spdif_src[] = {
1791f80590bSGabriel Fernandez 	"pll4_p", "pll3_q", "ck_hsi"
1801f80590bSGabriel Fernandez };
1811f80590bSGabriel Fernandez 
1821f80590bSGabriel Fernandez static const char * const spi123_src[] = {
1831f80590bSGabriel Fernandez 	"pll4_p", "pll3_q", "i2s_ckin", "ck_per", "pll3_r"
1841f80590bSGabriel Fernandez };
1851f80590bSGabriel Fernandez 
1861f80590bSGabriel Fernandez static const char * const spi45_src[] = {
1871f80590bSGabriel Fernandez 	"pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
1881f80590bSGabriel Fernandez };
1891f80590bSGabriel Fernandez 
1901f80590bSGabriel Fernandez static const char * const spi6_src[] = {
1911f80590bSGabriel Fernandez 	"pclk5", "pll4_q", "ck_hsi", "ck_csi", "ck_hse", "pll3_q"
1921f80590bSGabriel Fernandez };
1931f80590bSGabriel Fernandez 
1941f80590bSGabriel Fernandez static const char * const cec_src[] = {
1951f80590bSGabriel Fernandez 	"ck_lse", "ck_lsi", "ck_csi"
1961f80590bSGabriel Fernandez };
1971f80590bSGabriel Fernandez 
1981f80590bSGabriel Fernandez static const char * const i2c12_src[] = {
1991f80590bSGabriel Fernandez 	"pclk1", "pll4_r", "ck_hsi", "ck_csi"
2001f80590bSGabriel Fernandez };
2011f80590bSGabriel Fernandez 
2021f80590bSGabriel Fernandez static const char * const i2c35_src[] = {
2031f80590bSGabriel Fernandez 	"pclk1", "pll4_r", "ck_hsi", "ck_csi"
2041f80590bSGabriel Fernandez };
2051f80590bSGabriel Fernandez 
2061f80590bSGabriel Fernandez static const char * const i2c46_src[] = {
2071f80590bSGabriel Fernandez 	"pclk5", "pll3_q", "ck_hsi", "ck_csi"
2081f80590bSGabriel Fernandez };
2091f80590bSGabriel Fernandez 
2101f80590bSGabriel Fernandez static const char * const lptim1_src[] = {
2111f80590bSGabriel Fernandez 	"pclk1", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
2121f80590bSGabriel Fernandez };
2131f80590bSGabriel Fernandez 
2141f80590bSGabriel Fernandez static const char * const lptim23_src[] = {
2151f80590bSGabriel Fernandez 	"pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi"
2161f80590bSGabriel Fernandez };
2171f80590bSGabriel Fernandez 
2181f80590bSGabriel Fernandez static const char * const lptim45_src[] = {
2191f80590bSGabriel Fernandez 	"pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
2201f80590bSGabriel Fernandez };
2211f80590bSGabriel Fernandez 
2221f80590bSGabriel Fernandez static const char * const usart1_src[] = {
2231f80590bSGabriel Fernandez 	"pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse"
2241f80590bSGabriel Fernandez };
2251f80590bSGabriel Fernandez 
226e631ad60SGabriel Fernandez static const char * const usart234578_src[] = {
2271f80590bSGabriel Fernandez 	"pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
2281f80590bSGabriel Fernandez };
2291f80590bSGabriel Fernandez 
2301f80590bSGabriel Fernandez static const char * const usart6_src[] = {
2311f80590bSGabriel Fernandez 	"pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
2321f80590bSGabriel Fernandez };
2331f80590bSGabriel Fernandez 
2341f80590bSGabriel Fernandez static const char * const fdcan_src[] = {
235749c9e55SGabriel Fernandez 	"ck_hse", "pll3_q", "pll4_q", "pll4_r"
2361f80590bSGabriel Fernandez };
2371f80590bSGabriel Fernandez 
2381f80590bSGabriel Fernandez static const char * const sai_src[] = {
239749c9e55SGabriel Fernandez 	"pll4_q", "pll3_q", "i2s_ckin", "ck_per", "pll3_r"
2401f80590bSGabriel Fernandez };
2411f80590bSGabriel Fernandez 
2421f80590bSGabriel Fernandez static const char * const sai2_src[] = {
243749c9e55SGabriel Fernandez 	"pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb", "pll3_r"
2441f80590bSGabriel Fernandez };
2451f80590bSGabriel Fernandez 
2461f80590bSGabriel Fernandez static const char * const adc12_src[] = {
247749c9e55SGabriel Fernandez 	"pll4_r", "ck_per", "pll3_q"
2481f80590bSGabriel Fernandez };
2491f80590bSGabriel Fernandez 
2501f80590bSGabriel Fernandez static const char * const dsi_src[] = {
2511f80590bSGabriel Fernandez 	"ck_dsi_phy", "pll4_p"
2521f80590bSGabriel Fernandez };
2531f80590bSGabriel Fernandez 
2542c87c9d3SGabriel Fernandez static const char * const rtc_src[] = {
255152efe56SGabriel Fernandez 	"off", "ck_lse", "ck_lsi", "ck_hse"
2562c87c9d3SGabriel Fernandez };
2572c87c9d3SGabriel Fernandez 
25844cd455aSGabriel Fernandez static const char * const mco1_src[] = {
25944cd455aSGabriel Fernandez 	"ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse"
26044cd455aSGabriel Fernandez };
26144cd455aSGabriel Fernandez 
26244cd455aSGabriel Fernandez static const char * const mco2_src[] = {
26344cd455aSGabriel Fernandez 	"ck_mpu", "ck_axi", "ck_mcu", "pll4_p", "ck_hse", "ck_hsi"
26444cd455aSGabriel Fernandez };
26544cd455aSGabriel Fernandez 
2663a430067SGabriel Fernandez static const char * const ck_trace_src[] = {
2673a430067SGabriel Fernandez 	"ck_axi"
2683a430067SGabriel Fernandez };
2693a430067SGabriel Fernandez 
270e51d297eSGabriel Fernandez static const struct clk_div_table axi_div_table[] = {
271e51d297eSGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
272e51d297eSGabriel Fernandez 	{ 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
273e51d297eSGabriel Fernandez 	{ 0 },
274e51d297eSGabriel Fernandez };
275e51d297eSGabriel Fernandez 
276e51d297eSGabriel Fernandez static const struct clk_div_table mcu_div_table[] = {
277e51d297eSGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
278e51d297eSGabriel Fernandez 	{ 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
279140fc4e4SGabriel Fernandez 	{ 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 },
280e51d297eSGabriel Fernandez 	{ 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
281e51d297eSGabriel Fernandez 	{ 0 },
282e51d297eSGabriel Fernandez };
283e51d297eSGabriel Fernandez 
284e51d297eSGabriel Fernandez static const struct clk_div_table apb_div_table[] = {
285e51d297eSGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
286e51d297eSGabriel Fernandez 	{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
287e51d297eSGabriel Fernandez 	{ 0 },
288e51d297eSGabriel Fernandez };
289e51d297eSGabriel Fernandez 
2903a430067SGabriel Fernandez static const struct clk_div_table ck_trace_div_table[] = {
2913a430067SGabriel Fernandez 	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
2923a430067SGabriel Fernandez 	{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
2933a430067SGabriel Fernandez 	{ 0 },
2943a430067SGabriel Fernandez };
2953a430067SGabriel Fernandez 
2961f80590bSGabriel Fernandez #define MAX_MUX_CLK 2
2971f80590bSGabriel Fernandez 
2981f80590bSGabriel Fernandez struct stm32_mmux {
2991f80590bSGabriel Fernandez 	u8 nbr_clk;
3001f80590bSGabriel Fernandez 	struct clk_hw *hws[MAX_MUX_CLK];
3011f80590bSGabriel Fernandez };
3021f80590bSGabriel Fernandez 
3031f80590bSGabriel Fernandez struct stm32_clk_mmux {
3041f80590bSGabriel Fernandez 	struct clk_mux mux;
3051f80590bSGabriel Fernandez 	struct stm32_mmux *mmux;
3061f80590bSGabriel Fernandez };
3071f80590bSGabriel Fernandez 
3081f80590bSGabriel Fernandez struct stm32_mgate {
3091f80590bSGabriel Fernandez 	u8 nbr_clk;
3101f80590bSGabriel Fernandez 	u32 flag;
3111f80590bSGabriel Fernandez };
3121f80590bSGabriel Fernandez 
3131f80590bSGabriel Fernandez struct stm32_clk_mgate {
3141f80590bSGabriel Fernandez 	struct clk_gate gate;
3151f80590bSGabriel Fernandez 	struct stm32_mgate *mgate;
3161f80590bSGabriel Fernandez 	u32 mask;
3171f80590bSGabriel Fernandez };
3181f80590bSGabriel Fernandez 
3199bee94e7SGabriel Fernandez struct clock_config {
3209bee94e7SGabriel Fernandez 	u32 id;
3219bee94e7SGabriel Fernandez 	const char *name;
3229bee94e7SGabriel Fernandez 	const char *parent_name;
3239bee94e7SGabriel Fernandez 	const char * const *parent_names;
324e9ed1ef1SMarek Vasut 	const struct clk_parent_data *parent_data;
3259bee94e7SGabriel Fernandez 	int num_parents;
3269bee94e7SGabriel Fernandez 	unsigned long flags;
3279bee94e7SGabriel Fernandez 	void *cfg;
3289bee94e7SGabriel Fernandez 	struct clk_hw * (*func)(struct device *dev,
3299bee94e7SGabriel Fernandez 				struct clk_hw_onecell_data *clk_data,
3309bee94e7SGabriel Fernandez 				void __iomem *base, spinlock_t *lock,
3319bee94e7SGabriel Fernandez 				const struct clock_config *cfg);
3329bee94e7SGabriel Fernandez };
3339bee94e7SGabriel Fernandez 
3349bee94e7SGabriel Fernandez #define NO_ID ~0
3359bee94e7SGabriel Fernandez 
3369bee94e7SGabriel Fernandez struct gate_cfg {
3379bee94e7SGabriel Fernandez 	u32 reg_off;
3389bee94e7SGabriel Fernandez 	u8 bit_idx;
3399bee94e7SGabriel Fernandez 	u8 gate_flags;
3409bee94e7SGabriel Fernandez };
3419bee94e7SGabriel Fernandez 
3429bee94e7SGabriel Fernandez struct fixed_factor_cfg {
3439bee94e7SGabriel Fernandez 	unsigned int mult;
3449bee94e7SGabriel Fernandez 	unsigned int div;
3459bee94e7SGabriel Fernandez };
3469bee94e7SGabriel Fernandez 
3479bee94e7SGabriel Fernandez struct div_cfg {
3489bee94e7SGabriel Fernandez 	u32 reg_off;
3499bee94e7SGabriel Fernandez 	u8 shift;
3509bee94e7SGabriel Fernandez 	u8 width;
3519bee94e7SGabriel Fernandez 	u8 div_flags;
3529bee94e7SGabriel Fernandez 	const struct clk_div_table *table;
3539bee94e7SGabriel Fernandez };
3549bee94e7SGabriel Fernandez 
355dc32eaacSGabriel Fernandez struct mux_cfg {
356dc32eaacSGabriel Fernandez 	u32 reg_off;
357dc32eaacSGabriel Fernandez 	u8 shift;
358dc32eaacSGabriel Fernandez 	u8 width;
359dc32eaacSGabriel Fernandez 	u8 mux_flags;
360dc32eaacSGabriel Fernandez 	u32 *table;
361dc32eaacSGabriel Fernandez };
362dc32eaacSGabriel Fernandez 
3638e6c27c0SGabriel Fernandez struct stm32_gate_cfg {
3648e6c27c0SGabriel Fernandez 	struct gate_cfg		*gate;
3651f80590bSGabriel Fernandez 	struct stm32_mgate	*mgate;
3668e6c27c0SGabriel Fernandez 	const struct clk_ops	*ops;
3678e6c27c0SGabriel Fernandez };
3688e6c27c0SGabriel Fernandez 
369a97703c5SGabriel Fernandez struct stm32_div_cfg {
370a97703c5SGabriel Fernandez 	struct div_cfg		*div;
371a97703c5SGabriel Fernandez 	const struct clk_ops	*ops;
372a97703c5SGabriel Fernandez };
373a97703c5SGabriel Fernandez 
374a97703c5SGabriel Fernandez struct stm32_mux_cfg {
375a97703c5SGabriel Fernandez 	struct mux_cfg		*mux;
3761f80590bSGabriel Fernandez 	struct stm32_mmux	*mmux;
377a97703c5SGabriel Fernandez 	const struct clk_ops	*ops;
378a97703c5SGabriel Fernandez };
379a97703c5SGabriel Fernandez 
380a97703c5SGabriel Fernandez /* STM32 Composite clock */
381a97703c5SGabriel Fernandez struct stm32_composite_cfg {
382a97703c5SGabriel Fernandez 	const struct stm32_gate_cfg	*gate;
383a97703c5SGabriel Fernandez 	const struct stm32_div_cfg	*div;
384a97703c5SGabriel Fernandez 	const struct stm32_mux_cfg	*mux;
385a97703c5SGabriel Fernandez };
386a97703c5SGabriel Fernandez 
3879bee94e7SGabriel Fernandez static struct clk_hw *
_clk_hw_register_gate(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)3889bee94e7SGabriel Fernandez _clk_hw_register_gate(struct device *dev,
3899bee94e7SGabriel Fernandez 		      struct clk_hw_onecell_data *clk_data,
3909bee94e7SGabriel Fernandez 		      void __iomem *base, spinlock_t *lock,
3919bee94e7SGabriel Fernandez 		      const struct clock_config *cfg)
3929bee94e7SGabriel Fernandez {
3939bee94e7SGabriel Fernandez 	struct gate_cfg *gate_cfg = cfg->cfg;
3949bee94e7SGabriel Fernandez 
3959bee94e7SGabriel Fernandez 	return clk_hw_register_gate(dev,
3969bee94e7SGabriel Fernandez 				    cfg->name,
3979bee94e7SGabriel Fernandez 				    cfg->parent_name,
3989bee94e7SGabriel Fernandez 				    cfg->flags,
3999bee94e7SGabriel Fernandez 				    gate_cfg->reg_off + base,
4009bee94e7SGabriel Fernandez 				    gate_cfg->bit_idx,
4019bee94e7SGabriel Fernandez 				    gate_cfg->gate_flags,
4029bee94e7SGabriel Fernandez 				    lock);
4039bee94e7SGabriel Fernandez }
4049bee94e7SGabriel Fernandez 
4059bee94e7SGabriel Fernandez static struct clk_hw *
_clk_hw_register_fixed_factor(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)4069bee94e7SGabriel Fernandez _clk_hw_register_fixed_factor(struct device *dev,
4079bee94e7SGabriel Fernandez 			      struct clk_hw_onecell_data *clk_data,
4089bee94e7SGabriel Fernandez 			      void __iomem *base, spinlock_t *lock,
4099bee94e7SGabriel Fernandez 			      const struct clock_config *cfg)
4109bee94e7SGabriel Fernandez {
4119bee94e7SGabriel Fernandez 	struct fixed_factor_cfg *ff_cfg = cfg->cfg;
4129bee94e7SGabriel Fernandez 
4139bee94e7SGabriel Fernandez 	return clk_hw_register_fixed_factor(dev, cfg->name, cfg->parent_name,
4149bee94e7SGabriel Fernandez 					    cfg->flags, ff_cfg->mult,
4159bee94e7SGabriel Fernandez 					    ff_cfg->div);
4169bee94e7SGabriel Fernandez }
4179bee94e7SGabriel Fernandez 
4189bee94e7SGabriel Fernandez static struct clk_hw *
_clk_hw_register_divider_table(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)4199bee94e7SGabriel Fernandez _clk_hw_register_divider_table(struct device *dev,
4209bee94e7SGabriel Fernandez 			       struct clk_hw_onecell_data *clk_data,
4219bee94e7SGabriel Fernandez 			       void __iomem *base, spinlock_t *lock,
4229bee94e7SGabriel Fernandez 			       const struct clock_config *cfg)
4239bee94e7SGabriel Fernandez {
4249bee94e7SGabriel Fernandez 	struct div_cfg *div_cfg = cfg->cfg;
4259bee94e7SGabriel Fernandez 
4269bee94e7SGabriel Fernandez 	return clk_hw_register_divider_table(dev,
4279bee94e7SGabriel Fernandez 					     cfg->name,
4289bee94e7SGabriel Fernandez 					     cfg->parent_name,
4299bee94e7SGabriel Fernandez 					     cfg->flags,
4309bee94e7SGabriel Fernandez 					     div_cfg->reg_off + base,
4319bee94e7SGabriel Fernandez 					     div_cfg->shift,
4329bee94e7SGabriel Fernandez 					     div_cfg->width,
4339bee94e7SGabriel Fernandez 					     div_cfg->div_flags,
4349bee94e7SGabriel Fernandez 					     div_cfg->table,
4359bee94e7SGabriel Fernandez 					     lock);
4369bee94e7SGabriel Fernandez }
4379bee94e7SGabriel Fernandez 
438dc32eaacSGabriel Fernandez static struct clk_hw *
_clk_hw_register_mux(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)439dc32eaacSGabriel Fernandez _clk_hw_register_mux(struct device *dev,
440dc32eaacSGabriel Fernandez 		     struct clk_hw_onecell_data *clk_data,
441dc32eaacSGabriel Fernandez 		     void __iomem *base, spinlock_t *lock,
442dc32eaacSGabriel Fernandez 		     const struct clock_config *cfg)
443dc32eaacSGabriel Fernandez {
444dc32eaacSGabriel Fernandez 	struct mux_cfg *mux_cfg = cfg->cfg;
445dc32eaacSGabriel Fernandez 
446dc32eaacSGabriel Fernandez 	return clk_hw_register_mux(dev, cfg->name, cfg->parent_names,
447dc32eaacSGabriel Fernandez 				   cfg->num_parents, cfg->flags,
448dc32eaacSGabriel Fernandez 				   mux_cfg->reg_off + base, mux_cfg->shift,
449dc32eaacSGabriel Fernandez 				   mux_cfg->width, mux_cfg->mux_flags, lock);
450dc32eaacSGabriel Fernandez }
451dc32eaacSGabriel Fernandez 
4528e6c27c0SGabriel Fernandez /* MP1 Gate clock with set & clear registers */
4538e6c27c0SGabriel Fernandez 
mp1_gate_clk_enable(struct clk_hw * hw)4548e6c27c0SGabriel Fernandez static int mp1_gate_clk_enable(struct clk_hw *hw)
4558e6c27c0SGabriel Fernandez {
4568e6c27c0SGabriel Fernandez 	if (!clk_gate_ops.is_enabled(hw))
4578e6c27c0SGabriel Fernandez 		clk_gate_ops.enable(hw);
4588e6c27c0SGabriel Fernandez 
4598e6c27c0SGabriel Fernandez 	return 0;
4608e6c27c0SGabriel Fernandez }
4618e6c27c0SGabriel Fernandez 
mp1_gate_clk_disable(struct clk_hw * hw)4628e6c27c0SGabriel Fernandez static void mp1_gate_clk_disable(struct clk_hw *hw)
4638e6c27c0SGabriel Fernandez {
4648e6c27c0SGabriel Fernandez 	struct clk_gate *gate = to_clk_gate(hw);
4658e6c27c0SGabriel Fernandez 	unsigned long flags = 0;
4668e6c27c0SGabriel Fernandez 
4678e6c27c0SGabriel Fernandez 	if (clk_gate_ops.is_enabled(hw)) {
4688e6c27c0SGabriel Fernandez 		spin_lock_irqsave(gate->lock, flags);
4698e6c27c0SGabriel Fernandez 		writel_relaxed(BIT(gate->bit_idx), gate->reg + RCC_CLR);
4708e6c27c0SGabriel Fernandez 		spin_unlock_irqrestore(gate->lock, flags);
4718e6c27c0SGabriel Fernandez 	}
4728e6c27c0SGabriel Fernandez }
4738e6c27c0SGabriel Fernandez 
474e631ad60SGabriel Fernandez static const struct clk_ops mp1_gate_clk_ops = {
4758e6c27c0SGabriel Fernandez 	.enable		= mp1_gate_clk_enable,
4768e6c27c0SGabriel Fernandez 	.disable	= mp1_gate_clk_disable,
4778e6c27c0SGabriel Fernandez 	.is_enabled	= clk_gate_is_enabled,
4788e6c27c0SGabriel Fernandez };
4798e6c27c0SGabriel Fernandez 
_get_stm32_mux(struct device * dev,void __iomem * base,const struct stm32_mux_cfg * cfg,spinlock_t * lock)48095272370SGabriel Fernandez static struct clk_hw *_get_stm32_mux(struct device *dev, void __iomem *base,
481a97703c5SGabriel Fernandez 				     const struct stm32_mux_cfg *cfg,
482a97703c5SGabriel Fernandez 				     spinlock_t *lock)
483a97703c5SGabriel Fernandez {
4841f80590bSGabriel Fernandez 	struct stm32_clk_mmux *mmux;
485a97703c5SGabriel Fernandez 	struct clk_mux *mux;
486a97703c5SGabriel Fernandez 	struct clk_hw *mux_hw;
487a97703c5SGabriel Fernandez 
4881f80590bSGabriel Fernandez 	if (cfg->mmux) {
48995272370SGabriel Fernandez 		mmux = devm_kzalloc(dev, sizeof(*mmux), GFP_KERNEL);
4901f80590bSGabriel Fernandez 		if (!mmux)
4911f80590bSGabriel Fernandez 			return ERR_PTR(-ENOMEM);
4921f80590bSGabriel Fernandez 
4931f80590bSGabriel Fernandez 		mmux->mux.reg = cfg->mux->reg_off + base;
4941f80590bSGabriel Fernandez 		mmux->mux.shift = cfg->mux->shift;
4951f80590bSGabriel Fernandez 		mmux->mux.mask = (1 << cfg->mux->width) - 1;
4961f80590bSGabriel Fernandez 		mmux->mux.flags = cfg->mux->mux_flags;
4971f80590bSGabriel Fernandez 		mmux->mux.table = cfg->mux->table;
4981f80590bSGabriel Fernandez 		mmux->mux.lock = lock;
4991f80590bSGabriel Fernandez 		mmux->mmux = cfg->mmux;
5001f80590bSGabriel Fernandez 		mux_hw = &mmux->mux.hw;
5011f80590bSGabriel Fernandez 		cfg->mmux->hws[cfg->mmux->nbr_clk++] = mux_hw;
5021f80590bSGabriel Fernandez 
5031f80590bSGabriel Fernandez 	} else {
50495272370SGabriel Fernandez 		mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
505a97703c5SGabriel Fernandez 		if (!mux)
506a97703c5SGabriel Fernandez 			return ERR_PTR(-ENOMEM);
507a97703c5SGabriel Fernandez 
508a97703c5SGabriel Fernandez 		mux->reg = cfg->mux->reg_off + base;
509a97703c5SGabriel Fernandez 		mux->shift = cfg->mux->shift;
510a97703c5SGabriel Fernandez 		mux->mask = (1 << cfg->mux->width) - 1;
511a97703c5SGabriel Fernandez 		mux->flags = cfg->mux->mux_flags;
512a97703c5SGabriel Fernandez 		mux->table = cfg->mux->table;
513a97703c5SGabriel Fernandez 		mux->lock = lock;
514a97703c5SGabriel Fernandez 		mux_hw = &mux->hw;
5151f80590bSGabriel Fernandez 	}
516a97703c5SGabriel Fernandez 
517a97703c5SGabriel Fernandez 	return mux_hw;
518a97703c5SGabriel Fernandez }
519a97703c5SGabriel Fernandez 
_get_stm32_div(struct device * dev,void __iomem * base,const struct stm32_div_cfg * cfg,spinlock_t * lock)52095272370SGabriel Fernandez static struct clk_hw *_get_stm32_div(struct device *dev, void __iomem *base,
521a97703c5SGabriel Fernandez 				     const struct stm32_div_cfg *cfg,
522a97703c5SGabriel Fernandez 				     spinlock_t *lock)
523a97703c5SGabriel Fernandez {
524a97703c5SGabriel Fernandez 	struct clk_divider *div;
525a97703c5SGabriel Fernandez 
52695272370SGabriel Fernandez 	div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
527a97703c5SGabriel Fernandez 
528a97703c5SGabriel Fernandez 	if (!div)
529a97703c5SGabriel Fernandez 		return ERR_PTR(-ENOMEM);
530a97703c5SGabriel Fernandez 
531a97703c5SGabriel Fernandez 	div->reg = cfg->div->reg_off + base;
532a97703c5SGabriel Fernandez 	div->shift = cfg->div->shift;
533a97703c5SGabriel Fernandez 	div->width = cfg->div->width;
534a97703c5SGabriel Fernandez 	div->flags = cfg->div->div_flags;
535a97703c5SGabriel Fernandez 	div->table = cfg->div->table;
536a97703c5SGabriel Fernandez 	div->lock = lock;
537a97703c5SGabriel Fernandez 
538a97703c5SGabriel Fernandez 	return &div->hw;
539a97703c5SGabriel Fernandez }
540a97703c5SGabriel Fernandez 
_get_stm32_gate(struct device * dev,void __iomem * base,const struct stm32_gate_cfg * cfg,spinlock_t * lock)54195272370SGabriel Fernandez static struct clk_hw *_get_stm32_gate(struct device *dev, void __iomem *base,
54295272370SGabriel Fernandez 				      const struct stm32_gate_cfg *cfg,
54395272370SGabriel Fernandez 				      spinlock_t *lock)
5448e6c27c0SGabriel Fernandez {
5451f80590bSGabriel Fernandez 	struct stm32_clk_mgate *mgate;
5468e6c27c0SGabriel Fernandez 	struct clk_gate *gate;
5478e6c27c0SGabriel Fernandez 	struct clk_hw *gate_hw;
5488e6c27c0SGabriel Fernandez 
5491f80590bSGabriel Fernandez 	if (cfg->mgate) {
55095272370SGabriel Fernandez 		mgate = devm_kzalloc(dev, sizeof(*mgate), GFP_KERNEL);
5511f80590bSGabriel Fernandez 		if (!mgate)
5521f80590bSGabriel Fernandez 			return ERR_PTR(-ENOMEM);
5531f80590bSGabriel Fernandez 
5541f80590bSGabriel Fernandez 		mgate->gate.reg = cfg->gate->reg_off + base;
5551f80590bSGabriel Fernandez 		mgate->gate.bit_idx = cfg->gate->bit_idx;
5561f80590bSGabriel Fernandez 		mgate->gate.flags = cfg->gate->gate_flags;
5571f80590bSGabriel Fernandez 		mgate->gate.lock = lock;
5581f80590bSGabriel Fernandez 		mgate->mask = BIT(cfg->mgate->nbr_clk++);
5591f80590bSGabriel Fernandez 
5601f80590bSGabriel Fernandez 		mgate->mgate = cfg->mgate;
5611f80590bSGabriel Fernandez 
5621f80590bSGabriel Fernandez 		gate_hw = &mgate->gate.hw;
5631f80590bSGabriel Fernandez 
5641f80590bSGabriel Fernandez 	} else {
56595272370SGabriel Fernandez 		gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
5668e6c27c0SGabriel Fernandez 		if (!gate)
5678e6c27c0SGabriel Fernandez 			return ERR_PTR(-ENOMEM);
5688e6c27c0SGabriel Fernandez 
5698e6c27c0SGabriel Fernandez 		gate->reg = cfg->gate->reg_off + base;
5708e6c27c0SGabriel Fernandez 		gate->bit_idx = cfg->gate->bit_idx;
5718e6c27c0SGabriel Fernandez 		gate->flags = cfg->gate->gate_flags;
5728e6c27c0SGabriel Fernandez 		gate->lock = lock;
5731f80590bSGabriel Fernandez 
5748e6c27c0SGabriel Fernandez 		gate_hw = &gate->hw;
5751f80590bSGabriel Fernandez 	}
5768e6c27c0SGabriel Fernandez 
5778e6c27c0SGabriel Fernandez 	return gate_hw;
5788e6c27c0SGabriel Fernandez }
5798e6c27c0SGabriel Fernandez 
5808e6c27c0SGabriel Fernandez static struct clk_hw *
clk_stm32_register_gate_ops(struct device * dev,const char * name,const char * parent_name,const struct clk_parent_data * parent_data,unsigned long flags,void __iomem * base,const struct stm32_gate_cfg * cfg,spinlock_t * lock)5818e6c27c0SGabriel Fernandez clk_stm32_register_gate_ops(struct device *dev,
5828e6c27c0SGabriel Fernandez 			    const char *name,
5838e6c27c0SGabriel Fernandez 			    const char *parent_name,
584e9ed1ef1SMarek Vasut 			    const struct clk_parent_data *parent_data,
5858e6c27c0SGabriel Fernandez 			    unsigned long flags,
5868e6c27c0SGabriel Fernandez 			    void __iomem *base,
5878e6c27c0SGabriel Fernandez 			    const struct stm32_gate_cfg *cfg,
5888e6c27c0SGabriel Fernandez 			    spinlock_t *lock)
5898e6c27c0SGabriel Fernandez {
5908e6c27c0SGabriel Fernandez 	struct clk_init_data init = { NULL };
5918e6c27c0SGabriel Fernandez 	struct clk_hw *hw;
5928e6c27c0SGabriel Fernandez 	int ret;
5938e6c27c0SGabriel Fernandez 
5948e6c27c0SGabriel Fernandez 	init.name = name;
595e9ed1ef1SMarek Vasut 	if (parent_name)
5968e6c27c0SGabriel Fernandez 		init.parent_names = &parent_name;
597e9ed1ef1SMarek Vasut 	if (parent_data)
598e9ed1ef1SMarek Vasut 		init.parent_data = parent_data;
5998e6c27c0SGabriel Fernandez 	init.num_parents = 1;
6008e6c27c0SGabriel Fernandez 	init.flags = flags;
6018e6c27c0SGabriel Fernandez 
6028e6c27c0SGabriel Fernandez 	init.ops = &clk_gate_ops;
6038e6c27c0SGabriel Fernandez 
6048e6c27c0SGabriel Fernandez 	if (cfg->ops)
6058e6c27c0SGabriel Fernandez 		init.ops = cfg->ops;
6068e6c27c0SGabriel Fernandez 
60795272370SGabriel Fernandez 	hw = _get_stm32_gate(dev, base, cfg, lock);
6088e6c27c0SGabriel Fernandez 	if (IS_ERR(hw))
6098e6c27c0SGabriel Fernandez 		return ERR_PTR(-ENOMEM);
6108e6c27c0SGabriel Fernandez 
6118e6c27c0SGabriel Fernandez 	hw->init = &init;
6128e6c27c0SGabriel Fernandez 
6138e6c27c0SGabriel Fernandez 	ret = clk_hw_register(dev, hw);
614823b68eaSChristophe JAILLET 	if (ret)
6158e6c27c0SGabriel Fernandez 		hw = ERR_PTR(ret);
6168e6c27c0SGabriel Fernandez 
6178e6c27c0SGabriel Fernandez 	return hw;
6188e6c27c0SGabriel Fernandez }
6198e6c27c0SGabriel Fernandez 
620a97703c5SGabriel Fernandez static struct clk_hw *
clk_stm32_register_composite(struct device * dev,const char * name,const char * const * parent_names,const struct clk_parent_data * parent_data,int num_parents,void __iomem * base,const struct stm32_composite_cfg * cfg,unsigned long flags,spinlock_t * lock)621a97703c5SGabriel Fernandez clk_stm32_register_composite(struct device *dev,
622a97703c5SGabriel Fernandez 			     const char *name, const char * const *parent_names,
623e9ed1ef1SMarek Vasut 			     const struct clk_parent_data *parent_data,
624a97703c5SGabriel Fernandez 			     int num_parents, void __iomem *base,
625a97703c5SGabriel Fernandez 			     const struct stm32_composite_cfg *cfg,
626a97703c5SGabriel Fernandez 			     unsigned long flags, spinlock_t *lock)
627a97703c5SGabriel Fernandez {
628a97703c5SGabriel Fernandez 	const struct clk_ops *mux_ops, *div_ops, *gate_ops;
629a97703c5SGabriel Fernandez 	struct clk_hw *mux_hw, *div_hw, *gate_hw;
630a97703c5SGabriel Fernandez 
631a97703c5SGabriel Fernandez 	mux_hw = NULL;
632a97703c5SGabriel Fernandez 	div_hw = NULL;
633a97703c5SGabriel Fernandez 	gate_hw = NULL;
634a97703c5SGabriel Fernandez 	mux_ops = NULL;
635a97703c5SGabriel Fernandez 	div_ops = NULL;
636a97703c5SGabriel Fernandez 	gate_ops = NULL;
637a97703c5SGabriel Fernandez 
638a97703c5SGabriel Fernandez 	if (cfg->mux) {
63995272370SGabriel Fernandez 		mux_hw = _get_stm32_mux(dev, base, cfg->mux, lock);
640a97703c5SGabriel Fernandez 
641a97703c5SGabriel Fernandez 		if (!IS_ERR(mux_hw)) {
642a97703c5SGabriel Fernandez 			mux_ops = &clk_mux_ops;
643a97703c5SGabriel Fernandez 
644a97703c5SGabriel Fernandez 			if (cfg->mux->ops)
645a97703c5SGabriel Fernandez 				mux_ops = cfg->mux->ops;
646a97703c5SGabriel Fernandez 		}
647a97703c5SGabriel Fernandez 	}
648a97703c5SGabriel Fernandez 
649a97703c5SGabriel Fernandez 	if (cfg->div) {
65095272370SGabriel Fernandez 		div_hw = _get_stm32_div(dev, base, cfg->div, lock);
651a97703c5SGabriel Fernandez 
652a97703c5SGabriel Fernandez 		if (!IS_ERR(div_hw)) {
653a97703c5SGabriel Fernandez 			div_ops = &clk_divider_ops;
654a97703c5SGabriel Fernandez 
655a97703c5SGabriel Fernandez 			if (cfg->div->ops)
656a97703c5SGabriel Fernandez 				div_ops = cfg->div->ops;
657a97703c5SGabriel Fernandez 		}
658a97703c5SGabriel Fernandez 	}
659a97703c5SGabriel Fernandez 
660a97703c5SGabriel Fernandez 	if (cfg->gate) {
66195272370SGabriel Fernandez 		gate_hw = _get_stm32_gate(dev, base, cfg->gate, lock);
662a97703c5SGabriel Fernandez 
663a97703c5SGabriel Fernandez 		if (!IS_ERR(gate_hw)) {
664a97703c5SGabriel Fernandez 			gate_ops = &clk_gate_ops;
665a97703c5SGabriel Fernandez 
666a97703c5SGabriel Fernandez 			if (cfg->gate->ops)
667a97703c5SGabriel Fernandez 				gate_ops = cfg->gate->ops;
668a97703c5SGabriel Fernandez 		}
669a97703c5SGabriel Fernandez 	}
670a97703c5SGabriel Fernandez 
671a97703c5SGabriel Fernandez 	return clk_hw_register_composite(dev, name, parent_names, num_parents,
672a97703c5SGabriel Fernandez 				       mux_hw, mux_ops, div_hw, div_ops,
673a97703c5SGabriel Fernandez 				       gate_hw, gate_ops, flags);
674a97703c5SGabriel Fernandez }
675a97703c5SGabriel Fernandez 
6761f80590bSGabriel Fernandez #define to_clk_mgate(_gate) container_of(_gate, struct stm32_clk_mgate, gate)
677c6cf4d32SGabriel Fernandez 
mp1_mgate_clk_enable(struct clk_hw * hw)6781f80590bSGabriel Fernandez static int mp1_mgate_clk_enable(struct clk_hw *hw)
6791f80590bSGabriel Fernandez {
6801f80590bSGabriel Fernandez 	struct clk_gate *gate = to_clk_gate(hw);
6811f80590bSGabriel Fernandez 	struct stm32_clk_mgate *clk_mgate = to_clk_mgate(gate);
6821f80590bSGabriel Fernandez 
6831f80590bSGabriel Fernandez 	clk_mgate->mgate->flag |= clk_mgate->mask;
6841f80590bSGabriel Fernandez 
6851f80590bSGabriel Fernandez 	mp1_gate_clk_enable(hw);
6861f80590bSGabriel Fernandez 
6871f80590bSGabriel Fernandez 	return  0;
6881f80590bSGabriel Fernandez }
6891f80590bSGabriel Fernandez 
mp1_mgate_clk_disable(struct clk_hw * hw)6901f80590bSGabriel Fernandez static void mp1_mgate_clk_disable(struct clk_hw *hw)
6911f80590bSGabriel Fernandez {
6921f80590bSGabriel Fernandez 	struct clk_gate *gate = to_clk_gate(hw);
6931f80590bSGabriel Fernandez 	struct stm32_clk_mgate *clk_mgate = to_clk_mgate(gate);
6941f80590bSGabriel Fernandez 
6951f80590bSGabriel Fernandez 	clk_mgate->mgate->flag &= ~clk_mgate->mask;
6961f80590bSGabriel Fernandez 
6971f80590bSGabriel Fernandez 	if (clk_mgate->mgate->flag == 0)
6981f80590bSGabriel Fernandez 		mp1_gate_clk_disable(hw);
6991f80590bSGabriel Fernandez }
7001f80590bSGabriel Fernandez 
701e631ad60SGabriel Fernandez static const struct clk_ops mp1_mgate_clk_ops = {
7021f80590bSGabriel Fernandez 	.enable		= mp1_mgate_clk_enable,
7031f80590bSGabriel Fernandez 	.disable	= mp1_mgate_clk_disable,
7041f80590bSGabriel Fernandez 	.is_enabled	= clk_gate_is_enabled,
7051f80590bSGabriel Fernandez 
7061f80590bSGabriel Fernandez };
7071f80590bSGabriel Fernandez 
7081f80590bSGabriel Fernandez #define to_clk_mmux(_mux) container_of(_mux, struct stm32_clk_mmux, mux)
7091f80590bSGabriel Fernandez 
clk_mmux_get_parent(struct clk_hw * hw)7101f80590bSGabriel Fernandez static u8 clk_mmux_get_parent(struct clk_hw *hw)
7111f80590bSGabriel Fernandez {
7121f80590bSGabriel Fernandez 	return clk_mux_ops.get_parent(hw);
7131f80590bSGabriel Fernandez }
7141f80590bSGabriel Fernandez 
clk_mmux_set_parent(struct clk_hw * hw,u8 index)7151f80590bSGabriel Fernandez static int clk_mmux_set_parent(struct clk_hw *hw, u8 index)
7161f80590bSGabriel Fernandez {
7171f80590bSGabriel Fernandez 	struct clk_mux *mux = to_clk_mux(hw);
7181f80590bSGabriel Fernandez 	struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux);
7191f80590bSGabriel Fernandez 	struct clk_hw *hwp;
7201f80590bSGabriel Fernandez 	int ret, n;
7211f80590bSGabriel Fernandez 
7221f80590bSGabriel Fernandez 	ret = clk_mux_ops.set_parent(hw, index);
7231f80590bSGabriel Fernandez 	if (ret)
7241f80590bSGabriel Fernandez 		return ret;
7251f80590bSGabriel Fernandez 
7261f80590bSGabriel Fernandez 	hwp = clk_hw_get_parent(hw);
7271f80590bSGabriel Fernandez 
7281f80590bSGabriel Fernandez 	for (n = 0; n < clk_mmux->mmux->nbr_clk; n++)
7291f80590bSGabriel Fernandez 		if (clk_mmux->mmux->hws[n] != hw)
7301f80590bSGabriel Fernandez 			clk_hw_reparent(clk_mmux->mmux->hws[n], hwp);
7311f80590bSGabriel Fernandez 
7321f80590bSGabriel Fernandez 	return 0;
7331f80590bSGabriel Fernandez }
7341f80590bSGabriel Fernandez 
735e631ad60SGabriel Fernandez static const struct clk_ops clk_mmux_ops = {
7361f80590bSGabriel Fernandez 	.get_parent	= clk_mmux_get_parent,
7371f80590bSGabriel Fernandez 	.set_parent	= clk_mmux_set_parent,
7381f80590bSGabriel Fernandez 	.determine_rate	= __clk_mux_determine_rate,
7391f80590bSGabriel Fernandez };
7401f80590bSGabriel Fernandez 
7411f80590bSGabriel Fernandez /* STM32 PLL */
742c6cf4d32SGabriel Fernandez struct stm32_pll_obj {
743c6cf4d32SGabriel Fernandez 	/* lock pll enable/disable registers */
744c6cf4d32SGabriel Fernandez 	spinlock_t *lock;
745c6cf4d32SGabriel Fernandez 	void __iomem *reg;
746c6cf4d32SGabriel Fernandez 	struct clk_hw hw;
7479008fddeSGabriel Fernandez 	struct clk_mux mux;
748c6cf4d32SGabriel Fernandez };
749c6cf4d32SGabriel Fernandez 
750c6cf4d32SGabriel Fernandez #define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw)
751c6cf4d32SGabriel Fernandez 
752c6cf4d32SGabriel Fernandez #define PLL_ON		BIT(0)
753c6cf4d32SGabriel Fernandez #define PLL_RDY		BIT(1)
754c6cf4d32SGabriel Fernandez #define DIVN_MASK	0x1FF
755c6cf4d32SGabriel Fernandez #define DIVM_MASK	0x3F
756c6cf4d32SGabriel Fernandez #define DIVM_SHIFT	16
757c6cf4d32SGabriel Fernandez #define DIVN_SHIFT	0
758c6cf4d32SGabriel Fernandez #define FRAC_OFFSET	0xC
759c6cf4d32SGabriel Fernandez #define FRAC_MASK	0x1FFF
760c6cf4d32SGabriel Fernandez #define FRAC_SHIFT	3
761c6cf4d32SGabriel Fernandez #define FRACLE		BIT(16)
7629008fddeSGabriel Fernandez #define PLL_MUX_SHIFT	0
7639008fddeSGabriel Fernandez #define PLL_MUX_MASK	3
764c6cf4d32SGabriel Fernandez 
__pll_is_enabled(struct clk_hw * hw)765c6cf4d32SGabriel Fernandez static int __pll_is_enabled(struct clk_hw *hw)
766c6cf4d32SGabriel Fernandez {
767c6cf4d32SGabriel Fernandez 	struct stm32_pll_obj *clk_elem = to_pll(hw);
768c6cf4d32SGabriel Fernandez 
769c6cf4d32SGabriel Fernandez 	return readl_relaxed(clk_elem->reg) & PLL_ON;
770c6cf4d32SGabriel Fernandez }
771c6cf4d32SGabriel Fernandez 
772c6cf4d32SGabriel Fernandez #define TIMEOUT 5
773c6cf4d32SGabriel Fernandez 
pll_enable(struct clk_hw * hw)774c6cf4d32SGabriel Fernandez static int pll_enable(struct clk_hw *hw)
775c6cf4d32SGabriel Fernandez {
776c6cf4d32SGabriel Fernandez 	struct stm32_pll_obj *clk_elem = to_pll(hw);
777c6cf4d32SGabriel Fernandez 	u32 reg;
778c6cf4d32SGabriel Fernandez 	unsigned long flags = 0;
779c6cf4d32SGabriel Fernandez 	unsigned int timeout = TIMEOUT;
780c6cf4d32SGabriel Fernandez 	int bit_status = 0;
781c6cf4d32SGabriel Fernandez 
782c6cf4d32SGabriel Fernandez 	spin_lock_irqsave(clk_elem->lock, flags);
783c6cf4d32SGabriel Fernandez 
784c6cf4d32SGabriel Fernandez 	if (__pll_is_enabled(hw))
785c6cf4d32SGabriel Fernandez 		goto unlock;
786c6cf4d32SGabriel Fernandez 
787c6cf4d32SGabriel Fernandez 	reg = readl_relaxed(clk_elem->reg);
788c6cf4d32SGabriel Fernandez 	reg |= PLL_ON;
789c6cf4d32SGabriel Fernandez 	writel_relaxed(reg, clk_elem->reg);
790c6cf4d32SGabriel Fernandez 
791c6cf4d32SGabriel Fernandez 	/* We can't use readl_poll_timeout() because we can be blocked if
792c6cf4d32SGabriel Fernandez 	 * someone enables this clock before clocksource changes.
793c6cf4d32SGabriel Fernandez 	 * Only jiffies counter is available. Jiffies are incremented by
794c6cf4d32SGabriel Fernandez 	 * interruptions and enable op does not allow to be interrupted.
795c6cf4d32SGabriel Fernandez 	 */
796c6cf4d32SGabriel Fernandez 	do {
797c6cf4d32SGabriel Fernandez 		bit_status = !(readl_relaxed(clk_elem->reg) & PLL_RDY);
798c6cf4d32SGabriel Fernandez 
799c6cf4d32SGabriel Fernandez 		if (bit_status)
800c6cf4d32SGabriel Fernandez 			udelay(120);
801c6cf4d32SGabriel Fernandez 
802c6cf4d32SGabriel Fernandez 	} while (bit_status && --timeout);
803c6cf4d32SGabriel Fernandez 
804c6cf4d32SGabriel Fernandez unlock:
805c6cf4d32SGabriel Fernandez 	spin_unlock_irqrestore(clk_elem->lock, flags);
806c6cf4d32SGabriel Fernandez 
807c6cf4d32SGabriel Fernandez 	return bit_status;
808c6cf4d32SGabriel Fernandez }
809c6cf4d32SGabriel Fernandez 
pll_disable(struct clk_hw * hw)810c6cf4d32SGabriel Fernandez static void pll_disable(struct clk_hw *hw)
811c6cf4d32SGabriel Fernandez {
812c6cf4d32SGabriel Fernandez 	struct stm32_pll_obj *clk_elem = to_pll(hw);
813c6cf4d32SGabriel Fernandez 	u32 reg;
814c6cf4d32SGabriel Fernandez 	unsigned long flags = 0;
815c6cf4d32SGabriel Fernandez 
816c6cf4d32SGabriel Fernandez 	spin_lock_irqsave(clk_elem->lock, flags);
817c6cf4d32SGabriel Fernandez 
818c6cf4d32SGabriel Fernandez 	reg = readl_relaxed(clk_elem->reg);
819c6cf4d32SGabriel Fernandez 	reg &= ~PLL_ON;
820c6cf4d32SGabriel Fernandez 	writel_relaxed(reg, clk_elem->reg);
821c6cf4d32SGabriel Fernandez 
822c6cf4d32SGabriel Fernandez 	spin_unlock_irqrestore(clk_elem->lock, flags);
823c6cf4d32SGabriel Fernandez }
824c6cf4d32SGabriel Fernandez 
pll_frac_val(struct clk_hw * hw)825c6cf4d32SGabriel Fernandez static u32 pll_frac_val(struct clk_hw *hw)
826c6cf4d32SGabriel Fernandez {
827c6cf4d32SGabriel Fernandez 	struct stm32_pll_obj *clk_elem = to_pll(hw);
828c6cf4d32SGabriel Fernandez 	u32 reg, frac = 0;
829c6cf4d32SGabriel Fernandez 
830c6cf4d32SGabriel Fernandez 	reg = readl_relaxed(clk_elem->reg + FRAC_OFFSET);
831c6cf4d32SGabriel Fernandez 	if (reg & FRACLE)
832c6cf4d32SGabriel Fernandez 		frac = (reg >> FRAC_SHIFT) & FRAC_MASK;
833c6cf4d32SGabriel Fernandez 
834c6cf4d32SGabriel Fernandez 	return frac;
835c6cf4d32SGabriel Fernandez }
836c6cf4d32SGabriel Fernandez 
pll_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)837c6cf4d32SGabriel Fernandez static unsigned long pll_recalc_rate(struct clk_hw *hw,
838c6cf4d32SGabriel Fernandez 				     unsigned long parent_rate)
839c6cf4d32SGabriel Fernandez {
840c6cf4d32SGabriel Fernandez 	struct stm32_pll_obj *clk_elem = to_pll(hw);
841c6cf4d32SGabriel Fernandez 	u32 reg;
842c6cf4d32SGabriel Fernandez 	u32 frac, divm, divn;
843c6cf4d32SGabriel Fernandez 	u64 rate, rate_frac = 0;
844c6cf4d32SGabriel Fernandez 
845c6cf4d32SGabriel Fernandez 	reg = readl_relaxed(clk_elem->reg + 4);
846c6cf4d32SGabriel Fernandez 
847c6cf4d32SGabriel Fernandez 	divm = ((reg >> DIVM_SHIFT) & DIVM_MASK) + 1;
848c6cf4d32SGabriel Fernandez 	divn = ((reg >> DIVN_SHIFT) & DIVN_MASK) + 1;
849c6cf4d32SGabriel Fernandez 	rate = (u64)parent_rate * divn;
850c6cf4d32SGabriel Fernandez 
851c6cf4d32SGabriel Fernandez 	do_div(rate, divm);
852c6cf4d32SGabriel Fernandez 
853c6cf4d32SGabriel Fernandez 	frac = pll_frac_val(hw);
854c6cf4d32SGabriel Fernandez 	if (frac) {
855c6cf4d32SGabriel Fernandez 		rate_frac = (u64)parent_rate * (u64)frac;
856c6cf4d32SGabriel Fernandez 		do_div(rate_frac, (divm * 8192));
857c6cf4d32SGabriel Fernandez 	}
858c6cf4d32SGabriel Fernandez 
859c6cf4d32SGabriel Fernandez 	return rate + rate_frac;
860c6cf4d32SGabriel Fernandez }
861c6cf4d32SGabriel Fernandez 
pll_is_enabled(struct clk_hw * hw)862c6cf4d32SGabriel Fernandez static int pll_is_enabled(struct clk_hw *hw)
863c6cf4d32SGabriel Fernandez {
864c6cf4d32SGabriel Fernandez 	struct stm32_pll_obj *clk_elem = to_pll(hw);
865c6cf4d32SGabriel Fernandez 	unsigned long flags = 0;
866c6cf4d32SGabriel Fernandez 	int ret;
867c6cf4d32SGabriel Fernandez 
868c6cf4d32SGabriel Fernandez 	spin_lock_irqsave(clk_elem->lock, flags);
869c6cf4d32SGabriel Fernandez 	ret = __pll_is_enabled(hw);
870c6cf4d32SGabriel Fernandez 	spin_unlock_irqrestore(clk_elem->lock, flags);
871c6cf4d32SGabriel Fernandez 
872c6cf4d32SGabriel Fernandez 	return ret;
873c6cf4d32SGabriel Fernandez }
874c6cf4d32SGabriel Fernandez 
pll_get_parent(struct clk_hw * hw)8759008fddeSGabriel Fernandez static u8 pll_get_parent(struct clk_hw *hw)
8769008fddeSGabriel Fernandez {
8779008fddeSGabriel Fernandez 	struct stm32_pll_obj *clk_elem = to_pll(hw);
8789008fddeSGabriel Fernandez 	struct clk_hw *mux_hw = &clk_elem->mux.hw;
8799008fddeSGabriel Fernandez 
8809008fddeSGabriel Fernandez 	__clk_hw_set_clk(mux_hw, hw);
8819008fddeSGabriel Fernandez 
8829008fddeSGabriel Fernandez 	return clk_mux_ops.get_parent(mux_hw);
8839008fddeSGabriel Fernandez }
8849008fddeSGabriel Fernandez 
885c6cf4d32SGabriel Fernandez static const struct clk_ops pll_ops = {
886c6cf4d32SGabriel Fernandez 	.enable		= pll_enable,
887c6cf4d32SGabriel Fernandez 	.disable	= pll_disable,
888c6cf4d32SGabriel Fernandez 	.recalc_rate	= pll_recalc_rate,
889c6cf4d32SGabriel Fernandez 	.is_enabled	= pll_is_enabled,
8909008fddeSGabriel Fernandez 	.get_parent	= pll_get_parent,
891c6cf4d32SGabriel Fernandez };
892c6cf4d32SGabriel Fernandez 
clk_register_pll(struct device * dev,const char * name,const char * const * parent_names,int num_parents,void __iomem * reg,void __iomem * mux_reg,unsigned long flags,spinlock_t * lock)893c6cf4d32SGabriel Fernandez static struct clk_hw *clk_register_pll(struct device *dev, const char *name,
8949008fddeSGabriel Fernandez 				       const char * const *parent_names,
8959008fddeSGabriel Fernandez 				       int num_parents,
896c6cf4d32SGabriel Fernandez 				       void __iomem *reg,
8979008fddeSGabriel Fernandez 				       void __iomem *mux_reg,
898c6cf4d32SGabriel Fernandez 				       unsigned long flags,
899c6cf4d32SGabriel Fernandez 				       spinlock_t *lock)
900c6cf4d32SGabriel Fernandez {
901c6cf4d32SGabriel Fernandez 	struct stm32_pll_obj *element;
902c6cf4d32SGabriel Fernandez 	struct clk_init_data init;
903c6cf4d32SGabriel Fernandez 	struct clk_hw *hw;
904c6cf4d32SGabriel Fernandez 	int err;
905c6cf4d32SGabriel Fernandez 
90695272370SGabriel Fernandez 	element = devm_kzalloc(dev, sizeof(*element), GFP_KERNEL);
907c6cf4d32SGabriel Fernandez 	if (!element)
908c6cf4d32SGabriel Fernandez 		return ERR_PTR(-ENOMEM);
909c6cf4d32SGabriel Fernandez 
910c6cf4d32SGabriel Fernandez 	init.name = name;
911c6cf4d32SGabriel Fernandez 	init.ops = &pll_ops;
912c6cf4d32SGabriel Fernandez 	init.flags = flags;
9139008fddeSGabriel Fernandez 	init.parent_names = parent_names;
9149008fddeSGabriel Fernandez 	init.num_parents = num_parents;
9159008fddeSGabriel Fernandez 
9169008fddeSGabriel Fernandez 	element->mux.lock = lock;
9179008fddeSGabriel Fernandez 	element->mux.reg =  mux_reg;
9189008fddeSGabriel Fernandez 	element->mux.shift = PLL_MUX_SHIFT;
9199008fddeSGabriel Fernandez 	element->mux.mask =  PLL_MUX_MASK;
9209008fddeSGabriel Fernandez 	element->mux.flags =  CLK_MUX_READ_ONLY;
9219008fddeSGabriel Fernandez 	element->mux.reg =  mux_reg;
922c6cf4d32SGabriel Fernandez 
923c6cf4d32SGabriel Fernandez 	element->hw.init = &init;
924c6cf4d32SGabriel Fernandez 	element->reg = reg;
925c6cf4d32SGabriel Fernandez 	element->lock = lock;
926c6cf4d32SGabriel Fernandez 
927c6cf4d32SGabriel Fernandez 	hw = &element->hw;
928c6cf4d32SGabriel Fernandez 	err = clk_hw_register(dev, hw);
929c6cf4d32SGabriel Fernandez 
93095272370SGabriel Fernandez 	if (err)
931c6cf4d32SGabriel Fernandez 		return ERR_PTR(err);
932c6cf4d32SGabriel Fernandez 
933c6cf4d32SGabriel Fernandez 	return hw;
934c6cf4d32SGabriel Fernandez }
935c6cf4d32SGabriel Fernandez 
936799b6a12SGabriel Fernandez /* Kernel Timer */
937799b6a12SGabriel Fernandez struct timer_cker {
938799b6a12SGabriel Fernandez 	/* lock the kernel output divider register */
939799b6a12SGabriel Fernandez 	spinlock_t *lock;
940799b6a12SGabriel Fernandez 	void __iomem *apbdiv;
941799b6a12SGabriel Fernandez 	void __iomem *timpre;
942799b6a12SGabriel Fernandez 	struct clk_hw hw;
943799b6a12SGabriel Fernandez };
944799b6a12SGabriel Fernandez 
945799b6a12SGabriel Fernandez #define to_timer_cker(_hw) container_of(_hw, struct timer_cker, hw)
946799b6a12SGabriel Fernandez 
947799b6a12SGabriel Fernandez #define APB_DIV_MASK 0x07
948799b6a12SGabriel Fernandez #define TIM_PRE_MASK 0x01
949799b6a12SGabriel Fernandez 
__bestmult(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)950799b6a12SGabriel Fernandez static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
951799b6a12SGabriel Fernandez 				unsigned long parent_rate)
952799b6a12SGabriel Fernandez {
953799b6a12SGabriel Fernandez 	struct timer_cker *tim_ker = to_timer_cker(hw);
954799b6a12SGabriel Fernandez 	u32 prescaler;
955799b6a12SGabriel Fernandez 	unsigned int mult = 0;
956799b6a12SGabriel Fernandez 
957799b6a12SGabriel Fernandez 	prescaler = readl_relaxed(tim_ker->apbdiv) & APB_DIV_MASK;
958799b6a12SGabriel Fernandez 	if (prescaler < 2)
959799b6a12SGabriel Fernandez 		return 1;
960799b6a12SGabriel Fernandez 
961799b6a12SGabriel Fernandez 	mult = 2;
962799b6a12SGabriel Fernandez 
963799b6a12SGabriel Fernandez 	if (rate / parent_rate >= 4)
964799b6a12SGabriel Fernandez 		mult = 4;
965799b6a12SGabriel Fernandez 
966799b6a12SGabriel Fernandez 	return mult;
967799b6a12SGabriel Fernandez }
968799b6a12SGabriel Fernandez 
timer_ker_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * parent_rate)969799b6a12SGabriel Fernandez static long timer_ker_round_rate(struct clk_hw *hw, unsigned long rate,
970799b6a12SGabriel Fernandez 				 unsigned long *parent_rate)
971799b6a12SGabriel Fernandez {
972799b6a12SGabriel Fernandez 	unsigned long factor = __bestmult(hw, rate, *parent_rate);
973799b6a12SGabriel Fernandez 
974799b6a12SGabriel Fernandez 	return *parent_rate * factor;
975799b6a12SGabriel Fernandez }
976799b6a12SGabriel Fernandez 
timer_ker_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)977799b6a12SGabriel Fernandez static int timer_ker_set_rate(struct clk_hw *hw, unsigned long rate,
978799b6a12SGabriel Fernandez 			      unsigned long parent_rate)
979799b6a12SGabriel Fernandez {
980799b6a12SGabriel Fernandez 	struct timer_cker *tim_ker = to_timer_cker(hw);
981799b6a12SGabriel Fernandez 	unsigned long flags = 0;
982799b6a12SGabriel Fernandez 	unsigned long factor = __bestmult(hw, rate, parent_rate);
983799b6a12SGabriel Fernandez 	int ret = 0;
984799b6a12SGabriel Fernandez 
985799b6a12SGabriel Fernandez 	spin_lock_irqsave(tim_ker->lock, flags);
986799b6a12SGabriel Fernandez 
987799b6a12SGabriel Fernandez 	switch (factor) {
988799b6a12SGabriel Fernandez 	case 1:
989799b6a12SGabriel Fernandez 		break;
990799b6a12SGabriel Fernandez 	case 2:
991799b6a12SGabriel Fernandez 		writel_relaxed(0, tim_ker->timpre);
992799b6a12SGabriel Fernandez 		break;
993799b6a12SGabriel Fernandez 	case 4:
994799b6a12SGabriel Fernandez 		writel_relaxed(1, tim_ker->timpre);
995799b6a12SGabriel Fernandez 		break;
996799b6a12SGabriel Fernandez 	default:
997799b6a12SGabriel Fernandez 		ret = -EINVAL;
998799b6a12SGabriel Fernandez 	}
999799b6a12SGabriel Fernandez 	spin_unlock_irqrestore(tim_ker->lock, flags);
1000799b6a12SGabriel Fernandez 
1001799b6a12SGabriel Fernandez 	return ret;
1002799b6a12SGabriel Fernandez }
1003799b6a12SGabriel Fernandez 
timer_ker_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)1004799b6a12SGabriel Fernandez static unsigned long timer_ker_recalc_rate(struct clk_hw *hw,
1005799b6a12SGabriel Fernandez 					   unsigned long parent_rate)
1006799b6a12SGabriel Fernandez {
1007799b6a12SGabriel Fernandez 	struct timer_cker *tim_ker = to_timer_cker(hw);
1008799b6a12SGabriel Fernandez 	u32 prescaler, timpre;
1009799b6a12SGabriel Fernandez 	u32 mul;
1010799b6a12SGabriel Fernandez 
1011799b6a12SGabriel Fernandez 	prescaler = readl_relaxed(tim_ker->apbdiv) & APB_DIV_MASK;
1012799b6a12SGabriel Fernandez 
1013799b6a12SGabriel Fernandez 	timpre = readl_relaxed(tim_ker->timpre) & TIM_PRE_MASK;
1014799b6a12SGabriel Fernandez 
1015799b6a12SGabriel Fernandez 	if (!prescaler)
1016799b6a12SGabriel Fernandez 		return parent_rate;
1017799b6a12SGabriel Fernandez 
1018799b6a12SGabriel Fernandez 	mul = (timpre + 1) * 2;
1019799b6a12SGabriel Fernandez 
1020799b6a12SGabriel Fernandez 	return parent_rate * mul;
1021799b6a12SGabriel Fernandez }
1022799b6a12SGabriel Fernandez 
1023799b6a12SGabriel Fernandez static const struct clk_ops timer_ker_ops = {
1024799b6a12SGabriel Fernandez 	.recalc_rate	= timer_ker_recalc_rate,
1025799b6a12SGabriel Fernandez 	.round_rate	= timer_ker_round_rate,
1026799b6a12SGabriel Fernandez 	.set_rate	= timer_ker_set_rate,
1027799b6a12SGabriel Fernandez 
1028799b6a12SGabriel Fernandez };
1029799b6a12SGabriel Fernandez 
clk_register_cktim(struct device * dev,const char * name,const char * parent_name,unsigned long flags,void __iomem * apbdiv,void __iomem * timpre,spinlock_t * lock)1030799b6a12SGabriel Fernandez static struct clk_hw *clk_register_cktim(struct device *dev, const char *name,
1031799b6a12SGabriel Fernandez 					 const char *parent_name,
1032799b6a12SGabriel Fernandez 					 unsigned long flags,
1033799b6a12SGabriel Fernandez 					 void __iomem *apbdiv,
1034799b6a12SGabriel Fernandez 					 void __iomem *timpre,
1035799b6a12SGabriel Fernandez 					 spinlock_t *lock)
1036799b6a12SGabriel Fernandez {
1037799b6a12SGabriel Fernandez 	struct timer_cker *tim_ker;
1038799b6a12SGabriel Fernandez 	struct clk_init_data init;
1039799b6a12SGabriel Fernandez 	struct clk_hw *hw;
1040799b6a12SGabriel Fernandez 	int err;
1041799b6a12SGabriel Fernandez 
104295272370SGabriel Fernandez 	tim_ker = devm_kzalloc(dev, sizeof(*tim_ker), GFP_KERNEL);
1043799b6a12SGabriel Fernandez 	if (!tim_ker)
1044799b6a12SGabriel Fernandez 		return ERR_PTR(-ENOMEM);
1045799b6a12SGabriel Fernandez 
1046799b6a12SGabriel Fernandez 	init.name = name;
1047799b6a12SGabriel Fernandez 	init.ops = &timer_ker_ops;
1048799b6a12SGabriel Fernandez 	init.flags = flags;
1049799b6a12SGabriel Fernandez 	init.parent_names = &parent_name;
1050799b6a12SGabriel Fernandez 	init.num_parents = 1;
1051799b6a12SGabriel Fernandez 
1052799b6a12SGabriel Fernandez 	tim_ker->hw.init = &init;
1053799b6a12SGabriel Fernandez 	tim_ker->lock = lock;
1054799b6a12SGabriel Fernandez 	tim_ker->apbdiv = apbdiv;
1055799b6a12SGabriel Fernandez 	tim_ker->timpre = timpre;
1056799b6a12SGabriel Fernandez 
1057799b6a12SGabriel Fernandez 	hw = &tim_ker->hw;
1058799b6a12SGabriel Fernandez 	err = clk_hw_register(dev, hw);
1059799b6a12SGabriel Fernandez 
106095272370SGabriel Fernandez 	if (err)
1061799b6a12SGabriel Fernandez 		return ERR_PTR(err);
1062799b6a12SGabriel Fernandez 
1063799b6a12SGabriel Fernandez 	return hw;
1064799b6a12SGabriel Fernandez }
1065799b6a12SGabriel Fernandez 
1066152efe56SGabriel Fernandez /* The divider of RTC clock concerns only ck_hse clock */
1067152efe56SGabriel Fernandez #define HSE_RTC 3
1068152efe56SGabriel Fernandez 
clk_divider_rtc_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)1069152efe56SGabriel Fernandez static unsigned long clk_divider_rtc_recalc_rate(struct clk_hw *hw,
1070152efe56SGabriel Fernandez 						 unsigned long parent_rate)
1071152efe56SGabriel Fernandez {
1072152efe56SGabriel Fernandez 	if (clk_hw_get_parent(hw) == clk_hw_get_parent_by_index(hw, HSE_RTC))
1073152efe56SGabriel Fernandez 		return clk_divider_ops.recalc_rate(hw, parent_rate);
1074152efe56SGabriel Fernandez 
1075152efe56SGabriel Fernandez 	return parent_rate;
1076152efe56SGabriel Fernandez }
1077152efe56SGabriel Fernandez 
clk_divider_rtc_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)1078152efe56SGabriel Fernandez static int clk_divider_rtc_set_rate(struct clk_hw *hw, unsigned long rate,
1079152efe56SGabriel Fernandez 				    unsigned long parent_rate)
1080152efe56SGabriel Fernandez {
1081152efe56SGabriel Fernandez 	if (clk_hw_get_parent(hw) == clk_hw_get_parent_by_index(hw, HSE_RTC))
1082152efe56SGabriel Fernandez 		return clk_divider_ops.set_rate(hw, rate, parent_rate);
1083152efe56SGabriel Fernandez 
1084152efe56SGabriel Fernandez 	return parent_rate;
1085152efe56SGabriel Fernandez }
1086152efe56SGabriel Fernandez 
clk_divider_rtc_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)1087152efe56SGabriel Fernandez static int clk_divider_rtc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
1088152efe56SGabriel Fernandez {
108923a57ee7SMartin Blumenstingl 	if (req->best_parent_hw == clk_hw_get_parent_by_index(hw, HSE_RTC))
109023a57ee7SMartin Blumenstingl 		return clk_divider_ops.determine_rate(hw, req);
1091152efe56SGabriel Fernandez 
109223a57ee7SMartin Blumenstingl 	req->rate = req->best_parent_rate;
1093152efe56SGabriel Fernandez 
1094152efe56SGabriel Fernandez 	return 0;
1095152efe56SGabriel Fernandez }
1096152efe56SGabriel Fernandez 
1097152efe56SGabriel Fernandez static const struct clk_ops rtc_div_clk_ops = {
1098152efe56SGabriel Fernandez 	.recalc_rate	= clk_divider_rtc_recalc_rate,
1099152efe56SGabriel Fernandez 	.set_rate	= clk_divider_rtc_set_rate,
1100152efe56SGabriel Fernandez 	.determine_rate = clk_divider_rtc_determine_rate
1101152efe56SGabriel Fernandez };
1102152efe56SGabriel Fernandez 
1103c6cf4d32SGabriel Fernandez struct stm32_pll_cfg {
1104c6cf4d32SGabriel Fernandez 	u32 offset;
11059008fddeSGabriel Fernandez 	u32 muxoff;
1106c6cf4d32SGabriel Fernandez };
1107c6cf4d32SGabriel Fernandez 
_clk_register_pll(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)1108e631ad60SGabriel Fernandez static struct clk_hw *_clk_register_pll(struct device *dev,
1109c6cf4d32SGabriel Fernandez 					struct clk_hw_onecell_data *clk_data,
1110c6cf4d32SGabriel Fernandez 					void __iomem *base, spinlock_t *lock,
1111c6cf4d32SGabriel Fernandez 					const struct clock_config *cfg)
1112c6cf4d32SGabriel Fernandez {
1113c6cf4d32SGabriel Fernandez 	struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg;
1114c6cf4d32SGabriel Fernandez 
11159008fddeSGabriel Fernandez 	return clk_register_pll(dev, cfg->name, cfg->parent_names,
11169008fddeSGabriel Fernandez 				cfg->num_parents,
11179008fddeSGabriel Fernandez 				base + stm_pll_cfg->offset,
11189008fddeSGabriel Fernandez 				base + stm_pll_cfg->muxoff,
11199008fddeSGabriel Fernandez 				cfg->flags, lock);
1120c6cf4d32SGabriel Fernandez }
1121c6cf4d32SGabriel Fernandez 
1122799b6a12SGabriel Fernandez struct stm32_cktim_cfg {
1123799b6a12SGabriel Fernandez 	u32 offset_apbdiv;
1124799b6a12SGabriel Fernandez 	u32 offset_timpre;
1125799b6a12SGabriel Fernandez };
1126799b6a12SGabriel Fernandez 
_clk_register_cktim(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)1127799b6a12SGabriel Fernandez static struct clk_hw *_clk_register_cktim(struct device *dev,
1128799b6a12SGabriel Fernandez 					  struct clk_hw_onecell_data *clk_data,
1129799b6a12SGabriel Fernandez 					  void __iomem *base, spinlock_t *lock,
1130799b6a12SGabriel Fernandez 					  const struct clock_config *cfg)
1131799b6a12SGabriel Fernandez {
1132799b6a12SGabriel Fernandez 	struct stm32_cktim_cfg *cktim_cfg = cfg->cfg;
1133799b6a12SGabriel Fernandez 
1134799b6a12SGabriel Fernandez 	return clk_register_cktim(dev, cfg->name, cfg->parent_name, cfg->flags,
1135799b6a12SGabriel Fernandez 				  cktim_cfg->offset_apbdiv + base,
1136799b6a12SGabriel Fernandez 				  cktim_cfg->offset_timpre + base, lock);
1137799b6a12SGabriel Fernandez }
1138799b6a12SGabriel Fernandez 
11398e6c27c0SGabriel Fernandez static struct clk_hw *
_clk_stm32_register_gate(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)11408e6c27c0SGabriel Fernandez _clk_stm32_register_gate(struct device *dev,
11418e6c27c0SGabriel Fernandez 			 struct clk_hw_onecell_data *clk_data,
11428e6c27c0SGabriel Fernandez 			 void __iomem *base, spinlock_t *lock,
11438e6c27c0SGabriel Fernandez 			 const struct clock_config *cfg)
11448e6c27c0SGabriel Fernandez {
11458e6c27c0SGabriel Fernandez 	return clk_stm32_register_gate_ops(dev,
11468e6c27c0SGabriel Fernandez 				    cfg->name,
11478e6c27c0SGabriel Fernandez 				    cfg->parent_name,
1148e9ed1ef1SMarek Vasut 				    cfg->parent_data,
11498e6c27c0SGabriel Fernandez 				    cfg->flags,
11508e6c27c0SGabriel Fernandez 				    base,
11518e6c27c0SGabriel Fernandez 				    cfg->cfg,
11528e6c27c0SGabriel Fernandez 				    lock);
11538e6c27c0SGabriel Fernandez }
11548e6c27c0SGabriel Fernandez 
1155a97703c5SGabriel Fernandez static struct clk_hw *
_clk_stm32_register_composite(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)1156a97703c5SGabriel Fernandez _clk_stm32_register_composite(struct device *dev,
1157a97703c5SGabriel Fernandez 			      struct clk_hw_onecell_data *clk_data,
1158a97703c5SGabriel Fernandez 			      void __iomem *base, spinlock_t *lock,
1159a97703c5SGabriel Fernandez 			      const struct clock_config *cfg)
1160a97703c5SGabriel Fernandez {
1161a97703c5SGabriel Fernandez 	return clk_stm32_register_composite(dev, cfg->name, cfg->parent_names,
1162e9ed1ef1SMarek Vasut 					    cfg->parent_data, cfg->num_parents,
1163e9ed1ef1SMarek Vasut 					    base, cfg->cfg, cfg->flags, lock);
1164a97703c5SGabriel Fernandez }
1165a97703c5SGabriel Fernandez 
11669bee94e7SGabriel Fernandez #define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
11679bee94e7SGabriel Fernandez {\
11689bee94e7SGabriel Fernandez 	.id		= _id,\
11699bee94e7SGabriel Fernandez 	.name		= _name,\
11709bee94e7SGabriel Fernandez 	.parent_name	= _parent,\
11719bee94e7SGabriel Fernandez 	.flags		= _flags,\
11729bee94e7SGabriel Fernandez 	.cfg		=  &(struct gate_cfg) {\
11739bee94e7SGabriel Fernandez 		.reg_off	= _offset,\
11749bee94e7SGabriel Fernandez 		.bit_idx	= _bit_idx,\
11759bee94e7SGabriel Fernandez 		.gate_flags	= _gate_flags,\
11769bee94e7SGabriel Fernandez 	},\
11779bee94e7SGabriel Fernandez 	.func		= _clk_hw_register_gate,\
11789bee94e7SGabriel Fernandez }
11799bee94e7SGabriel Fernandez 
11809bee94e7SGabriel Fernandez #define FIXED_FACTOR(_id, _name, _parent, _flags, _mult, _div)\
11819bee94e7SGabriel Fernandez {\
11829bee94e7SGabriel Fernandez 	.id		= _id,\
11839bee94e7SGabriel Fernandez 	.name		= _name,\
11849bee94e7SGabriel Fernandez 	.parent_name	= _parent,\
11859bee94e7SGabriel Fernandez 	.flags		= _flags,\
11869bee94e7SGabriel Fernandez 	.cfg		=  &(struct fixed_factor_cfg) {\
11879bee94e7SGabriel Fernandez 		.mult = _mult,\
11889bee94e7SGabriel Fernandez 		.div = _div,\
11899bee94e7SGabriel Fernandez 	},\
11909bee94e7SGabriel Fernandez 	.func		= _clk_hw_register_fixed_factor,\
11919bee94e7SGabriel Fernandez }
11929bee94e7SGabriel Fernandez 
11939bee94e7SGabriel Fernandez #define DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
11949bee94e7SGabriel Fernandez 		  _div_flags, _div_table)\
11959bee94e7SGabriel Fernandez {\
11969bee94e7SGabriel Fernandez 	.id		= _id,\
11979bee94e7SGabriel Fernandez 	.name		= _name,\
11989bee94e7SGabriel Fernandez 	.parent_name	= _parent,\
11999bee94e7SGabriel Fernandez 	.flags		= _flags,\
12009bee94e7SGabriel Fernandez 	.cfg		=  &(struct div_cfg) {\
12019bee94e7SGabriel Fernandez 		.reg_off	= _offset,\
12029bee94e7SGabriel Fernandez 		.shift		= _shift,\
12039bee94e7SGabriel Fernandez 		.width		= _width,\
12049bee94e7SGabriel Fernandez 		.div_flags	= _div_flags,\
12059bee94e7SGabriel Fernandez 		.table		= _div_table,\
12069bee94e7SGabriel Fernandez 	},\
12079bee94e7SGabriel Fernandez 	.func		= _clk_hw_register_divider_table,\
12089bee94e7SGabriel Fernandez }
12099bee94e7SGabriel Fernandez 
12109bee94e7SGabriel Fernandez #define DIV(_id, _name, _parent, _flags, _offset, _shift, _width, _div_flags)\
12119bee94e7SGabriel Fernandez 	DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
12129bee94e7SGabriel Fernandez 		  _div_flags, NULL)
12139bee94e7SGabriel Fernandez 
1214dc32eaacSGabriel Fernandez #define MUX(_id, _name, _parents, _flags, _offset, _shift, _width, _mux_flags)\
1215dc32eaacSGabriel Fernandez {\
1216dc32eaacSGabriel Fernandez 	.id		= _id,\
1217dc32eaacSGabriel Fernandez 	.name		= _name,\
1218dc32eaacSGabriel Fernandez 	.parent_names	= _parents,\
1219dc32eaacSGabriel Fernandez 	.num_parents	= ARRAY_SIZE(_parents),\
1220dc32eaacSGabriel Fernandez 	.flags		= _flags,\
1221dc32eaacSGabriel Fernandez 	.cfg		=  &(struct mux_cfg) {\
1222dc32eaacSGabriel Fernandez 		.reg_off	= _offset,\
1223dc32eaacSGabriel Fernandez 		.shift		= _shift,\
1224dc32eaacSGabriel Fernandez 		.width		= _width,\
1225dc32eaacSGabriel Fernandez 		.mux_flags	= _mux_flags,\
1226dc32eaacSGabriel Fernandez 	},\
1227dc32eaacSGabriel Fernandez 	.func		= _clk_hw_register_mux,\
1228dc32eaacSGabriel Fernandez }
1229dc32eaacSGabriel Fernandez 
12309008fddeSGabriel Fernandez #define PLL(_id, _name, _parents, _flags, _offset_p, _offset_mux)\
1231c6cf4d32SGabriel Fernandez {\
1232c6cf4d32SGabriel Fernandez 	.id		= _id,\
1233c6cf4d32SGabriel Fernandez 	.name		= _name,\
12349008fddeSGabriel Fernandez 	.parent_names	= _parents,\
12359008fddeSGabriel Fernandez 	.num_parents	= ARRAY_SIZE(_parents),\
12369008fddeSGabriel Fernandez 	.flags		= CLK_IGNORE_UNUSED | (_flags),\
1237c6cf4d32SGabriel Fernandez 	.cfg		=  &(struct stm32_pll_cfg) {\
12389008fddeSGabriel Fernandez 		.offset = _offset_p,\
12399008fddeSGabriel Fernandez 		.muxoff = _offset_mux,\
1240c6cf4d32SGabriel Fernandez 	},\
1241c6cf4d32SGabriel Fernandez 	.func		= _clk_register_pll,\
1242c6cf4d32SGabriel Fernandez }
1243c6cf4d32SGabriel Fernandez 
1244799b6a12SGabriel Fernandez #define STM32_CKTIM(_name, _parent, _flags, _offset_apbdiv, _offset_timpre)\
1245799b6a12SGabriel Fernandez {\
1246799b6a12SGabriel Fernandez 	.id		= NO_ID,\
1247799b6a12SGabriel Fernandez 	.name		= _name,\
1248799b6a12SGabriel Fernandez 	.parent_name	= _parent,\
1249799b6a12SGabriel Fernandez 	.flags		= _flags,\
1250799b6a12SGabriel Fernandez 	.cfg		=  &(struct stm32_cktim_cfg) {\
1251799b6a12SGabriel Fernandez 		.offset_apbdiv = _offset_apbdiv,\
1252799b6a12SGabriel Fernandez 		.offset_timpre = _offset_timpre,\
1253799b6a12SGabriel Fernandez 	},\
1254799b6a12SGabriel Fernandez 	.func		= _clk_register_cktim,\
1255799b6a12SGabriel Fernandez }
1256799b6a12SGabriel Fernandez 
1257799b6a12SGabriel Fernandez #define STM32_TIM(_id, _name, _parent, _offset_set, _bit_idx)\
1258799b6a12SGabriel Fernandez 		  GATE_MP1(_id, _name, _parent, CLK_SET_RATE_PARENT,\
1259799b6a12SGabriel Fernandez 			   _offset_set, _bit_idx, 0)
1260799b6a12SGabriel Fernandez 
12618e6c27c0SGabriel Fernandez /* STM32 GATE */
12628e6c27c0SGabriel Fernandez #define STM32_GATE(_id, _name, _parent, _flags, _gate)\
12638e6c27c0SGabriel Fernandez {\
12648e6c27c0SGabriel Fernandez 	.id		= _id,\
12658e6c27c0SGabriel Fernandez 	.name		= _name,\
12668e6c27c0SGabriel Fernandez 	.parent_name	= _parent,\
12678e6c27c0SGabriel Fernandez 	.flags		= _flags,\
12688e6c27c0SGabriel Fernandez 	.cfg		= (struct stm32_gate_cfg *) {_gate},\
12698e6c27c0SGabriel Fernandez 	.func		= _clk_stm32_register_gate,\
12708e6c27c0SGabriel Fernandez }
12718e6c27c0SGabriel Fernandez 
1272e9ed1ef1SMarek Vasut #define STM32_GATE_PDATA(_id, _name, _parent, _flags, _gate)\
1273e9ed1ef1SMarek Vasut {\
1274e9ed1ef1SMarek Vasut 	.id		= _id,\
1275e9ed1ef1SMarek Vasut 	.name		= _name,\
1276e9ed1ef1SMarek Vasut 	.parent_data	= _parent,\
1277e9ed1ef1SMarek Vasut 	.flags		= _flags,\
1278e9ed1ef1SMarek Vasut 	.cfg		= (struct stm32_gate_cfg *) {_gate},\
1279e9ed1ef1SMarek Vasut 	.func		= _clk_stm32_register_gate,\
1280e9ed1ef1SMarek Vasut }
1281e9ed1ef1SMarek Vasut 
12821f80590bSGabriel Fernandez #define _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags, _mgate, _ops)\
12838e6c27c0SGabriel Fernandez 	(&(struct stm32_gate_cfg) {\
12848e6c27c0SGabriel Fernandez 		&(struct gate_cfg) {\
12858e6c27c0SGabriel Fernandez 			.reg_off	= _gate_offset,\
12868e6c27c0SGabriel Fernandez 			.bit_idx	= _gate_bit_idx,\
12878e6c27c0SGabriel Fernandez 			.gate_flags	= _gate_flags,\
12888e6c27c0SGabriel Fernandez 		},\
12891f80590bSGabriel Fernandez 		.mgate		= _mgate,\
12908e6c27c0SGabriel Fernandez 		.ops		= _ops,\
12918e6c27c0SGabriel Fernandez 	})
12928e6c27c0SGabriel Fernandez 
12931f80590bSGabriel Fernandez #define _STM32_MGATE(_mgate)\
12941f80590bSGabriel Fernandez 	(&per_gate_cfg[_mgate])
12951f80590bSGabriel Fernandez 
1296a97703c5SGabriel Fernandez #define _GATE(_gate_offset, _gate_bit_idx, _gate_flags)\
1297a97703c5SGabriel Fernandez 	_STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\
12981f80590bSGabriel Fernandez 		    NULL, NULL)\
1299a97703c5SGabriel Fernandez 
13008e6c27c0SGabriel Fernandez #define _GATE_MP1(_gate_offset, _gate_bit_idx, _gate_flags)\
13018e6c27c0SGabriel Fernandez 	_STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\
13021f80590bSGabriel Fernandez 		    NULL, &mp1_gate_clk_ops)\
13031f80590bSGabriel Fernandez 
13041f80590bSGabriel Fernandez #define _MGATE_MP1(_mgate)\
13051f80590bSGabriel Fernandez 	.gate = &per_gate_cfg[_mgate]
13068e6c27c0SGabriel Fernandez 
13078e6c27c0SGabriel Fernandez #define GATE_MP1(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
13088e6c27c0SGabriel Fernandez 	STM32_GATE(_id, _name, _parent, _flags,\
13098e6c27c0SGabriel Fernandez 		   _GATE_MP1(_offset, _bit_idx, _gate_flags))
13108e6c27c0SGabriel Fernandez 
13111f80590bSGabriel Fernandez #define MGATE_MP1(_id, _name, _parent, _flags, _mgate)\
13121f80590bSGabriel Fernandez 	STM32_GATE(_id, _name, _parent, _flags,\
13131f80590bSGabriel Fernandez 		   _STM32_MGATE(_mgate))
13141f80590bSGabriel Fernandez 
1315e9ed1ef1SMarek Vasut #define MGATE_MP1_PDATA(_id, _name, _parent, _flags, _mgate)\
1316e9ed1ef1SMarek Vasut 	STM32_GATE_PDATA(_id, _name, _parent, _flags,\
1317e9ed1ef1SMarek Vasut 		   _STM32_MGATE(_mgate))
1318e9ed1ef1SMarek Vasut 
1319a97703c5SGabriel Fernandez #define _STM32_DIV(_div_offset, _div_shift, _div_width,\
1320a97703c5SGabriel Fernandez 		   _div_flags, _div_table, _ops)\
1321a97703c5SGabriel Fernandez 	.div = &(struct stm32_div_cfg) {\
1322a97703c5SGabriel Fernandez 		&(struct div_cfg) {\
1323a97703c5SGabriel Fernandez 			.reg_off	= _div_offset,\
1324a97703c5SGabriel Fernandez 			.shift		= _div_shift,\
1325a97703c5SGabriel Fernandez 			.width		= _div_width,\
1326a97703c5SGabriel Fernandez 			.div_flags	= _div_flags,\
1327a97703c5SGabriel Fernandez 			.table		= _div_table,\
1328a97703c5SGabriel Fernandez 		},\
1329a97703c5SGabriel Fernandez 		.ops		= _ops,\
1330a97703c5SGabriel Fernandez 	}
1331a97703c5SGabriel Fernandez 
1332a97703c5SGabriel Fernandez #define _DIV(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\
1333a97703c5SGabriel Fernandez 	_STM32_DIV(_div_offset, _div_shift, _div_width,\
1334a97703c5SGabriel Fernandez 		   _div_flags, _div_table, NULL)\
1335a97703c5SGabriel Fernandez 
1336152efe56SGabriel Fernandez #define _DIV_RTC(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\
1337152efe56SGabriel Fernandez 	_STM32_DIV(_div_offset, _div_shift, _div_width,\
1338152efe56SGabriel Fernandez 		   _div_flags, _div_table, &rtc_div_clk_ops)
1339152efe56SGabriel Fernandez 
13401f80590bSGabriel Fernandez #define _STM32_MUX(_offset, _shift, _width, _mux_flags, _mmux, _ops)\
1341e51d297eSGabriel Fernandez 	.mux = &(struct stm32_mux_cfg) {\
1342e51d297eSGabriel Fernandez 		&(struct mux_cfg) {\
1343e51d297eSGabriel Fernandez 			.reg_off	= _offset,\
1344e51d297eSGabriel Fernandez 			.shift		= _shift,\
1345e51d297eSGabriel Fernandez 			.width		= _width,\
1346e51d297eSGabriel Fernandez 			.mux_flags	= _mux_flags,\
1347e51d297eSGabriel Fernandez 			.table		= NULL,\
1348e51d297eSGabriel Fernandez 		},\
13491f80590bSGabriel Fernandez 		.mmux		= _mmux,\
1350e51d297eSGabriel Fernandez 		.ops		= _ops,\
1351e51d297eSGabriel Fernandez 	}
1352e51d297eSGabriel Fernandez 
1353e51d297eSGabriel Fernandez #define _MUX(_offset, _shift, _width, _mux_flags)\
13541f80590bSGabriel Fernandez 	_STM32_MUX(_offset, _shift, _width, _mux_flags, NULL, NULL)\
13551f80590bSGabriel Fernandez 
13561f80590bSGabriel Fernandez #define _MMUX(_mmux) .mux = &ker_mux_cfg[_mmux]
1357e51d297eSGabriel Fernandez 
1358a97703c5SGabriel Fernandez #define PARENT(_parent) ((const char *[]) { _parent})
1359a97703c5SGabriel Fernandez 
1360a97703c5SGabriel Fernandez #define _NO_MUX .mux = NULL
1361a97703c5SGabriel Fernandez #define _NO_DIV .div = NULL
1362a97703c5SGabriel Fernandez #define _NO_GATE .gate = NULL
1363a97703c5SGabriel Fernandez 
1364a97703c5SGabriel Fernandez #define COMPOSITE(_id, _name, _parents, _flags, _gate, _mux, _div)\
1365a97703c5SGabriel Fernandez {\
1366a97703c5SGabriel Fernandez 	.id		= _id,\
1367a97703c5SGabriel Fernandez 	.name		= _name,\
1368a97703c5SGabriel Fernandez 	.parent_names	= _parents,\
1369a97703c5SGabriel Fernandez 	.num_parents	= ARRAY_SIZE(_parents),\
1370a97703c5SGabriel Fernandez 	.flags		= _flags,\
1371a97703c5SGabriel Fernandez 	.cfg		= &(struct stm32_composite_cfg) {\
1372a97703c5SGabriel Fernandez 		_gate,\
1373a97703c5SGabriel Fernandez 		_mux,\
1374a97703c5SGabriel Fernandez 		_div,\
1375a97703c5SGabriel Fernandez 	},\
1376a97703c5SGabriel Fernandez 	.func		= _clk_stm32_register_composite,\
1377a97703c5SGabriel Fernandez }
1378a97703c5SGabriel Fernandez 
13791f80590bSGabriel Fernandez #define PCLK(_id, _name, _parent, _flags, _mgate)\
13801f80590bSGabriel Fernandez 	MGATE_MP1(_id, _name, _parent, _flags, _mgate)
13811f80590bSGabriel Fernandez 
1382e9ed1ef1SMarek Vasut #define PCLK_PDATA(_id, _name, _parent, _flags, _mgate)\
1383e9ed1ef1SMarek Vasut 	MGATE_MP1_PDATA(_id, _name, _parent, _flags, _mgate)
1384e9ed1ef1SMarek Vasut 
13851f80590bSGabriel Fernandez #define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\
138672cfd1adSGabriel Fernandez 	     COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE |\
138772cfd1adSGabriel Fernandez 		       CLK_SET_RATE_NO_REPARENT | _flags,\
13881f80590bSGabriel Fernandez 		       _MGATE_MP1(_mgate),\
13891f80590bSGabriel Fernandez 		       _MMUX(_mmux),\
13901f80590bSGabriel Fernandez 		       _NO_DIV)
13911f80590bSGabriel Fernandez 
13921f80590bSGabriel Fernandez enum {
13931f80590bSGabriel Fernandez 	G_SAI1,
13941f80590bSGabriel Fernandez 	G_SAI2,
13951f80590bSGabriel Fernandez 	G_SAI3,
13961f80590bSGabriel Fernandez 	G_SAI4,
13971f80590bSGabriel Fernandez 	G_SPI1,
13981f80590bSGabriel Fernandez 	G_SPI2,
13991f80590bSGabriel Fernandez 	G_SPI3,
14001f80590bSGabriel Fernandez 	G_SPI4,
14011f80590bSGabriel Fernandez 	G_SPI5,
14021f80590bSGabriel Fernandez 	G_SPI6,
14031f80590bSGabriel Fernandez 	G_SPDIF,
14041f80590bSGabriel Fernandez 	G_I2C1,
14051f80590bSGabriel Fernandez 	G_I2C2,
14061f80590bSGabriel Fernandez 	G_I2C3,
14071f80590bSGabriel Fernandez 	G_I2C4,
14081f80590bSGabriel Fernandez 	G_I2C5,
14091f80590bSGabriel Fernandez 	G_I2C6,
14101f80590bSGabriel Fernandez 	G_USART2,
14111f80590bSGabriel Fernandez 	G_UART4,
14121f80590bSGabriel Fernandez 	G_USART3,
14131f80590bSGabriel Fernandez 	G_UART5,
14141f80590bSGabriel Fernandez 	G_USART1,
14151f80590bSGabriel Fernandez 	G_USART6,
14161f80590bSGabriel Fernandez 	G_UART7,
14171f80590bSGabriel Fernandez 	G_UART8,
14181f80590bSGabriel Fernandez 	G_LPTIM1,
14191f80590bSGabriel Fernandez 	G_LPTIM2,
14201f80590bSGabriel Fernandez 	G_LPTIM3,
14211f80590bSGabriel Fernandez 	G_LPTIM4,
14221f80590bSGabriel Fernandez 	G_LPTIM5,
14231f80590bSGabriel Fernandez 	G_LTDC,
14241f80590bSGabriel Fernandez 	G_DSI,
14251f80590bSGabriel Fernandez 	G_QSPI,
14261f80590bSGabriel Fernandez 	G_FMC,
14271f80590bSGabriel Fernandez 	G_SDMMC1,
14281f80590bSGabriel Fernandez 	G_SDMMC2,
14291f80590bSGabriel Fernandez 	G_SDMMC3,
14301f80590bSGabriel Fernandez 	G_USBO,
14311f80590bSGabriel Fernandez 	G_USBPHY,
14321f80590bSGabriel Fernandez 	G_RNG1,
14331f80590bSGabriel Fernandez 	G_RNG2,
14341f80590bSGabriel Fernandez 	G_FDCAN,
14351f80590bSGabriel Fernandez 	G_DAC12,
14361f80590bSGabriel Fernandez 	G_CEC,
14371f80590bSGabriel Fernandez 	G_ADC12,
14381f80590bSGabriel Fernandez 	G_GPU,
14391f80590bSGabriel Fernandez 	G_STGEN,
14401f80590bSGabriel Fernandez 	G_DFSDM,
14411f80590bSGabriel Fernandez 	G_ADFSDM,
14421f80590bSGabriel Fernandez 	G_TIM2,
14431f80590bSGabriel Fernandez 	G_TIM3,
14441f80590bSGabriel Fernandez 	G_TIM4,
14451f80590bSGabriel Fernandez 	G_TIM5,
14461f80590bSGabriel Fernandez 	G_TIM6,
14471f80590bSGabriel Fernandez 	G_TIM7,
14481f80590bSGabriel Fernandez 	G_TIM12,
14491f80590bSGabriel Fernandez 	G_TIM13,
14501f80590bSGabriel Fernandez 	G_TIM14,
14511f80590bSGabriel Fernandez 	G_MDIO,
14521f80590bSGabriel Fernandez 	G_TIM1,
14531f80590bSGabriel Fernandez 	G_TIM8,
14541f80590bSGabriel Fernandez 	G_TIM15,
14551f80590bSGabriel Fernandez 	G_TIM16,
14561f80590bSGabriel Fernandez 	G_TIM17,
14571f80590bSGabriel Fernandez 	G_SYSCFG,
14581f80590bSGabriel Fernandez 	G_VREF,
14591f80590bSGabriel Fernandez 	G_TMPSENS,
14601f80590bSGabriel Fernandez 	G_PMBCTRL,
14611f80590bSGabriel Fernandez 	G_HDP,
14621f80590bSGabriel Fernandez 	G_IWDG2,
14631f80590bSGabriel Fernandez 	G_STGENRO,
14641f80590bSGabriel Fernandez 	G_DMA1,
14651f80590bSGabriel Fernandez 	G_DMA2,
14661f80590bSGabriel Fernandez 	G_DMAMUX,
14671f80590bSGabriel Fernandez 	G_DCMI,
14681f80590bSGabriel Fernandez 	G_CRYP2,
14691f80590bSGabriel Fernandez 	G_HASH2,
14701f80590bSGabriel Fernandez 	G_CRC2,
14711f80590bSGabriel Fernandez 	G_HSEM,
14721f80590bSGabriel Fernandez 	G_IPCC,
14731f80590bSGabriel Fernandez 	G_GPIOA,
14741f80590bSGabriel Fernandez 	G_GPIOB,
14751f80590bSGabriel Fernandez 	G_GPIOC,
14761f80590bSGabriel Fernandez 	G_GPIOD,
14771f80590bSGabriel Fernandez 	G_GPIOE,
14781f80590bSGabriel Fernandez 	G_GPIOF,
14791f80590bSGabriel Fernandez 	G_GPIOG,
14801f80590bSGabriel Fernandez 	G_GPIOH,
14811f80590bSGabriel Fernandez 	G_GPIOI,
14821f80590bSGabriel Fernandez 	G_GPIOJ,
14831f80590bSGabriel Fernandez 	G_GPIOK,
14841f80590bSGabriel Fernandez 	G_MDMA,
14851f80590bSGabriel Fernandez 	G_ETHCK,
14861f80590bSGabriel Fernandez 	G_ETHTX,
14871f80590bSGabriel Fernandez 	G_ETHRX,
14881f80590bSGabriel Fernandez 	G_ETHMAC,
14891f80590bSGabriel Fernandez 	G_CRC1,
14901f80590bSGabriel Fernandez 	G_USBH,
14911f80590bSGabriel Fernandez 	G_ETHSTP,
14921f80590bSGabriel Fernandez 	G_RTCAPB,
1493a1bf646fSGabriel Fernandez 	G_TZC1,
1494a1bf646fSGabriel Fernandez 	G_TZC2,
14951f80590bSGabriel Fernandez 	G_TZPC,
14961f80590bSGabriel Fernandez 	G_IWDG1,
14971f80590bSGabriel Fernandez 	G_BSEC,
14981f80590bSGabriel Fernandez 	G_GPIOZ,
14991f80590bSGabriel Fernandez 	G_CRYP1,
15001f80590bSGabriel Fernandez 	G_HASH1,
15011f80590bSGabriel Fernandez 	G_BKPSRAM,
1502b06df56bSGabriel Fernandez 	G_DDRPERFM,
15031f80590bSGabriel Fernandez 
15041f80590bSGabriel Fernandez 	G_LAST
15051f80590bSGabriel Fernandez };
15061f80590bSGabriel Fernandez 
1507e631ad60SGabriel Fernandez static struct stm32_mgate mp1_mgate[G_LAST];
15081f80590bSGabriel Fernandez 
15091f80590bSGabriel Fernandez #define _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
15101f80590bSGabriel Fernandez 	       _mgate, _ops)\
15111f80590bSGabriel Fernandez 	[_id] = {\
15121f80590bSGabriel Fernandez 		&(struct gate_cfg) {\
15131f80590bSGabriel Fernandez 			.reg_off	= _gate_offset,\
15141f80590bSGabriel Fernandez 			.bit_idx	= _gate_bit_idx,\
15151f80590bSGabriel Fernandez 			.gate_flags	= _gate_flags,\
15161f80590bSGabriel Fernandez 		},\
15171f80590bSGabriel Fernandez 		.mgate		= _mgate,\
15181f80590bSGabriel Fernandez 		.ops		= _ops,\
15191f80590bSGabriel Fernandez 	}
15201f80590bSGabriel Fernandez 
15211f80590bSGabriel Fernandez #define K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags)\
15221f80590bSGabriel Fernandez 	_K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
15231f80590bSGabriel Fernandez 	       NULL, &mp1_gate_clk_ops)
15241f80590bSGabriel Fernandez 
15251f80590bSGabriel Fernandez #define K_MGATE(_id, _gate_offset, _gate_bit_idx, _gate_flags)\
15261f80590bSGabriel Fernandez 	_K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
15271f80590bSGabriel Fernandez 	       &mp1_mgate[_id], &mp1_mgate_clk_ops)
15281f80590bSGabriel Fernandez 
15291f80590bSGabriel Fernandez /* Peripheral gates */
1530e631ad60SGabriel Fernandez static struct stm32_gate_cfg per_gate_cfg[G_LAST] = {
15311f80590bSGabriel Fernandez 	/* Multi gates */
15321f80590bSGabriel Fernandez 	K_GATE(G_MDIO,		RCC_APB1ENSETR, 31, 0),
15331f80590bSGabriel Fernandez 	K_MGATE(G_DAC12,	RCC_APB1ENSETR, 29, 0),
15341f80590bSGabriel Fernandez 	K_MGATE(G_CEC,		RCC_APB1ENSETR, 27, 0),
15351f80590bSGabriel Fernandez 	K_MGATE(G_SPDIF,	RCC_APB1ENSETR, 26, 0),
15361f80590bSGabriel Fernandez 	K_MGATE(G_I2C5,		RCC_APB1ENSETR, 24, 0),
15371f80590bSGabriel Fernandez 	K_MGATE(G_I2C3,		RCC_APB1ENSETR, 23, 0),
15381f80590bSGabriel Fernandez 	K_MGATE(G_I2C2,		RCC_APB1ENSETR, 22, 0),
15391f80590bSGabriel Fernandez 	K_MGATE(G_I2C1,		RCC_APB1ENSETR, 21, 0),
15401f80590bSGabriel Fernandez 	K_MGATE(G_UART8,	RCC_APB1ENSETR, 19, 0),
15411f80590bSGabriel Fernandez 	K_MGATE(G_UART7,	RCC_APB1ENSETR, 18, 0),
15421f80590bSGabriel Fernandez 	K_MGATE(G_UART5,	RCC_APB1ENSETR, 17, 0),
15431f80590bSGabriel Fernandez 	K_MGATE(G_UART4,	RCC_APB1ENSETR, 16, 0),
15441f80590bSGabriel Fernandez 	K_MGATE(G_USART3,	RCC_APB1ENSETR, 15, 0),
15451f80590bSGabriel Fernandez 	K_MGATE(G_USART2,	RCC_APB1ENSETR, 14, 0),
15461f80590bSGabriel Fernandez 	K_MGATE(G_SPI3,		RCC_APB1ENSETR, 12, 0),
15471f80590bSGabriel Fernandez 	K_MGATE(G_SPI2,		RCC_APB1ENSETR, 11, 0),
15481f80590bSGabriel Fernandez 	K_MGATE(G_LPTIM1,	RCC_APB1ENSETR, 9, 0),
15491f80590bSGabriel Fernandez 	K_GATE(G_TIM14,		RCC_APB1ENSETR, 8, 0),
15501f80590bSGabriel Fernandez 	K_GATE(G_TIM13,		RCC_APB1ENSETR, 7, 0),
15511f80590bSGabriel Fernandez 	K_GATE(G_TIM12,		RCC_APB1ENSETR, 6, 0),
15521f80590bSGabriel Fernandez 	K_GATE(G_TIM7,		RCC_APB1ENSETR, 5, 0),
15531f80590bSGabriel Fernandez 	K_GATE(G_TIM6,		RCC_APB1ENSETR, 4, 0),
15541f80590bSGabriel Fernandez 	K_GATE(G_TIM5,		RCC_APB1ENSETR, 3, 0),
15551f80590bSGabriel Fernandez 	K_GATE(G_TIM4,		RCC_APB1ENSETR, 2, 0),
15561f80590bSGabriel Fernandez 	K_GATE(G_TIM3,		RCC_APB1ENSETR, 1, 0),
15571f80590bSGabriel Fernandez 	K_GATE(G_TIM2,		RCC_APB1ENSETR, 0, 0),
15581f80590bSGabriel Fernandez 
15591f80590bSGabriel Fernandez 	K_MGATE(G_FDCAN,	RCC_APB2ENSETR, 24, 0),
15601f80590bSGabriel Fernandez 	K_GATE(G_ADFSDM,	RCC_APB2ENSETR, 21, 0),
15611f80590bSGabriel Fernandez 	K_GATE(G_DFSDM,		RCC_APB2ENSETR, 20, 0),
15621f80590bSGabriel Fernandez 	K_MGATE(G_SAI3,		RCC_APB2ENSETR, 18, 0),
15631f80590bSGabriel Fernandez 	K_MGATE(G_SAI2,		RCC_APB2ENSETR, 17, 0),
15641f80590bSGabriel Fernandez 	K_MGATE(G_SAI1,		RCC_APB2ENSETR, 16, 0),
15651f80590bSGabriel Fernandez 	K_MGATE(G_USART6,	RCC_APB2ENSETR, 13, 0),
15661f80590bSGabriel Fernandez 	K_MGATE(G_SPI5,		RCC_APB2ENSETR, 10, 0),
15671f80590bSGabriel Fernandez 	K_MGATE(G_SPI4,		RCC_APB2ENSETR, 9, 0),
15681f80590bSGabriel Fernandez 	K_MGATE(G_SPI1,		RCC_APB2ENSETR, 8, 0),
15691f80590bSGabriel Fernandez 	K_GATE(G_TIM17,		RCC_APB2ENSETR, 4, 0),
15701f80590bSGabriel Fernandez 	K_GATE(G_TIM16,		RCC_APB2ENSETR, 3, 0),
15711f80590bSGabriel Fernandez 	K_GATE(G_TIM15,		RCC_APB2ENSETR, 2, 0),
15721f80590bSGabriel Fernandez 	K_GATE(G_TIM8,		RCC_APB2ENSETR, 1, 0),
15731f80590bSGabriel Fernandez 	K_GATE(G_TIM1,		RCC_APB2ENSETR, 0, 0),
15741f80590bSGabriel Fernandez 
15751f80590bSGabriel Fernandez 	K_GATE(G_HDP,		RCC_APB3ENSETR, 20, 0),
15761f80590bSGabriel Fernandez 	K_GATE(G_PMBCTRL,	RCC_APB3ENSETR, 17, 0),
15771f80590bSGabriel Fernandez 	K_GATE(G_TMPSENS,	RCC_APB3ENSETR, 16, 0),
15781f80590bSGabriel Fernandez 	K_GATE(G_VREF,		RCC_APB3ENSETR, 13, 0),
15791f80590bSGabriel Fernandez 	K_GATE(G_SYSCFG,	RCC_APB3ENSETR, 11, 0),
15801f80590bSGabriel Fernandez 	K_MGATE(G_SAI4,		RCC_APB3ENSETR, 8, 0),
15811f80590bSGabriel Fernandez 	K_MGATE(G_LPTIM5,	RCC_APB3ENSETR, 3, 0),
15821f80590bSGabriel Fernandez 	K_MGATE(G_LPTIM4,	RCC_APB3ENSETR, 2, 0),
15831f80590bSGabriel Fernandez 	K_MGATE(G_LPTIM3,	RCC_APB3ENSETR, 1, 0),
15841f80590bSGabriel Fernandez 	K_MGATE(G_LPTIM2,	RCC_APB3ENSETR, 0, 0),
15851f80590bSGabriel Fernandez 
15861f80590bSGabriel Fernandez 	K_GATE(G_STGENRO,	RCC_APB4ENSETR, 20, 0),
15871f80590bSGabriel Fernandez 	K_MGATE(G_USBPHY,	RCC_APB4ENSETR, 16, 0),
15881f80590bSGabriel Fernandez 	K_GATE(G_IWDG2,		RCC_APB4ENSETR, 15, 0),
1589b06df56bSGabriel Fernandez 	K_GATE(G_DDRPERFM,	RCC_APB4ENSETR, 8, 0),
15901f80590bSGabriel Fernandez 	K_MGATE(G_DSI,		RCC_APB4ENSETR, 4, 0),
15911f80590bSGabriel Fernandez 	K_MGATE(G_LTDC,		RCC_APB4ENSETR, 0, 0),
15921f80590bSGabriel Fernandez 
15931f80590bSGabriel Fernandez 	K_GATE(G_STGEN,		RCC_APB5ENSETR, 20, 0),
15941f80590bSGabriel Fernandez 	K_GATE(G_BSEC,		RCC_APB5ENSETR, 16, 0),
15951f80590bSGabriel Fernandez 	K_GATE(G_IWDG1,		RCC_APB5ENSETR, 15, 0),
15961f80590bSGabriel Fernandez 	K_GATE(G_TZPC,		RCC_APB5ENSETR, 13, 0),
1597a1bf646fSGabriel Fernandez 	K_GATE(G_TZC2,		RCC_APB5ENSETR, 12, 0),
1598a1bf646fSGabriel Fernandez 	K_GATE(G_TZC1,		RCC_APB5ENSETR, 11, 0),
15991f80590bSGabriel Fernandez 	K_GATE(G_RTCAPB,	RCC_APB5ENSETR, 8, 0),
16001f80590bSGabriel Fernandez 	K_MGATE(G_USART1,	RCC_APB5ENSETR, 4, 0),
16011f80590bSGabriel Fernandez 	K_MGATE(G_I2C6,		RCC_APB5ENSETR, 3, 0),
16021f80590bSGabriel Fernandez 	K_MGATE(G_I2C4,		RCC_APB5ENSETR, 2, 0),
16031f80590bSGabriel Fernandez 	K_MGATE(G_SPI6,		RCC_APB5ENSETR, 0, 0),
16041f80590bSGabriel Fernandez 
16051f80590bSGabriel Fernandez 	K_MGATE(G_SDMMC3,	RCC_AHB2ENSETR, 16, 0),
16061f80590bSGabriel Fernandez 	K_MGATE(G_USBO,		RCC_AHB2ENSETR, 8, 0),
16071f80590bSGabriel Fernandez 	K_MGATE(G_ADC12,	RCC_AHB2ENSETR, 5, 0),
16081f80590bSGabriel Fernandez 	K_GATE(G_DMAMUX,	RCC_AHB2ENSETR, 2, 0),
16091f80590bSGabriel Fernandez 	K_GATE(G_DMA2,		RCC_AHB2ENSETR, 1, 0),
16101f80590bSGabriel Fernandez 	K_GATE(G_DMA1,		RCC_AHB2ENSETR, 0, 0),
16111f80590bSGabriel Fernandez 
16121f80590bSGabriel Fernandez 	K_GATE(G_IPCC,		RCC_AHB3ENSETR, 12, 0),
16131f80590bSGabriel Fernandez 	K_GATE(G_HSEM,		RCC_AHB3ENSETR, 11, 0),
16141f80590bSGabriel Fernandez 	K_GATE(G_CRC2,		RCC_AHB3ENSETR, 7, 0),
16151f80590bSGabriel Fernandez 	K_MGATE(G_RNG2,		RCC_AHB3ENSETR, 6, 0),
16161f80590bSGabriel Fernandez 	K_GATE(G_HASH2,		RCC_AHB3ENSETR, 5, 0),
16171f80590bSGabriel Fernandez 	K_GATE(G_CRYP2,		RCC_AHB3ENSETR, 4, 0),
16181f80590bSGabriel Fernandez 	K_GATE(G_DCMI,		RCC_AHB3ENSETR, 0, 0),
16191f80590bSGabriel Fernandez 
16201f80590bSGabriel Fernandez 	K_GATE(G_GPIOK,		RCC_AHB4ENSETR, 10, 0),
16211f80590bSGabriel Fernandez 	K_GATE(G_GPIOJ,		RCC_AHB4ENSETR, 9, 0),
16221f80590bSGabriel Fernandez 	K_GATE(G_GPIOI,		RCC_AHB4ENSETR, 8, 0),
16231f80590bSGabriel Fernandez 	K_GATE(G_GPIOH,		RCC_AHB4ENSETR, 7, 0),
16241f80590bSGabriel Fernandez 	K_GATE(G_GPIOG,		RCC_AHB4ENSETR, 6, 0),
16251f80590bSGabriel Fernandez 	K_GATE(G_GPIOF,		RCC_AHB4ENSETR, 5, 0),
16261f80590bSGabriel Fernandez 	K_GATE(G_GPIOE,		RCC_AHB4ENSETR, 4, 0),
16271f80590bSGabriel Fernandez 	K_GATE(G_GPIOD,		RCC_AHB4ENSETR, 3, 0),
16281f80590bSGabriel Fernandez 	K_GATE(G_GPIOC,		RCC_AHB4ENSETR, 2, 0),
16291f80590bSGabriel Fernandez 	K_GATE(G_GPIOB,		RCC_AHB4ENSETR, 1, 0),
16301f80590bSGabriel Fernandez 	K_GATE(G_GPIOA,		RCC_AHB4ENSETR, 0, 0),
16311f80590bSGabriel Fernandez 
16321f80590bSGabriel Fernandez 	K_GATE(G_BKPSRAM,	RCC_AHB5ENSETR, 8, 0),
16331f80590bSGabriel Fernandez 	K_MGATE(G_RNG1,		RCC_AHB5ENSETR, 6, 0),
16341f80590bSGabriel Fernandez 	K_GATE(G_HASH1,		RCC_AHB5ENSETR, 5, 0),
16351f80590bSGabriel Fernandez 	K_GATE(G_CRYP1,		RCC_AHB5ENSETR, 4, 0),
16361f80590bSGabriel Fernandez 	K_GATE(G_GPIOZ,		RCC_AHB5ENSETR, 0, 0),
16371f80590bSGabriel Fernandez 
16381f80590bSGabriel Fernandez 	K_GATE(G_USBH,		RCC_AHB6ENSETR, 24, 0),
16391f80590bSGabriel Fernandez 	K_GATE(G_CRC1,		RCC_AHB6ENSETR, 20, 0),
16401f80590bSGabriel Fernandez 	K_MGATE(G_SDMMC2,	RCC_AHB6ENSETR, 17, 0),
16411f80590bSGabriel Fernandez 	K_MGATE(G_SDMMC1,	RCC_AHB6ENSETR, 16, 0),
16421f80590bSGabriel Fernandez 	K_MGATE(G_QSPI,		RCC_AHB6ENSETR, 14, 0),
16431f80590bSGabriel Fernandez 	K_MGATE(G_FMC,		RCC_AHB6ENSETR, 12, 0),
16441f80590bSGabriel Fernandez 	K_GATE(G_ETHMAC,	RCC_AHB6ENSETR, 10, 0),
16451f80590bSGabriel Fernandez 	K_GATE(G_ETHRX,		RCC_AHB6ENSETR, 9, 0),
16461f80590bSGabriel Fernandez 	K_GATE(G_ETHTX,		RCC_AHB6ENSETR, 8, 0),
16471f80590bSGabriel Fernandez 	K_GATE(G_ETHCK,		RCC_AHB6ENSETR, 7, 0),
16481f80590bSGabriel Fernandez 	K_MGATE(G_GPU,		RCC_AHB6ENSETR, 5, 0),
16491f80590bSGabriel Fernandez 	K_GATE(G_MDMA,		RCC_AHB6ENSETR, 0, 0),
16501f80590bSGabriel Fernandez 	K_GATE(G_ETHSTP,	RCC_AHB6LPENSETR, 11, 0),
16511f80590bSGabriel Fernandez };
16521f80590bSGabriel Fernandez 
16531f80590bSGabriel Fernandez enum {
16541f80590bSGabriel Fernandez 	M_SDMMC12,
16551f80590bSGabriel Fernandez 	M_SDMMC3,
16561f80590bSGabriel Fernandez 	M_FMC,
16571f80590bSGabriel Fernandez 	M_QSPI,
16581f80590bSGabriel Fernandez 	M_RNG1,
16591f80590bSGabriel Fernandez 	M_RNG2,
16601f80590bSGabriel Fernandez 	M_USBPHY,
16611f80590bSGabriel Fernandez 	M_USBO,
16621f80590bSGabriel Fernandez 	M_STGEN,
16631f80590bSGabriel Fernandez 	M_SPDIF,
16641f80590bSGabriel Fernandez 	M_SPI1,
16651f80590bSGabriel Fernandez 	M_SPI23,
16661f80590bSGabriel Fernandez 	M_SPI45,
16671f80590bSGabriel Fernandez 	M_SPI6,
16681f80590bSGabriel Fernandez 	M_CEC,
16691f80590bSGabriel Fernandez 	M_I2C12,
16701f80590bSGabriel Fernandez 	M_I2C35,
16711f80590bSGabriel Fernandez 	M_I2C46,
16721f80590bSGabriel Fernandez 	M_LPTIM1,
16731f80590bSGabriel Fernandez 	M_LPTIM23,
16741f80590bSGabriel Fernandez 	M_LPTIM45,
16751f80590bSGabriel Fernandez 	M_USART1,
16761f80590bSGabriel Fernandez 	M_UART24,
16771f80590bSGabriel Fernandez 	M_UART35,
16781f80590bSGabriel Fernandez 	M_USART6,
16791f80590bSGabriel Fernandez 	M_UART78,
16801f80590bSGabriel Fernandez 	M_SAI1,
16811f80590bSGabriel Fernandez 	M_SAI2,
16821f80590bSGabriel Fernandez 	M_SAI3,
16831f80590bSGabriel Fernandez 	M_SAI4,
16841f80590bSGabriel Fernandez 	M_DSI,
16851f80590bSGabriel Fernandez 	M_FDCAN,
16861f80590bSGabriel Fernandez 	M_ADC12,
16871f80590bSGabriel Fernandez 	M_ETHCK,
16881f80590bSGabriel Fernandez 	M_CKPER,
16891f80590bSGabriel Fernandez 	M_LAST
16901f80590bSGabriel Fernandez };
16911f80590bSGabriel Fernandez 
1692e631ad60SGabriel Fernandez static struct stm32_mmux ker_mux[M_LAST];
16931f80590bSGabriel Fernandez 
16941f80590bSGabriel Fernandez #define _K_MUX(_id, _offset, _shift, _width, _mux_flags, _mmux, _ops)\
16951f80590bSGabriel Fernandez 	[_id] = {\
16961f80590bSGabriel Fernandez 		&(struct mux_cfg) {\
16971f80590bSGabriel Fernandez 			.reg_off	= _offset,\
16981f80590bSGabriel Fernandez 			.shift		= _shift,\
16991f80590bSGabriel Fernandez 			.width		= _width,\
17001f80590bSGabriel Fernandez 			.mux_flags	= _mux_flags,\
17011f80590bSGabriel Fernandez 			.table		= NULL,\
17021f80590bSGabriel Fernandez 		},\
17031f80590bSGabriel Fernandez 		.mmux		= _mmux,\
17041f80590bSGabriel Fernandez 		.ops		= _ops,\
17051f80590bSGabriel Fernandez 	}
17061f80590bSGabriel Fernandez 
17071f80590bSGabriel Fernandez #define K_MUX(_id, _offset, _shift, _width, _mux_flags)\
17081f80590bSGabriel Fernandez 	_K_MUX(_id, _offset, _shift, _width, _mux_flags,\
17091f80590bSGabriel Fernandez 			NULL, NULL)
17101f80590bSGabriel Fernandez 
17111f80590bSGabriel Fernandez #define K_MMUX(_id, _offset, _shift, _width, _mux_flags)\
17121f80590bSGabriel Fernandez 	_K_MUX(_id, _offset, _shift, _width, _mux_flags,\
17131f80590bSGabriel Fernandez 			&ker_mux[_id], &clk_mmux_ops)
17141f80590bSGabriel Fernandez 
1715e631ad60SGabriel Fernandez static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = {
17161f80590bSGabriel Fernandez 	/* Kernel multi mux */
17171f80590bSGabriel Fernandez 	K_MMUX(M_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0),
17181f80590bSGabriel Fernandez 	K_MMUX(M_SPI23, RCC_SPI2S23CKSELR, 0, 3, 0),
17191f80590bSGabriel Fernandez 	K_MMUX(M_SPI45, RCC_SPI2S45CKSELR, 0, 3, 0),
17201f80590bSGabriel Fernandez 	K_MMUX(M_I2C12, RCC_I2C12CKSELR, 0, 3, 0),
17211f80590bSGabriel Fernandez 	K_MMUX(M_I2C35, RCC_I2C35CKSELR, 0, 3, 0),
17221f80590bSGabriel Fernandez 	K_MMUX(M_LPTIM23, RCC_LPTIM23CKSELR, 0, 3, 0),
17231f80590bSGabriel Fernandez 	K_MMUX(M_LPTIM45, RCC_LPTIM45CKSELR, 0, 3, 0),
17241f80590bSGabriel Fernandez 	K_MMUX(M_UART24, RCC_UART24CKSELR, 0, 3, 0),
17251f80590bSGabriel Fernandez 	K_MMUX(M_UART35, RCC_UART35CKSELR, 0, 3, 0),
17261f80590bSGabriel Fernandez 	K_MMUX(M_UART78, RCC_UART78CKSELR, 0, 3, 0),
17271f80590bSGabriel Fernandez 	K_MMUX(M_SAI1, RCC_SAI1CKSELR, 0, 3, 0),
17281f80590bSGabriel Fernandez 	K_MMUX(M_ETHCK, RCC_ETHCKSELR, 0, 2, 0),
17291f80590bSGabriel Fernandez 	K_MMUX(M_I2C46, RCC_I2C46CKSELR, 0, 3, 0),
17301f80590bSGabriel Fernandez 
17311f80590bSGabriel Fernandez 	/*  Kernel simple mux */
17321f80590bSGabriel Fernandez 	K_MUX(M_RNG2, RCC_RNG2CKSELR, 0, 2, 0),
17331f80590bSGabriel Fernandez 	K_MUX(M_SDMMC3, RCC_SDMMC3CKSELR, 0, 3, 0),
17341f80590bSGabriel Fernandez 	K_MUX(M_FMC, RCC_FMCCKSELR, 0, 2, 0),
17351f80590bSGabriel Fernandez 	K_MUX(M_QSPI, RCC_QSPICKSELR, 0, 2, 0),
17361f80590bSGabriel Fernandez 	K_MUX(M_USBPHY, RCC_USBCKSELR, 0, 2, 0),
17371f80590bSGabriel Fernandez 	K_MUX(M_USBO, RCC_USBCKSELR, 4, 1, 0),
17381f80590bSGabriel Fernandez 	K_MUX(M_SPDIF, RCC_SPDIFCKSELR, 0, 2, 0),
17391f80590bSGabriel Fernandez 	K_MUX(M_SPI1, RCC_SPI2S1CKSELR, 0, 3, 0),
17401f80590bSGabriel Fernandez 	K_MUX(M_CEC, RCC_CECCKSELR, 0, 2, 0),
17411f80590bSGabriel Fernandez 	K_MUX(M_LPTIM1, RCC_LPTIM1CKSELR, 0, 3, 0),
17421f80590bSGabriel Fernandez 	K_MUX(M_USART6, RCC_UART6CKSELR, 0, 3, 0),
17431f80590bSGabriel Fernandez 	K_MUX(M_FDCAN, RCC_FDCANCKSELR, 0, 2, 0),
17441f80590bSGabriel Fernandez 	K_MUX(M_SAI2, RCC_SAI2CKSELR, 0, 3, 0),
17451f80590bSGabriel Fernandez 	K_MUX(M_SAI3, RCC_SAI3CKSELR, 0, 3, 0),
17461f80590bSGabriel Fernandez 	K_MUX(M_SAI4, RCC_SAI4CKSELR, 0, 3, 0),
17471f80590bSGabriel Fernandez 	K_MUX(M_ADC12, RCC_ADCCKSELR, 0, 2, 0),
17481f80590bSGabriel Fernandez 	K_MUX(M_DSI, RCC_DSICKSELR, 0, 1, 0),
17491f80590bSGabriel Fernandez 	K_MUX(M_CKPER, RCC_CPERCKSELR, 0, 2, 0),
17501f80590bSGabriel Fernandez 	K_MUX(M_RNG1, RCC_RNG1CKSELR, 0, 2, 0),
17511f80590bSGabriel Fernandez 	K_MUX(M_STGEN, RCC_STGENCKSELR, 0, 2, 0),
17521f80590bSGabriel Fernandez 	K_MUX(M_USART1, RCC_UART1CKSELR, 0, 3, 0),
17531f80590bSGabriel Fernandez 	K_MUX(M_SPI6, RCC_SPI6CKSELR, 0, 3, 0),
17541f80590bSGabriel Fernandez };
17551f80590bSGabriel Fernandez 
17569bee94e7SGabriel Fernandez static const struct clock_config stm32mp1_clock_cfg[] = {
17579bee94e7SGabriel Fernandez 	/*  External / Internal Oscillators */
17588e6c27c0SGabriel Fernandez 	GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0),
1759c488b24fSGabriel Fernandez 	/* ck_csi is used by IO compensation and should be critical */
1760c488b24fSGabriel Fernandez 	GATE_MP1(CK_CSI, "ck_csi", "clk-csi", CLK_IS_CRITICAL,
1761c488b24fSGabriel Fernandez 		 RCC_OCENSETR, 4, 0),
176247c671daSGabriel Fernandez 	COMPOSITE(CK_HSI, "ck_hsi", PARENT("clk-hsi"), 0,
176347c671daSGabriel Fernandez 		  _GATE_MP1(RCC_OCENSETR, 0, 0),
176447c671daSGabriel Fernandez 		  _NO_MUX,
176547c671daSGabriel Fernandez 		  _DIV(RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO |
176647c671daSGabriel Fernandez 		       CLK_DIVIDER_READ_ONLY, NULL)),
17679bee94e7SGabriel Fernandez 	GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
17689bee94e7SGabriel Fernandez 	GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
17699bee94e7SGabriel Fernandez 
17709bee94e7SGabriel Fernandez 	FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2),
1771dc32eaacSGabriel Fernandez 
1772c6cf4d32SGabriel Fernandez 	/* PLLs */
17739008fddeSGabriel Fernandez 	PLL(PLL1, "pll1", ref12_parents, 0, RCC_PLL1CR, RCC_RCK12SELR),
17749008fddeSGabriel Fernandez 	PLL(PLL2, "pll2", ref12_parents, 0, RCC_PLL2CR, RCC_RCK12SELR),
17759008fddeSGabriel Fernandez 	PLL(PLL3, "pll3", ref3_parents, 0, RCC_PLL3CR, RCC_RCK3SELR),
17769008fddeSGabriel Fernandez 	PLL(PLL4, "pll4", ref4_parents, 0, RCC_PLL4CR, RCC_RCK4SELR),
1777a97703c5SGabriel Fernandez 
1778a97703c5SGabriel Fernandez 	/* ODF */
1779a97703c5SGabriel Fernandez 	COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0,
1780a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL1CR, 4, 0),
1781a97703c5SGabriel Fernandez 		  _NO_MUX,
1782a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL1CFGR2, 0, 7, 0, NULL)),
1783a97703c5SGabriel Fernandez 
1784a97703c5SGabriel Fernandez 	COMPOSITE(PLL2_P, "pll2_p", PARENT("pll2"), 0,
1785a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL2CR, 4, 0),
1786a97703c5SGabriel Fernandez 		  _NO_MUX,
1787a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL2CFGR2, 0, 7, 0, NULL)),
1788a97703c5SGabriel Fernandez 
1789a97703c5SGabriel Fernandez 	COMPOSITE(PLL2_Q, "pll2_q", PARENT("pll2"), 0,
1790a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL2CR, 5, 0),
1791a97703c5SGabriel Fernandez 		  _NO_MUX,
1792a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL2CFGR2, 8, 7, 0, NULL)),
1793a97703c5SGabriel Fernandez 
1794a97703c5SGabriel Fernandez 	COMPOSITE(PLL2_R, "pll2_r", PARENT("pll2"), CLK_IS_CRITICAL,
1795a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL2CR, 6, 0),
1796a97703c5SGabriel Fernandez 		  _NO_MUX,
1797a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL2CFGR2, 16, 7, 0, NULL)),
1798a97703c5SGabriel Fernandez 
1799a97703c5SGabriel Fernandez 	COMPOSITE(PLL3_P, "pll3_p", PARENT("pll3"), 0,
1800a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL3CR, 4, 0),
1801a97703c5SGabriel Fernandez 		  _NO_MUX,
1802a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL3CFGR2, 0, 7, 0, NULL)),
1803a97703c5SGabriel Fernandez 
1804a97703c5SGabriel Fernandez 	COMPOSITE(PLL3_Q, "pll3_q", PARENT("pll3"), 0,
1805a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL3CR, 5, 0),
1806a97703c5SGabriel Fernandez 		  _NO_MUX,
1807a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL3CFGR2, 8, 7, 0, NULL)),
1808a97703c5SGabriel Fernandez 
1809a97703c5SGabriel Fernandez 	COMPOSITE(PLL3_R, "pll3_r", PARENT("pll3"), 0,
1810a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL3CR, 6, 0),
1811a97703c5SGabriel Fernandez 		  _NO_MUX,
1812a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL3CFGR2, 16, 7, 0, NULL)),
1813a97703c5SGabriel Fernandez 
1814a97703c5SGabriel Fernandez 	COMPOSITE(PLL4_P, "pll4_p", PARENT("pll4"), 0,
1815a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL4CR, 4, 0),
1816a97703c5SGabriel Fernandez 		  _NO_MUX,
1817a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL4CFGR2, 0, 7, 0, NULL)),
1818a97703c5SGabriel Fernandez 
1819a97703c5SGabriel Fernandez 	COMPOSITE(PLL4_Q, "pll4_q", PARENT("pll4"), 0,
1820a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL4CR, 5, 0),
1821a97703c5SGabriel Fernandez 		  _NO_MUX,
1822a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL4CFGR2, 8, 7, 0, NULL)),
1823a97703c5SGabriel Fernandez 
1824a97703c5SGabriel Fernandez 	COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0,
1825a97703c5SGabriel Fernandez 		  _GATE(RCC_PLL4CR, 6, 0),
1826a97703c5SGabriel Fernandez 		  _NO_MUX,
1827a97703c5SGabriel Fernandez 		  _DIV(RCC_PLL4CFGR2, 16, 7, 0, NULL)),
1828e51d297eSGabriel Fernandez 
1829e51d297eSGabriel Fernandez 	/* MUX system clocks */
1830e51d297eSGabriel Fernandez 	MUX(CK_PER, "ck_per", per_src, CLK_OPS_PARENT_ENABLE,
1831e51d297eSGabriel Fernandez 	    RCC_CPERCKSELR, 0, 2, 0),
1832e51d297eSGabriel Fernandez 
1833e51d297eSGabriel Fernandez 	MUX(CK_MPU, "ck_mpu", cpu_src, CLK_OPS_PARENT_ENABLE |
1834e51d297eSGabriel Fernandez 	     CLK_IS_CRITICAL, RCC_MPCKSELR, 0, 2, 0),
1835e51d297eSGabriel Fernandez 
1836e51d297eSGabriel Fernandez 	COMPOSITE(CK_AXI, "ck_axi", axi_src, CLK_IS_CRITICAL |
1837e51d297eSGabriel Fernandez 		   CLK_OPS_PARENT_ENABLE,
1838e51d297eSGabriel Fernandez 		   _NO_GATE,
1839e51d297eSGabriel Fernandez 		   _MUX(RCC_ASSCKSELR, 0, 2, 0),
1840e51d297eSGabriel Fernandez 		   _DIV(RCC_AXIDIVR, 0, 3, 0, axi_div_table)),
1841e51d297eSGabriel Fernandez 
1842e51d297eSGabriel Fernandez 	COMPOSITE(CK_MCU, "ck_mcu", mcu_src, CLK_IS_CRITICAL |
1843e51d297eSGabriel Fernandez 		   CLK_OPS_PARENT_ENABLE,
1844e51d297eSGabriel Fernandez 		   _NO_GATE,
1845e51d297eSGabriel Fernandez 		   _MUX(RCC_MSSCKSELR, 0, 2, 0),
1846e51d297eSGabriel Fernandez 		   _DIV(RCC_MCUDIVR, 0, 4, 0, mcu_div_table)),
1847e51d297eSGabriel Fernandez 
1848e51d297eSGabriel Fernandez 	DIV_TABLE(NO_ID, "pclk1", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB1DIVR, 0,
1849e51d297eSGabriel Fernandez 		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1850e51d297eSGabriel Fernandez 
1851e51d297eSGabriel Fernandez 	DIV_TABLE(NO_ID, "pclk2", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB2DIVR, 0,
1852e51d297eSGabriel Fernandez 		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1853e51d297eSGabriel Fernandez 
1854e51d297eSGabriel Fernandez 	DIV_TABLE(NO_ID, "pclk3", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB3DIVR, 0,
1855e51d297eSGabriel Fernandez 		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1856e51d297eSGabriel Fernandez 
1857e51d297eSGabriel Fernandez 	DIV_TABLE(NO_ID, "pclk4", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB4DIVR, 0,
1858e51d297eSGabriel Fernandez 		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1859e51d297eSGabriel Fernandez 
1860e51d297eSGabriel Fernandez 	DIV_TABLE(NO_ID, "pclk5", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB5DIVR, 0,
1861e51d297eSGabriel Fernandez 		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1862799b6a12SGabriel Fernandez 
1863799b6a12SGabriel Fernandez 	/* Kernel Timers */
1864799b6a12SGabriel Fernandez 	STM32_CKTIM("ck1_tim", "pclk1", 0, RCC_APB1DIVR, RCC_TIMG1PRER),
1865799b6a12SGabriel Fernandez 	STM32_CKTIM("ck2_tim", "pclk2", 0, RCC_APB2DIVR, RCC_TIMG2PRER),
1866799b6a12SGabriel Fernandez 
1867799b6a12SGabriel Fernandez 	STM32_TIM(TIM2_K, "tim2_k", "ck1_tim", RCC_APB1ENSETR, 0),
1868799b6a12SGabriel Fernandez 	STM32_TIM(TIM3_K, "tim3_k", "ck1_tim", RCC_APB1ENSETR, 1),
1869799b6a12SGabriel Fernandez 	STM32_TIM(TIM4_K, "tim4_k", "ck1_tim", RCC_APB1ENSETR, 2),
1870799b6a12SGabriel Fernandez 	STM32_TIM(TIM5_K, "tim5_k", "ck1_tim", RCC_APB1ENSETR, 3),
1871799b6a12SGabriel Fernandez 	STM32_TIM(TIM6_K, "tim6_k", "ck1_tim", RCC_APB1ENSETR, 4),
1872799b6a12SGabriel Fernandez 	STM32_TIM(TIM7_K, "tim7_k", "ck1_tim", RCC_APB1ENSETR, 5),
1873799b6a12SGabriel Fernandez 	STM32_TIM(TIM12_K, "tim12_k", "ck1_tim", RCC_APB1ENSETR, 6),
1874799b6a12SGabriel Fernandez 	STM32_TIM(TIM13_K, "tim13_k", "ck1_tim", RCC_APB1ENSETR, 7),
1875799b6a12SGabriel Fernandez 	STM32_TIM(TIM14_K, "tim14_k", "ck1_tim", RCC_APB1ENSETR, 8),
1876799b6a12SGabriel Fernandez 	STM32_TIM(TIM1_K, "tim1_k", "ck2_tim", RCC_APB2ENSETR, 0),
1877799b6a12SGabriel Fernandez 	STM32_TIM(TIM8_K, "tim8_k", "ck2_tim", RCC_APB2ENSETR, 1),
1878799b6a12SGabriel Fernandez 	STM32_TIM(TIM15_K, "tim15_k", "ck2_tim", RCC_APB2ENSETR, 2),
1879799b6a12SGabriel Fernandez 	STM32_TIM(TIM16_K, "tim16_k", "ck2_tim", RCC_APB2ENSETR, 3),
1880799b6a12SGabriel Fernandez 	STM32_TIM(TIM17_K, "tim17_k", "ck2_tim", RCC_APB2ENSETR, 4),
18811f80590bSGabriel Fernandez 
18821f80590bSGabriel Fernandez 	/* Peripheral clocks */
18831f80590bSGabriel Fernandez 	PCLK(TIM2, "tim2", "pclk1", CLK_IGNORE_UNUSED, G_TIM2),
18841f80590bSGabriel Fernandez 	PCLK(TIM3, "tim3", "pclk1", CLK_IGNORE_UNUSED, G_TIM3),
18851f80590bSGabriel Fernandez 	PCLK(TIM4, "tim4", "pclk1", CLK_IGNORE_UNUSED, G_TIM4),
18861f80590bSGabriel Fernandez 	PCLK(TIM5, "tim5", "pclk1", CLK_IGNORE_UNUSED, G_TIM5),
18871f80590bSGabriel Fernandez 	PCLK(TIM6, "tim6", "pclk1", CLK_IGNORE_UNUSED, G_TIM6),
18881f80590bSGabriel Fernandez 	PCLK(TIM7, "tim7", "pclk1", CLK_IGNORE_UNUSED, G_TIM7),
18891f80590bSGabriel Fernandez 	PCLK(TIM12, "tim12", "pclk1", CLK_IGNORE_UNUSED, G_TIM12),
18901f80590bSGabriel Fernandez 	PCLK(TIM13, "tim13", "pclk1", CLK_IGNORE_UNUSED, G_TIM13),
18911f80590bSGabriel Fernandez 	PCLK(TIM14, "tim14", "pclk1", CLK_IGNORE_UNUSED, G_TIM14),
18921f80590bSGabriel Fernandez 	PCLK(LPTIM1, "lptim1", "pclk1", 0, G_LPTIM1),
18931f80590bSGabriel Fernandez 	PCLK(SPI2, "spi2", "pclk1", 0, G_SPI2),
18941f80590bSGabriel Fernandez 	PCLK(SPI3, "spi3", "pclk1", 0, G_SPI3),
18951f80590bSGabriel Fernandez 	PCLK(USART2, "usart2", "pclk1", 0, G_USART2),
18961f80590bSGabriel Fernandez 	PCLK(USART3, "usart3", "pclk1", 0, G_USART3),
18971f80590bSGabriel Fernandez 	PCLK(UART4, "uart4", "pclk1", 0, G_UART4),
18981f80590bSGabriel Fernandez 	PCLK(UART5, "uart5", "pclk1", 0, G_UART5),
18991f80590bSGabriel Fernandez 	PCLK(UART7, "uart7", "pclk1", 0, G_UART7),
19001f80590bSGabriel Fernandez 	PCLK(UART8, "uart8", "pclk1", 0, G_UART8),
19011f80590bSGabriel Fernandez 	PCLK(I2C1, "i2c1", "pclk1", 0, G_I2C1),
19021f80590bSGabriel Fernandez 	PCLK(I2C2, "i2c2", "pclk1", 0, G_I2C2),
19031f80590bSGabriel Fernandez 	PCLK(I2C3, "i2c3", "pclk1", 0, G_I2C3),
19041f80590bSGabriel Fernandez 	PCLK(I2C5, "i2c5", "pclk1", 0, G_I2C5),
19051f80590bSGabriel Fernandez 	PCLK(SPDIF, "spdif", "pclk1", 0, G_SPDIF),
19061f80590bSGabriel Fernandez 	PCLK(CEC, "cec", "pclk1", 0, G_CEC),
19071f80590bSGabriel Fernandez 	PCLK(DAC12, "dac12", "pclk1", 0, G_DAC12),
19081f80590bSGabriel Fernandez 	PCLK(MDIO, "mdio", "pclk1", 0, G_MDIO),
19091f80590bSGabriel Fernandez 	PCLK(TIM1, "tim1", "pclk2", CLK_IGNORE_UNUSED, G_TIM1),
19101f80590bSGabriel Fernandez 	PCLK(TIM8, "tim8", "pclk2", CLK_IGNORE_UNUSED, G_TIM8),
19111f80590bSGabriel Fernandez 	PCLK(TIM15, "tim15", "pclk2", CLK_IGNORE_UNUSED, G_TIM15),
19121f80590bSGabriel Fernandez 	PCLK(TIM16, "tim16", "pclk2", CLK_IGNORE_UNUSED, G_TIM16),
19131f80590bSGabriel Fernandez 	PCLK(TIM17, "tim17", "pclk2", CLK_IGNORE_UNUSED, G_TIM17),
19141f80590bSGabriel Fernandez 	PCLK(SPI1, "spi1", "pclk2", 0, G_SPI1),
19151f80590bSGabriel Fernandez 	PCLK(SPI4, "spi4", "pclk2", 0, G_SPI4),
19161f80590bSGabriel Fernandez 	PCLK(SPI5, "spi5", "pclk2", 0, G_SPI5),
19171f80590bSGabriel Fernandez 	PCLK(USART6, "usart6", "pclk2", 0, G_USART6),
19181f80590bSGabriel Fernandez 	PCLK(SAI1, "sai1", "pclk2", 0, G_SAI1),
19191f80590bSGabriel Fernandez 	PCLK(SAI2, "sai2", "pclk2", 0, G_SAI2),
19201f80590bSGabriel Fernandez 	PCLK(SAI3, "sai3", "pclk2", 0, G_SAI3),
19211f80590bSGabriel Fernandez 	PCLK(DFSDM, "dfsdm", "pclk2", 0, G_DFSDM),
19221f80590bSGabriel Fernandez 	PCLK(FDCAN, "fdcan", "pclk2", 0, G_FDCAN),
19231f80590bSGabriel Fernandez 	PCLK(LPTIM2, "lptim2", "pclk3", 0, G_LPTIM2),
19241f80590bSGabriel Fernandez 	PCLK(LPTIM3, "lptim3", "pclk3", 0, G_LPTIM3),
19251f80590bSGabriel Fernandez 	PCLK(LPTIM4, "lptim4", "pclk3", 0, G_LPTIM4),
19261f80590bSGabriel Fernandez 	PCLK(LPTIM5, "lptim5", "pclk3", 0, G_LPTIM5),
19271f80590bSGabriel Fernandez 	PCLK(SAI4, "sai4", "pclk3", 0, G_SAI4),
19281f80590bSGabriel Fernandez 	PCLK(SYSCFG, "syscfg", "pclk3", 0, G_SYSCFG),
19291f80590bSGabriel Fernandez 	PCLK(VREF, "vref", "pclk3", 13, G_VREF),
19301f80590bSGabriel Fernandez 	PCLK(TMPSENS, "tmpsens", "pclk3", 0, G_TMPSENS),
19311f80590bSGabriel Fernandez 	PCLK(PMBCTRL, "pmbctrl", "pclk3", 0, G_PMBCTRL),
19321f80590bSGabriel Fernandez 	PCLK(HDP, "hdp", "pclk3", 0, G_HDP),
19331f80590bSGabriel Fernandez 	PCLK(LTDC, "ltdc", "pclk4", 0, G_LTDC),
19341f80590bSGabriel Fernandez 	PCLK(DSI, "dsi", "pclk4", 0, G_DSI),
19351f80590bSGabriel Fernandez 	PCLK(IWDG2, "iwdg2", "pclk4", 0, G_IWDG2),
19361f80590bSGabriel Fernandez 	PCLK(USBPHY, "usbphy", "pclk4", 0, G_USBPHY),
19371f80590bSGabriel Fernandez 	PCLK(STGENRO, "stgenro", "pclk4", 0, G_STGENRO),
19381f80590bSGabriel Fernandez 	PCLK(SPI6, "spi6", "pclk5", 0, G_SPI6),
19391f80590bSGabriel Fernandez 	PCLK(I2C4, "i2c4", "pclk5", 0, G_I2C4),
19401f80590bSGabriel Fernandez 	PCLK(I2C6, "i2c6", "pclk5", 0, G_I2C6),
19411f80590bSGabriel Fernandez 	PCLK(USART1, "usart1", "pclk5", 0, G_USART1),
19421f80590bSGabriel Fernandez 	PCLK(RTCAPB, "rtcapb", "pclk5", CLK_IGNORE_UNUSED |
19431f80590bSGabriel Fernandez 	     CLK_IS_CRITICAL, G_RTCAPB),
1944a1bf646fSGabriel Fernandez 	PCLK(TZC1, "tzc1", "ck_axi", CLK_IGNORE_UNUSED, G_TZC1),
1945a1bf646fSGabriel Fernandez 	PCLK(TZC2, "tzc2", "ck_axi", CLK_IGNORE_UNUSED, G_TZC2),
19461f80590bSGabriel Fernandez 	PCLK(TZPC, "tzpc", "pclk5", CLK_IGNORE_UNUSED, G_TZPC),
19471f80590bSGabriel Fernandez 	PCLK(IWDG1, "iwdg1", "pclk5", 0, G_IWDG1),
19481f80590bSGabriel Fernandez 	PCLK(BSEC, "bsec", "pclk5", CLK_IGNORE_UNUSED, G_BSEC),
19491f80590bSGabriel Fernandez 	PCLK(STGEN, "stgen", "pclk5", CLK_IGNORE_UNUSED, G_STGEN),
19501f80590bSGabriel Fernandez 	PCLK(DMA1, "dma1", "ck_mcu", 0, G_DMA1),
19511f80590bSGabriel Fernandez 	PCLK(DMA2, "dma2", "ck_mcu",  0, G_DMA2),
19521f80590bSGabriel Fernandez 	PCLK(DMAMUX, "dmamux", "ck_mcu", 0, G_DMAMUX),
19531f80590bSGabriel Fernandez 	PCLK(ADC12, "adc12", "ck_mcu", 0, G_ADC12),
19541f80590bSGabriel Fernandez 	PCLK(USBO, "usbo", "ck_mcu", 0, G_USBO),
19551f80590bSGabriel Fernandez 	PCLK(SDMMC3, "sdmmc3", "ck_mcu", 0, G_SDMMC3),
19561f80590bSGabriel Fernandez 	PCLK(DCMI, "dcmi", "ck_mcu", 0, G_DCMI),
19571f80590bSGabriel Fernandez 	PCLK(CRYP2, "cryp2", "ck_mcu", 0, G_CRYP2),
19581f80590bSGabriel Fernandez 	PCLK(HASH2, "hash2", "ck_mcu", 0, G_HASH2),
19591f80590bSGabriel Fernandez 	PCLK(RNG2, "rng2", "ck_mcu", 0, G_RNG2),
19601f80590bSGabriel Fernandez 	PCLK(CRC2, "crc2", "ck_mcu", 0, G_CRC2),
19611f80590bSGabriel Fernandez 	PCLK(HSEM, "hsem", "ck_mcu", 0, G_HSEM),
19621f80590bSGabriel Fernandez 	PCLK(IPCC, "ipcc", "ck_mcu", 0, G_IPCC),
19631f80590bSGabriel Fernandez 	PCLK(GPIOA, "gpioa", "ck_mcu", 0, G_GPIOA),
19641f80590bSGabriel Fernandez 	PCLK(GPIOB, "gpiob", "ck_mcu", 0, G_GPIOB),
19651f80590bSGabriel Fernandez 	PCLK(GPIOC, "gpioc", "ck_mcu", 0, G_GPIOC),
19661f80590bSGabriel Fernandez 	PCLK(GPIOD, "gpiod", "ck_mcu", 0, G_GPIOD),
19671f80590bSGabriel Fernandez 	PCLK(GPIOE, "gpioe", "ck_mcu", 0, G_GPIOE),
19681f80590bSGabriel Fernandez 	PCLK(GPIOF, "gpiof", "ck_mcu", 0, G_GPIOF),
19691f80590bSGabriel Fernandez 	PCLK(GPIOG, "gpiog", "ck_mcu", 0, G_GPIOG),
19701f80590bSGabriel Fernandez 	PCLK(GPIOH, "gpioh", "ck_mcu", 0, G_GPIOH),
19711f80590bSGabriel Fernandez 	PCLK(GPIOI, "gpioi", "ck_mcu", 0, G_GPIOI),
19721f80590bSGabriel Fernandez 	PCLK(GPIOJ, "gpioj", "ck_mcu", 0, G_GPIOJ),
19731f80590bSGabriel Fernandez 	PCLK(GPIOK, "gpiok", "ck_mcu", 0, G_GPIOK),
19741f80590bSGabriel Fernandez 	PCLK(GPIOZ, "gpioz", "ck_axi", CLK_IGNORE_UNUSED, G_GPIOZ),
19751f80590bSGabriel Fernandez 	PCLK(CRYP1, "cryp1", "ck_axi", CLK_IGNORE_UNUSED, G_CRYP1),
19761f80590bSGabriel Fernandez 	PCLK(HASH1, "hash1", "ck_axi", CLK_IGNORE_UNUSED, G_HASH1),
19771f80590bSGabriel Fernandez 	PCLK(RNG1, "rng1", "ck_axi", 0, G_RNG1),
19781f80590bSGabriel Fernandez 	PCLK(BKPSRAM, "bkpsram", "ck_axi", CLK_IGNORE_UNUSED, G_BKPSRAM),
19791f80590bSGabriel Fernandez 	PCLK(MDMA, "mdma", "ck_axi", 0, G_MDMA),
19801f80590bSGabriel Fernandez 	PCLK(GPU, "gpu", "ck_axi", 0, G_GPU),
19811f80590bSGabriel Fernandez 	PCLK(ETHTX, "ethtx", "ck_axi", 0, G_ETHTX),
1982e9ed1ef1SMarek Vasut 	PCLK_PDATA(ETHRX, "ethrx", ethrx_src, 0, G_ETHRX),
19831f80590bSGabriel Fernandez 	PCLK(ETHMAC, "ethmac", "ck_axi", 0, G_ETHMAC),
19841f80590bSGabriel Fernandez 	PCLK(FMC, "fmc", "ck_axi", CLK_IGNORE_UNUSED, G_FMC),
19851f80590bSGabriel Fernandez 	PCLK(QSPI, "qspi", "ck_axi", CLK_IGNORE_UNUSED, G_QSPI),
19861f80590bSGabriel Fernandez 	PCLK(SDMMC1, "sdmmc1", "ck_axi", 0, G_SDMMC1),
19871f80590bSGabriel Fernandez 	PCLK(SDMMC2, "sdmmc2", "ck_axi", 0, G_SDMMC2),
19881f80590bSGabriel Fernandez 	PCLK(CRC1, "crc1", "ck_axi", 0, G_CRC1),
19891f80590bSGabriel Fernandez 	PCLK(USBH, "usbh", "ck_axi", 0, G_USBH),
19901f80590bSGabriel Fernandez 	PCLK(ETHSTP, "ethstp", "ck_axi", 0, G_ETHSTP),
1991b06df56bSGabriel Fernandez 	PCLK(DDRPERFM, "ddrperfm", "pclk4", 0, G_DDRPERFM),
19921f80590bSGabriel Fernandez 
19931f80590bSGabriel Fernandez 	/* Kernel clocks */
19941f80590bSGabriel Fernandez 	KCLK(SDMMC1_K, "sdmmc1_k", sdmmc12_src, 0, G_SDMMC1, M_SDMMC12),
19951f80590bSGabriel Fernandez 	KCLK(SDMMC2_K, "sdmmc2_k", sdmmc12_src, 0, G_SDMMC2, M_SDMMC12),
19961f80590bSGabriel Fernandez 	KCLK(SDMMC3_K, "sdmmc3_k", sdmmc3_src, 0, G_SDMMC3, M_SDMMC3),
19971f80590bSGabriel Fernandez 	KCLK(FMC_K, "fmc_k", fmc_src, 0, G_FMC, M_FMC),
19981f80590bSGabriel Fernandez 	KCLK(QSPI_K, "qspi_k", qspi_src, 0, G_QSPI, M_QSPI),
19991f80590bSGabriel Fernandez 	KCLK(RNG1_K, "rng1_k", rng_src, 0, G_RNG1, M_RNG1),
20001f80590bSGabriel Fernandez 	KCLK(RNG2_K, "rng2_k", rng_src, 0, G_RNG2, M_RNG2),
20011f80590bSGabriel Fernandez 	KCLK(USBPHY_K, "usbphy_k", usbphy_src, 0, G_USBPHY, M_USBPHY),
20021742aed6SGabriel Fernandez 	KCLK(STGEN_K, "stgen_k", stgen_src, CLK_IS_CRITICAL, G_STGEN, M_STGEN),
20031f80590bSGabriel Fernandez 	KCLK(SPDIF_K, "spdif_k", spdif_src, 0, G_SPDIF, M_SPDIF),
20041f80590bSGabriel Fernandez 	KCLK(SPI1_K, "spi1_k", spi123_src, 0, G_SPI1, M_SPI1),
20051f80590bSGabriel Fernandez 	KCLK(SPI2_K, "spi2_k", spi123_src, 0, G_SPI2, M_SPI23),
20061f80590bSGabriel Fernandez 	KCLK(SPI3_K, "spi3_k", spi123_src, 0, G_SPI3, M_SPI23),
20071f80590bSGabriel Fernandez 	KCLK(SPI4_K, "spi4_k", spi45_src, 0, G_SPI4, M_SPI45),
20081f80590bSGabriel Fernandez 	KCLK(SPI5_K, "spi5_k", spi45_src, 0, G_SPI5, M_SPI45),
20091f80590bSGabriel Fernandez 	KCLK(SPI6_K, "spi6_k", spi6_src, 0, G_SPI6, M_SPI6),
20101f80590bSGabriel Fernandez 	KCLK(CEC_K, "cec_k", cec_src, 0, G_CEC, M_CEC),
20111f80590bSGabriel Fernandez 	KCLK(I2C1_K, "i2c1_k", i2c12_src, 0, G_I2C1, M_I2C12),
20121f80590bSGabriel Fernandez 	KCLK(I2C2_K, "i2c2_k", i2c12_src, 0, G_I2C2, M_I2C12),
20131f80590bSGabriel Fernandez 	KCLK(I2C3_K, "i2c3_k", i2c35_src, 0, G_I2C3, M_I2C35),
20141f80590bSGabriel Fernandez 	KCLK(I2C5_K, "i2c5_k", i2c35_src, 0, G_I2C5, M_I2C35),
20151f80590bSGabriel Fernandez 	KCLK(I2C4_K, "i2c4_k", i2c46_src, 0, G_I2C4, M_I2C46),
20161f80590bSGabriel Fernandez 	KCLK(I2C6_K, "i2c6_k", i2c46_src, 0, G_I2C6, M_I2C46),
20171f80590bSGabriel Fernandez 	KCLK(LPTIM1_K, "lptim1_k", lptim1_src, 0, G_LPTIM1, M_LPTIM1),
20181f80590bSGabriel Fernandez 	KCLK(LPTIM2_K, "lptim2_k", lptim23_src, 0, G_LPTIM2, M_LPTIM23),
20191f80590bSGabriel Fernandez 	KCLK(LPTIM3_K, "lptim3_k", lptim23_src, 0, G_LPTIM3, M_LPTIM23),
20201f80590bSGabriel Fernandez 	KCLK(LPTIM4_K, "lptim4_k", lptim45_src, 0, G_LPTIM4, M_LPTIM45),
20211f80590bSGabriel Fernandez 	KCLK(LPTIM5_K, "lptim5_k", lptim45_src, 0, G_LPTIM5, M_LPTIM45),
20221f80590bSGabriel Fernandez 	KCLK(USART1_K, "usart1_k", usart1_src, 0, G_USART1, M_USART1),
20231f80590bSGabriel Fernandez 	KCLK(USART2_K, "usart2_k", usart234578_src, 0, G_USART2, M_UART24),
20241f80590bSGabriel Fernandez 	KCLK(USART3_K, "usart3_k", usart234578_src, 0, G_USART3, M_UART35),
20251f80590bSGabriel Fernandez 	KCLK(UART4_K, "uart4_k", usart234578_src, 0, G_UART4, M_UART24),
20261f80590bSGabriel Fernandez 	KCLK(UART5_K, "uart5_k", usart234578_src, 0, G_UART5, M_UART35),
20271f80590bSGabriel Fernandez 	KCLK(USART6_K, "uart6_k", usart6_src, 0, G_USART6, M_USART6),
20281f80590bSGabriel Fernandez 	KCLK(UART7_K, "uart7_k", usart234578_src, 0, G_UART7, M_UART78),
20291f80590bSGabriel Fernandez 	KCLK(UART8_K, "uart8_k", usart234578_src, 0, G_UART8, M_UART78),
20301f80590bSGabriel Fernandez 	KCLK(FDCAN_K, "fdcan_k", fdcan_src, 0, G_FDCAN, M_FDCAN),
20311f80590bSGabriel Fernandez 	KCLK(SAI1_K, "sai1_k", sai_src, 0, G_SAI1, M_SAI1),
20321f80590bSGabriel Fernandez 	KCLK(SAI2_K, "sai2_k", sai2_src, 0, G_SAI2, M_SAI2),
20334cd21360SGabriel Fernandez 	KCLK(SAI3_K, "sai3_k", sai_src, 0, G_SAI3, M_SAI3),
20344cd21360SGabriel Fernandez 	KCLK(SAI4_K, "sai4_k", sai_src, 0, G_SAI4, M_SAI4),
20351f80590bSGabriel Fernandez 	KCLK(ADC12_K, "adc12_k", adc12_src, 0, G_ADC12, M_ADC12),
20361f80590bSGabriel Fernandez 	KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI),
20371f80590bSGabriel Fernandez 	KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1),
20381f80590bSGabriel Fernandez 	KCLK(USBO_K, "usbo_k", usbo_src, 0, G_USBO, M_USBO),
20391f80590bSGabriel Fernandez 
20401f80590bSGabriel Fernandez 	/* Particulary Kernel Clocks (no mux or no gate) */
20411f80590bSGabriel Fernandez 	MGATE_MP1(DFSDM_K, "dfsdm_k", "ck_mcu", 0, G_DFSDM),
20421f80590bSGabriel Fernandez 	MGATE_MP1(DSI_PX, "dsi_px", "pll4_q", CLK_SET_RATE_PARENT, G_DSI),
20431f80590bSGabriel Fernandez 	MGATE_MP1(LTDC_PX, "ltdc_px", "pll4_q", CLK_SET_RATE_PARENT, G_LTDC),
20441f80590bSGabriel Fernandez 	MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU),
20451f80590bSGabriel Fernandez 	MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
20461f80590bSGabriel Fernandez 
2047e33b88b6SMarek Vasut 	COMPOSITE(NO_ID, "ck_ker_eth", eth_src, CLK_OPS_PARENT_ENABLE |
204872cfd1adSGabriel Fernandez 		  CLK_SET_RATE_NO_REPARENT,
20491f80590bSGabriel Fernandez 		  _NO_GATE,
20501f80590bSGabriel Fernandez 		  _MMUX(M_ETHCK),
2051e33b88b6SMarek Vasut 		  _NO_DIV),
2052e33b88b6SMarek Vasut 
2053e33b88b6SMarek Vasut 	MGATE_MP1(ETHCK_K, "ethck_k", "ck_ker_eth", 0, G_ETHCK),
2054e33b88b6SMarek Vasut 
2055e33b88b6SMarek Vasut 	DIV(ETHPTP_K, "ethptp_k", "ck_ker_eth", CLK_OPS_PARENT_ENABLE |
2056e33b88b6SMarek Vasut 	    CLK_SET_RATE_NO_REPARENT, RCC_ETHCKSELR, 4, 4, 0),
20572c87c9d3SGabriel Fernandez 
20582c87c9d3SGabriel Fernandez 	/* RTC clock */
2059152efe56SGabriel Fernandez 	COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE,
20602c87c9d3SGabriel Fernandez 		  _GATE(RCC_BDCR, 20, 0),
20612c87c9d3SGabriel Fernandez 		  _MUX(RCC_BDCR, 16, 2, 0),
2062152efe56SGabriel Fernandez 		  _DIV_RTC(RCC_RTCDIVR, 0, 6, 0, NULL)),
20632c87c9d3SGabriel Fernandez 
206444cd455aSGabriel Fernandez 	/* MCO clocks */
206544cd455aSGabriel Fernandez 	COMPOSITE(CK_MCO1, "ck_mco1", mco1_src, CLK_OPS_PARENT_ENABLE |
206644cd455aSGabriel Fernandez 		  CLK_SET_RATE_NO_REPARENT,
206744cd455aSGabriel Fernandez 		  _GATE(RCC_MCO1CFGR, 12, 0),
206844cd455aSGabriel Fernandez 		  _MUX(RCC_MCO1CFGR, 0, 3, 0),
206944cd455aSGabriel Fernandez 		  _DIV(RCC_MCO1CFGR, 4, 4, 0, NULL)),
207044cd455aSGabriel Fernandez 
207144cd455aSGabriel Fernandez 	COMPOSITE(CK_MCO2, "ck_mco2", mco2_src, CLK_OPS_PARENT_ENABLE |
207244cd455aSGabriel Fernandez 		  CLK_SET_RATE_NO_REPARENT,
207344cd455aSGabriel Fernandez 		  _GATE(RCC_MCO2CFGR, 12, 0),
207444cd455aSGabriel Fernandez 		  _MUX(RCC_MCO2CFGR, 0, 3, 0),
207544cd455aSGabriel Fernandez 		  _DIV(RCC_MCO2CFGR, 4, 4, 0, NULL)),
20763a430067SGabriel Fernandez 
20773a430067SGabriel Fernandez 	/* Debug clocks */
207877dc0020SGabriel Fernandez 	GATE(CK_DBG, "ck_sys_dbg", "ck_axi", CLK_IGNORE_UNUSED,
207977dc0020SGabriel Fernandez 	     RCC_DBGCFGR, 8, 0),
20803a430067SGabriel Fernandez 
20813a430067SGabriel Fernandez 	COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, CLK_OPS_PARENT_ENABLE,
20823a430067SGabriel Fernandez 		  _GATE(RCC_DBGCFGR, 9, 0),
20833a430067SGabriel Fernandez 		  _NO_MUX,
20843a430067SGabriel Fernandez 		  _DIV(RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table)),
20859bee94e7SGabriel Fernandez };
20869bee94e7SGabriel Fernandez 
208721e74330SGabriel Fernandez static const u32 stm32mp1_clock_secured[] = {
208821e74330SGabriel Fernandez 	CK_HSE,
208921e74330SGabriel Fernandez 	CK_HSI,
209021e74330SGabriel Fernandez 	CK_CSI,
209121e74330SGabriel Fernandez 	CK_LSI,
209221e74330SGabriel Fernandez 	CK_LSE,
209321e74330SGabriel Fernandez 	PLL1,
209421e74330SGabriel Fernandez 	PLL2,
209521e74330SGabriel Fernandez 	PLL1_P,
209621e74330SGabriel Fernandez 	PLL2_P,
209721e74330SGabriel Fernandez 	PLL2_Q,
209821e74330SGabriel Fernandez 	PLL2_R,
209921e74330SGabriel Fernandez 	CK_MPU,
210021e74330SGabriel Fernandez 	CK_AXI,
210121e74330SGabriel Fernandez 	SPI6,
210221e74330SGabriel Fernandez 	I2C4,
210321e74330SGabriel Fernandez 	I2C6,
210421e74330SGabriel Fernandez 	USART1,
210521e74330SGabriel Fernandez 	RTCAPB,
210621e74330SGabriel Fernandez 	TZC1,
210721e74330SGabriel Fernandez 	TZC2,
210821e74330SGabriel Fernandez 	TZPC,
210921e74330SGabriel Fernandez 	IWDG1,
211021e74330SGabriel Fernandez 	BSEC,
211121e74330SGabriel Fernandez 	STGEN,
211221e74330SGabriel Fernandez 	GPIOZ,
211321e74330SGabriel Fernandez 	CRYP1,
211421e74330SGabriel Fernandez 	HASH1,
211521e74330SGabriel Fernandez 	RNG1,
211621e74330SGabriel Fernandez 	BKPSRAM,
211721e74330SGabriel Fernandez 	RNG1_K,
211821e74330SGabriel Fernandez 	STGEN_K,
211921e74330SGabriel Fernandez 	SPI6_K,
212021e74330SGabriel Fernandez 	I2C4_K,
212121e74330SGabriel Fernandez 	I2C6_K,
212221e74330SGabriel Fernandez 	USART1_K,
212321e74330SGabriel Fernandez 	RTC,
212421e74330SGabriel Fernandez };
212521e74330SGabriel Fernandez 
stm32_check_security(const struct clock_config * cfg)212621e74330SGabriel Fernandez static bool stm32_check_security(const struct clock_config *cfg)
212721e74330SGabriel Fernandez {
212821e74330SGabriel Fernandez 	int i;
212921e74330SGabriel Fernandez 
213021e74330SGabriel Fernandez 	for (i = 0; i < ARRAY_SIZE(stm32mp1_clock_secured); i++)
213121e74330SGabriel Fernandez 		if (cfg->id == stm32mp1_clock_secured[i])
213221e74330SGabriel Fernandez 			return true;
213321e74330SGabriel Fernandez 	return false;
213421e74330SGabriel Fernandez }
213521e74330SGabriel Fernandez 
2136c392df19SGabriel Fernandez struct stm32_rcc_match_data {
21379bee94e7SGabriel Fernandez 	const struct clock_config *cfg;
21389bee94e7SGabriel Fernandez 	unsigned int num;
21399bee94e7SGabriel Fernandez 	unsigned int maxbinding;
2140c392df19SGabriel Fernandez 	u32 clear_offset;
214121e74330SGabriel Fernandez 	bool (*check_security)(const struct clock_config *cfg);
21429bee94e7SGabriel Fernandez };
21439bee94e7SGabriel Fernandez 
2144c392df19SGabriel Fernandez static struct stm32_rcc_match_data stm32mp1_data = {
21459bee94e7SGabriel Fernandez 	.cfg		= stm32mp1_clock_cfg,
21469bee94e7SGabriel Fernandez 	.num		= ARRAY_SIZE(stm32mp1_clock_cfg),
21479bee94e7SGabriel Fernandez 	.maxbinding	= STM32MP1_LAST_CLK,
2148c392df19SGabriel Fernandez 	.clear_offset	= RCC_CLR,
21499bee94e7SGabriel Fernandez };
21509bee94e7SGabriel Fernandez 
215121e74330SGabriel Fernandez static struct stm32_rcc_match_data stm32mp1_data_secure = {
215221e74330SGabriel Fernandez 	.cfg		= stm32mp1_clock_cfg,
215321e74330SGabriel Fernandez 	.num		= ARRAY_SIZE(stm32mp1_clock_cfg),
215421e74330SGabriel Fernandez 	.maxbinding	= STM32MP1_LAST_CLK,
215521e74330SGabriel Fernandez 	.clear_offset	= RCC_CLR,
215621e74330SGabriel Fernandez 	.check_security = &stm32_check_security
215721e74330SGabriel Fernandez };
215821e74330SGabriel Fernandez 
21599bee94e7SGabriel Fernandez static const struct of_device_id stm32mp1_match_data[] = {
21609bee94e7SGabriel Fernandez 	{
21619bee94e7SGabriel Fernandez 		.compatible = "st,stm32mp1-rcc",
21629bee94e7SGabriel Fernandez 		.data = &stm32mp1_data,
21639bee94e7SGabriel Fernandez 	},
216421e74330SGabriel Fernandez 	{
216521e74330SGabriel Fernandez 		.compatible = "st,stm32mp1-rcc-secure",
216621e74330SGabriel Fernandez 		.data = &stm32mp1_data_secure,
216721e74330SGabriel Fernandez 	},
21689bee94e7SGabriel Fernandez 	{ }
21699bee94e7SGabriel Fernandez };
217095272370SGabriel Fernandez MODULE_DEVICE_TABLE(of, stm32mp1_match_data);
21719bee94e7SGabriel Fernandez 
stm32_register_hw_clk(struct device * dev,struct clk_hw_onecell_data * clk_data,void __iomem * base,spinlock_t * lock,const struct clock_config * cfg)21729bee94e7SGabriel Fernandez static int stm32_register_hw_clk(struct device *dev,
21739bee94e7SGabriel Fernandez 				 struct clk_hw_onecell_data *clk_data,
21749bee94e7SGabriel Fernandez 				 void __iomem *base, spinlock_t *lock,
21759bee94e7SGabriel Fernandez 				 const struct clock_config *cfg)
21769bee94e7SGabriel Fernandez {
217725bf466bSYueHaibing 	struct clk_hw **hws;
21789bee94e7SGabriel Fernandez 	struct clk_hw *hw = ERR_PTR(-ENOENT);
21799bee94e7SGabriel Fernandez 
21809bee94e7SGabriel Fernandez 	hws = clk_data->hws;
21819bee94e7SGabriel Fernandez 
21829bee94e7SGabriel Fernandez 	if (cfg->func)
21839bee94e7SGabriel Fernandez 		hw = (*cfg->func)(dev, clk_data, base, lock, cfg);
21849bee94e7SGabriel Fernandez 
21859bee94e7SGabriel Fernandez 	if (IS_ERR(hw)) {
21869bee94e7SGabriel Fernandez 		pr_err("Unable to register %s\n", cfg->name);
21879bee94e7SGabriel Fernandez 		return  PTR_ERR(hw);
21889bee94e7SGabriel Fernandez 	}
21899bee94e7SGabriel Fernandez 
21909bee94e7SGabriel Fernandez 	if (cfg->id != NO_ID)
21919bee94e7SGabriel Fernandez 		hws[cfg->id] = hw;
21929bee94e7SGabriel Fernandez 
21939bee94e7SGabriel Fernandez 	return 0;
21949bee94e7SGabriel Fernandez }
21959bee94e7SGabriel Fernandez 
2196c392df19SGabriel Fernandez #define STM32_RESET_ID_MASK GENMASK(15, 0)
21979bee94e7SGabriel Fernandez 
2198c392df19SGabriel Fernandez struct stm32_reset_data {
2199c392df19SGabriel Fernandez 	/* reset lock */
2200c392df19SGabriel Fernandez 	spinlock_t			lock;
2201c392df19SGabriel Fernandez 	struct reset_controller_dev	rcdev;
2202c392df19SGabriel Fernandez 	void __iomem			*membase;
2203c392df19SGabriel Fernandez 	u32				clear_offset;
2204c392df19SGabriel Fernandez };
2205c392df19SGabriel Fernandez 
2206c392df19SGabriel Fernandez static inline struct stm32_reset_data *
to_stm32_reset_data(struct reset_controller_dev * rcdev)2207c392df19SGabriel Fernandez to_stm32_reset_data(struct reset_controller_dev *rcdev)
2208c392df19SGabriel Fernandez {
2209c392df19SGabriel Fernandez 	return container_of(rcdev, struct stm32_reset_data, rcdev);
22109bee94e7SGabriel Fernandez }
22119bee94e7SGabriel Fernandez 
stm32_reset_update(struct reset_controller_dev * rcdev,unsigned long id,bool assert)2212c392df19SGabriel Fernandez static int stm32_reset_update(struct reset_controller_dev *rcdev,
2213c392df19SGabriel Fernandez 			      unsigned long id, bool assert)
2214c392df19SGabriel Fernandez {
2215c392df19SGabriel Fernandez 	struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
2216c392df19SGabriel Fernandez 	int reg_width = sizeof(u32);
2217c392df19SGabriel Fernandez 	int bank = id / (reg_width * BITS_PER_BYTE);
2218c392df19SGabriel Fernandez 	int offset = id % (reg_width * BITS_PER_BYTE);
2219c392df19SGabriel Fernandez 
2220c392df19SGabriel Fernandez 	if (data->clear_offset) {
2221c392df19SGabriel Fernandez 		void __iomem *addr;
2222c392df19SGabriel Fernandez 
2223c392df19SGabriel Fernandez 		addr = data->membase + (bank * reg_width);
2224c392df19SGabriel Fernandez 		if (!assert)
2225c392df19SGabriel Fernandez 			addr += data->clear_offset;
2226c392df19SGabriel Fernandez 
2227c392df19SGabriel Fernandez 		writel(BIT(offset), addr);
2228c392df19SGabriel Fernandez 
2229c392df19SGabriel Fernandez 	} else {
2230c392df19SGabriel Fernandez 		unsigned long flags;
2231c392df19SGabriel Fernandez 		u32 reg;
2232c392df19SGabriel Fernandez 
2233c392df19SGabriel Fernandez 		spin_lock_irqsave(&data->lock, flags);
2234c392df19SGabriel Fernandez 
2235c392df19SGabriel Fernandez 		reg = readl(data->membase + (bank * reg_width));
2236c392df19SGabriel Fernandez 
2237c392df19SGabriel Fernandez 		if (assert)
2238c392df19SGabriel Fernandez 			reg |= BIT(offset);
2239c392df19SGabriel Fernandez 		else
2240c392df19SGabriel Fernandez 			reg &= ~BIT(offset);
2241c392df19SGabriel Fernandez 
2242c392df19SGabriel Fernandez 		writel(reg, data->membase + (bank * reg_width));
2243c392df19SGabriel Fernandez 
2244c392df19SGabriel Fernandez 		spin_unlock_irqrestore(&data->lock, flags);
2245c392df19SGabriel Fernandez 	}
2246c392df19SGabriel Fernandez 
2247c392df19SGabriel Fernandez 	return 0;
2248c392df19SGabriel Fernandez }
2249c392df19SGabriel Fernandez 
stm32_reset_assert(struct reset_controller_dev * rcdev,unsigned long id)2250c392df19SGabriel Fernandez static int stm32_reset_assert(struct reset_controller_dev *rcdev,
2251c392df19SGabriel Fernandez 			      unsigned long id)
2252c392df19SGabriel Fernandez {
2253c392df19SGabriel Fernandez 	return stm32_reset_update(rcdev, id, true);
2254c392df19SGabriel Fernandez }
2255c392df19SGabriel Fernandez 
stm32_reset_deassert(struct reset_controller_dev * rcdev,unsigned long id)2256c392df19SGabriel Fernandez static int stm32_reset_deassert(struct reset_controller_dev *rcdev,
2257c392df19SGabriel Fernandez 				unsigned long id)
2258c392df19SGabriel Fernandez {
2259c392df19SGabriel Fernandez 	return stm32_reset_update(rcdev, id, false);
2260c392df19SGabriel Fernandez }
2261c392df19SGabriel Fernandez 
stm32_reset_status(struct reset_controller_dev * rcdev,unsigned long id)2262c392df19SGabriel Fernandez static int stm32_reset_status(struct reset_controller_dev *rcdev,
2263c392df19SGabriel Fernandez 			      unsigned long id)
2264c392df19SGabriel Fernandez {
2265c392df19SGabriel Fernandez 	struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
2266c392df19SGabriel Fernandez 	int reg_width = sizeof(u32);
2267c392df19SGabriel Fernandez 	int bank = id / (reg_width * BITS_PER_BYTE);
2268c392df19SGabriel Fernandez 	int offset = id % (reg_width * BITS_PER_BYTE);
2269c392df19SGabriel Fernandez 	u32 reg;
2270c392df19SGabriel Fernandez 
2271c392df19SGabriel Fernandez 	reg = readl(data->membase + (bank * reg_width));
2272c392df19SGabriel Fernandez 
2273c392df19SGabriel Fernandez 	return !!(reg & BIT(offset));
2274c392df19SGabriel Fernandez }
2275c392df19SGabriel Fernandez 
2276c392df19SGabriel Fernandez static const struct reset_control_ops stm32_reset_ops = {
2277c392df19SGabriel Fernandez 	.assert		= stm32_reset_assert,
2278c392df19SGabriel Fernandez 	.deassert	= stm32_reset_deassert,
2279c392df19SGabriel Fernandez 	.status		= stm32_reset_status,
2280c392df19SGabriel Fernandez };
2281c392df19SGabriel Fernandez 
stm32_rcc_reset_init(struct device * dev,void __iomem * base,const struct of_device_id * match)2282c392df19SGabriel Fernandez static int stm32_rcc_reset_init(struct device *dev, void __iomem *base,
2283c392df19SGabriel Fernandez 				const struct of_device_id *match)
2284c392df19SGabriel Fernandez {
2285c392df19SGabriel Fernandez 	const struct stm32_rcc_match_data *data = match->data;
2286c392df19SGabriel Fernandez 	struct stm32_reset_data *reset_data = NULL;
2287c392df19SGabriel Fernandez 
2288c392df19SGabriel Fernandez 	reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
2289c392df19SGabriel Fernandez 	if (!reset_data)
2290c392df19SGabriel Fernandez 		return -ENOMEM;
2291c392df19SGabriel Fernandez 
2292b1f24771SWang Hai 	spin_lock_init(&reset_data->lock);
2293c392df19SGabriel Fernandez 	reset_data->membase = base;
2294c392df19SGabriel Fernandez 	reset_data->rcdev.owner = THIS_MODULE;
2295c392df19SGabriel Fernandez 	reset_data->rcdev.ops = &stm32_reset_ops;
2296c392df19SGabriel Fernandez 	reset_data->rcdev.of_node = dev_of_node(dev);
2297c392df19SGabriel Fernandez 	reset_data->rcdev.nr_resets = STM32_RESET_ID_MASK;
2298c392df19SGabriel Fernandez 	reset_data->clear_offset = data->clear_offset;
2299c392df19SGabriel Fernandez 
2300c392df19SGabriel Fernandez 	return reset_controller_register(&reset_data->rcdev);
2301c392df19SGabriel Fernandez }
2302c392df19SGabriel Fernandez 
stm32_rcc_clock_init(struct device * dev,void __iomem * base,const struct of_device_id * match)2303c392df19SGabriel Fernandez static int stm32_rcc_clock_init(struct device *dev, void __iomem *base,
2304c392df19SGabriel Fernandez 				const struct of_device_id *match)
2305c392df19SGabriel Fernandez {
2306c392df19SGabriel Fernandez 	const struct stm32_rcc_match_data *data = match->data;
2307c392df19SGabriel Fernandez 	struct clk_hw_onecell_data *clk_data;
2308c392df19SGabriel Fernandez 	struct clk_hw **hws;
2309c392df19SGabriel Fernandez 	int err, n, max_binding;
2310c392df19SGabriel Fernandez 
23119bee94e7SGabriel Fernandez 	max_binding =  data->maxbinding;
23129bee94e7SGabriel Fernandez 
231395272370SGabriel Fernandez 	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, max_binding),
23149bee94e7SGabriel Fernandez 				GFP_KERNEL);
23159bee94e7SGabriel Fernandez 	if (!clk_data)
23169bee94e7SGabriel Fernandez 		return -ENOMEM;
23179bee94e7SGabriel Fernandez 
23189bee94e7SGabriel Fernandez 	clk_data->num = max_binding;
23199bee94e7SGabriel Fernandez 
23209bee94e7SGabriel Fernandez 	hws = clk_data->hws;
23219bee94e7SGabriel Fernandez 
23229bee94e7SGabriel Fernandez 	for (n = 0; n < max_binding; n++)
23239bee94e7SGabriel Fernandez 		hws[n] = ERR_PTR(-ENOENT);
23249bee94e7SGabriel Fernandez 
23259bee94e7SGabriel Fernandez 	for (n = 0; n < data->num; n++) {
232621e74330SGabriel Fernandez 		if (data->check_security && data->check_security(&data->cfg[n]))
232721e74330SGabriel Fernandez 			continue;
232821e74330SGabriel Fernandez 
232995272370SGabriel Fernandez 		err = stm32_register_hw_clk(dev, clk_data, base, &rlock,
23309bee94e7SGabriel Fernandez 					    &data->cfg[n]);
23319bee94e7SGabriel Fernandez 		if (err) {
233295272370SGabriel Fernandez 			dev_err(dev, "Can't register clk %s: %d\n",
233395272370SGabriel Fernandez 				data->cfg[n].name, err);
23349bee94e7SGabriel Fernandez 
23359bee94e7SGabriel Fernandez 			return err;
23369bee94e7SGabriel Fernandez 		}
23379bee94e7SGabriel Fernandez 	}
23389bee94e7SGabriel Fernandez 
233995272370SGabriel Fernandez 	return of_clk_add_hw_provider(dev_of_node(dev), of_clk_hw_onecell_get, clk_data);
23409bee94e7SGabriel Fernandez }
23419bee94e7SGabriel Fernandez 
stm32_rcc_init(struct device * dev,void __iomem * base,const struct of_device_id * match_data)2342c392df19SGabriel Fernandez static int stm32_rcc_init(struct device *dev, void __iomem *base,
2343c392df19SGabriel Fernandez 			  const struct of_device_id *match_data)
2344c392df19SGabriel Fernandez {
2345c392df19SGabriel Fernandez 	const struct of_device_id *match;
2346c392df19SGabriel Fernandez 	int err;
2347c392df19SGabriel Fernandez 
2348c392df19SGabriel Fernandez 	match = of_match_node(match_data, dev_of_node(dev));
2349c392df19SGabriel Fernandez 	if (!match) {
2350c392df19SGabriel Fernandez 		dev_err(dev, "match data not found\n");
2351c392df19SGabriel Fernandez 		return -ENODEV;
2352c392df19SGabriel Fernandez 	}
2353c392df19SGabriel Fernandez 
2354c392df19SGabriel Fernandez 	/* RCC Reset Configuration */
2355c392df19SGabriel Fernandez 	err = stm32_rcc_reset_init(dev, base, match);
2356c392df19SGabriel Fernandez 	if (err) {
2357c392df19SGabriel Fernandez 		pr_err("stm32mp1 reset failed to initialize\n");
2358c392df19SGabriel Fernandez 		return err;
2359c392df19SGabriel Fernandez 	}
2360c392df19SGabriel Fernandez 
2361c392df19SGabriel Fernandez 	/* RCC Clock Configuration */
2362c392df19SGabriel Fernandez 	err = stm32_rcc_clock_init(dev, base, match);
2363c392df19SGabriel Fernandez 	if (err) {
2364c392df19SGabriel Fernandez 		pr_err("stm32mp1 clock failed to initialize\n");
2365c392df19SGabriel Fernandez 		return err;
2366c392df19SGabriel Fernandez 	}
2367c392df19SGabriel Fernandez 
2368c392df19SGabriel Fernandez 	return 0;
2369c392df19SGabriel Fernandez }
2370c392df19SGabriel Fernandez 
stm32mp1_rcc_init(struct device * dev)237195272370SGabriel Fernandez static int stm32mp1_rcc_init(struct device *dev)
23729bee94e7SGabriel Fernandez {
23739bee94e7SGabriel Fernandez 	void __iomem *base;
237495272370SGabriel Fernandez 	int ret;
23759bee94e7SGabriel Fernandez 
237695272370SGabriel Fernandez 	base = of_iomap(dev_of_node(dev), 0);
23779bee94e7SGabriel Fernandez 	if (!base) {
237895272370SGabriel Fernandez 		pr_err("%pOFn: unable to map resource", dev_of_node(dev));
237995272370SGabriel Fernandez 		ret = -ENOMEM;
238095272370SGabriel Fernandez 		goto out;
23819bee94e7SGabriel Fernandez 	}
23829bee94e7SGabriel Fernandez 
238395272370SGabriel Fernandez 	ret = stm32_rcc_init(dev, base, stm32mp1_match_data);
238495272370SGabriel Fernandez 
238595272370SGabriel Fernandez out:
238695272370SGabriel Fernandez 	if (ret) {
238795272370SGabriel Fernandez 		if (base)
23889bee94e7SGabriel Fernandez 			iounmap(base);
238995272370SGabriel Fernandez 
239095272370SGabriel Fernandez 		of_node_put(dev_of_node(dev));
23919bee94e7SGabriel Fernandez 	}
23929bee94e7SGabriel Fernandez 
239395272370SGabriel Fernandez 	return ret;
239495272370SGabriel Fernandez }
239595272370SGabriel Fernandez 
get_clock_deps(struct device * dev)239621e74330SGabriel Fernandez static int get_clock_deps(struct device *dev)
239721e74330SGabriel Fernandez {
239821e74330SGabriel Fernandez 	static const char * const clock_deps_name[] = {
239921e74330SGabriel Fernandez 		"hsi", "hse", "csi", "lsi", "lse",
240021e74330SGabriel Fernandez 	};
240121e74330SGabriel Fernandez 	size_t deps_size = sizeof(struct clk *) * ARRAY_SIZE(clock_deps_name);
240221e74330SGabriel Fernandez 	struct clk **clk_deps;
240321e74330SGabriel Fernandez 	int i;
240421e74330SGabriel Fernandez 
240521e74330SGabriel Fernandez 	clk_deps = devm_kzalloc(dev, deps_size, GFP_KERNEL);
240621e74330SGabriel Fernandez 	if (!clk_deps)
240721e74330SGabriel Fernandez 		return -ENOMEM;
240821e74330SGabriel Fernandez 
240921e74330SGabriel Fernandez 	for (i = 0; i < ARRAY_SIZE(clock_deps_name); i++) {
241021e74330SGabriel Fernandez 		struct clk *clk = of_clk_get_by_name(dev_of_node(dev),
241121e74330SGabriel Fernandez 						     clock_deps_name[i]);
241221e74330SGabriel Fernandez 
241321e74330SGabriel Fernandez 		if (IS_ERR(clk)) {
241421e74330SGabriel Fernandez 			if (PTR_ERR(clk) != -EINVAL && PTR_ERR(clk) != -ENOENT)
241521e74330SGabriel Fernandez 				return PTR_ERR(clk);
241621e74330SGabriel Fernandez 		} else {
241721e74330SGabriel Fernandez 			/* Device gets a reference count on the clock */
241821e74330SGabriel Fernandez 			clk_deps[i] = devm_clk_get(dev, __clk_get_name(clk));
241921e74330SGabriel Fernandez 			clk_put(clk);
242021e74330SGabriel Fernandez 		}
242121e74330SGabriel Fernandez 	}
242221e74330SGabriel Fernandez 
242321e74330SGabriel Fernandez 	return 0;
242421e74330SGabriel Fernandez }
242521e74330SGabriel Fernandez 
stm32mp1_rcc_clocks_probe(struct platform_device * pdev)242695272370SGabriel Fernandez static int stm32mp1_rcc_clocks_probe(struct platform_device *pdev)
242795272370SGabriel Fernandez {
242895272370SGabriel Fernandez 	struct device *dev = &pdev->dev;
242921e74330SGabriel Fernandez 	int ret = get_clock_deps(dev);
243095272370SGabriel Fernandez 
243121e74330SGabriel Fernandez 	if (!ret)
243221e74330SGabriel Fernandez 		ret = stm32mp1_rcc_init(dev);
243321e74330SGabriel Fernandez 
243421e74330SGabriel Fernandez 	return ret;
243595272370SGabriel Fernandez }
243695272370SGabriel Fernandez 
stm32mp1_rcc_clocks_remove(struct platform_device * pdev)2437*8ad00c14SUwe Kleine-König static void stm32mp1_rcc_clocks_remove(struct platform_device *pdev)
243895272370SGabriel Fernandez {
243995272370SGabriel Fernandez 	struct device *dev = &pdev->dev;
244095272370SGabriel Fernandez 	struct device_node *child, *np = dev_of_node(dev);
244195272370SGabriel Fernandez 
244295272370SGabriel Fernandez 	for_each_available_child_of_node(np, child)
244395272370SGabriel Fernandez 		of_clk_del_provider(child);
244495272370SGabriel Fernandez }
244595272370SGabriel Fernandez 
244695272370SGabriel Fernandez static struct platform_driver stm32mp1_rcc_clocks_driver = {
244795272370SGabriel Fernandez 	.driver	= {
244895272370SGabriel Fernandez 		.name = "stm32mp1_rcc",
244995272370SGabriel Fernandez 		.of_match_table = stm32mp1_match_data,
245095272370SGabriel Fernandez 	},
245195272370SGabriel Fernandez 	.probe = stm32mp1_rcc_clocks_probe,
2452*8ad00c14SUwe Kleine-König 	.remove_new = stm32mp1_rcc_clocks_remove,
245395272370SGabriel Fernandez };
245495272370SGabriel Fernandez 
stm32mp1_clocks_init(void)245595272370SGabriel Fernandez static int __init stm32mp1_clocks_init(void)
245695272370SGabriel Fernandez {
245795272370SGabriel Fernandez 	return platform_driver_register(&stm32mp1_rcc_clocks_driver);
245895272370SGabriel Fernandez }
245995272370SGabriel Fernandez core_initcall(stm32mp1_clocks_init);
2460