1f26c8a8eSSimon Glass /* 2f26c8a8eSSimon Glass * Copyright (c) 2015 Google, Inc 3f26c8a8eSSimon Glass * Written by Simon Glass <sjg@chromium.org> 4135aa950SStephen Warren * Copyright (c) 2016, NVIDIA CORPORATION. 5f26c8a8eSSimon Glass * 6f26c8a8eSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 7f26c8a8eSSimon Glass */ 8f26c8a8eSSimon Glass 908d0d6f3SMichal Simek #ifndef _CLK_H_ 1008d0d6f3SMichal Simek #define _CLK_H_ 1108d0d6f3SMichal Simek 121221ce45SMasahiro Yamada #include <linux/errno.h> 13ad1cf785SMasahiro Yamada #include <linux/types.h> 14ad1cf785SMasahiro Yamada 15135aa950SStephen Warren /** 16135aa950SStephen Warren * A clock is a hardware signal that oscillates autonomously at a specific 17135aa950SStephen Warren * frequency and duty cycle. Most hardware modules require one or more clock 18135aa950SStephen Warren * signal to drive their operation. Clock signals are typically generated 19135aa950SStephen Warren * externally to the HW module consuming them, by an entity this API calls a 20135aa950SStephen Warren * clock provider. This API provides a standard means for drivers to enable and 21135aa950SStephen Warren * disable clocks, and to set the rate at which they oscillate. 22135aa950SStephen Warren * 23135aa950SStephen Warren * A driver that implements UCLASS_CLOCK is a clock provider. A provider will 24135aa950SStephen Warren * often implement multiple separate clocks, since the hardware it manages 25135aa950SStephen Warren * often has this capability. clock_uclass.h describes the interface which 26135aa950SStephen Warren * clock providers must implement. 27135aa950SStephen Warren * 28135aa950SStephen Warren * Clock consumers/clients are the HW modules driven by the clock signals. This 29135aa950SStephen Warren * header file describes the API used by drivers for those HW modules. 30135aa950SStephen Warren */ 31135aa950SStephen Warren 32ad1cf785SMasahiro Yamada struct udevice; 33ad1cf785SMasahiro Yamada 34f26c8a8eSSimon Glass /** 35135aa950SStephen Warren * struct clk - A handle to (allowing control of) a single clock. 36f26c8a8eSSimon Glass * 37135aa950SStephen Warren * Clients provide storage for clock handles. The content of the structure is 38135aa950SStephen Warren * managed solely by the clock API and clock drivers. A clock struct is 39135aa950SStephen Warren * initialized by "get"ing the clock struct. The clock struct is passed to all 40135aa950SStephen Warren * other clock APIs to identify which clock signal to operate upon. 41f26c8a8eSSimon Glass * 42135aa950SStephen Warren * @dev: The device which implements the clock signal. 43135aa950SStephen Warren * @id: The clock signal ID within the provider. 44f0e07516SMasahiro Yamada * 45135aa950SStephen Warren * Currently, the clock API assumes that a single integer ID is enough to 46135aa950SStephen Warren * identify and configure any clock signal for any clock provider. If this 47135aa950SStephen Warren * assumption becomes invalid in the future, the struct could be expanded to 48135aa950SStephen Warren * either (a) add more fields to allow clock providers to store additional 49135aa950SStephen Warren * information, or (b) replace the id field with an opaque pointer, which the 50135aa950SStephen Warren * provider would dynamically allocated during its .of_xlate op, and process 51135aa950SStephen Warren * during is .request op. This may require the addition of an extra op to clean 52135aa950SStephen Warren * up the allocation. 53f0e07516SMasahiro Yamada */ 54135aa950SStephen Warren struct clk { 55135aa950SStephen Warren struct udevice *dev; 56135aa950SStephen Warren /* 57135aa950SStephen Warren * Written by of_xlate. We assume a single id is enough for now. In the 58135aa950SStephen Warren * future, we might add more fields here. 59f26c8a8eSSimon Glass */ 60135aa950SStephen Warren unsigned long id; 61f26c8a8eSSimon Glass }; 62f26c8a8eSSimon Glass 633f96f875SPaul Burton #if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK) 643a40acd4SSimon Glass struct phandle_1_arg; 657423daa6SSimon Glass int clk_get_by_index_platdata(struct udevice *dev, int index, 663a40acd4SSimon Glass struct phandle_1_arg *cells, struct clk *clk); 677423daa6SSimon Glass 68e70cc438SSimon Glass /** 69135aa950SStephen Warren * clock_get_by_index - Get/request a clock by integer index. 70e70cc438SSimon Glass * 71135aa950SStephen Warren * This looks up and requests a clock. The index is relative to the client 72135aa950SStephen Warren * device; each device is assumed to have n clocks associated with it somehow, 73135aa950SStephen Warren * and this function finds and requests one of them. The mapping of client 74135aa950SStephen Warren * device clock indices to provider clocks may be via device-tree properties, 75135aa950SStephen Warren * board-provided mapping tables, or some other mechanism. 76e70cc438SSimon Glass * 77135aa950SStephen Warren * @dev: The client device. 78135aa950SStephen Warren * @index: The index of the clock to request, within the client's list of 79135aa950SStephen Warren * clocks. 80135aa950SStephen Warren * @clock A pointer to a clock struct to initialize. 81135aa950SStephen Warren * @return 0 if OK, or a negative error code. 82e70cc438SSimon Glass */ 83135aa950SStephen Warren int clk_get_by_index(struct udevice *dev, int index, struct clk *clk); 84135aa950SStephen Warren 85135aa950SStephen Warren /** 86135aa950SStephen Warren * clock_get_by_name - Get/request a clock by name. 87135aa950SStephen Warren * 88135aa950SStephen Warren * This looks up and requests a clock. The name is relative to the client 89135aa950SStephen Warren * device; each device is assumed to have n clocks associated with it somehow, 90135aa950SStephen Warren * and this function finds and requests one of them. The mapping of client 91135aa950SStephen Warren * device clock names to provider clocks may be via device-tree properties, 92135aa950SStephen Warren * board-provided mapping tables, or some other mechanism. 93135aa950SStephen Warren * 94135aa950SStephen Warren * @dev: The client device. 95135aa950SStephen Warren * @name: The name of the clock to request, within the client's list of 96135aa950SStephen Warren * clocks. 97135aa950SStephen Warren * @clock: A pointer to a clock struct to initialize. 98135aa950SStephen Warren * @return 0 if OK, or a negative error code. 99135aa950SStephen Warren */ 100135aa950SStephen Warren int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk); 101b108d8a0SPatrice Chotard 102b108d8a0SPatrice Chotard /** 103b108d8a0SPatrice Chotard * clk_release_all() - Disable (turn off)/Free an array of previously 104b108d8a0SPatrice Chotard * requested clocks. 105b108d8a0SPatrice Chotard * 106b108d8a0SPatrice Chotard * For each clock contained in the clock array, this function will check if 107b108d8a0SPatrice Chotard * clock has been previously requested and then will disable and free it. 108b108d8a0SPatrice Chotard * 109b108d8a0SPatrice Chotard * @clk: A clock struct array that was previously successfully 110b108d8a0SPatrice Chotard * requested by clk_request/get_by_*(). 111b108d8a0SPatrice Chotard * @count Number of clock contained in the array 112b108d8a0SPatrice Chotard * @return zero on success, or -ve error code. 113b108d8a0SPatrice Chotard */ 114b108d8a0SPatrice Chotard int clk_release_all(struct clk *clk, int count); 115b108d8a0SPatrice Chotard 116021abf69SMasahiro Yamada #else 117021abf69SMasahiro Yamada static inline int clk_get_by_index(struct udevice *dev, int index, 118021abf69SMasahiro Yamada struct clk *clk) 119021abf69SMasahiro Yamada { 120021abf69SMasahiro Yamada return -ENOSYS; 121021abf69SMasahiro Yamada } 122021abf69SMasahiro Yamada 123021abf69SMasahiro Yamada static inline int clk_get_by_name(struct udevice *dev, const char *name, 124021abf69SMasahiro Yamada struct clk *clk) 125021abf69SMasahiro Yamada { 126021abf69SMasahiro Yamada return -ENOSYS; 127021abf69SMasahiro Yamada } 128b108d8a0SPatrice Chotard 129b108d8a0SPatrice Chotard static inline int clk_release_all(struct clk *clk, int count) 130b108d8a0SPatrice Chotard { 131b108d8a0SPatrice Chotard return -ENOSYS; 132b108d8a0SPatrice Chotard } 133b108d8a0SPatrice Chotard 134021abf69SMasahiro Yamada #endif 135e70cc438SSimon Glass 136135aa950SStephen Warren /** 137135aa950SStephen Warren * clk_request - Request a clock by provider-specific ID. 138135aa950SStephen Warren * 139135aa950SStephen Warren * This requests a clock using a provider-specific ID. Generally, this function 140135aa950SStephen Warren * should not be used, since clk_get_by_index/name() provide an interface that 141135aa950SStephen Warren * better separates clients from intimate knowledge of clock providers. 142135aa950SStephen Warren * However, this function may be useful in core SoC-specific code. 143135aa950SStephen Warren * 144135aa950SStephen Warren * @dev: The clock provider device. 145135aa950SStephen Warren * @clock: A pointer to a clock struct to initialize. The caller must 146135aa950SStephen Warren * have already initialized any field in this struct which the 147135aa950SStephen Warren * clock provider uses to identify the clock. 148135aa950SStephen Warren * @return 0 if OK, or a negative error code. 149135aa950SStephen Warren */ 150135aa950SStephen Warren int clk_request(struct udevice *dev, struct clk *clk); 151135aa950SStephen Warren 152135aa950SStephen Warren /** 153135aa950SStephen Warren * clock_free - Free a previously requested clock. 154135aa950SStephen Warren * 155135aa950SStephen Warren * @clock: A clock struct that was previously successfully requested by 156135aa950SStephen Warren * clk_request/get_by_*(). 157135aa950SStephen Warren * @return 0 if OK, or a negative error code. 158135aa950SStephen Warren */ 159135aa950SStephen Warren int clk_free(struct clk *clk); 160135aa950SStephen Warren 161135aa950SStephen Warren /** 162135aa950SStephen Warren * clk_get_rate() - Get current clock rate. 163135aa950SStephen Warren * 164135aa950SStephen Warren * @clk: A clock struct that was previously successfully requested by 165135aa950SStephen Warren * clk_request/get_by_*(). 166135aa950SStephen Warren * @return clock rate in Hz, or -ve error code. 167135aa950SStephen Warren */ 168135aa950SStephen Warren ulong clk_get_rate(struct clk *clk); 169135aa950SStephen Warren 170135aa950SStephen Warren /** 171135aa950SStephen Warren * clk_set_rate() - Set current clock rate. 172135aa950SStephen Warren * 173135aa950SStephen Warren * @clk: A clock struct that was previously successfully requested by 174135aa950SStephen Warren * clk_request/get_by_*(). 175135aa950SStephen Warren * @rate: New clock rate in Hz. 176135aa950SStephen Warren * @return new rate, or -ve error code. 177135aa950SStephen Warren */ 178135aa950SStephen Warren ulong clk_set_rate(struct clk *clk, ulong rate); 179135aa950SStephen Warren 180135aa950SStephen Warren /** 181724f9587SZiyuan Xu * clk_get_phase() - Get the phase shift of a clock signal. 182724f9587SZiyuan Xu * 183724f9587SZiyuan Xu * @clk: A clock struct that was previously successfully requested by 184724f9587SZiyuan Xu * clk_request/get_by_*(). 185724f9587SZiyuan Xu * @return the phase shift of a clock node in degrees, otherwise returns 186724f9587SZiyuan Xu * -ve error code. 187724f9587SZiyuan Xu */ 188724f9587SZiyuan Xu int clk_get_phase(struct clk *clk); 189724f9587SZiyuan Xu 190724f9587SZiyuan Xu /** 191724f9587SZiyuan Xu * clk_set_rate() - Adjust the phase shift of a clock signal. 192724f9587SZiyuan Xu * 193724f9587SZiyuan Xu * @clk: A clock struct that was previously successfully requested by 194724f9587SZiyuan Xu * clk_request/get_by_*(). 195724f9587SZiyuan Xu * @degrees: Numberof degrees the signal is shifted. 196724f9587SZiyuan Xu * @return 0 on success, or -ve error code. 197724f9587SZiyuan Xu */ 198724f9587SZiyuan Xu int clk_set_phase(struct clk *clk, int degrees); 199724f9587SZiyuan Xu 200724f9587SZiyuan Xu /** 201*4686bbffSPhilipp Tomsich * clk_set_parent() - Set current clock parent. 202*4686bbffSPhilipp Tomsich * 203*4686bbffSPhilipp Tomsich * @clk: A clock struct that was previously successfully requested by 204*4686bbffSPhilipp Tomsich * clk_request/get_by_*(). 205*4686bbffSPhilipp Tomsich * @parent: A clock struct that was previously successfully requested by 206*4686bbffSPhilipp Tomsich * clk_request/get_by_*(). 207*4686bbffSPhilipp Tomsich * @return new rate, or -ve error code. 208*4686bbffSPhilipp Tomsich */ 209*4686bbffSPhilipp Tomsich int clk_set_parent(struct clk *clk, struct clk *parent); 210*4686bbffSPhilipp Tomsich 211*4686bbffSPhilipp Tomsich /** 212135aa950SStephen Warren * clk_enable() - Enable (turn on) a clock. 213135aa950SStephen Warren * 214135aa950SStephen Warren * @clk: A clock struct that was previously successfully requested by 215135aa950SStephen Warren * clk_request/get_by_*(). 216135aa950SStephen Warren * @return zero on success, or -ve error code. 217135aa950SStephen Warren */ 218135aa950SStephen Warren int clk_enable(struct clk *clk); 219135aa950SStephen Warren 220135aa950SStephen Warren /** 221135aa950SStephen Warren * clk_disable() - Disable (turn off) a clock. 222135aa950SStephen Warren * 223135aa950SStephen Warren * @clk: A clock struct that was previously successfully requested by 224135aa950SStephen Warren * clk_request/get_by_*(). 225135aa950SStephen Warren * @return zero on success, or -ve error code. 226135aa950SStephen Warren */ 227135aa950SStephen Warren int clk_disable(struct clk *clk); 228135aa950SStephen Warren 229135aa950SStephen Warren int soc_clk_dump(void); 230135aa950SStephen Warren 231135aa950SStephen Warren #endif 232