xref: /optee_os/core/drivers/clk/clk-stm32-core.h (revision 6a977fc40fb1e5069ee1a0d3da67d52759c9ef3b)
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