xref: /optee_os/core/include/drivers/clk_dt.h (revision c282ebd61200b0cb0830399c1c33514dbd129dfd)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2021, Bootlin
4  */
5 
6 #ifndef __DRIVERS_CLK_DT_H
7 #define __DRIVERS_CLK_DT_H
8 
9 #include <kernel/dt.h>
10 #include <stdint.h>
11 #include <sys/queue.h>
12 
13 /**
14  * struct clk_dt_phandle_args - Devicetree clock args
15  * @nodeoffset: Clock consumer node offset
16  * @args_count: Count of items in @args
17  * @args: Clocks consumer specifiers
18  */
19 struct clk_dt_phandle_args {
20 	int nodeoffset;
21 	int args_count;
22 	uint32_t *args;
23 };
24 
25 /**
26  * struct clk_driver - Clock driver setup struct
27  * probe: probe function for the clock driver
28  */
29 struct clk_driver {
30 	TEE_Result (*probe)(const void *fdt, int nodeoffset, const void *data);
31 };
32 
33 /**
34  * CLK_DT_DECLARE - Declare a clock driver
35  * @__name: Clock driver name
36  * @__compat: Compatible string
37  * @__probe: Clock probe function
38  */
39 #define CLK_DT_DECLARE(__name, __compat, __probe) \
40 	static const struct clk_driver __name ## _driver = { \
41 		.probe = __probe, \
42 	}; \
43 	static const struct dt_device_match __name ## _match_table[] = { \
44 		{ .compatible = __compat }, \
45 		{ } \
46 	}; \
47 	const struct dt_driver __name ## _dt_driver __dt_driver = { \
48 		.name = # __name, \
49 		.type = DT_DRIVER_CLK, \
50 		.match_table = __name ## _match_table, \
51 		.driver = &__name ## _driver, \
52 	}
53 
54 /**
55  * clk_dt_get_by_idx - Get a clock at a specific index in "clocks" property
56  *
57  * @fdt: Device tree to work on
58  * @nodeoffset: Node offset of the subnode containing a clock property
59  * @clk_idx: Clock index to get
60  * Returns a clk struct pointer matching the clock at index clk_idx in clocks
61  * property or NULL if no clock match the given index.
62  */
63 struct clk *clk_dt_get_by_idx(const void *fdt, int nodeoffset,
64 			      unsigned int clk_idx);
65 
66 /**
67  * clk_dt_get_by_name - Get a clock matching a name in the "clock-names"
68  * property
69  *
70  * @fdt: Device tree to work on
71  * @nodeoffset: Node offset of the subnode containing a clock property
72  * @name: Clock name to get
73  * Returns a clk struct pointer matching the name in "clock-names" property or
74  * NULL if no clock match the given name.
75  */
76 struct clk *clk_dt_get_by_name(const void *fdt, int nodeoffset,
77 			       const char *name);
78 
79 /**
80  * clk_dt_get_func - Typedef of function to get clock from devicetree properties
81  *
82  * @args: Pointer to devicetree description of the clock to parse
83  * @data: Pointer to data given at clk_dt_register_clk_provider() call
84  *
85  * Returns a clk struct pointer pointing to a clock matching the devicetree
86  * description or NULL if invalid description.
87  */
88 typedef struct clk *(*clk_dt_get_func)(struct clk_dt_phandle_args *args,
89 				       void *data);
90 
91 /**
92  * clk_dt_register_clk_provider - Register a clock provider
93  *
94  * @fdt: Device tree to work on
95  * @nodeoffset: Node offset of the clock
96  * @get_dt_clk: Callback to match the devicetree clock with a clock struct
97  * @data: Data which will be passed to the get_dt_clk callback
98  * Returns TEE_Result value
99  */
100 TEE_Result clk_dt_register_clk_provider(const void *fdt, int nodeoffset,
101 					clk_dt_get_func get_dt_clk, void *data);
102 
103 /**
104  * clk_dt_get_simple_clk: simple clock matching function for single clock
105  * providers
106  */
107 static inline
108 struct clk *clk_dt_get_simple_clk(struct clk_dt_phandle_args *args __unused,
109 				  void *data)
110 {
111 	return data;
112 }
113 
114 #endif /* __DRIVERS_CLK_DT_H */
115