xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision a8be748a2821355734f603342b2d2cf7105f6a30)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3  * Copyright 2020-2024 NXP
4  */
5 #ifndef S32CC_CLK_MODULES_H
6 #define S32CC_CLK_MODULES_H
7 
8 #include <inttypes.h>
9 #include <stddef.h>
10 
11 #define MHZ	UL(1000000)
12 #define GHZ	(UL(1000) * MHZ)
13 
14 enum s32cc_clkm_type {
15 	s32cc_osc_t,
16 	s32cc_clk_t,
17 	s32cc_pll_t,
18 	s32cc_pll_out_div_t,
19 	s32cc_clkmux_t,
20 };
21 
22 enum s32cc_clk_source {
23 	S32CC_FIRC,
24 	S32CC_FXOSC,
25 	S32CC_SIRC,
26 	S32CC_ARM_PLL,
27 };
28 
29 struct s32cc_clk_obj {
30 	enum s32cc_clkm_type type;
31 	uint32_t refcount;
32 };
33 
34 struct s32cc_osc {
35 	struct s32cc_clk_obj desc;
36 	enum s32cc_clk_source source;
37 	unsigned long freq;
38 	void *base;
39 };
40 
41 #define S32CC_OSC_INIT(SOURCE)       \
42 {                                    \
43 	.desc = {                    \
44 		.type = s32cc_osc_t, \
45 	},                           \
46 	.source = (SOURCE),          \
47 }
48 
49 struct s32cc_clkmux {
50 	struct s32cc_clk_obj desc;
51 	enum s32cc_clk_source module;
52 	uint8_t index; /* Mux index in parent module */
53 	unsigned long source_id; /* Selected source */
54 	uint8_t nclks; /* Number of input clocks */
55 	unsigned long clkids[5]; /* IDs of the input clocks */
56 };
57 
58 #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
59 {                                                               \
60 	.desc = {                                               \
61 		.type = (TYPE),                                 \
62 	},                                                      \
63 	.module = (MODULE),                                     \
64 	.index = (INDEX),                                       \
65 	.nclks = (NCLKS),                                       \
66 	.clkids = {__VA_ARGS__},                                \
67 }
68 
69 #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)     \
70 	S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE,   \
71 			       INDEX, NCLKS, __VA_ARGS__)
72 
73 struct s32cc_pll {
74 	struct s32cc_clk_obj desc;
75 	struct s32cc_clk_obj *source;
76 	enum s32cc_clk_source instance;
77 	unsigned long vco_freq;
78 	uint32_t ndividers;
79 	uintptr_t base;
80 };
81 
82 #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
83 {                                                        \
84 	.desc = {                                        \
85 		.type = s32cc_pll_t,                     \
86 	},                                               \
87 	.source = &(PLL_MUX_CLK).desc,                   \
88 	.instance = (INSTANCE),                          \
89 	.ndividers = (NDIVIDERS),                        \
90 }
91 
92 struct s32cc_pll_out_div {
93 	struct s32cc_clk_obj desc;
94 	struct s32cc_clk_obj *parent;
95 	uint32_t index;
96 	unsigned long freq;
97 };
98 
99 #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
100 {                                              \
101 	.desc = {                              \
102 		.type = s32cc_pll_out_div_t,   \
103 	},                                     \
104 	.parent = &(PARENT).desc,              \
105 	.index = (INDEX),                      \
106 }
107 
108 struct s32cc_clk {
109 	struct s32cc_clk_obj desc;
110 	struct s32cc_clk_obj *module;
111 	struct s32cc_clk *pclock;
112 	unsigned long min_freq;
113 	unsigned long max_freq;
114 };
115 
116 struct s32cc_clk_array {
117 	unsigned long type_mask;
118 	struct s32cc_clk **clks;
119 	size_t n_clks;
120 };
121 
122 #define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
123 {                                                      \
124 	.desc = {                                      \
125 		.type = s32cc_clk_t,                   \
126 	},                                             \
127 	.module = &(PARENT_MODULE).desc,               \
128 	.min_freq = (MIN_F),                           \
129 	.max_freq = (MAX_F),                           \
130 }
131 
132 #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
133 	S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
134 
135 #define S32CC_MODULE_CLK(PARENT_MODULE) \
136 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
137 
138 static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
139 {
140 	uintptr_t osc_addr;
141 
142 	osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
143 	return (struct s32cc_osc *)osc_addr;
144 }
145 
146 static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
147 {
148 	uintptr_t clk_addr;
149 
150 	clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
151 	return (struct s32cc_clk *)clk_addr;
152 }
153 
154 #endif /* S32CC_CLK_MODULES_H */
155