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