1e5e793a6SGabriel Fernandez /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2e5e793a6SGabriel Fernandez /* 3e5e793a6SGabriel Fernandez * Copyright (C) STMicroelectronics 2022 - All Rights Reserved 4e5e793a6SGabriel Fernandez */ 5e5e793a6SGabriel Fernandez 6e5e793a6SGabriel Fernandez #ifndef CLK_STM32_CORE_H 7e5e793a6SGabriel Fernandez #define CLK_STM32_CORE_H 8e5e793a6SGabriel Fernandez 9e5e793a6SGabriel Fernandez #include <drivers/clk.h> 10e5e793a6SGabriel Fernandez 11e5e793a6SGabriel Fernandez struct mux_cfg { 12e5e793a6SGabriel Fernandez uint16_t offset; 13e5e793a6SGabriel Fernandez uint8_t shift; 14e5e793a6SGabriel Fernandez uint8_t width; 15e5e793a6SGabriel Fernandez uint8_t ready; 16e5e793a6SGabriel Fernandez }; 17e5e793a6SGabriel Fernandez 18e5e793a6SGabriel Fernandez struct gate_cfg { 19e5e793a6SGabriel Fernandez uint16_t offset; 20e5e793a6SGabriel Fernandez uint8_t bit_idx; 21e5e793a6SGabriel Fernandez uint8_t set_clr; 22e5e793a6SGabriel Fernandez }; 23e5e793a6SGabriel Fernandez 24e5e793a6SGabriel Fernandez struct div_table_cfg { 25e5e793a6SGabriel Fernandez unsigned int val; 26e5e793a6SGabriel Fernandez unsigned int div; 27e5e793a6SGabriel Fernandez }; 28e5e793a6SGabriel Fernandez 29e5e793a6SGabriel Fernandez struct div_cfg { 30e5e793a6SGabriel Fernandez uint16_t offset; 31e5e793a6SGabriel Fernandez uint8_t shift; 32e5e793a6SGabriel Fernandez uint8_t width; 33e5e793a6SGabriel Fernandez uint8_t flags; 34e5e793a6SGabriel Fernandez uint8_t ready; 35e5e793a6SGabriel Fernandez const struct div_table_cfg *table; 36e5e793a6SGabriel Fernandez }; 37e5e793a6SGabriel Fernandez 38e5e793a6SGabriel Fernandez struct clk_stm32_priv { 39e5e793a6SGabriel Fernandez uintptr_t base; 405436921fSGabriel Fernandez size_t nb_clk_refs; 415436921fSGabriel Fernandez struct clk **clk_refs; 42e5e793a6SGabriel Fernandez const struct mux_cfg *muxes; 43e5e793a6SGabriel Fernandez const uint32_t nb_muxes; 44e5e793a6SGabriel Fernandez const struct gate_cfg *gates; 452b028a2bSGatien Chevallier uint8_t *gate_cpt; 46e5e793a6SGabriel Fernandez const uint32_t nb_gates; 47e5e793a6SGabriel Fernandez const struct div_cfg *div; 48e5e793a6SGabriel Fernandez const uint32_t nb_div; 495436921fSGabriel Fernandez bool (*is_critical)(struct clk *clk); 50e5e793a6SGabriel Fernandez void *pdata; 51e5e793a6SGabriel Fernandez }; 52e5e793a6SGabriel Fernandez 53e5e793a6SGabriel Fernandez struct clk_fixed_rate_cfg { 54e5e793a6SGabriel Fernandez unsigned long rate; 55e5e793a6SGabriel Fernandez }; 56e5e793a6SGabriel Fernandez 57e5e793a6SGabriel Fernandez struct fixed_factor_cfg { 58e5e793a6SGabriel Fernandez unsigned int mult; 59e5e793a6SGabriel Fernandez unsigned int div; 60e5e793a6SGabriel Fernandez }; 61e5e793a6SGabriel Fernandez 62e5e793a6SGabriel Fernandez struct clk_gate_cfg { 63e5e793a6SGabriel Fernandez uint32_t offset; 64e5e793a6SGabriel Fernandez uint8_t bit_idx; 65e5e793a6SGabriel Fernandez }; 66e5e793a6SGabriel Fernandez 67e5e793a6SGabriel Fernandez struct clk_stm32_mux_cfg { 68e5e793a6SGabriel Fernandez int mux_id; 69e5e793a6SGabriel Fernandez }; 70e5e793a6SGabriel Fernandez 71e5e793a6SGabriel Fernandez struct clk_stm32_gate_cfg { 72e5e793a6SGabriel Fernandez int gate_id; 73e5e793a6SGabriel Fernandez }; 74e5e793a6SGabriel Fernandez 75e5e793a6SGabriel Fernandez struct clk_stm32_div_cfg { 76e5e793a6SGabriel Fernandez int div_id; 77e5e793a6SGabriel Fernandez }; 78e5e793a6SGabriel Fernandez 79e5e793a6SGabriel Fernandez struct clk_stm32_composite_cfg { 80e5e793a6SGabriel Fernandez int gate_id; 81e5e793a6SGabriel Fernandez int div_id; 82e5e793a6SGabriel Fernandez int mux_id; 83e5e793a6SGabriel Fernandez }; 84e5e793a6SGabriel Fernandez 85e5e793a6SGabriel Fernandez struct clk_stm32_timer_cfg { 86e5e793a6SGabriel Fernandez uint32_t apbdiv; 87e5e793a6SGabriel Fernandez uint32_t timpre; 88e5e793a6SGabriel Fernandez }; 89e5e793a6SGabriel Fernandez 90e5e793a6SGabriel Fernandez struct clk_stm32_gate_ready_cfg { 91e5e793a6SGabriel Fernandez int gate_id; 92e5e793a6SGabriel Fernandez int gate_rdy_id; 93e5e793a6SGabriel Fernandez }; 94e5e793a6SGabriel Fernandez 95e5e793a6SGabriel Fernandez /* Define for divider clocks */ 96e5e793a6SGabriel Fernandez #define CLK_DIVIDER_ONE_BASED BIT(0) 97e5e793a6SGabriel Fernandez #define CLK_DIVIDER_POWER_OF_TWO BIT(1) 98e5e793a6SGabriel Fernandez #define CLK_DIVIDER_ALLOW_ZERO BIT(2) 99e5e793a6SGabriel Fernandez #define CLK_DIVIDER_HIWORD_MASK BIT(3) 100e5e793a6SGabriel Fernandez #define CLK_DIVIDER_ROUND_CLOSEST BIT(4) 101e5e793a6SGabriel Fernandez #define CLK_DIVIDER_READ_ONLY BIT(5) 102e5e793a6SGabriel Fernandez #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) 103e5e793a6SGabriel Fernandez #define CLK_DIVIDER_BIG_ENDIAN BIT(7) 104e5e793a6SGabriel Fernandez 105e5e793a6SGabriel Fernandez #define DIV_NO_RDY UINT8_MAX 106e5e793a6SGabriel Fernandez #define MUX_NO_RDY UINT8_MAX 107e5e793a6SGabriel Fernandez 108e5e793a6SGabriel Fernandez #define MASK_WIDTH_SHIFT(_width, _shift) \ 109e5e793a6SGabriel Fernandez GENMASK_32(((_width) + (_shift) - 1U), (_shift)) 110e5e793a6SGabriel Fernandez 111e5e793a6SGabriel Fernandez /* Define for composite clocks */ 112e5e793a6SGabriel Fernandez #define NO_MUX INT32_MAX 113e5e793a6SGabriel Fernandez #define NO_DIV INT32_MAX 114e5e793a6SGabriel Fernandez #define NO_GATE INT32_MAX 115e5e793a6SGabriel Fernandez 116e5e793a6SGabriel Fernandez void stm32_gate_enable(uint16_t gate_id); 117e5e793a6SGabriel Fernandez void stm32_gate_disable(uint16_t gate_id); 118e5e793a6SGabriel Fernandez bool stm32_gate_is_enabled(uint16_t gate_id); 119e5e793a6SGabriel Fernandez TEE_Result stm32_gate_wait_ready(uint16_t gate_id, bool ready_on); 120e5e793a6SGabriel Fernandez TEE_Result stm32_gate_rdy_enable(uint16_t gate_id); 121e5e793a6SGabriel Fernandez TEE_Result stm32_gate_rdy_disable(uint16_t gate_id); 122e5e793a6SGabriel Fernandez 123*6a977fc4SEtienne Carriere /* 124*6a977fc4SEtienne Carriere * Set gate to an enable or disable state without updating its 125*6a977fc4SEtienne Carriere * refcount. This is exclusively intended to be used during initialization 126*6a977fc4SEtienne Carriere * where refcount value are 0. 127*6a977fc4SEtienne Carriere */ 128*6a977fc4SEtienne Carriere void stm32_gate_set_init_state(uint16_t gate_id, bool enable); 129*6a977fc4SEtienne Carriere 130e5e793a6SGabriel Fernandez size_t stm32_mux_get_parent(uint32_t mux_id); 131e5e793a6SGabriel Fernandez TEE_Result stm32_mux_set_parent(uint16_t pid, uint8_t sel); 132e5e793a6SGabriel Fernandez 133e5e793a6SGabriel Fernandez TEE_Result stm32_div_set_rate(int div_id, unsigned long rate, 134e5e793a6SGabriel Fernandez unsigned long prate); 135e5e793a6SGabriel Fernandez 136e5e793a6SGabriel Fernandez uint32_t stm32_div_get_value(int div_id); 137e5e793a6SGabriel Fernandez TEE_Result stm32_div_set_value(uint32_t div_id, uint32_t value); 138e5e793a6SGabriel Fernandez 139e5e793a6SGabriel Fernandez int clk_stm32_parse_fdt_by_name(const void *fdt, int node, const char *name, 140e5e793a6SGabriel Fernandez uint32_t *tab, uint32_t *nb); 141e5e793a6SGabriel Fernandez 1425436921fSGabriel Fernandez unsigned long clk_stm32_divider_get_rate(struct clk *clk, 1435436921fSGabriel Fernandez unsigned long parent_rate); 1445436921fSGabriel Fernandez 1455436921fSGabriel Fernandez TEE_Result clk_stm32_divider_set_rate(struct clk *clk, 1465436921fSGabriel Fernandez unsigned long rate, 1475436921fSGabriel Fernandez unsigned long parent_rate); 1485436921fSGabriel Fernandez 1495436921fSGabriel Fernandez size_t clk_stm32_composite_get_parent(struct clk *clk); 1505436921fSGabriel Fernandez TEE_Result clk_stm32_composite_set_parent(struct clk *clk, size_t pidx); 1515436921fSGabriel Fernandez unsigned long clk_stm32_composite_get_rate(struct clk *clk, 1525436921fSGabriel Fernandez unsigned long parent_rate); 1535436921fSGabriel Fernandez TEE_Result clk_stm32_composite_set_rate(struct clk *clk, unsigned long rate, 1545436921fSGabriel Fernandez unsigned long parent_rate); 1555436921fSGabriel Fernandez TEE_Result clk_stm32_composite_gate_enable(struct clk *clk); 1565436921fSGabriel Fernandez void clk_stm32_composite_gate_disable(struct clk *clk); 1575436921fSGabriel Fernandez 1585436921fSGabriel Fernandez TEE_Result clk_stm32_set_parent_by_index(struct clk *clk, size_t pidx); 1595436921fSGabriel Fernandez 1605436921fSGabriel Fernandez extern const struct clk_ops clk_fixed_factor_ops; 1615436921fSGabriel Fernandez extern const struct clk_ops clk_fixed_clk_ops; 1625436921fSGabriel Fernandez extern const struct clk_ops clk_stm32_gate_ops; 1635436921fSGabriel Fernandez extern const struct clk_ops clk_stm32_gate_ready_ops; 1645436921fSGabriel Fernandez extern const struct clk_ops clk_stm32_divider_ops; 1655436921fSGabriel Fernandez extern const struct clk_ops clk_stm32_mux_ops; 1665436921fSGabriel Fernandez extern const struct clk_ops clk_stm32_composite_ops; 1675436921fSGabriel Fernandez 1685436921fSGabriel Fernandez #define PARENT(x...) { x } 1695436921fSGabriel Fernandez 1705436921fSGabriel Fernandez #define STM32_FIXED_RATE(_name, _rate)\ 1715436921fSGabriel Fernandez struct clk _name = {\ 1725436921fSGabriel Fernandez .ops = &clk_fixed_clk_ops,\ 1735436921fSGabriel Fernandez .priv = &(struct clk_fixed_rate_cfg) {\ 1745436921fSGabriel Fernandez .rate = (_rate),\ 1755436921fSGabriel Fernandez },\ 1765436921fSGabriel Fernandez .name = #_name,\ 1775436921fSGabriel Fernandez .flags = 0,\ 1785436921fSGabriel Fernandez .num_parents = 0,\ 1795436921fSGabriel Fernandez } 1805436921fSGabriel Fernandez 1815436921fSGabriel Fernandez #define STM32_FIXED_FACTOR(_name, _parent, _flags, _mult, _div)\ 1825436921fSGabriel Fernandez struct clk _name = {\ 1835436921fSGabriel Fernandez .ops = &clk_fixed_factor_ops,\ 1845436921fSGabriel Fernandez .priv = &(struct fixed_factor_cfg) {\ 1855436921fSGabriel Fernandez .mult = _mult,\ 1865436921fSGabriel Fernandez .div = _div,\ 1875436921fSGabriel Fernandez },\ 1885436921fSGabriel Fernandez .name = #_name,\ 1895436921fSGabriel Fernandez .flags = (_flags),\ 1905436921fSGabriel Fernandez .num_parents = 1,\ 1915436921fSGabriel Fernandez .parents = { (_parent) },\ 1925436921fSGabriel Fernandez } 1935436921fSGabriel Fernandez 1945436921fSGabriel Fernandez #define STM32_GATE(_name, _parent, _flags, _gate_id)\ 1955436921fSGabriel Fernandez struct clk _name = {\ 1965436921fSGabriel Fernandez .ops = &clk_stm32_gate_ops,\ 1975436921fSGabriel Fernandez .priv = &(struct clk_stm32_gate_cfg) {\ 1985436921fSGabriel Fernandez .gate_id = _gate_id,\ 1995436921fSGabriel Fernandez },\ 2005436921fSGabriel Fernandez .name = #_name,\ 2015436921fSGabriel Fernandez .flags = (_flags),\ 2025436921fSGabriel Fernandez .num_parents = 1,\ 2035436921fSGabriel Fernandez .parents = { (_parent) },\ 2045436921fSGabriel Fernandez } 2055436921fSGabriel Fernandez 2065436921fSGabriel Fernandez #define STM32_DIVIDER(_name, _parent, _flags, _div_id)\ 2075436921fSGabriel Fernandez struct clk _name = {\ 2085436921fSGabriel Fernandez .ops = &clk_stm32_divider_ops,\ 2095436921fSGabriel Fernandez .priv = &(struct clk_stm32_div_cfg) {\ 2105436921fSGabriel Fernandez .div_id = (_div_id),\ 2115436921fSGabriel Fernandez },\ 2125436921fSGabriel Fernandez .name = #_name,\ 2135436921fSGabriel Fernandez .flags = (_flags),\ 2145436921fSGabriel Fernandez .num_parents = 1,\ 2155436921fSGabriel Fernandez .parents = { (_parent) },\ 2165436921fSGabriel Fernandez } 2175436921fSGabriel Fernandez 2185436921fSGabriel Fernandez #define STM32_MUX(_name, _nb_parents, _parents, _flags, _mux_id)\ 2195436921fSGabriel Fernandez struct clk _name = {\ 2205436921fSGabriel Fernandez .ops = &clk_stm32_mux_ops,\ 2215436921fSGabriel Fernandez .priv = &(struct clk_stm32_mux_cfg) {\ 2225436921fSGabriel Fernandez .mux_id = (_mux_id),\ 2235436921fSGabriel Fernandez },\ 2245436921fSGabriel Fernandez .name = #_name,\ 2255436921fSGabriel Fernandez .flags = (_flags),\ 2265436921fSGabriel Fernandez .num_parents = (_nb_parents),\ 2275436921fSGabriel Fernandez .parents = _parents,\ 2285436921fSGabriel Fernandez } 2295436921fSGabriel Fernandez 2305436921fSGabriel Fernandez #define STM32_GATE_READY(_name, _parent, _flags, _gate_id)\ 2315436921fSGabriel Fernandez struct clk _name = {\ 2325436921fSGabriel Fernandez .ops = &clk_stm32_gate_ready_ops,\ 2335436921fSGabriel Fernandez .priv = &(struct clk_stm32_gate_cfg) {\ 2345436921fSGabriel Fernandez .gate_id = _gate_id,\ 2355436921fSGabriel Fernandez },\ 2365436921fSGabriel Fernandez .name = #_name,\ 2375436921fSGabriel Fernandez .flags = (_flags),\ 2385436921fSGabriel Fernandez .num_parents = 1,\ 2395436921fSGabriel Fernandez .parents = { _parent },\ 2405436921fSGabriel Fernandez } 2415436921fSGabriel Fernandez 2425436921fSGabriel Fernandez #define STM32_COMPOSITE(_name, _nb_parents, _parents, _flags,\ 2435436921fSGabriel Fernandez _gate_id, _div_id, _mux_id)\ 2445436921fSGabriel Fernandez struct clk _name = {\ 2455436921fSGabriel Fernandez .ops = &clk_stm32_composite_ops,\ 2465436921fSGabriel Fernandez .priv = &(struct clk_stm32_composite_cfg) {\ 2475436921fSGabriel Fernandez .gate_id = (_gate_id),\ 2485436921fSGabriel Fernandez .div_id = (_div_id),\ 2495436921fSGabriel Fernandez .mux_id = (_mux_id),\ 2505436921fSGabriel Fernandez },\ 2515436921fSGabriel Fernandez .name = #_name,\ 2525436921fSGabriel Fernandez .flags = (_flags),\ 2535436921fSGabriel Fernandez .num_parents = (_nb_parents),\ 2545436921fSGabriel Fernandez .parents = _parents,\ 2555436921fSGabriel Fernandez } 2565436921fSGabriel Fernandez 257e5e793a6SGabriel Fernandez struct clk_stm32_priv *clk_stm32_get_priv(void); 258e5e793a6SGabriel Fernandez uintptr_t clk_stm32_get_rcc_base(void); 259e5e793a6SGabriel Fernandez 260e5e793a6SGabriel Fernandez TEE_Result clk_stm32_init(struct clk_stm32_priv *priv, uintptr_t base); 261e5e793a6SGabriel Fernandez 2625436921fSGabriel Fernandez void stm32mp_clk_provider_probe_final(const void *fdt, int node, 2635436921fSGabriel Fernandez struct clk_stm32_priv *priv); 2645436921fSGabriel Fernandez 265e5e793a6SGabriel Fernandez #endif /* CLK_STM32_CORE_H */ 266