1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) STMicroelectronics 2022 - All Rights Reserved 4 * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics. 5 */ 6 7 #include <linux/clk-provider.h> 8 9 struct stm32_rcc_match_data; 10 11 struct stm32_mux_cfg { 12 u16 offset; 13 u8 shift; 14 u8 width; 15 u8 flags; 16 u32 *table; 17 u8 ready; 18 }; 19 20 struct stm32_gate_cfg { 21 u16 offset; 22 u8 bit_idx; 23 u8 set_clr; 24 }; 25 26 struct stm32_div_cfg { 27 u16 offset; 28 u8 shift; 29 u8 width; 30 u8 flags; 31 u8 ready; 32 const struct clk_div_table *table; 33 }; 34 35 struct stm32_composite_cfg { 36 int mux; 37 int gate; 38 int div; 39 }; 40 41 #define NO_ID 0xFFFFFFFF 42 43 #define NO_STM32_MUX 0xFFFF 44 #define NO_STM32_DIV 0xFFFF 45 #define NO_STM32_GATE 0xFFFF 46 47 struct clock_config { 48 unsigned long id; 49 int sec_id; 50 void *clock_cfg; 51 52 struct clk_hw *(*func)(struct device *dev, 53 const struct stm32_rcc_match_data *data, 54 void __iomem *base, 55 spinlock_t *lock, 56 const struct clock_config *cfg); 57 }; 58 59 struct clk_stm32_clock_data { 60 u16 *gate_cpt; 61 const struct stm32_gate_cfg *gates; 62 const struct stm32_mux_cfg *muxes; 63 const struct stm32_div_cfg *dividers; 64 struct clk_hw *(*is_multi_mux)(struct clk_hw *hw); 65 }; 66 67 struct stm32_rcc_match_data { 68 struct clk_hw_onecell_data *hw_clks; 69 unsigned int num_clocks; 70 const struct clock_config *tab_clocks; 71 unsigned int maxbinding; 72 struct clk_stm32_clock_data *clock_data; 73 u32 clear_offset; 74 int (*check_security)(void __iomem *base, 75 const struct clock_config *cfg); 76 int (*multi_mux)(void __iomem *base, const struct clock_config *cfg); 77 }; 78 79 int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match, 80 void __iomem *base); 81 82 int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data, 83 void __iomem *base); 84 85 /* MUX define */ 86 #define MUX_NO_RDY 0xFF 87 #define MUX_SAFE BIT(7) 88 89 /* DIV define */ 90 #define DIV_NO_RDY 0xFF 91 92 /* Definition of clock structure */ 93 struct clk_stm32_mux { 94 u16 mux_id; 95 struct clk_hw hw; 96 void __iomem *base; 97 struct clk_stm32_clock_data *clock_data; 98 spinlock_t *lock; /* spin lock */ 99 }; 100 101 #define to_clk_stm32_mux(_hw) container_of(_hw, struct clk_stm32_mux, hw) 102 103 struct clk_stm32_gate { 104 u16 gate_id; 105 struct clk_hw hw; 106 void __iomem *base; 107 struct clk_stm32_clock_data *clock_data; 108 spinlock_t *lock; /* spin lock */ 109 }; 110 111 #define to_clk_stm32_gate(_hw) container_of(_hw, struct clk_stm32_gate, hw) 112 113 struct clk_stm32_div { 114 u16 div_id; 115 struct clk_hw hw; 116 void __iomem *base; 117 struct clk_stm32_clock_data *clock_data; 118 spinlock_t *lock; /* spin lock */ 119 }; 120 121 #define to_clk_stm32_divider(_hw) container_of(_hw, struct clk_stm32_div, hw) 122 123 struct clk_stm32_composite { 124 u16 gate_id; 125 u16 mux_id; 126 u16 div_id; 127 struct clk_hw hw; 128 void __iomem *base; 129 struct clk_stm32_clock_data *clock_data; 130 spinlock_t *lock; /* spin lock */ 131 }; 132 133 #define to_clk_stm32_composite(_hw) container_of(_hw, struct clk_stm32_composite, hw) 134 135 /* Clock operators */ 136 extern const struct clk_ops clk_stm32_mux_ops; 137 extern const struct clk_ops clk_stm32_gate_ops; 138 extern const struct clk_ops clk_stm32_divider_ops; 139 extern const struct clk_ops clk_stm32_composite_ops; 140 141 /* Clock registering */ 142 struct clk_hw *clk_stm32_mux_register(struct device *dev, 143 const struct stm32_rcc_match_data *data, 144 void __iomem *base, 145 spinlock_t *lock, 146 const struct clock_config *cfg); 147 148 struct clk_hw *clk_stm32_gate_register(struct device *dev, 149 const struct stm32_rcc_match_data *data, 150 void __iomem *base, 151 spinlock_t *lock, 152 const struct clock_config *cfg); 153 154 struct clk_hw *clk_stm32_div_register(struct device *dev, 155 const struct stm32_rcc_match_data *data, 156 void __iomem *base, 157 spinlock_t *lock, 158 const struct clock_config *cfg); 159 160 struct clk_hw *clk_stm32_composite_register(struct device *dev, 161 const struct stm32_rcc_match_data *data, 162 void __iomem *base, 163 spinlock_t *lock, 164 const struct clock_config *cfg); 165 166 #define STM32_CLOCK_CFG(_binding, _clk, _sec_id, _struct, _register)\ 167 {\ 168 .id = (_binding),\ 169 .sec_id = (_sec_id),\ 170 .clock_cfg = (_struct) {_clk},\ 171 .func = (_register),\ 172 } 173 174 #define STM32_MUX_CFG(_binding, _clk, _sec_id)\ 175 STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_mux *,\ 176 &clk_stm32_mux_register) 177 178 #define STM32_GATE_CFG(_binding, _clk, _sec_id)\ 179 STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_gate *,\ 180 &clk_stm32_gate_register) 181 182 #define STM32_DIV_CFG(_binding, _clk, _sec_id)\ 183 STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_div *,\ 184 &clk_stm32_div_register) 185 186 #define STM32_COMPOSITE_CFG(_binding, _clk, _sec_id)\ 187 STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_composite *,\ 188 &clk_stm32_composite_register) 189