1*2305544bSClément Léger /* SPDX-License-Identifier: BSD-2-Clause */ 2*2305544bSClément Léger /* 3*2305544bSClément Léger * Copyright (c) 2021, Bootlin 4*2305544bSClément Léger */ 5*2305544bSClément Léger 6*2305544bSClément Léger #ifndef __DRIVERS_CLK_H 7*2305544bSClément Léger #define __DRIVERS_CLK_H 8*2305544bSClément Léger 9*2305544bSClément Léger #include <kernel/refcount.h> 10*2305544bSClément Léger #include <stdint.h> 11*2305544bSClément Léger #include <tee_api_types.h> 12*2305544bSClément Léger 13*2305544bSClément Léger /* Flags for clock */ 14*2305544bSClément Léger #define CLK_SET_RATE_GATE BIT(0) /* must be gated across rate change */ 15*2305544bSClément Léger #define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */ 16*2305544bSClément Léger 17*2305544bSClément Léger /** 18*2305544bSClément Léger * struct clk - Clock structure 19*2305544bSClément Léger * 20*2305544bSClément Léger * @name: Clock name 21*2305544bSClément Léger * @priv: Private data for the clock provider 22*2305544bSClément Léger * @ops: Clock operations 23*2305544bSClément Léger * @parent: Current parent 24*2305544bSClément Léger * @rate: Current clock rate (cached after init or rate change) 25*2305544bSClément Léger * @flags: Specific clock flags 26*2305544bSClément Léger * @enabled_count: Enable/disable reference counter 27*2305544bSClément Léger * @num_parents: Number of parents 28*2305544bSClément Léger * @parents: Array of possible parents of the clock 29*2305544bSClément Léger */ 30*2305544bSClément Léger struct clk { 31*2305544bSClément Léger const char *name; 32*2305544bSClément Léger void *priv; 33*2305544bSClément Léger const struct clk_ops *ops; 34*2305544bSClément Léger struct clk *parent; 35*2305544bSClément Léger unsigned long rate; 36*2305544bSClément Léger unsigned int flags; 37*2305544bSClément Léger struct refcount enabled_count; 38*2305544bSClément Léger size_t num_parents; 39*2305544bSClément Léger struct clk *parents[]; 40*2305544bSClément Léger }; 41*2305544bSClément Léger 42*2305544bSClément Léger /** 43*2305544bSClément Léger * struct clk_ops 44*2305544bSClément Léger * 45*2305544bSClément Léger * @enable: Enable the clock 46*2305544bSClément Léger * @disable: Disable the clock 47*2305544bSClément Léger * @set_parent: Set the clock parent based on index 48*2305544bSClément Léger * @get_parent: Get the current parent index of the clock 49*2305544bSClément Léger * @set_rate: Set the clock rate 50*2305544bSClément Léger * @get_rate: Get the clock rate 51*2305544bSClément Léger */ 52*2305544bSClément Léger struct clk_ops { 53*2305544bSClément Léger TEE_Result (*enable)(struct clk *clk); 54*2305544bSClément Léger void (*disable)(struct clk *clk); 55*2305544bSClément Léger TEE_Result (*set_parent)(struct clk *clk, size_t index); 56*2305544bSClément Léger size_t (*get_parent)(struct clk *clk); 57*2305544bSClément Léger TEE_Result (*set_rate)(struct clk *clk, unsigned long rate, 58*2305544bSClément Léger unsigned long parent_rate); 59*2305544bSClément Léger unsigned long (*get_rate)(struct clk *clk, 60*2305544bSClément Léger unsigned long parent_rate); 61*2305544bSClément Léger }; 62*2305544bSClément Léger 63*2305544bSClément Léger /** 64*2305544bSClément Léger * Return the clock name 65*2305544bSClément Léger * 66*2305544bSClément Léger * @clk: Clock for which the name is needed 67*2305544bSClément Léger * Return a const char * pointing to the clock name 68*2305544bSClément Léger */ 69*2305544bSClément Léger static inline const char *clk_get_name(struct clk *clk) 70*2305544bSClément Léger { 71*2305544bSClément Léger return clk->name; 72*2305544bSClément Léger } 73*2305544bSClément Léger 74*2305544bSClément Léger /** 75*2305544bSClément Léger * clk_alloc - Allocate a clock structure 76*2305544bSClément Léger * 77*2305544bSClément Léger * @name: Clock name 78*2305544bSClément Léger * @ops: Clock operations 79*2305544bSClément Léger * @parent_clks: Parents of the clock 80*2305544bSClément Léger * @parent_count: Number of parents of the clock 81*2305544bSClément Léger * 82*2305544bSClément Léger * Return a clock struct properly initialized or NULL if allocation failed 83*2305544bSClément Léger */ 84*2305544bSClément Léger struct clk *clk_alloc(const char *name, const struct clk_ops *ops, 85*2305544bSClément Léger struct clk **parent_clks, size_t parent_count); 86*2305544bSClément Léger 87*2305544bSClément Léger /** 88*2305544bSClément Léger * clk_free - Free a clock structure 89*2305544bSClément Léger * 90*2305544bSClément Léger * @clk: Clock to be freed or NULL 91*2305544bSClément Léger */ 92*2305544bSClément Léger void clk_free(struct clk *clk); 93*2305544bSClément Léger 94*2305544bSClément Léger /** 95*2305544bSClément Léger * clk_register - Register a clock within the clock framework 96*2305544bSClément Léger * 97*2305544bSClément Léger * @clk: Clock struct to be registered 98*2305544bSClément Léger * Return a TEE_Result compliant value 99*2305544bSClément Léger */ 100*2305544bSClément Léger TEE_Result clk_register(struct clk *clk); 101*2305544bSClément Léger 102*2305544bSClément Léger /** 103*2305544bSClément Léger * clk_get_rate - Get clock rate 104*2305544bSClément Léger * 105*2305544bSClément Léger * @clk: Clock for which the rate is needed 106*2305544bSClément Léger * Return the clock rate in Hz 107*2305544bSClément Léger */ 108*2305544bSClément Léger unsigned long clk_get_rate(struct clk *clk); 109*2305544bSClément Léger 110*2305544bSClément Léger /** 111*2305544bSClément Léger * clk_set_rate - Set a clock rate 112*2305544bSClément Léger * 113*2305544bSClément Léger * @clk: Clock to be set with the rate 114*2305544bSClément Léger * @rate: Rate to set in Hz 115*2305544bSClément Léger * Return a TEE_Result compliant value 116*2305544bSClément Léger */ 117*2305544bSClément Léger TEE_Result clk_set_rate(struct clk *clk, unsigned long rate); 118*2305544bSClément Léger 119*2305544bSClément Léger /** 120*2305544bSClément Léger * clk_enable - Enable a clock and its ascendance 121*2305544bSClément Léger * 122*2305544bSClément Léger * @clk: Clock to be enabled 123*2305544bSClément Léger * Return a TEE_Result compliant value 124*2305544bSClément Léger */ 125*2305544bSClément Léger TEE_Result clk_enable(struct clk *clk); 126*2305544bSClément Léger 127*2305544bSClément Léger /** 128*2305544bSClément Léger * clk_disable - Disable a clock 129*2305544bSClément Léger * 130*2305544bSClément Léger * @clk: Clock to be disabled 131*2305544bSClément Léger */ 132*2305544bSClément Léger void clk_disable(struct clk *clk); 133*2305544bSClément Léger 134*2305544bSClément Léger /** 135*2305544bSClément Léger * clk_get_parent - Get the current clock parent 136*2305544bSClément Léger * 137*2305544bSClément Léger * @clk: Clock for which the parent is needed 138*2305544bSClément Léger * Return the clock parent or NULL if there is no parent 139*2305544bSClément Léger */ 140*2305544bSClément Léger struct clk *clk_get_parent(struct clk *clk); 141*2305544bSClément Léger 142*2305544bSClément Léger /** 143*2305544bSClément Léger * clk_get_num_parents - Get the number of parents for a clock 144*2305544bSClément Léger * 145*2305544bSClément Léger * @clk: Clock for which the number of parents is needed 146*2305544bSClément Léger * Return the number of parents 147*2305544bSClément Léger */ 148*2305544bSClément Léger static inline size_t clk_get_num_parents(struct clk *clk) 149*2305544bSClément Léger { 150*2305544bSClément Léger return clk->num_parents; 151*2305544bSClément Léger } 152*2305544bSClément Léger 153*2305544bSClément Léger /** 154*2305544bSClément Léger * Get a clock parent by its index 155*2305544bSClément Léger * 156*2305544bSClément Léger * @clk: Clock for which the parent is needed 157*2305544bSClément Léger * @pidx: Parent index for the clock 158*2305544bSClément Léger * Return the clock parent at index @pidx or NULL if out of bound 159*2305544bSClément Léger */ 160*2305544bSClément Léger struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx); 161*2305544bSClément Léger 162*2305544bSClément Léger /** 163*2305544bSClément Léger * clk_set_parent - Set the current clock parent 164*2305544bSClément Léger * 165*2305544bSClément Léger * @clk: Clock for which the parent should be set 166*2305544bSClément Léger * @parent: Parent clock to set 167*2305544bSClément Léger * Return a TEE_Result compliant value 168*2305544bSClément Léger */ 169*2305544bSClément Léger TEE_Result clk_set_parent(struct clk *clk, struct clk *parent); 170*2305544bSClément Léger 171*2305544bSClément Léger #endif /* __DRIVERS_CLK_H */ 172