• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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