162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Author: Daniel Thompson <daniel.thompson@linaro.org> 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Inspired by clk-asm9260.c . 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/clk-provider.h> 962306a36Sopenharmony_ci#include <linux/err.h> 1062306a36Sopenharmony_ci#include <linux/io.h> 1162306a36Sopenharmony_ci#include <linux/iopoll.h> 1262306a36Sopenharmony_ci#include <linux/ioport.h> 1362306a36Sopenharmony_ci#include <linux/slab.h> 1462306a36Sopenharmony_ci#include <linux/spinlock.h> 1562306a36Sopenharmony_ci#include <linux/of.h> 1662306a36Sopenharmony_ci#include <linux/of_address.h> 1762306a36Sopenharmony_ci#include <linux/regmap.h> 1862306a36Sopenharmony_ci#include <linux/mfd/syscon.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* 2162306a36Sopenharmony_ci * Include list of clocks wich are not derived from system clock (SYSCLOCK) 2262306a36Sopenharmony_ci * The index of these clocks is the secondary index of DT bindings 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci#include <dt-bindings/clock/stm32fx-clock.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define STM32F4_RCC_CR 0x00 2862306a36Sopenharmony_ci#define STM32F4_RCC_PLLCFGR 0x04 2962306a36Sopenharmony_ci#define STM32F4_RCC_CFGR 0x08 3062306a36Sopenharmony_ci#define STM32F4_RCC_AHB1ENR 0x30 3162306a36Sopenharmony_ci#define STM32F4_RCC_AHB2ENR 0x34 3262306a36Sopenharmony_ci#define STM32F4_RCC_AHB3ENR 0x38 3362306a36Sopenharmony_ci#define STM32F4_RCC_APB1ENR 0x40 3462306a36Sopenharmony_ci#define STM32F4_RCC_APB2ENR 0x44 3562306a36Sopenharmony_ci#define STM32F4_RCC_BDCR 0x70 3662306a36Sopenharmony_ci#define STM32F4_RCC_CSR 0x74 3762306a36Sopenharmony_ci#define STM32F4_RCC_PLLI2SCFGR 0x84 3862306a36Sopenharmony_ci#define STM32F4_RCC_PLLSAICFGR 0x88 3962306a36Sopenharmony_ci#define STM32F4_RCC_DCKCFGR 0x8c 4062306a36Sopenharmony_ci#define STM32F7_RCC_DCKCFGR2 0x90 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define NONE -1 4362306a36Sopenharmony_ci#define NO_IDX NONE 4462306a36Sopenharmony_ci#define NO_MUX NONE 4562306a36Sopenharmony_ci#define NO_GATE NONE 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistruct stm32f4_gate_data { 4862306a36Sopenharmony_ci u8 offset; 4962306a36Sopenharmony_ci u8 bit_idx; 5062306a36Sopenharmony_ci const char *name; 5162306a36Sopenharmony_ci const char *parent_name; 5262306a36Sopenharmony_ci unsigned long flags; 5362306a36Sopenharmony_ci}; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic const struct stm32f4_gate_data stm32f429_gates[] __initconst = { 5662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" }, 5762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" }, 5862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" }, 5962306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 3, "gpiod", "ahb_div" }, 6062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 4, "gpioe", "ahb_div" }, 6162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 5, "gpiof", "ahb_div" }, 6262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 6, "gpiog", "ahb_div" }, 6362306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 7, "gpioh", "ahb_div" }, 6462306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 8, "gpioi", "ahb_div" }, 6562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 9, "gpioj", "ahb_div" }, 6662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 10, "gpiok", "ahb_div" }, 6762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 12, "crc", "ahb_div" }, 6862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 18, "bkpsra", "ahb_div" }, 6962306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 20, "ccmdatam", "ahb_div" }, 7062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 21, "dma1", "ahb_div" }, 7162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 22, "dma2", "ahb_div" }, 7262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 23, "dma2d", "ahb_div" }, 7362306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 25, "ethmac", "ahb_div" }, 7462306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 26, "ethmactx", "ahb_div" }, 7562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 27, "ethmacrx", "ahb_div" }, 7662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 28, "ethmacptp", "ahb_div" }, 7762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 29, "otghs", "ahb_div" }, 7862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 30, "otghsulpi", "ahb_div" }, 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 0, "dcmi", "ahb_div" }, 8162306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 4, "cryp", "ahb_div" }, 8262306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 5, "hash", "ahb_div" }, 8362306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 6, "rng", "pll48" }, 8462306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 7, "otgfs", "pll48" }, 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci { STM32F4_RCC_AHB3ENR, 0, "fmc", "ahb_div", 8762306a36Sopenharmony_ci CLK_IGNORE_UNUSED }, 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 0, "tim2", "apb1_mul" }, 9062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 1, "tim3", "apb1_mul" }, 9162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 2, "tim4", "apb1_mul" }, 9262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 3, "tim5", "apb1_mul" }, 9362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 4, "tim6", "apb1_mul" }, 9462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 5, "tim7", "apb1_mul" }, 9562306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 6, "tim12", "apb1_mul" }, 9662306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 7, "tim13", "apb1_mul" }, 9762306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 8, "tim14", "apb1_mul" }, 9862306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 11, "wwdg", "apb1_div" }, 9962306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 14, "spi2", "apb1_div" }, 10062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 15, "spi3", "apb1_div" }, 10162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 17, "uart2", "apb1_div" }, 10262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 18, "uart3", "apb1_div" }, 10362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 19, "uart4", "apb1_div" }, 10462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 20, "uart5", "apb1_div" }, 10562306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 21, "i2c1", "apb1_div" }, 10662306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 22, "i2c2", "apb1_div" }, 10762306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 23, "i2c3", "apb1_div" }, 10862306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 25, "can1", "apb1_div" }, 10962306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 26, "can2", "apb1_div" }, 11062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 28, "pwr", "apb1_div" }, 11162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 29, "dac", "apb1_div" }, 11262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 30, "uart7", "apb1_div" }, 11362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 31, "uart8", "apb1_div" }, 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" }, 11662306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" }, 11762306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 4, "usart1", "apb2_div" }, 11862306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 5, "usart6", "apb2_div" }, 11962306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 12062306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 12162306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 12262306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 11, "sdio", "pll48" }, 12362306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" }, 12462306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" }, 12562306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" }, 12662306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 16, "tim9", "apb2_mul" }, 12762306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 17, "tim10", "apb2_mul" }, 12862306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 18, "tim11", "apb2_mul" }, 12962306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, 13062306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, 13162306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic const struct stm32f4_gate_data stm32f469_gates[] __initconst = { 13562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" }, 13662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" }, 13762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" }, 13862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 3, "gpiod", "ahb_div" }, 13962306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 4, "gpioe", "ahb_div" }, 14062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 5, "gpiof", "ahb_div" }, 14162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 6, "gpiog", "ahb_div" }, 14262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 7, "gpioh", "ahb_div" }, 14362306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 8, "gpioi", "ahb_div" }, 14462306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 9, "gpioj", "ahb_div" }, 14562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 10, "gpiok", "ahb_div" }, 14662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 12, "crc", "ahb_div" }, 14762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 18, "bkpsra", "ahb_div" }, 14862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 20, "ccmdatam", "ahb_div" }, 14962306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 21, "dma1", "ahb_div" }, 15062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 22, "dma2", "ahb_div" }, 15162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 23, "dma2d", "ahb_div" }, 15262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 25, "ethmac", "ahb_div" }, 15362306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 26, "ethmactx", "ahb_div" }, 15462306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 27, "ethmacrx", "ahb_div" }, 15562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 28, "ethmacptp", "ahb_div" }, 15662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 29, "otghs", "ahb_div" }, 15762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 30, "otghsulpi", "ahb_div" }, 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 0, "dcmi", "ahb_div" }, 16062306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 4, "cryp", "ahb_div" }, 16162306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 5, "hash", "ahb_div" }, 16262306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 6, "rng", "pll48" }, 16362306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 7, "otgfs", "pll48" }, 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci { STM32F4_RCC_AHB3ENR, 0, "fmc", "ahb_div", 16662306a36Sopenharmony_ci CLK_IGNORE_UNUSED }, 16762306a36Sopenharmony_ci { STM32F4_RCC_AHB3ENR, 1, "qspi", "ahb_div", 16862306a36Sopenharmony_ci CLK_IGNORE_UNUSED }, 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 0, "tim2", "apb1_mul" }, 17162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 1, "tim3", "apb1_mul" }, 17262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 2, "tim4", "apb1_mul" }, 17362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 3, "tim5", "apb1_mul" }, 17462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 4, "tim6", "apb1_mul" }, 17562306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 5, "tim7", "apb1_mul" }, 17662306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 6, "tim12", "apb1_mul" }, 17762306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 7, "tim13", "apb1_mul" }, 17862306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 8, "tim14", "apb1_mul" }, 17962306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 11, "wwdg", "apb1_div" }, 18062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 14, "spi2", "apb1_div" }, 18162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 15, "spi3", "apb1_div" }, 18262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 17, "uart2", "apb1_div" }, 18362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 18, "uart3", "apb1_div" }, 18462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 19, "uart4", "apb1_div" }, 18562306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 20, "uart5", "apb1_div" }, 18662306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 21, "i2c1", "apb1_div" }, 18762306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 22, "i2c2", "apb1_div" }, 18862306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 23, "i2c3", "apb1_div" }, 18962306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 25, "can1", "apb1_div" }, 19062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 26, "can2", "apb1_div" }, 19162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 28, "pwr", "apb1_div" }, 19262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 29, "dac", "apb1_div" }, 19362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 30, "uart7", "apb1_div" }, 19462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 31, "uart8", "apb1_div" }, 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" }, 19762306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" }, 19862306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 4, "usart1", "apb2_div" }, 19962306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 5, "usart6", "apb2_div" }, 20062306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 20162306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 20262306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 20362306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 11, "sdio", "sdmux" }, 20462306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" }, 20562306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" }, 20662306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" }, 20762306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 16, "tim9", "apb2_mul" }, 20862306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 17, "tim10", "apb2_mul" }, 20962306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 18, "tim11", "apb2_mul" }, 21062306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, 21162306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, 21262306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, 21362306a36Sopenharmony_ci}; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistatic const struct stm32f4_gate_data stm32f746_gates[] __initconst = { 21662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" }, 21762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" }, 21862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" }, 21962306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 3, "gpiod", "ahb_div" }, 22062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 4, "gpioe", "ahb_div" }, 22162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 5, "gpiof", "ahb_div" }, 22262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 6, "gpiog", "ahb_div" }, 22362306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 7, "gpioh", "ahb_div" }, 22462306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 8, "gpioi", "ahb_div" }, 22562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 9, "gpioj", "ahb_div" }, 22662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 10, "gpiok", "ahb_div" }, 22762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 12, "crc", "ahb_div" }, 22862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 18, "bkpsra", "ahb_div" }, 22962306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 20, "dtcmram", "ahb_div" }, 23062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 21, "dma1", "ahb_div" }, 23162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 22, "dma2", "ahb_div" }, 23262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 23, "dma2d", "ahb_div" }, 23362306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 25, "ethmac", "ahb_div" }, 23462306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 26, "ethmactx", "ahb_div" }, 23562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 27, "ethmacrx", "ahb_div" }, 23662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 28, "ethmacptp", "ahb_div" }, 23762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 29, "otghs", "ahb_div" }, 23862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 30, "otghsulpi", "ahb_div" }, 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 0, "dcmi", "ahb_div" }, 24162306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 4, "cryp", "ahb_div" }, 24262306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 5, "hash", "ahb_div" }, 24362306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 6, "rng", "pll48" }, 24462306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 7, "otgfs", "pll48" }, 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci { STM32F4_RCC_AHB3ENR, 0, "fmc", "ahb_div", 24762306a36Sopenharmony_ci CLK_IGNORE_UNUSED }, 24862306a36Sopenharmony_ci { STM32F4_RCC_AHB3ENR, 1, "qspi", "ahb_div", 24962306a36Sopenharmony_ci CLK_IGNORE_UNUSED }, 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 0, "tim2", "apb1_mul" }, 25262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 1, "tim3", "apb1_mul" }, 25362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 2, "tim4", "apb1_mul" }, 25462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 3, "tim5", "apb1_mul" }, 25562306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 4, "tim6", "apb1_mul" }, 25662306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 5, "tim7", "apb1_mul" }, 25762306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 6, "tim12", "apb1_mul" }, 25862306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 7, "tim13", "apb1_mul" }, 25962306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 8, "tim14", "apb1_mul" }, 26062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 11, "wwdg", "apb1_div" }, 26162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 14, "spi2", "apb1_div" }, 26262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 15, "spi3", "apb1_div" }, 26362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 16, "spdifrx", "apb1_div" }, 26462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 25, "can1", "apb1_div" }, 26562306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 26, "can2", "apb1_div" }, 26662306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 27, "cec", "apb1_div" }, 26762306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 28, "pwr", "apb1_div" }, 26862306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 29, "dac", "apb1_div" }, 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" }, 27162306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" }, 27262306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 7, "sdmmc2", "sdmux" }, 27362306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 27462306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 27562306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 27662306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 11, "sdmmc", "sdmux" }, 27762306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" }, 27862306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" }, 27962306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" }, 28062306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 16, "tim9", "apb2_mul" }, 28162306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 17, "tim10", "apb2_mul" }, 28262306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 18, "tim11", "apb2_mul" }, 28362306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, 28462306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, 28562306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, 28662306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, 28762306a36Sopenharmony_ci}; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic const struct stm32f4_gate_data stm32f769_gates[] __initconst = { 29062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" }, 29162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" }, 29262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" }, 29362306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 3, "gpiod", "ahb_div" }, 29462306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 4, "gpioe", "ahb_div" }, 29562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 5, "gpiof", "ahb_div" }, 29662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 6, "gpiog", "ahb_div" }, 29762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 7, "gpioh", "ahb_div" }, 29862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 8, "gpioi", "ahb_div" }, 29962306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 9, "gpioj", "ahb_div" }, 30062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 10, "gpiok", "ahb_div" }, 30162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 12, "crc", "ahb_div" }, 30262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 18, "bkpsra", "ahb_div" }, 30362306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 20, "dtcmram", "ahb_div" }, 30462306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 21, "dma1", "ahb_div" }, 30562306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 22, "dma2", "ahb_div" }, 30662306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 23, "dma2d", "ahb_div" }, 30762306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 25, "ethmac", "ahb_div" }, 30862306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 26, "ethmactx", "ahb_div" }, 30962306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 27, "ethmacrx", "ahb_div" }, 31062306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 28, "ethmacptp", "ahb_div" }, 31162306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 29, "otghs", "ahb_div" }, 31262306a36Sopenharmony_ci { STM32F4_RCC_AHB1ENR, 30, "otghsulpi", "ahb_div" }, 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 0, "dcmi", "ahb_div" }, 31562306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 1, "jpeg", "ahb_div" }, 31662306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 4, "cryp", "ahb_div" }, 31762306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 5, "hash", "ahb_div" }, 31862306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 6, "rng", "pll48" }, 31962306a36Sopenharmony_ci { STM32F4_RCC_AHB2ENR, 7, "otgfs", "pll48" }, 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci { STM32F4_RCC_AHB3ENR, 0, "fmc", "ahb_div", 32262306a36Sopenharmony_ci CLK_IGNORE_UNUSED }, 32362306a36Sopenharmony_ci { STM32F4_RCC_AHB3ENR, 1, "qspi", "ahb_div", 32462306a36Sopenharmony_ci CLK_IGNORE_UNUSED }, 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 0, "tim2", "apb1_mul" }, 32762306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 1, "tim3", "apb1_mul" }, 32862306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 2, "tim4", "apb1_mul" }, 32962306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 3, "tim5", "apb1_mul" }, 33062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 4, "tim6", "apb1_mul" }, 33162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 5, "tim7", "apb1_mul" }, 33262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 6, "tim12", "apb1_mul" }, 33362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 7, "tim13", "apb1_mul" }, 33462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 8, "tim14", "apb1_mul" }, 33562306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 10, "rtcapb", "apb1_mul" }, 33662306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 11, "wwdg", "apb1_div" }, 33762306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 13, "can3", "apb1_div" }, 33862306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 14, "spi2", "apb1_div" }, 33962306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 15, "spi3", "apb1_div" }, 34062306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 16, "spdifrx", "apb1_div" }, 34162306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 25, "can1", "apb1_div" }, 34262306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 26, "can2", "apb1_div" }, 34362306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 27, "cec", "apb1_div" }, 34462306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 28, "pwr", "apb1_div" }, 34562306a36Sopenharmony_ci { STM32F4_RCC_APB1ENR, 29, "dac", "apb1_div" }, 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" }, 34862306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" }, 34962306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 7, "sdmmc2", "sdmux2" }, 35062306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 35162306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 35262306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 35362306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 11, "sdmmc1", "sdmux1" }, 35462306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" }, 35562306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" }, 35662306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" }, 35762306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 16, "tim9", "apb2_mul" }, 35862306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 17, "tim10", "apb2_mul" }, 35962306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 18, "tim11", "apb2_mul" }, 36062306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, 36162306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, 36262306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, 36362306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, 36462306a36Sopenharmony_ci { STM32F4_RCC_APB2ENR, 30, "mdio", "apb2_div" }, 36562306a36Sopenharmony_ci}; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci/* 36862306a36Sopenharmony_ci * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx 36962306a36Sopenharmony_ci * have gate bits associated with them. Its combined hweight is 71. 37062306a36Sopenharmony_ci */ 37162306a36Sopenharmony_ci#define MAX_GATE_MAP 3 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_cistatic const u64 stm32f42xx_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, 37462306a36Sopenharmony_ci 0x0000000000000001ull, 37562306a36Sopenharmony_ci 0x04777f33f6fec9ffull }; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_cistatic const u64 stm32f46xx_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, 37862306a36Sopenharmony_ci 0x0000000000000003ull, 37962306a36Sopenharmony_ci 0x0c777f33f6fec9ffull }; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_cistatic const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, 38262306a36Sopenharmony_ci 0x0000000000000003ull, 38362306a36Sopenharmony_ci 0x04f77f833e01c9ffull }; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_cistatic const u64 stm32f769_gate_map[MAX_GATE_MAP] = { 0x000000f37ef417ffull, 38662306a36Sopenharmony_ci 0x0000000000000003ull, 38762306a36Sopenharmony_ci 0x44F77F833E01EDFFull }; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_cistatic const u64 *stm32f4_gate_map; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_cistatic struct clk_hw **clks; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_cistatic DEFINE_SPINLOCK(stm32f4_clk_lock); 39462306a36Sopenharmony_cistatic void __iomem *base; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_cistatic struct regmap *pdrm; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_cistatic int stm32fx_end_primary_clk; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci/* 40162306a36Sopenharmony_ci * "Multiplier" device for APBx clocks. 40262306a36Sopenharmony_ci * 40362306a36Sopenharmony_ci * The APBx dividers are power-of-two dividers and, if *not* running in 1:1 40462306a36Sopenharmony_ci * mode, they also tap out the one of the low order state bits to run the 40562306a36Sopenharmony_ci * timers. ST datasheets represent this feature as a (conditional) clock 40662306a36Sopenharmony_ci * multiplier. 40762306a36Sopenharmony_ci */ 40862306a36Sopenharmony_cistruct clk_apb_mul { 40962306a36Sopenharmony_ci struct clk_hw hw; 41062306a36Sopenharmony_ci u8 bit_idx; 41162306a36Sopenharmony_ci}; 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci#define to_clk_apb_mul(_hw) container_of(_hw, struct clk_apb_mul, hw) 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_cistatic unsigned long clk_apb_mul_recalc_rate(struct clk_hw *hw, 41662306a36Sopenharmony_ci unsigned long parent_rate) 41762306a36Sopenharmony_ci{ 41862306a36Sopenharmony_ci struct clk_apb_mul *am = to_clk_apb_mul(hw); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci if (readl(base + STM32F4_RCC_CFGR) & BIT(am->bit_idx)) 42162306a36Sopenharmony_ci return parent_rate * 2; 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci return parent_rate; 42462306a36Sopenharmony_ci} 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_cistatic long clk_apb_mul_round_rate(struct clk_hw *hw, unsigned long rate, 42762306a36Sopenharmony_ci unsigned long *prate) 42862306a36Sopenharmony_ci{ 42962306a36Sopenharmony_ci struct clk_apb_mul *am = to_clk_apb_mul(hw); 43062306a36Sopenharmony_ci unsigned long mult = 1; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci if (readl(base + STM32F4_RCC_CFGR) & BIT(am->bit_idx)) 43362306a36Sopenharmony_ci mult = 2; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { 43662306a36Sopenharmony_ci unsigned long best_parent = rate / mult; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci return *prate * mult; 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic int clk_apb_mul_set_rate(struct clk_hw *hw, unsigned long rate, 44562306a36Sopenharmony_ci unsigned long parent_rate) 44662306a36Sopenharmony_ci{ 44762306a36Sopenharmony_ci /* 44862306a36Sopenharmony_ci * We must report success but we can do so unconditionally because 44962306a36Sopenharmony_ci * clk_apb_mul_round_rate returns values that ensure this call is a 45062306a36Sopenharmony_ci * nop. 45162306a36Sopenharmony_ci */ 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci return 0; 45462306a36Sopenharmony_ci} 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_cistatic const struct clk_ops clk_apb_mul_factor_ops = { 45762306a36Sopenharmony_ci .round_rate = clk_apb_mul_round_rate, 45862306a36Sopenharmony_ci .set_rate = clk_apb_mul_set_rate, 45962306a36Sopenharmony_ci .recalc_rate = clk_apb_mul_recalc_rate, 46062306a36Sopenharmony_ci}; 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_cistatic struct clk *clk_register_apb_mul(struct device *dev, const char *name, 46362306a36Sopenharmony_ci const char *parent_name, 46462306a36Sopenharmony_ci unsigned long flags, u8 bit_idx) 46562306a36Sopenharmony_ci{ 46662306a36Sopenharmony_ci struct clk_apb_mul *am; 46762306a36Sopenharmony_ci struct clk_init_data init; 46862306a36Sopenharmony_ci struct clk *clk; 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci am = kzalloc(sizeof(*am), GFP_KERNEL); 47162306a36Sopenharmony_ci if (!am) 47262306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci am->bit_idx = bit_idx; 47562306a36Sopenharmony_ci am->hw.init = &init; 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci init.name = name; 47862306a36Sopenharmony_ci init.ops = &clk_apb_mul_factor_ops; 47962306a36Sopenharmony_ci init.flags = flags; 48062306a36Sopenharmony_ci init.parent_names = &parent_name; 48162306a36Sopenharmony_ci init.num_parents = 1; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci clk = clk_register(dev, &am->hw); 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci if (IS_ERR(clk)) 48662306a36Sopenharmony_ci kfree(am); 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci return clk; 48962306a36Sopenharmony_ci} 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cienum { 49262306a36Sopenharmony_ci PLL, 49362306a36Sopenharmony_ci PLL_I2S, 49462306a36Sopenharmony_ci PLL_SAI, 49562306a36Sopenharmony_ci}; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_cistatic const struct clk_div_table pll_divp_table[] = { 49862306a36Sopenharmony_ci { 0, 2 }, { 1, 4 }, { 2, 6 }, { 3, 8 }, { 0 } 49962306a36Sopenharmony_ci}; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_cistatic const struct clk_div_table pll_divq_table[] = { 50262306a36Sopenharmony_ci { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, 50362306a36Sopenharmony_ci { 8, 8 }, { 9, 9 }, { 10, 10 }, { 11, 11 }, { 12, 12 }, { 13, 13 }, 50462306a36Sopenharmony_ci { 14, 14 }, { 15, 15 }, 50562306a36Sopenharmony_ci { 0 } 50662306a36Sopenharmony_ci}; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_cistatic const struct clk_div_table pll_divr_table[] = { 50962306a36Sopenharmony_ci { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, { 0 } 51062306a36Sopenharmony_ci}; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_cistruct stm32f4_pll { 51362306a36Sopenharmony_ci spinlock_t *lock; 51462306a36Sopenharmony_ci struct clk_gate gate; 51562306a36Sopenharmony_ci u8 offset; 51662306a36Sopenharmony_ci u8 bit_rdy_idx; 51762306a36Sopenharmony_ci u8 status; 51862306a36Sopenharmony_ci u8 n_start; 51962306a36Sopenharmony_ci}; 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci#define to_stm32f4_pll(_gate) container_of(_gate, struct stm32f4_pll, gate) 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_cistruct stm32f4_pll_post_div_data { 52462306a36Sopenharmony_ci int idx; 52562306a36Sopenharmony_ci int pll_idx; 52662306a36Sopenharmony_ci const char *name; 52762306a36Sopenharmony_ci const char *parent; 52862306a36Sopenharmony_ci u8 flag; 52962306a36Sopenharmony_ci u8 offset; 53062306a36Sopenharmony_ci u8 shift; 53162306a36Sopenharmony_ci u8 width; 53262306a36Sopenharmony_ci u8 flag_div; 53362306a36Sopenharmony_ci const struct clk_div_table *div_table; 53462306a36Sopenharmony_ci}; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistruct stm32f4_vco_data { 53762306a36Sopenharmony_ci const char *vco_name; 53862306a36Sopenharmony_ci u8 offset; 53962306a36Sopenharmony_ci u8 bit_idx; 54062306a36Sopenharmony_ci u8 bit_rdy_idx; 54162306a36Sopenharmony_ci}; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistatic const struct stm32f4_vco_data vco_data[] = { 54462306a36Sopenharmony_ci { "vco", STM32F4_RCC_PLLCFGR, 24, 25 }, 54562306a36Sopenharmony_ci { "vco-i2s", STM32F4_RCC_PLLI2SCFGR, 26, 27 }, 54662306a36Sopenharmony_ci { "vco-sai", STM32F4_RCC_PLLSAICFGR, 28, 29 }, 54762306a36Sopenharmony_ci}; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_cistatic const struct clk_div_table post_divr_table[] = { 55162306a36Sopenharmony_ci { 0, 2 }, { 1, 4 }, { 2, 8 }, { 3, 16 }, { 0 } 55262306a36Sopenharmony_ci}; 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci#define MAX_POST_DIV 3 55562306a36Sopenharmony_cistatic const struct stm32f4_pll_post_div_data post_div_data[MAX_POST_DIV] = { 55662306a36Sopenharmony_ci { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q", 55762306a36Sopenharmony_ci CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL}, 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q", 56062306a36Sopenharmony_ci CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL }, 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT, 56362306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table }, 56462306a36Sopenharmony_ci}; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_cistruct stm32f4_div_data { 56762306a36Sopenharmony_ci u8 shift; 56862306a36Sopenharmony_ci u8 width; 56962306a36Sopenharmony_ci u8 flag_div; 57062306a36Sopenharmony_ci const struct clk_div_table *div_table; 57162306a36Sopenharmony_ci}; 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci#define MAX_PLL_DIV 3 57462306a36Sopenharmony_cistatic const struct stm32f4_div_data div_data[MAX_PLL_DIV] = { 57562306a36Sopenharmony_ci { 16, 2, 0, pll_divp_table }, 57662306a36Sopenharmony_ci { 24, 4, 0, pll_divq_table }, 57762306a36Sopenharmony_ci { 28, 3, 0, pll_divr_table }, 57862306a36Sopenharmony_ci}; 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cistruct stm32f4_pll_data { 58162306a36Sopenharmony_ci u8 pll_num; 58262306a36Sopenharmony_ci u8 n_start; 58362306a36Sopenharmony_ci const char *div_name[MAX_PLL_DIV]; 58462306a36Sopenharmony_ci}; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_cistatic const struct stm32f4_pll_data stm32f429_pll[MAX_PLL_DIV] = { 58762306a36Sopenharmony_ci { PLL, 192, { "pll", "pll48", NULL } }, 58862306a36Sopenharmony_ci { PLL_I2S, 192, { NULL, "plli2s-q", "plli2s-r" } }, 58962306a36Sopenharmony_ci { PLL_SAI, 49, { NULL, "pllsai-q", "pllsai-r" } }, 59062306a36Sopenharmony_ci}; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_cistatic const struct stm32f4_pll_data stm32f469_pll[MAX_PLL_DIV] = { 59362306a36Sopenharmony_ci { PLL, 50, { "pll", "pll-q", "pll-r" } }, 59462306a36Sopenharmony_ci { PLL_I2S, 50, { "plli2s-p", "plli2s-q", "plli2s-r" } }, 59562306a36Sopenharmony_ci { PLL_SAI, 50, { "pllsai-p", "pllsai-q", "pllsai-r" } }, 59662306a36Sopenharmony_ci}; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_cistatic int stm32f4_pll_is_enabled(struct clk_hw *hw) 59962306a36Sopenharmony_ci{ 60062306a36Sopenharmony_ci return clk_gate_ops.is_enabled(hw); 60162306a36Sopenharmony_ci} 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci#define PLL_TIMEOUT 10000 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_cistatic int stm32f4_pll_enable(struct clk_hw *hw) 60662306a36Sopenharmony_ci{ 60762306a36Sopenharmony_ci struct clk_gate *gate = to_clk_gate(hw); 60862306a36Sopenharmony_ci struct stm32f4_pll *pll = to_stm32f4_pll(gate); 60962306a36Sopenharmony_ci int bit_status; 61062306a36Sopenharmony_ci unsigned int timeout = PLL_TIMEOUT; 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci if (clk_gate_ops.is_enabled(hw)) 61362306a36Sopenharmony_ci return 0; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci clk_gate_ops.enable(hw); 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci do { 61862306a36Sopenharmony_ci bit_status = !(readl(gate->reg) & BIT(pll->bit_rdy_idx)); 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci } while (bit_status && --timeout); 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci return bit_status; 62362306a36Sopenharmony_ci} 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_cistatic void stm32f4_pll_disable(struct clk_hw *hw) 62662306a36Sopenharmony_ci{ 62762306a36Sopenharmony_ci clk_gate_ops.disable(hw); 62862306a36Sopenharmony_ci} 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_cistatic unsigned long stm32f4_pll_recalc(struct clk_hw *hw, 63162306a36Sopenharmony_ci unsigned long parent_rate) 63262306a36Sopenharmony_ci{ 63362306a36Sopenharmony_ci struct clk_gate *gate = to_clk_gate(hw); 63462306a36Sopenharmony_ci struct stm32f4_pll *pll = to_stm32f4_pll(gate); 63562306a36Sopenharmony_ci unsigned long n; 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci n = (readl(base + pll->offset) >> 6) & 0x1ff; 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci return parent_rate * n; 64062306a36Sopenharmony_ci} 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_cistatic long stm32f4_pll_round_rate(struct clk_hw *hw, unsigned long rate, 64362306a36Sopenharmony_ci unsigned long *prate) 64462306a36Sopenharmony_ci{ 64562306a36Sopenharmony_ci struct clk_gate *gate = to_clk_gate(hw); 64662306a36Sopenharmony_ci struct stm32f4_pll *pll = to_stm32f4_pll(gate); 64762306a36Sopenharmony_ci unsigned long n; 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci n = rate / *prate; 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci if (n < pll->n_start) 65262306a36Sopenharmony_ci n = pll->n_start; 65362306a36Sopenharmony_ci else if (n > 432) 65462306a36Sopenharmony_ci n = 432; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci return *prate * n; 65762306a36Sopenharmony_ci} 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_cistatic int stm32f4_pll_set_rate(struct clk_hw *hw, unsigned long rate, 66062306a36Sopenharmony_ci unsigned long parent_rate) 66162306a36Sopenharmony_ci{ 66262306a36Sopenharmony_ci struct clk_gate *gate = to_clk_gate(hw); 66362306a36Sopenharmony_ci struct stm32f4_pll *pll = to_stm32f4_pll(gate); 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci unsigned long n; 66662306a36Sopenharmony_ci unsigned long val; 66762306a36Sopenharmony_ci int pll_state; 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci pll_state = stm32f4_pll_is_enabled(hw); 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci if (pll_state) 67262306a36Sopenharmony_ci stm32f4_pll_disable(hw); 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci n = rate / parent_rate; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci val = readl(base + pll->offset) & ~(0x1ff << 6); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci writel(val | ((n & 0x1ff) << 6), base + pll->offset); 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci if (pll_state) 68162306a36Sopenharmony_ci stm32f4_pll_enable(hw); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci return 0; 68462306a36Sopenharmony_ci} 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_cistatic const struct clk_ops stm32f4_pll_gate_ops = { 68762306a36Sopenharmony_ci .enable = stm32f4_pll_enable, 68862306a36Sopenharmony_ci .disable = stm32f4_pll_disable, 68962306a36Sopenharmony_ci .is_enabled = stm32f4_pll_is_enabled, 69062306a36Sopenharmony_ci .recalc_rate = stm32f4_pll_recalc, 69162306a36Sopenharmony_ci .round_rate = stm32f4_pll_round_rate, 69262306a36Sopenharmony_ci .set_rate = stm32f4_pll_set_rate, 69362306a36Sopenharmony_ci}; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_cistruct stm32f4_pll_div { 69662306a36Sopenharmony_ci struct clk_divider div; 69762306a36Sopenharmony_ci struct clk_hw *hw_pll; 69862306a36Sopenharmony_ci}; 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci#define to_pll_div_clk(_div) container_of(_div, struct stm32f4_pll_div, div) 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_cistatic unsigned long stm32f4_pll_div_recalc_rate(struct clk_hw *hw, 70362306a36Sopenharmony_ci unsigned long parent_rate) 70462306a36Sopenharmony_ci{ 70562306a36Sopenharmony_ci return clk_divider_ops.recalc_rate(hw, parent_rate); 70662306a36Sopenharmony_ci} 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_cistatic int stm32f4_pll_div_determine_rate(struct clk_hw *hw, 70962306a36Sopenharmony_ci struct clk_rate_request *req) 71062306a36Sopenharmony_ci{ 71162306a36Sopenharmony_ci return clk_divider_ops.determine_rate(hw, req); 71262306a36Sopenharmony_ci} 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_cistatic int stm32f4_pll_div_set_rate(struct clk_hw *hw, unsigned long rate, 71562306a36Sopenharmony_ci unsigned long parent_rate) 71662306a36Sopenharmony_ci{ 71762306a36Sopenharmony_ci int pll_state, ret; 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci struct clk_divider *div = to_clk_divider(hw); 72062306a36Sopenharmony_ci struct stm32f4_pll_div *pll_div = to_pll_div_clk(div); 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci pll_state = stm32f4_pll_is_enabled(pll_div->hw_pll); 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci if (pll_state) 72562306a36Sopenharmony_ci stm32f4_pll_disable(pll_div->hw_pll); 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci ret = clk_divider_ops.set_rate(hw, rate, parent_rate); 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci if (pll_state) 73062306a36Sopenharmony_ci stm32f4_pll_enable(pll_div->hw_pll); 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci return ret; 73362306a36Sopenharmony_ci} 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_cistatic const struct clk_ops stm32f4_pll_div_ops = { 73662306a36Sopenharmony_ci .recalc_rate = stm32f4_pll_div_recalc_rate, 73762306a36Sopenharmony_ci .determine_rate = stm32f4_pll_div_determine_rate, 73862306a36Sopenharmony_ci .set_rate = stm32f4_pll_div_set_rate, 73962306a36Sopenharmony_ci}; 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_cistatic struct clk_hw *clk_register_pll_div(const char *name, 74262306a36Sopenharmony_ci const char *parent_name, unsigned long flags, 74362306a36Sopenharmony_ci void __iomem *reg, u8 shift, u8 width, 74462306a36Sopenharmony_ci u8 clk_divider_flags, const struct clk_div_table *table, 74562306a36Sopenharmony_ci struct clk_hw *pll_hw, spinlock_t *lock) 74662306a36Sopenharmony_ci{ 74762306a36Sopenharmony_ci struct stm32f4_pll_div *pll_div; 74862306a36Sopenharmony_ci struct clk_hw *hw; 74962306a36Sopenharmony_ci struct clk_init_data init; 75062306a36Sopenharmony_ci int ret; 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_ci /* allocate the divider */ 75362306a36Sopenharmony_ci pll_div = kzalloc(sizeof(*pll_div), GFP_KERNEL); 75462306a36Sopenharmony_ci if (!pll_div) 75562306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci init.name = name; 75862306a36Sopenharmony_ci init.ops = &stm32f4_pll_div_ops; 75962306a36Sopenharmony_ci init.flags = flags; 76062306a36Sopenharmony_ci init.parent_names = (parent_name ? &parent_name : NULL); 76162306a36Sopenharmony_ci init.num_parents = (parent_name ? 1 : 0); 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci /* struct clk_divider assignments */ 76462306a36Sopenharmony_ci pll_div->div.reg = reg; 76562306a36Sopenharmony_ci pll_div->div.shift = shift; 76662306a36Sopenharmony_ci pll_div->div.width = width; 76762306a36Sopenharmony_ci pll_div->div.flags = clk_divider_flags; 76862306a36Sopenharmony_ci pll_div->div.lock = lock; 76962306a36Sopenharmony_ci pll_div->div.table = table; 77062306a36Sopenharmony_ci pll_div->div.hw.init = &init; 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci pll_div->hw_pll = pll_hw; 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci /* register the clock */ 77562306a36Sopenharmony_ci hw = &pll_div->div.hw; 77662306a36Sopenharmony_ci ret = clk_hw_register(NULL, hw); 77762306a36Sopenharmony_ci if (ret) { 77862306a36Sopenharmony_ci kfree(pll_div); 77962306a36Sopenharmony_ci hw = ERR_PTR(ret); 78062306a36Sopenharmony_ci } 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci return hw; 78362306a36Sopenharmony_ci} 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_cistatic struct clk_hw *stm32f4_rcc_register_pll(const char *pllsrc, 78662306a36Sopenharmony_ci const struct stm32f4_pll_data *data, spinlock_t *lock) 78762306a36Sopenharmony_ci{ 78862306a36Sopenharmony_ci struct stm32f4_pll *pll; 78962306a36Sopenharmony_ci struct clk_init_data init = { NULL }; 79062306a36Sopenharmony_ci void __iomem *reg; 79162306a36Sopenharmony_ci struct clk_hw *pll_hw; 79262306a36Sopenharmony_ci int ret; 79362306a36Sopenharmony_ci int i; 79462306a36Sopenharmony_ci const struct stm32f4_vco_data *vco; 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci pll = kzalloc(sizeof(*pll), GFP_KERNEL); 79862306a36Sopenharmony_ci if (!pll) 79962306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci vco = &vco_data[data->pll_num]; 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci init.name = vco->vco_name; 80462306a36Sopenharmony_ci init.ops = &stm32f4_pll_gate_ops; 80562306a36Sopenharmony_ci init.flags = CLK_SET_RATE_GATE; 80662306a36Sopenharmony_ci init.parent_names = &pllsrc; 80762306a36Sopenharmony_ci init.num_parents = 1; 80862306a36Sopenharmony_ci 80962306a36Sopenharmony_ci pll->gate.lock = lock; 81062306a36Sopenharmony_ci pll->gate.reg = base + STM32F4_RCC_CR; 81162306a36Sopenharmony_ci pll->gate.bit_idx = vco->bit_idx; 81262306a36Sopenharmony_ci pll->gate.hw.init = &init; 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_ci pll->offset = vco->offset; 81562306a36Sopenharmony_ci pll->n_start = data->n_start; 81662306a36Sopenharmony_ci pll->bit_rdy_idx = vco->bit_rdy_idx; 81762306a36Sopenharmony_ci pll->status = (readl(base + STM32F4_RCC_CR) >> vco->bit_idx) & 0x1; 81862306a36Sopenharmony_ci 81962306a36Sopenharmony_ci reg = base + pll->offset; 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci pll_hw = &pll->gate.hw; 82262306a36Sopenharmony_ci ret = clk_hw_register(NULL, pll_hw); 82362306a36Sopenharmony_ci if (ret) { 82462306a36Sopenharmony_ci kfree(pll); 82562306a36Sopenharmony_ci return ERR_PTR(ret); 82662306a36Sopenharmony_ci } 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci for (i = 0; i < MAX_PLL_DIV; i++) 82962306a36Sopenharmony_ci if (data->div_name[i]) 83062306a36Sopenharmony_ci clk_register_pll_div(data->div_name[i], 83162306a36Sopenharmony_ci vco->vco_name, 83262306a36Sopenharmony_ci 0, 83362306a36Sopenharmony_ci reg, 83462306a36Sopenharmony_ci div_data[i].shift, 83562306a36Sopenharmony_ci div_data[i].width, 83662306a36Sopenharmony_ci div_data[i].flag_div, 83762306a36Sopenharmony_ci div_data[i].div_table, 83862306a36Sopenharmony_ci pll_hw, 83962306a36Sopenharmony_ci lock); 84062306a36Sopenharmony_ci return pll_hw; 84162306a36Sopenharmony_ci} 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci/* 84462306a36Sopenharmony_ci * Converts the primary and secondary indices (as they appear in DT) to an 84562306a36Sopenharmony_ci * offset into our struct clock array. 84662306a36Sopenharmony_ci */ 84762306a36Sopenharmony_cistatic int stm32f4_rcc_lookup_clk_idx(u8 primary, u8 secondary) 84862306a36Sopenharmony_ci{ 84962306a36Sopenharmony_ci u64 table[MAX_GATE_MAP]; 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_ci if (primary == 1) { 85262306a36Sopenharmony_ci if (WARN_ON(secondary >= stm32fx_end_primary_clk)) 85362306a36Sopenharmony_ci return -EINVAL; 85462306a36Sopenharmony_ci return secondary; 85562306a36Sopenharmony_ci } 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci memcpy(table, stm32f4_gate_map, sizeof(table)); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci /* only bits set in table can be used as indices */ 86062306a36Sopenharmony_ci if (WARN_ON(secondary >= BITS_PER_BYTE * sizeof(table) || 86162306a36Sopenharmony_ci 0 == (table[BIT_ULL_WORD(secondary)] & 86262306a36Sopenharmony_ci BIT_ULL_MASK(secondary)))) 86362306a36Sopenharmony_ci return -EINVAL; 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_ci /* mask out bits above our current index */ 86662306a36Sopenharmony_ci table[BIT_ULL_WORD(secondary)] &= 86762306a36Sopenharmony_ci GENMASK_ULL(secondary % BITS_PER_LONG_LONG, 0); 86862306a36Sopenharmony_ci 86962306a36Sopenharmony_ci return stm32fx_end_primary_clk - 1 + hweight64(table[0]) + 87062306a36Sopenharmony_ci (BIT_ULL_WORD(secondary) >= 1 ? hweight64(table[1]) : 0) + 87162306a36Sopenharmony_ci (BIT_ULL_WORD(secondary) >= 2 ? hweight64(table[2]) : 0); 87262306a36Sopenharmony_ci} 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_cistatic struct clk_hw * 87562306a36Sopenharmony_cistm32f4_rcc_lookup_clk(struct of_phandle_args *clkspec, void *data) 87662306a36Sopenharmony_ci{ 87762306a36Sopenharmony_ci int i = stm32f4_rcc_lookup_clk_idx(clkspec->args[0], clkspec->args[1]); 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_ci if (i < 0) 88062306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci return clks[i]; 88362306a36Sopenharmony_ci} 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci#define to_rgclk(_rgate) container_of(_rgate, struct stm32_rgate, gate) 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_cistatic inline void disable_power_domain_write_protection(void) 88862306a36Sopenharmony_ci{ 88962306a36Sopenharmony_ci if (pdrm) 89062306a36Sopenharmony_ci regmap_update_bits(pdrm, 0x00, (1 << 8), (1 << 8)); 89162306a36Sopenharmony_ci} 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_cistatic inline void enable_power_domain_write_protection(void) 89462306a36Sopenharmony_ci{ 89562306a36Sopenharmony_ci if (pdrm) 89662306a36Sopenharmony_ci regmap_update_bits(pdrm, 0x00, (1 << 8), (0 << 8)); 89762306a36Sopenharmony_ci} 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_cistatic inline void sofware_reset_backup_domain(void) 90062306a36Sopenharmony_ci{ 90162306a36Sopenharmony_ci unsigned long val; 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_ci val = readl(base + STM32F4_RCC_BDCR); 90462306a36Sopenharmony_ci writel(val | BIT(16), base + STM32F4_RCC_BDCR); 90562306a36Sopenharmony_ci writel(val & ~BIT(16), base + STM32F4_RCC_BDCR); 90662306a36Sopenharmony_ci} 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_cistruct stm32_rgate { 90962306a36Sopenharmony_ci struct clk_gate gate; 91062306a36Sopenharmony_ci u8 bit_rdy_idx; 91162306a36Sopenharmony_ci}; 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci#define RGATE_TIMEOUT 50000 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_cistatic int rgclk_enable(struct clk_hw *hw) 91662306a36Sopenharmony_ci{ 91762306a36Sopenharmony_ci struct clk_gate *gate = to_clk_gate(hw); 91862306a36Sopenharmony_ci struct stm32_rgate *rgate = to_rgclk(gate); 91962306a36Sopenharmony_ci int bit_status; 92062306a36Sopenharmony_ci unsigned int timeout = RGATE_TIMEOUT; 92162306a36Sopenharmony_ci 92262306a36Sopenharmony_ci if (clk_gate_ops.is_enabled(hw)) 92362306a36Sopenharmony_ci return 0; 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci disable_power_domain_write_protection(); 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci clk_gate_ops.enable(hw); 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci do { 93062306a36Sopenharmony_ci bit_status = !(readl(gate->reg) & BIT(rgate->bit_rdy_idx)); 93162306a36Sopenharmony_ci if (bit_status) 93262306a36Sopenharmony_ci udelay(100); 93362306a36Sopenharmony_ci 93462306a36Sopenharmony_ci } while (bit_status && --timeout); 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci enable_power_domain_write_protection(); 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci return bit_status; 93962306a36Sopenharmony_ci} 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_cistatic void rgclk_disable(struct clk_hw *hw) 94262306a36Sopenharmony_ci{ 94362306a36Sopenharmony_ci clk_gate_ops.disable(hw); 94462306a36Sopenharmony_ci} 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_cistatic int rgclk_is_enabled(struct clk_hw *hw) 94762306a36Sopenharmony_ci{ 94862306a36Sopenharmony_ci return clk_gate_ops.is_enabled(hw); 94962306a36Sopenharmony_ci} 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_cistatic const struct clk_ops rgclk_ops = { 95262306a36Sopenharmony_ci .enable = rgclk_enable, 95362306a36Sopenharmony_ci .disable = rgclk_disable, 95462306a36Sopenharmony_ci .is_enabled = rgclk_is_enabled, 95562306a36Sopenharmony_ci}; 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_cistatic struct clk_hw *clk_register_rgate(struct device *dev, const char *name, 95862306a36Sopenharmony_ci const char *parent_name, unsigned long flags, 95962306a36Sopenharmony_ci void __iomem *reg, u8 bit_idx, u8 bit_rdy_idx, 96062306a36Sopenharmony_ci u8 clk_gate_flags, spinlock_t *lock) 96162306a36Sopenharmony_ci{ 96262306a36Sopenharmony_ci struct stm32_rgate *rgate; 96362306a36Sopenharmony_ci struct clk_init_data init = { NULL }; 96462306a36Sopenharmony_ci struct clk_hw *hw; 96562306a36Sopenharmony_ci int ret; 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci rgate = kzalloc(sizeof(*rgate), GFP_KERNEL); 96862306a36Sopenharmony_ci if (!rgate) 96962306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci init.name = name; 97262306a36Sopenharmony_ci init.ops = &rgclk_ops; 97362306a36Sopenharmony_ci init.flags = flags; 97462306a36Sopenharmony_ci init.parent_names = &parent_name; 97562306a36Sopenharmony_ci init.num_parents = 1; 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_ci rgate->bit_rdy_idx = bit_rdy_idx; 97862306a36Sopenharmony_ci 97962306a36Sopenharmony_ci rgate->gate.lock = lock; 98062306a36Sopenharmony_ci rgate->gate.reg = reg; 98162306a36Sopenharmony_ci rgate->gate.bit_idx = bit_idx; 98262306a36Sopenharmony_ci rgate->gate.hw.init = &init; 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ci hw = &rgate->gate.hw; 98562306a36Sopenharmony_ci ret = clk_hw_register(dev, hw); 98662306a36Sopenharmony_ci if (ret) { 98762306a36Sopenharmony_ci kfree(rgate); 98862306a36Sopenharmony_ci hw = ERR_PTR(ret); 98962306a36Sopenharmony_ci } 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci return hw; 99262306a36Sopenharmony_ci} 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_cistatic int cclk_gate_enable(struct clk_hw *hw) 99562306a36Sopenharmony_ci{ 99662306a36Sopenharmony_ci int ret; 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci disable_power_domain_write_protection(); 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci ret = clk_gate_ops.enable(hw); 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci enable_power_domain_write_protection(); 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci return ret; 100562306a36Sopenharmony_ci} 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_cistatic void cclk_gate_disable(struct clk_hw *hw) 100862306a36Sopenharmony_ci{ 100962306a36Sopenharmony_ci disable_power_domain_write_protection(); 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci clk_gate_ops.disable(hw); 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci enable_power_domain_write_protection(); 101462306a36Sopenharmony_ci} 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_cistatic int cclk_gate_is_enabled(struct clk_hw *hw) 101762306a36Sopenharmony_ci{ 101862306a36Sopenharmony_ci return clk_gate_ops.is_enabled(hw); 101962306a36Sopenharmony_ci} 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_cistatic const struct clk_ops cclk_gate_ops = { 102262306a36Sopenharmony_ci .enable = cclk_gate_enable, 102362306a36Sopenharmony_ci .disable = cclk_gate_disable, 102462306a36Sopenharmony_ci .is_enabled = cclk_gate_is_enabled, 102562306a36Sopenharmony_ci}; 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_cistatic u8 cclk_mux_get_parent(struct clk_hw *hw) 102862306a36Sopenharmony_ci{ 102962306a36Sopenharmony_ci return clk_mux_ops.get_parent(hw); 103062306a36Sopenharmony_ci} 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_cistatic int cclk_mux_set_parent(struct clk_hw *hw, u8 index) 103362306a36Sopenharmony_ci{ 103462306a36Sopenharmony_ci int ret; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci disable_power_domain_write_protection(); 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci sofware_reset_backup_domain(); 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci ret = clk_mux_ops.set_parent(hw, index); 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ci enable_power_domain_write_protection(); 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ci return ret; 104562306a36Sopenharmony_ci} 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_cistatic const struct clk_ops cclk_mux_ops = { 104862306a36Sopenharmony_ci .determine_rate = clk_hw_determine_rate_no_reparent, 104962306a36Sopenharmony_ci .get_parent = cclk_mux_get_parent, 105062306a36Sopenharmony_ci .set_parent = cclk_mux_set_parent, 105162306a36Sopenharmony_ci}; 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_cistatic struct clk_hw *stm32_register_cclk(struct device *dev, const char *name, 105462306a36Sopenharmony_ci const char * const *parent_names, int num_parents, 105562306a36Sopenharmony_ci void __iomem *reg, u8 bit_idx, u8 shift, unsigned long flags, 105662306a36Sopenharmony_ci spinlock_t *lock) 105762306a36Sopenharmony_ci{ 105862306a36Sopenharmony_ci struct clk_hw *hw; 105962306a36Sopenharmony_ci struct clk_gate *gate; 106062306a36Sopenharmony_ci struct clk_mux *mux; 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ci gate = kzalloc(sizeof(*gate), GFP_KERNEL); 106362306a36Sopenharmony_ci if (!gate) { 106462306a36Sopenharmony_ci hw = ERR_PTR(-EINVAL); 106562306a36Sopenharmony_ci goto fail; 106662306a36Sopenharmony_ci } 106762306a36Sopenharmony_ci 106862306a36Sopenharmony_ci mux = kzalloc(sizeof(*mux), GFP_KERNEL); 106962306a36Sopenharmony_ci if (!mux) { 107062306a36Sopenharmony_ci kfree(gate); 107162306a36Sopenharmony_ci hw = ERR_PTR(-EINVAL); 107262306a36Sopenharmony_ci goto fail; 107362306a36Sopenharmony_ci } 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci gate->reg = reg; 107662306a36Sopenharmony_ci gate->bit_idx = bit_idx; 107762306a36Sopenharmony_ci gate->flags = 0; 107862306a36Sopenharmony_ci gate->lock = lock; 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci mux->reg = reg; 108162306a36Sopenharmony_ci mux->shift = shift; 108262306a36Sopenharmony_ci mux->mask = 3; 108362306a36Sopenharmony_ci mux->flags = 0; 108462306a36Sopenharmony_ci 108562306a36Sopenharmony_ci hw = clk_hw_register_composite(dev, name, parent_names, num_parents, 108662306a36Sopenharmony_ci &mux->hw, &cclk_mux_ops, 108762306a36Sopenharmony_ci NULL, NULL, 108862306a36Sopenharmony_ci &gate->hw, &cclk_gate_ops, 108962306a36Sopenharmony_ci flags); 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_ci if (IS_ERR(hw)) { 109262306a36Sopenharmony_ci kfree(gate); 109362306a36Sopenharmony_ci kfree(mux); 109462306a36Sopenharmony_ci } 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_cifail: 109762306a36Sopenharmony_ci return hw; 109862306a36Sopenharmony_ci} 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_cistatic const char *sys_parents[] __initdata = { "hsi", NULL, "pll" }; 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_cistatic const struct clk_div_table ahb_div_table[] = { 110362306a36Sopenharmony_ci { 0x0, 1 }, { 0x1, 1 }, { 0x2, 1 }, { 0x3, 1 }, 110462306a36Sopenharmony_ci { 0x4, 1 }, { 0x5, 1 }, { 0x6, 1 }, { 0x7, 1 }, 110562306a36Sopenharmony_ci { 0x8, 2 }, { 0x9, 4 }, { 0xa, 8 }, { 0xb, 16 }, 110662306a36Sopenharmony_ci { 0xc, 64 }, { 0xd, 128 }, { 0xe, 256 }, { 0xf, 512 }, 110762306a36Sopenharmony_ci { 0 }, 110862306a36Sopenharmony_ci}; 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_cistatic const struct clk_div_table apb_div_table[] = { 111162306a36Sopenharmony_ci { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, 111262306a36Sopenharmony_ci { 4, 2 }, { 5, 4 }, { 6, 8 }, { 7, 16 }, 111362306a36Sopenharmony_ci { 0 }, 111462306a36Sopenharmony_ci}; 111562306a36Sopenharmony_ci 111662306a36Sopenharmony_cistatic const char *rtc_parents[4] = { 111762306a36Sopenharmony_ci "no-clock", "lse", "lsi", "hse-rtc" 111862306a36Sopenharmony_ci}; 111962306a36Sopenharmony_ci 112062306a36Sopenharmony_cistatic const char *pll_src = "pll-src"; 112162306a36Sopenharmony_ci 112262306a36Sopenharmony_cistatic const char *pllsrc_parent[2] = { "hsi", NULL }; 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_cistatic const char *dsi_parent[2] = { NULL, "pll-r" }; 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_cistatic const char *lcd_parent[1] = { "pllsai-r-div" }; 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_cistatic const char *i2s_parents[2] = { "plli2s-r", NULL }; 112962306a36Sopenharmony_ci 113062306a36Sopenharmony_cistatic const char *sai_parents[4] = { "pllsai-q-div", "plli2s-q-div", NULL, 113162306a36Sopenharmony_ci "no-clock" }; 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_cistatic const char *pll48_parents[2] = { "pll-q", "pllsai-p" }; 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_cistatic const char *sdmux_parents[2] = { "pll48", "sys" }; 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_cistatic const char *hdmi_parents[2] = { "lse", "hsi_div488" }; 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_cistatic const char *spdif_parent[1] = { "plli2s-p" }; 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_cistatic const char *lptim_parent[4] = { "apb1_mul", "lsi", "hsi", "lse" }; 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_cistatic const char *uart_parents1[4] = { "apb2_div", "sys", "hsi", "lse" }; 114462306a36Sopenharmony_cistatic const char *uart_parents2[4] = { "apb1_div", "sys", "hsi", "lse" }; 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_cistatic const char *i2c_parents[4] = { "apb1_div", "sys", "hsi", "no-clock" }; 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_cistatic const char * const dfsdm1_src[] = { "apb2_div", "sys" }; 114962306a36Sopenharmony_cistatic const char * const adsfdm1_parent[] = { "sai1_clk", "sai2_clk" }; 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_cistruct stm32_aux_clk { 115262306a36Sopenharmony_ci int idx; 115362306a36Sopenharmony_ci const char *name; 115462306a36Sopenharmony_ci const char * const *parent_names; 115562306a36Sopenharmony_ci int num_parents; 115662306a36Sopenharmony_ci int offset_mux; 115762306a36Sopenharmony_ci u8 shift; 115862306a36Sopenharmony_ci u8 mask; 115962306a36Sopenharmony_ci int offset_gate; 116062306a36Sopenharmony_ci u8 bit_idx; 116162306a36Sopenharmony_ci unsigned long flags; 116262306a36Sopenharmony_ci}; 116362306a36Sopenharmony_ci 116462306a36Sopenharmony_cistruct stm32f4_clk_data { 116562306a36Sopenharmony_ci const struct stm32f4_gate_data *gates_data; 116662306a36Sopenharmony_ci const u64 *gates_map; 116762306a36Sopenharmony_ci int gates_num; 116862306a36Sopenharmony_ci const struct stm32f4_pll_data *pll_data; 116962306a36Sopenharmony_ci const struct stm32_aux_clk *aux_clk; 117062306a36Sopenharmony_ci int aux_clk_num; 117162306a36Sopenharmony_ci int end_primary; 117262306a36Sopenharmony_ci}; 117362306a36Sopenharmony_ci 117462306a36Sopenharmony_cistatic const struct stm32_aux_clk stm32f429_aux_clk[] = { 117562306a36Sopenharmony_ci { 117662306a36Sopenharmony_ci CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent), 117762306a36Sopenharmony_ci NO_MUX, 0, 0, 117862306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 26, 117962306a36Sopenharmony_ci CLK_SET_RATE_PARENT 118062306a36Sopenharmony_ci }, 118162306a36Sopenharmony_ci { 118262306a36Sopenharmony_ci CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents), 118362306a36Sopenharmony_ci STM32F4_RCC_CFGR, 23, 1, 118462306a36Sopenharmony_ci NO_GATE, 0, 118562306a36Sopenharmony_ci CLK_SET_RATE_PARENT 118662306a36Sopenharmony_ci }, 118762306a36Sopenharmony_ci { 118862306a36Sopenharmony_ci CLK_SAI1, "sai1-a", sai_parents, ARRAY_SIZE(sai_parents), 118962306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 20, 3, 119062306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 22, 119162306a36Sopenharmony_ci CLK_SET_RATE_PARENT 119262306a36Sopenharmony_ci }, 119362306a36Sopenharmony_ci { 119462306a36Sopenharmony_ci CLK_SAI2, "sai1-b", sai_parents, ARRAY_SIZE(sai_parents), 119562306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 22, 3, 119662306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 22, 119762306a36Sopenharmony_ci CLK_SET_RATE_PARENT 119862306a36Sopenharmony_ci }, 119962306a36Sopenharmony_ci}; 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_cistatic const struct stm32_aux_clk stm32f469_aux_clk[] = { 120262306a36Sopenharmony_ci { 120362306a36Sopenharmony_ci CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent), 120462306a36Sopenharmony_ci NO_MUX, 0, 0, 120562306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 26, 120662306a36Sopenharmony_ci CLK_SET_RATE_PARENT 120762306a36Sopenharmony_ci }, 120862306a36Sopenharmony_ci { 120962306a36Sopenharmony_ci CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents), 121062306a36Sopenharmony_ci STM32F4_RCC_CFGR, 23, 1, 121162306a36Sopenharmony_ci NO_GATE, 0, 121262306a36Sopenharmony_ci CLK_SET_RATE_PARENT 121362306a36Sopenharmony_ci }, 121462306a36Sopenharmony_ci { 121562306a36Sopenharmony_ci CLK_SAI1, "sai1-a", sai_parents, ARRAY_SIZE(sai_parents), 121662306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 20, 3, 121762306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 22, 121862306a36Sopenharmony_ci CLK_SET_RATE_PARENT 121962306a36Sopenharmony_ci }, 122062306a36Sopenharmony_ci { 122162306a36Sopenharmony_ci CLK_SAI2, "sai1-b", sai_parents, ARRAY_SIZE(sai_parents), 122262306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 22, 3, 122362306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 22, 122462306a36Sopenharmony_ci CLK_SET_RATE_PARENT 122562306a36Sopenharmony_ci }, 122662306a36Sopenharmony_ci { 122762306a36Sopenharmony_ci NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents), 122862306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 27, 1, 122962306a36Sopenharmony_ci NO_GATE, 0, 123062306a36Sopenharmony_ci 0 123162306a36Sopenharmony_ci }, 123262306a36Sopenharmony_ci { 123362306a36Sopenharmony_ci NO_IDX, "sdmux", sdmux_parents, ARRAY_SIZE(sdmux_parents), 123462306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 28, 1, 123562306a36Sopenharmony_ci NO_GATE, 0, 123662306a36Sopenharmony_ci 0 123762306a36Sopenharmony_ci }, 123862306a36Sopenharmony_ci { 123962306a36Sopenharmony_ci CLK_F469_DSI, "dsi", dsi_parent, ARRAY_SIZE(dsi_parent), 124062306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 29, 1, 124162306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 27, 124262306a36Sopenharmony_ci CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT 124362306a36Sopenharmony_ci }, 124462306a36Sopenharmony_ci}; 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_cistatic const struct stm32_aux_clk stm32f746_aux_clk[] = { 124762306a36Sopenharmony_ci { 124862306a36Sopenharmony_ci CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent), 124962306a36Sopenharmony_ci NO_MUX, 0, 0, 125062306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 26, 125162306a36Sopenharmony_ci CLK_SET_RATE_PARENT 125262306a36Sopenharmony_ci }, 125362306a36Sopenharmony_ci { 125462306a36Sopenharmony_ci CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents), 125562306a36Sopenharmony_ci STM32F4_RCC_CFGR, 23, 1, 125662306a36Sopenharmony_ci NO_GATE, 0, 125762306a36Sopenharmony_ci CLK_SET_RATE_PARENT 125862306a36Sopenharmony_ci }, 125962306a36Sopenharmony_ci { 126062306a36Sopenharmony_ci CLK_SAI1, "sai1_clk", sai_parents, ARRAY_SIZE(sai_parents), 126162306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 20, 3, 126262306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 22, 126362306a36Sopenharmony_ci CLK_SET_RATE_PARENT 126462306a36Sopenharmony_ci }, 126562306a36Sopenharmony_ci { 126662306a36Sopenharmony_ci CLK_SAI2, "sai2_clk", sai_parents, ARRAY_SIZE(sai_parents), 126762306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 22, 3, 126862306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 23, 126962306a36Sopenharmony_ci CLK_SET_RATE_PARENT 127062306a36Sopenharmony_ci }, 127162306a36Sopenharmony_ci { 127262306a36Sopenharmony_ci NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents), 127362306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 27, 1, 127462306a36Sopenharmony_ci NO_GATE, 0, 127562306a36Sopenharmony_ci 0 127662306a36Sopenharmony_ci }, 127762306a36Sopenharmony_ci { 127862306a36Sopenharmony_ci NO_IDX, "sdmux", sdmux_parents, ARRAY_SIZE(sdmux_parents), 127962306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 28, 1, 128062306a36Sopenharmony_ci NO_GATE, 0, 128162306a36Sopenharmony_ci 0 128262306a36Sopenharmony_ci }, 128362306a36Sopenharmony_ci { 128462306a36Sopenharmony_ci CLK_HDMI_CEC, "hdmi-cec", 128562306a36Sopenharmony_ci hdmi_parents, ARRAY_SIZE(hdmi_parents), 128662306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 26, 1, 128762306a36Sopenharmony_ci NO_GATE, 0, 128862306a36Sopenharmony_ci 0 128962306a36Sopenharmony_ci }, 129062306a36Sopenharmony_ci { 129162306a36Sopenharmony_ci CLK_SPDIF, "spdif-rx", 129262306a36Sopenharmony_ci spdif_parent, ARRAY_SIZE(spdif_parent), 129362306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 22, 3, 129462306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 23, 129562306a36Sopenharmony_ci CLK_SET_RATE_PARENT 129662306a36Sopenharmony_ci }, 129762306a36Sopenharmony_ci { 129862306a36Sopenharmony_ci CLK_USART1, "usart1", 129962306a36Sopenharmony_ci uart_parents1, ARRAY_SIZE(uart_parents1), 130062306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 0, 3, 130162306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 4, 130262306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 130362306a36Sopenharmony_ci }, 130462306a36Sopenharmony_ci { 130562306a36Sopenharmony_ci CLK_USART2, "usart2", 130662306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 130762306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 2, 3, 130862306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 17, 130962306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 131062306a36Sopenharmony_ci }, 131162306a36Sopenharmony_ci { 131262306a36Sopenharmony_ci CLK_USART3, "usart3", 131362306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 131462306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 4, 3, 131562306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 18, 131662306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 131762306a36Sopenharmony_ci }, 131862306a36Sopenharmony_ci { 131962306a36Sopenharmony_ci CLK_UART4, "uart4", 132062306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 132162306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 6, 3, 132262306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 19, 132362306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 132462306a36Sopenharmony_ci }, 132562306a36Sopenharmony_ci { 132662306a36Sopenharmony_ci CLK_UART5, "uart5", 132762306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 132862306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 8, 3, 132962306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 20, 133062306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 133162306a36Sopenharmony_ci }, 133262306a36Sopenharmony_ci { 133362306a36Sopenharmony_ci CLK_USART6, "usart6", 133462306a36Sopenharmony_ci uart_parents1, ARRAY_SIZE(uart_parents1), 133562306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 10, 3, 133662306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 5, 133762306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 133862306a36Sopenharmony_ci }, 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_ci { 134162306a36Sopenharmony_ci CLK_UART7, "uart7", 134262306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 134362306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 12, 3, 134462306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 30, 134562306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 134662306a36Sopenharmony_ci }, 134762306a36Sopenharmony_ci { 134862306a36Sopenharmony_ci CLK_UART8, "uart8", 134962306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 135062306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 14, 3, 135162306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 31, 135262306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 135362306a36Sopenharmony_ci }, 135462306a36Sopenharmony_ci { 135562306a36Sopenharmony_ci CLK_I2C1, "i2c1", 135662306a36Sopenharmony_ci i2c_parents, ARRAY_SIZE(i2c_parents), 135762306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 16, 3, 135862306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 21, 135962306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 136062306a36Sopenharmony_ci }, 136162306a36Sopenharmony_ci { 136262306a36Sopenharmony_ci CLK_I2C2, "i2c2", 136362306a36Sopenharmony_ci i2c_parents, ARRAY_SIZE(i2c_parents), 136462306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 18, 3, 136562306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 22, 136662306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 136762306a36Sopenharmony_ci }, 136862306a36Sopenharmony_ci { 136962306a36Sopenharmony_ci CLK_I2C3, "i2c3", 137062306a36Sopenharmony_ci i2c_parents, ARRAY_SIZE(i2c_parents), 137162306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 20, 3, 137262306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 23, 137362306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 137462306a36Sopenharmony_ci }, 137562306a36Sopenharmony_ci { 137662306a36Sopenharmony_ci CLK_I2C4, "i2c4", 137762306a36Sopenharmony_ci i2c_parents, ARRAY_SIZE(i2c_parents), 137862306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 22, 3, 137962306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 24, 138062306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 138162306a36Sopenharmony_ci }, 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci { 138462306a36Sopenharmony_ci CLK_LPTIMER, "lptim1", 138562306a36Sopenharmony_ci lptim_parent, ARRAY_SIZE(lptim_parent), 138662306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 24, 3, 138762306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 9, 138862306a36Sopenharmony_ci CLK_SET_RATE_PARENT 138962306a36Sopenharmony_ci }, 139062306a36Sopenharmony_ci}; 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_cistatic const struct stm32_aux_clk stm32f769_aux_clk[] = { 139362306a36Sopenharmony_ci { 139462306a36Sopenharmony_ci CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent), 139562306a36Sopenharmony_ci NO_MUX, 0, 0, 139662306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 26, 139762306a36Sopenharmony_ci CLK_SET_RATE_PARENT 139862306a36Sopenharmony_ci }, 139962306a36Sopenharmony_ci { 140062306a36Sopenharmony_ci CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents), 140162306a36Sopenharmony_ci STM32F4_RCC_CFGR, 23, 1, 140262306a36Sopenharmony_ci NO_GATE, 0, 140362306a36Sopenharmony_ci CLK_SET_RATE_PARENT 140462306a36Sopenharmony_ci }, 140562306a36Sopenharmony_ci { 140662306a36Sopenharmony_ci CLK_SAI1, "sai1_clk", sai_parents, ARRAY_SIZE(sai_parents), 140762306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 20, 3, 140862306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 22, 140962306a36Sopenharmony_ci CLK_SET_RATE_PARENT 141062306a36Sopenharmony_ci }, 141162306a36Sopenharmony_ci { 141262306a36Sopenharmony_ci CLK_SAI2, "sai2_clk", sai_parents, ARRAY_SIZE(sai_parents), 141362306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 22, 3, 141462306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 23, 141562306a36Sopenharmony_ci CLK_SET_RATE_PARENT 141662306a36Sopenharmony_ci }, 141762306a36Sopenharmony_ci { 141862306a36Sopenharmony_ci NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents), 141962306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 27, 1, 142062306a36Sopenharmony_ci NO_GATE, 0, 142162306a36Sopenharmony_ci 0 142262306a36Sopenharmony_ci }, 142362306a36Sopenharmony_ci { 142462306a36Sopenharmony_ci NO_IDX, "sdmux1", sdmux_parents, ARRAY_SIZE(sdmux_parents), 142562306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 28, 1, 142662306a36Sopenharmony_ci NO_GATE, 0, 142762306a36Sopenharmony_ci 0 142862306a36Sopenharmony_ci }, 142962306a36Sopenharmony_ci { 143062306a36Sopenharmony_ci NO_IDX, "sdmux2", sdmux_parents, ARRAY_SIZE(sdmux_parents), 143162306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 29, 1, 143262306a36Sopenharmony_ci NO_GATE, 0, 143362306a36Sopenharmony_ci 0 143462306a36Sopenharmony_ci }, 143562306a36Sopenharmony_ci { 143662306a36Sopenharmony_ci CLK_HDMI_CEC, "hdmi-cec", 143762306a36Sopenharmony_ci hdmi_parents, ARRAY_SIZE(hdmi_parents), 143862306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 26, 1, 143962306a36Sopenharmony_ci NO_GATE, 0, 144062306a36Sopenharmony_ci 0 144162306a36Sopenharmony_ci }, 144262306a36Sopenharmony_ci { 144362306a36Sopenharmony_ci CLK_SPDIF, "spdif-rx", 144462306a36Sopenharmony_ci spdif_parent, ARRAY_SIZE(spdif_parent), 144562306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 22, 3, 144662306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 23, 144762306a36Sopenharmony_ci CLK_SET_RATE_PARENT 144862306a36Sopenharmony_ci }, 144962306a36Sopenharmony_ci { 145062306a36Sopenharmony_ci CLK_USART1, "usart1", 145162306a36Sopenharmony_ci uart_parents1, ARRAY_SIZE(uart_parents1), 145262306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 0, 3, 145362306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 4, 145462306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 145562306a36Sopenharmony_ci }, 145662306a36Sopenharmony_ci { 145762306a36Sopenharmony_ci CLK_USART2, "usart2", 145862306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 145962306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 2, 3, 146062306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 17, 146162306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 146262306a36Sopenharmony_ci }, 146362306a36Sopenharmony_ci { 146462306a36Sopenharmony_ci CLK_USART3, "usart3", 146562306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 146662306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 4, 3, 146762306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 18, 146862306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 146962306a36Sopenharmony_ci }, 147062306a36Sopenharmony_ci { 147162306a36Sopenharmony_ci CLK_UART4, "uart4", 147262306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 147362306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 6, 3, 147462306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 19, 147562306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 147662306a36Sopenharmony_ci }, 147762306a36Sopenharmony_ci { 147862306a36Sopenharmony_ci CLK_UART5, "uart5", 147962306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 148062306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 8, 3, 148162306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 20, 148262306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 148362306a36Sopenharmony_ci }, 148462306a36Sopenharmony_ci { 148562306a36Sopenharmony_ci CLK_USART6, "usart6", 148662306a36Sopenharmony_ci uart_parents1, ARRAY_SIZE(uart_parents1), 148762306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 10, 3, 148862306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 5, 148962306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 149062306a36Sopenharmony_ci }, 149162306a36Sopenharmony_ci { 149262306a36Sopenharmony_ci CLK_UART7, "uart7", 149362306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 149462306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 12, 3, 149562306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 30, 149662306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 149762306a36Sopenharmony_ci }, 149862306a36Sopenharmony_ci { 149962306a36Sopenharmony_ci CLK_UART8, "uart8", 150062306a36Sopenharmony_ci uart_parents2, ARRAY_SIZE(uart_parents1), 150162306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 14, 3, 150262306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 31, 150362306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 150462306a36Sopenharmony_ci }, 150562306a36Sopenharmony_ci { 150662306a36Sopenharmony_ci CLK_I2C1, "i2c1", 150762306a36Sopenharmony_ci i2c_parents, ARRAY_SIZE(i2c_parents), 150862306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 16, 3, 150962306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 21, 151062306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 151162306a36Sopenharmony_ci }, 151262306a36Sopenharmony_ci { 151362306a36Sopenharmony_ci CLK_I2C2, "i2c2", 151462306a36Sopenharmony_ci i2c_parents, ARRAY_SIZE(i2c_parents), 151562306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 18, 3, 151662306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 22, 151762306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 151862306a36Sopenharmony_ci }, 151962306a36Sopenharmony_ci { 152062306a36Sopenharmony_ci CLK_I2C3, "i2c3", 152162306a36Sopenharmony_ci i2c_parents, ARRAY_SIZE(i2c_parents), 152262306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 20, 3, 152362306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 23, 152462306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 152562306a36Sopenharmony_ci }, 152662306a36Sopenharmony_ci { 152762306a36Sopenharmony_ci CLK_I2C4, "i2c4", 152862306a36Sopenharmony_ci i2c_parents, ARRAY_SIZE(i2c_parents), 152962306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 22, 3, 153062306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 24, 153162306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 153262306a36Sopenharmony_ci }, 153362306a36Sopenharmony_ci { 153462306a36Sopenharmony_ci CLK_LPTIMER, "lptim1", 153562306a36Sopenharmony_ci lptim_parent, ARRAY_SIZE(lptim_parent), 153662306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 24, 3, 153762306a36Sopenharmony_ci STM32F4_RCC_APB1ENR, 9, 153862306a36Sopenharmony_ci CLK_SET_RATE_PARENT 153962306a36Sopenharmony_ci }, 154062306a36Sopenharmony_ci { 154162306a36Sopenharmony_ci CLK_F769_DSI, "dsi", 154262306a36Sopenharmony_ci dsi_parent, ARRAY_SIZE(dsi_parent), 154362306a36Sopenharmony_ci STM32F7_RCC_DCKCFGR2, 0, 1, 154462306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 27, 154562306a36Sopenharmony_ci CLK_SET_RATE_PARENT 154662306a36Sopenharmony_ci }, 154762306a36Sopenharmony_ci { 154862306a36Sopenharmony_ci CLK_DFSDM1, "dfsdm1", 154962306a36Sopenharmony_ci dfsdm1_src, ARRAY_SIZE(dfsdm1_src), 155062306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 25, 1, 155162306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 29, 155262306a36Sopenharmony_ci CLK_SET_RATE_PARENT 155362306a36Sopenharmony_ci }, 155462306a36Sopenharmony_ci { 155562306a36Sopenharmony_ci CLK_ADFSDM1, "adfsdm1", 155662306a36Sopenharmony_ci adsfdm1_parent, ARRAY_SIZE(adsfdm1_parent), 155762306a36Sopenharmony_ci STM32F4_RCC_DCKCFGR, 26, 1, 155862306a36Sopenharmony_ci STM32F4_RCC_APB2ENR, 29, 155962306a36Sopenharmony_ci CLK_SET_RATE_PARENT 156062306a36Sopenharmony_ci }, 156162306a36Sopenharmony_ci}; 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_cistatic const struct stm32f4_clk_data stm32f429_clk_data = { 156462306a36Sopenharmony_ci .end_primary = END_PRIMARY_CLK, 156562306a36Sopenharmony_ci .gates_data = stm32f429_gates, 156662306a36Sopenharmony_ci .gates_map = stm32f42xx_gate_map, 156762306a36Sopenharmony_ci .gates_num = ARRAY_SIZE(stm32f429_gates), 156862306a36Sopenharmony_ci .pll_data = stm32f429_pll, 156962306a36Sopenharmony_ci .aux_clk = stm32f429_aux_clk, 157062306a36Sopenharmony_ci .aux_clk_num = ARRAY_SIZE(stm32f429_aux_clk), 157162306a36Sopenharmony_ci}; 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_cistatic const struct stm32f4_clk_data stm32f469_clk_data = { 157462306a36Sopenharmony_ci .end_primary = END_PRIMARY_CLK, 157562306a36Sopenharmony_ci .gates_data = stm32f469_gates, 157662306a36Sopenharmony_ci .gates_map = stm32f46xx_gate_map, 157762306a36Sopenharmony_ci .gates_num = ARRAY_SIZE(stm32f469_gates), 157862306a36Sopenharmony_ci .pll_data = stm32f469_pll, 157962306a36Sopenharmony_ci .aux_clk = stm32f469_aux_clk, 158062306a36Sopenharmony_ci .aux_clk_num = ARRAY_SIZE(stm32f469_aux_clk), 158162306a36Sopenharmony_ci}; 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_cistatic const struct stm32f4_clk_data stm32f746_clk_data = { 158462306a36Sopenharmony_ci .end_primary = END_PRIMARY_CLK_F7, 158562306a36Sopenharmony_ci .gates_data = stm32f746_gates, 158662306a36Sopenharmony_ci .gates_map = stm32f746_gate_map, 158762306a36Sopenharmony_ci .gates_num = ARRAY_SIZE(stm32f746_gates), 158862306a36Sopenharmony_ci .pll_data = stm32f469_pll, 158962306a36Sopenharmony_ci .aux_clk = stm32f746_aux_clk, 159062306a36Sopenharmony_ci .aux_clk_num = ARRAY_SIZE(stm32f746_aux_clk), 159162306a36Sopenharmony_ci}; 159262306a36Sopenharmony_ci 159362306a36Sopenharmony_cistatic const struct stm32f4_clk_data stm32f769_clk_data = { 159462306a36Sopenharmony_ci .end_primary = END_PRIMARY_CLK_F7, 159562306a36Sopenharmony_ci .gates_data = stm32f769_gates, 159662306a36Sopenharmony_ci .gates_map = stm32f769_gate_map, 159762306a36Sopenharmony_ci .gates_num = ARRAY_SIZE(stm32f769_gates), 159862306a36Sopenharmony_ci .pll_data = stm32f469_pll, 159962306a36Sopenharmony_ci .aux_clk = stm32f769_aux_clk, 160062306a36Sopenharmony_ci .aux_clk_num = ARRAY_SIZE(stm32f769_aux_clk), 160162306a36Sopenharmony_ci}; 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_cistatic const struct of_device_id stm32f4_of_match[] = { 160462306a36Sopenharmony_ci { 160562306a36Sopenharmony_ci .compatible = "st,stm32f42xx-rcc", 160662306a36Sopenharmony_ci .data = &stm32f429_clk_data 160762306a36Sopenharmony_ci }, 160862306a36Sopenharmony_ci { 160962306a36Sopenharmony_ci .compatible = "st,stm32f469-rcc", 161062306a36Sopenharmony_ci .data = &stm32f469_clk_data 161162306a36Sopenharmony_ci }, 161262306a36Sopenharmony_ci { 161362306a36Sopenharmony_ci .compatible = "st,stm32f746-rcc", 161462306a36Sopenharmony_ci .data = &stm32f746_clk_data 161562306a36Sopenharmony_ci }, 161662306a36Sopenharmony_ci { 161762306a36Sopenharmony_ci .compatible = "st,stm32f769-rcc", 161862306a36Sopenharmony_ci .data = &stm32f769_clk_data 161962306a36Sopenharmony_ci }, 162062306a36Sopenharmony_ci {} 162162306a36Sopenharmony_ci}; 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_cistatic struct clk_hw *stm32_register_aux_clk(const char *name, 162462306a36Sopenharmony_ci const char * const *parent_names, int num_parents, 162562306a36Sopenharmony_ci int offset_mux, u8 shift, u8 mask, 162662306a36Sopenharmony_ci int offset_gate, u8 bit_idx, 162762306a36Sopenharmony_ci unsigned long flags, spinlock_t *lock) 162862306a36Sopenharmony_ci{ 162962306a36Sopenharmony_ci struct clk_hw *hw; 163062306a36Sopenharmony_ci struct clk_gate *gate = NULL; 163162306a36Sopenharmony_ci struct clk_mux *mux = NULL; 163262306a36Sopenharmony_ci struct clk_hw *mux_hw = NULL, *gate_hw = NULL; 163362306a36Sopenharmony_ci const struct clk_ops *mux_ops = NULL, *gate_ops = NULL; 163462306a36Sopenharmony_ci 163562306a36Sopenharmony_ci if (offset_gate != NO_GATE) { 163662306a36Sopenharmony_ci gate = kzalloc(sizeof(*gate), GFP_KERNEL); 163762306a36Sopenharmony_ci if (!gate) { 163862306a36Sopenharmony_ci hw = ERR_PTR(-EINVAL); 163962306a36Sopenharmony_ci goto fail; 164062306a36Sopenharmony_ci } 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci gate->reg = base + offset_gate; 164362306a36Sopenharmony_ci gate->bit_idx = bit_idx; 164462306a36Sopenharmony_ci gate->flags = 0; 164562306a36Sopenharmony_ci gate->lock = lock; 164662306a36Sopenharmony_ci gate_hw = &gate->hw; 164762306a36Sopenharmony_ci gate_ops = &clk_gate_ops; 164862306a36Sopenharmony_ci } 164962306a36Sopenharmony_ci 165062306a36Sopenharmony_ci if (offset_mux != NO_MUX) { 165162306a36Sopenharmony_ci mux = kzalloc(sizeof(*mux), GFP_KERNEL); 165262306a36Sopenharmony_ci if (!mux) { 165362306a36Sopenharmony_ci hw = ERR_PTR(-EINVAL); 165462306a36Sopenharmony_ci goto fail; 165562306a36Sopenharmony_ci } 165662306a36Sopenharmony_ci 165762306a36Sopenharmony_ci mux->reg = base + offset_mux; 165862306a36Sopenharmony_ci mux->shift = shift; 165962306a36Sopenharmony_ci mux->mask = mask; 166062306a36Sopenharmony_ci mux->flags = 0; 166162306a36Sopenharmony_ci mux_hw = &mux->hw; 166262306a36Sopenharmony_ci mux_ops = &clk_mux_ops; 166362306a36Sopenharmony_ci } 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_ci if (mux_hw == NULL && gate_hw == NULL) { 166662306a36Sopenharmony_ci hw = ERR_PTR(-EINVAL); 166762306a36Sopenharmony_ci goto fail; 166862306a36Sopenharmony_ci } 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, 167162306a36Sopenharmony_ci mux_hw, mux_ops, 167262306a36Sopenharmony_ci NULL, NULL, 167362306a36Sopenharmony_ci gate_hw, gate_ops, 167462306a36Sopenharmony_ci flags); 167562306a36Sopenharmony_ci 167662306a36Sopenharmony_cifail: 167762306a36Sopenharmony_ci if (IS_ERR(hw)) { 167862306a36Sopenharmony_ci kfree(gate); 167962306a36Sopenharmony_ci kfree(mux); 168062306a36Sopenharmony_ci } 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci return hw; 168362306a36Sopenharmony_ci} 168462306a36Sopenharmony_ci 168562306a36Sopenharmony_cistatic void __init stm32f4_rcc_init(struct device_node *np) 168662306a36Sopenharmony_ci{ 168762306a36Sopenharmony_ci const char *hse_clk, *i2s_in_clk; 168862306a36Sopenharmony_ci int n; 168962306a36Sopenharmony_ci const struct of_device_id *match; 169062306a36Sopenharmony_ci const struct stm32f4_clk_data *data; 169162306a36Sopenharmony_ci unsigned long pllm; 169262306a36Sopenharmony_ci struct clk_hw *pll_src_hw; 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ci base = of_iomap(np, 0); 169562306a36Sopenharmony_ci if (!base) { 169662306a36Sopenharmony_ci pr_err("%pOFn: unable to map resource\n", np); 169762306a36Sopenharmony_ci return; 169862306a36Sopenharmony_ci } 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_ci pdrm = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); 170162306a36Sopenharmony_ci if (IS_ERR(pdrm)) { 170262306a36Sopenharmony_ci pdrm = NULL; 170362306a36Sopenharmony_ci pr_warn("%s: Unable to get syscfg\n", __func__); 170462306a36Sopenharmony_ci } 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_ci match = of_match_node(stm32f4_of_match, np); 170762306a36Sopenharmony_ci if (WARN_ON(!match)) 170862306a36Sopenharmony_ci return; 170962306a36Sopenharmony_ci 171062306a36Sopenharmony_ci data = match->data; 171162306a36Sopenharmony_ci 171262306a36Sopenharmony_ci stm32fx_end_primary_clk = data->end_primary; 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_ci clks = kmalloc_array(data->gates_num + stm32fx_end_primary_clk, 171562306a36Sopenharmony_ci sizeof(*clks), GFP_KERNEL); 171662306a36Sopenharmony_ci if (!clks) 171762306a36Sopenharmony_ci goto fail; 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci stm32f4_gate_map = data->gates_map; 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_ci hse_clk = of_clk_get_parent_name(np, 0); 172262306a36Sopenharmony_ci dsi_parent[0] = hse_clk; 172362306a36Sopenharmony_ci pllsrc_parent[1] = hse_clk; 172462306a36Sopenharmony_ci 172562306a36Sopenharmony_ci i2s_in_clk = of_clk_get_parent_name(np, 1); 172662306a36Sopenharmony_ci 172762306a36Sopenharmony_ci i2s_parents[1] = i2s_in_clk; 172862306a36Sopenharmony_ci sai_parents[2] = i2s_in_clk; 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci if (of_device_is_compatible(np, "st,stm32f769-rcc")) { 173162306a36Sopenharmony_ci clk_hw_register_gate(NULL, "dfsdm1_apb", "apb2_div", 0, 173262306a36Sopenharmony_ci base + STM32F4_RCC_APB2ENR, 29, 173362306a36Sopenharmony_ci CLK_IGNORE_UNUSED, &stm32f4_clk_lock); 173462306a36Sopenharmony_ci dsi_parent[0] = pll_src; 173562306a36Sopenharmony_ci sai_parents[3] = pll_src; 173662306a36Sopenharmony_ci } 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci clks[CLK_HSI] = clk_hw_register_fixed_rate_with_accuracy(NULL, "hsi", 173962306a36Sopenharmony_ci NULL, 0, 16000000, 160000); 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci pll_src_hw = clk_hw_register_mux(NULL, pll_src, pllsrc_parent, 174262306a36Sopenharmony_ci ARRAY_SIZE(pllsrc_parent), 0, 174362306a36Sopenharmony_ci base + STM32F4_RCC_PLLCFGR, 22, 1, 0, 174462306a36Sopenharmony_ci &stm32f4_clk_lock); 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ci pllm = readl(base + STM32F4_RCC_PLLCFGR) & 0x3f; 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci clk_hw_register_fixed_factor(NULL, "vco_in", pll_src, 174962306a36Sopenharmony_ci 0, 1, pllm); 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci stm32f4_rcc_register_pll("vco_in", &data->pll_data[0], 175262306a36Sopenharmony_ci &stm32f4_clk_lock); 175362306a36Sopenharmony_ci 175462306a36Sopenharmony_ci clks[PLL_VCO_I2S] = stm32f4_rcc_register_pll("vco_in", 175562306a36Sopenharmony_ci &data->pll_data[1], &stm32f4_clk_lock); 175662306a36Sopenharmony_ci 175762306a36Sopenharmony_ci clks[PLL_VCO_SAI] = stm32f4_rcc_register_pll("vco_in", 175862306a36Sopenharmony_ci &data->pll_data[2], &stm32f4_clk_lock); 175962306a36Sopenharmony_ci 176062306a36Sopenharmony_ci for (n = 0; n < MAX_POST_DIV; n++) { 176162306a36Sopenharmony_ci const struct stm32f4_pll_post_div_data *post_div; 176262306a36Sopenharmony_ci struct clk_hw *hw; 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_ci post_div = &post_div_data[n]; 176562306a36Sopenharmony_ci 176662306a36Sopenharmony_ci hw = clk_register_pll_div(post_div->name, 176762306a36Sopenharmony_ci post_div->parent, 176862306a36Sopenharmony_ci post_div->flag, 176962306a36Sopenharmony_ci base + post_div->offset, 177062306a36Sopenharmony_ci post_div->shift, 177162306a36Sopenharmony_ci post_div->width, 177262306a36Sopenharmony_ci post_div->flag_div, 177362306a36Sopenharmony_ci post_div->div_table, 177462306a36Sopenharmony_ci clks[post_div->pll_idx], 177562306a36Sopenharmony_ci &stm32f4_clk_lock); 177662306a36Sopenharmony_ci 177762306a36Sopenharmony_ci if (post_div->idx != NO_IDX) 177862306a36Sopenharmony_ci clks[post_div->idx] = hw; 177962306a36Sopenharmony_ci } 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_ci sys_parents[1] = hse_clk; 178262306a36Sopenharmony_ci 178362306a36Sopenharmony_ci clks[CLK_SYSCLK] = clk_hw_register_mux_table( 178462306a36Sopenharmony_ci NULL, "sys", sys_parents, ARRAY_SIZE(sys_parents), 0, 178562306a36Sopenharmony_ci base + STM32F4_RCC_CFGR, 0, 3, 0, NULL, &stm32f4_clk_lock); 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_ci clk_register_divider_table(NULL, "ahb_div", "sys", 178862306a36Sopenharmony_ci CLK_SET_RATE_PARENT, base + STM32F4_RCC_CFGR, 178962306a36Sopenharmony_ci 4, 4, 0, ahb_div_table, &stm32f4_clk_lock); 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci clk_register_divider_table(NULL, "apb1_div", "ahb_div", 179262306a36Sopenharmony_ci CLK_SET_RATE_PARENT, base + STM32F4_RCC_CFGR, 179362306a36Sopenharmony_ci 10, 3, 0, apb_div_table, &stm32f4_clk_lock); 179462306a36Sopenharmony_ci clk_register_apb_mul(NULL, "apb1_mul", "apb1_div", 179562306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 12); 179662306a36Sopenharmony_ci 179762306a36Sopenharmony_ci clk_register_divider_table(NULL, "apb2_div", "ahb_div", 179862306a36Sopenharmony_ci CLK_SET_RATE_PARENT, base + STM32F4_RCC_CFGR, 179962306a36Sopenharmony_ci 13, 3, 0, apb_div_table, &stm32f4_clk_lock); 180062306a36Sopenharmony_ci clk_register_apb_mul(NULL, "apb2_mul", "apb2_div", 180162306a36Sopenharmony_ci CLK_SET_RATE_PARENT, 15); 180262306a36Sopenharmony_ci 180362306a36Sopenharmony_ci clks[SYSTICK] = clk_hw_register_fixed_factor(NULL, "systick", "ahb_div", 180462306a36Sopenharmony_ci 0, 1, 8); 180562306a36Sopenharmony_ci clks[FCLK] = clk_hw_register_fixed_factor(NULL, "fclk", "ahb_div", 180662306a36Sopenharmony_ci 0, 1, 1); 180762306a36Sopenharmony_ci 180862306a36Sopenharmony_ci for (n = 0; n < data->gates_num; n++) { 180962306a36Sopenharmony_ci const struct stm32f4_gate_data *gd; 181062306a36Sopenharmony_ci unsigned int secondary; 181162306a36Sopenharmony_ci int idx; 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_ci gd = &data->gates_data[n]; 181462306a36Sopenharmony_ci secondary = 8 * (gd->offset - STM32F4_RCC_AHB1ENR) + 181562306a36Sopenharmony_ci gd->bit_idx; 181662306a36Sopenharmony_ci idx = stm32f4_rcc_lookup_clk_idx(0, secondary); 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_ci if (idx < 0) 181962306a36Sopenharmony_ci goto fail; 182062306a36Sopenharmony_ci 182162306a36Sopenharmony_ci clks[idx] = clk_hw_register_gate( 182262306a36Sopenharmony_ci NULL, gd->name, gd->parent_name, gd->flags, 182362306a36Sopenharmony_ci base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock); 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_ci if (IS_ERR(clks[idx])) { 182662306a36Sopenharmony_ci pr_err("%pOF: Unable to register leaf clock %s\n", 182762306a36Sopenharmony_ci np, gd->name); 182862306a36Sopenharmony_ci goto fail; 182962306a36Sopenharmony_ci } 183062306a36Sopenharmony_ci } 183162306a36Sopenharmony_ci 183262306a36Sopenharmony_ci clks[CLK_LSI] = clk_register_rgate(NULL, "lsi", "clk-lsi", 0, 183362306a36Sopenharmony_ci base + STM32F4_RCC_CSR, 0, 1, 0, &stm32f4_clk_lock); 183462306a36Sopenharmony_ci 183562306a36Sopenharmony_ci if (IS_ERR(clks[CLK_LSI])) { 183662306a36Sopenharmony_ci pr_err("Unable to register lsi clock\n"); 183762306a36Sopenharmony_ci goto fail; 183862306a36Sopenharmony_ci } 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ci clks[CLK_LSE] = clk_register_rgate(NULL, "lse", "clk-lse", 0, 184162306a36Sopenharmony_ci base + STM32F4_RCC_BDCR, 0, 1, 0, &stm32f4_clk_lock); 184262306a36Sopenharmony_ci 184362306a36Sopenharmony_ci if (IS_ERR(clks[CLK_LSE])) { 184462306a36Sopenharmony_ci pr_err("Unable to register lse clock\n"); 184562306a36Sopenharmony_ci goto fail; 184662306a36Sopenharmony_ci } 184762306a36Sopenharmony_ci 184862306a36Sopenharmony_ci clks[CLK_HSE_RTC] = clk_hw_register_divider(NULL, "hse-rtc", "clk-hse", 184962306a36Sopenharmony_ci 0, base + STM32F4_RCC_CFGR, 16, 5, 0, 185062306a36Sopenharmony_ci &stm32f4_clk_lock); 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_ci if (IS_ERR(clks[CLK_HSE_RTC])) { 185362306a36Sopenharmony_ci pr_err("Unable to register hse-rtc clock\n"); 185462306a36Sopenharmony_ci goto fail; 185562306a36Sopenharmony_ci } 185662306a36Sopenharmony_ci 185762306a36Sopenharmony_ci clks[CLK_RTC] = stm32_register_cclk(NULL, "rtc", rtc_parents, 4, 185862306a36Sopenharmony_ci base + STM32F4_RCC_BDCR, 15, 8, 0, &stm32f4_clk_lock); 185962306a36Sopenharmony_ci 186062306a36Sopenharmony_ci if (IS_ERR(clks[CLK_RTC])) { 186162306a36Sopenharmony_ci pr_err("Unable to register rtc clock\n"); 186262306a36Sopenharmony_ci goto fail; 186362306a36Sopenharmony_ci } 186462306a36Sopenharmony_ci 186562306a36Sopenharmony_ci for (n = 0; n < data->aux_clk_num; n++) { 186662306a36Sopenharmony_ci const struct stm32_aux_clk *aux_clk; 186762306a36Sopenharmony_ci struct clk_hw *hw; 186862306a36Sopenharmony_ci 186962306a36Sopenharmony_ci aux_clk = &data->aux_clk[n]; 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci hw = stm32_register_aux_clk(aux_clk->name, 187262306a36Sopenharmony_ci aux_clk->parent_names, aux_clk->num_parents, 187362306a36Sopenharmony_ci aux_clk->offset_mux, aux_clk->shift, 187462306a36Sopenharmony_ci aux_clk->mask, aux_clk->offset_gate, 187562306a36Sopenharmony_ci aux_clk->bit_idx, aux_clk->flags, 187662306a36Sopenharmony_ci &stm32f4_clk_lock); 187762306a36Sopenharmony_ci 187862306a36Sopenharmony_ci if (IS_ERR(hw)) { 187962306a36Sopenharmony_ci pr_warn("Unable to register %s clk\n", aux_clk->name); 188062306a36Sopenharmony_ci continue; 188162306a36Sopenharmony_ci } 188262306a36Sopenharmony_ci 188362306a36Sopenharmony_ci if (aux_clk->idx != NO_IDX) 188462306a36Sopenharmony_ci clks[aux_clk->idx] = hw; 188562306a36Sopenharmony_ci } 188662306a36Sopenharmony_ci 188762306a36Sopenharmony_ci if (of_device_is_compatible(np, "st,stm32f746-rcc")) { 188862306a36Sopenharmony_ci 188962306a36Sopenharmony_ci clk_hw_register_fixed_factor(NULL, "hsi_div488", "hsi", 0, 189062306a36Sopenharmony_ci 1, 488); 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_ci clks[CLK_PLL_SRC] = pll_src_hw; 189362306a36Sopenharmony_ci } 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_ci of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL); 189662306a36Sopenharmony_ci 189762306a36Sopenharmony_ci return; 189862306a36Sopenharmony_cifail: 189962306a36Sopenharmony_ci kfree(clks); 190062306a36Sopenharmony_ci iounmap(base); 190162306a36Sopenharmony_ci} 190262306a36Sopenharmony_ciCLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); 190362306a36Sopenharmony_ciCLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init); 190462306a36Sopenharmony_ciCLK_OF_DECLARE_DRIVER(stm32f746_rcc, "st,stm32f746-rcc", stm32f4_rcc_init); 190562306a36Sopenharmony_ciCLK_OF_DECLARE_DRIVER(stm32f769_rcc, "st,stm32f769-rcc", stm32f4_rcc_init); 1906