xref: /optee_os/core/include/drivers/clk.h (revision 6c9ed8423414aceb4ded7de166fe29ed919b3847)
12305544bSClément Léger /* SPDX-License-Identifier: BSD-2-Clause */
22305544bSClément Léger /*
32305544bSClément Léger  * Copyright (c) 2021, Bootlin
42305544bSClément Léger  */
52305544bSClément Léger 
62305544bSClément Léger #ifndef __DRIVERS_CLK_H
72305544bSClément Léger #define __DRIVERS_CLK_H
82305544bSClément Léger 
92305544bSClément Léger #include <kernel/refcount.h>
102305544bSClément Léger #include <stdint.h>
112305544bSClément Léger #include <tee_api_types.h>
122305544bSClément Léger 
132305544bSClément Léger /* Flags for clock */
142305544bSClément Léger #define CLK_SET_RATE_GATE	BIT(0) /* must be gated across rate change */
152305544bSClément Léger #define CLK_SET_PARENT_GATE	BIT(1) /* must be gated across re-parent */
162305544bSClément Léger 
172305544bSClément Léger /**
182305544bSClément Léger  * struct clk - Clock structure
192305544bSClément Léger  *
202305544bSClément Léger  * @name: Clock name
212305544bSClément Léger  * @priv: Private data for the clock provider
222305544bSClément Léger  * @ops: Clock operations
232305544bSClément Léger  * @parent: Current parent
242305544bSClément Léger  * @rate: Current clock rate (cached after init or rate change)
252305544bSClément Léger  * @flags: Specific clock flags
262305544bSClément Léger  * @enabled_count: Enable/disable reference counter
272305544bSClément Léger  * @num_parents: Number of parents
282305544bSClément Léger  * @parents: Array of possible parents of the clock
292305544bSClément Léger  */
302305544bSClément Léger struct clk {
312305544bSClément Léger 	const char *name;
322305544bSClément Léger 	void *priv;
332305544bSClément Léger 	const struct clk_ops *ops;
342305544bSClément Léger 	struct clk *parent;
352305544bSClément Léger 	unsigned long rate;
362305544bSClément Léger 	unsigned int flags;
372305544bSClément Léger 	struct refcount enabled_count;
382305544bSClément Léger 	size_t num_parents;
392305544bSClément Léger 	struct clk *parents[];
402305544bSClément Léger };
412305544bSClément Léger 
422305544bSClément Léger /**
432305544bSClément Léger  * struct clk_ops
442305544bSClément Léger  *
452305544bSClément Léger  * @enable: Enable the clock
462305544bSClément Léger  * @disable: Disable the clock
472305544bSClément Léger  * @set_parent: Set the clock parent based on index
482305544bSClément Léger  * @get_parent: Get the current parent index of the clock
492305544bSClément Léger  * @set_rate: Set the clock rate
502305544bSClément Léger  * @get_rate: Get the clock rate
512305544bSClément Léger  */
522305544bSClément Léger struct clk_ops {
532305544bSClément Léger 	TEE_Result (*enable)(struct clk *clk);
542305544bSClément Léger 	void (*disable)(struct clk *clk);
552305544bSClément Léger 	TEE_Result (*set_parent)(struct clk *clk, size_t index);
562305544bSClément Léger 	size_t (*get_parent)(struct clk *clk);
572305544bSClément Léger 	TEE_Result (*set_rate)(struct clk *clk, unsigned long rate,
582305544bSClément Léger 			       unsigned long parent_rate);
592305544bSClément Léger 	unsigned long (*get_rate)(struct clk *clk,
602305544bSClément Léger 				  unsigned long parent_rate);
612305544bSClément Léger };
622305544bSClément Léger 
632305544bSClément Léger /**
642305544bSClément Léger  * Return the clock name
652305544bSClément Léger  *
662305544bSClément Léger  * @clk: Clock for which the name is needed
672305544bSClément Léger  * Return a const char * pointing to the clock name
682305544bSClément Léger  */
692305544bSClément Léger static inline const char *clk_get_name(struct clk *clk)
702305544bSClément Léger {
712305544bSClément Léger 	return clk->name;
722305544bSClément Léger }
732305544bSClément Léger 
742305544bSClément Léger /**
752305544bSClément Léger  * clk_alloc - Allocate a clock structure
762305544bSClément Léger  *
772305544bSClément Léger  * @name: Clock name
782305544bSClément Léger  * @ops: Clock operations
792305544bSClément Léger  * @parent_clks: Parents of the clock
802305544bSClément Léger  * @parent_count: Number of parents of the clock
812305544bSClément Léger  *
822305544bSClément Léger  * Return a clock struct properly initialized or NULL if allocation failed
832305544bSClément Léger  */
842305544bSClément Léger struct clk *clk_alloc(const char *name, const struct clk_ops *ops,
852305544bSClément Léger 		      struct clk **parent_clks, size_t parent_count);
862305544bSClément Léger 
872305544bSClément Léger /**
882305544bSClément Léger  * clk_free - Free a clock structure
892305544bSClément Léger  *
902305544bSClément Léger  * @clk: Clock to be freed or NULL
912305544bSClément Léger  */
922305544bSClément Léger void clk_free(struct clk *clk);
932305544bSClément Léger 
942305544bSClément Léger /**
952305544bSClément Léger  * clk_register - Register a clock within the clock framework
962305544bSClément Léger  *
972305544bSClément Léger  * @clk: Clock struct to be registered
982305544bSClément Léger  * Return a TEE_Result compliant value
992305544bSClément Léger  */
1002305544bSClément Léger TEE_Result clk_register(struct clk *clk);
1012305544bSClément Léger 
1022305544bSClément Léger /**
1032305544bSClément Léger  * clk_get_rate - Get clock rate
1042305544bSClément Léger  *
1052305544bSClément Léger  * @clk: Clock for which the rate is needed
1062305544bSClément Léger  * Return the clock rate in Hz
1072305544bSClément Léger  */
1082305544bSClément Léger unsigned long clk_get_rate(struct clk *clk);
1092305544bSClément Léger 
1102305544bSClément Léger /**
1112305544bSClément Léger  * clk_set_rate - Set a clock rate
1122305544bSClément Léger  *
1132305544bSClément Léger  * @clk: Clock to be set with the rate
1142305544bSClément Léger  * @rate: Rate to set in Hz
1152305544bSClément Léger  * Return a TEE_Result compliant value
1162305544bSClément Léger  */
1172305544bSClément Léger TEE_Result clk_set_rate(struct clk *clk, unsigned long rate);
1182305544bSClément Léger 
1192305544bSClément Léger /**
1202305544bSClément Léger  * clk_enable - Enable a clock and its ascendance
1212305544bSClément Léger  *
1222305544bSClément Léger  * @clk: Clock to be enabled
1232305544bSClément Léger  * Return a TEE_Result compliant value
1242305544bSClément Léger  */
1252305544bSClément Léger TEE_Result clk_enable(struct clk *clk);
1262305544bSClément Léger 
1272305544bSClément Léger /**
1282305544bSClément Léger  * clk_disable - Disable a clock
1292305544bSClément Léger  *
1302305544bSClément Léger  * @clk: Clock to be disabled
1312305544bSClément Léger  */
1322305544bSClément Léger void clk_disable(struct clk *clk);
1332305544bSClément Léger 
1342305544bSClément Léger /**
135*6c9ed842SEtienne Carriere  * clk_is_enabled - Informative state on the clock
136*6c9ed842SEtienne Carriere  *
137*6c9ed842SEtienne Carriere  * This function is useful during specific system sequences where core
138*6c9ed842SEtienne Carriere  * executes atomically (primary core boot, some low power sequences).
139*6c9ed842SEtienne Carriere  *
140*6c9ed842SEtienne Carriere  * @clk: Clock refernece
141*6c9ed842SEtienne Carriere  */
142*6c9ed842SEtienne Carriere bool clk_is_enabled(struct clk *clk);
143*6c9ed842SEtienne Carriere 
144*6c9ed842SEtienne Carriere /**
1452305544bSClément Léger  * clk_get_parent - Get the current clock parent
1462305544bSClément Léger  *
1472305544bSClément Léger  * @clk: Clock for which the parent is needed
1482305544bSClément Léger  * Return the clock parent or NULL if there is no parent
1492305544bSClément Léger  */
1502305544bSClément Léger struct clk *clk_get_parent(struct clk *clk);
1512305544bSClément Léger 
1522305544bSClément Léger /**
1532305544bSClément Léger  * clk_get_num_parents - Get the number of parents for a clock
1542305544bSClément Léger  *
1552305544bSClément Léger  * @clk: Clock for which the number of parents is needed
1562305544bSClément Léger  * Return the number of parents
1572305544bSClément Léger  */
1582305544bSClément Léger static inline size_t clk_get_num_parents(struct clk *clk)
1592305544bSClément Léger {
1602305544bSClément Léger 	return clk->num_parents;
1612305544bSClément Léger }
1622305544bSClément Léger 
1632305544bSClément Léger /**
1642305544bSClément Léger  * Get a clock parent by its index
1652305544bSClément Léger  *
1662305544bSClément Léger  * @clk: Clock for which the parent is needed
1672305544bSClément Léger  * @pidx: Parent index for the clock
1682305544bSClément Léger  * Return the clock parent at index @pidx or NULL if out of bound
1692305544bSClément Léger  */
1702305544bSClément Léger struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx);
1712305544bSClément Léger 
1722305544bSClément Léger /**
1732305544bSClément Léger  * clk_set_parent - Set the current clock parent
1742305544bSClément Léger  *
1752305544bSClément Léger  * @clk: Clock for which the parent should be set
1762305544bSClément Léger  * @parent: Parent clock to set
1772305544bSClément Léger  * Return a TEE_Result compliant value
1782305544bSClément Léger  */
1792305544bSClément Léger TEE_Result clk_set_parent(struct clk *clk, struct clk *parent);
1802305544bSClément Léger 
1812305544bSClément Léger #endif /* __DRIVERS_CLK_H */
182