blob: 23a611c55f89effcd214f126887cbcf0fb998176 [file] [log] [blame]
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +03001/* 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>
Ghennadi Procopciuc12e7a2c2024-06-12 10:02:07 +03009#include <stdbool.h>
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +030010#include <stddef.h>
11
12#define MHZ UL(1000000)
13#define GHZ (UL(1000) * MHZ)
14
15enum s32cc_clkm_type {
16 s32cc_osc_t,
17 s32cc_clk_t,
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030018 s32cc_pll_t,
19 s32cc_pll_out_div_t,
20 s32cc_clkmux_t,
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +030021};
22
23enum s32cc_clk_source {
24 S32CC_FIRC,
25 S32CC_FXOSC,
26 S32CC_SIRC,
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030027 S32CC_ARM_PLL,
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +030028};
29
30struct s32cc_clk_obj {
31 enum s32cc_clkm_type type;
32 uint32_t refcount;
33};
34
35struct s32cc_osc {
36 struct s32cc_clk_obj desc;
37 enum s32cc_clk_source source;
38 unsigned long freq;
39 void *base;
40};
41
42#define S32CC_OSC_INIT(SOURCE) \
43{ \
44 .desc = { \
45 .type = s32cc_osc_t, \
46 }, \
47 .source = (SOURCE), \
48}
49
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030050struct s32cc_clkmux {
51 struct s32cc_clk_obj desc;
52 enum s32cc_clk_source module;
53 uint8_t index; /* Mux index in parent module */
54 unsigned long source_id; /* Selected source */
55 uint8_t nclks; /* Number of input clocks */
56 unsigned long clkids[5]; /* IDs of the input clocks */
57};
58
59#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
60{ \
61 .desc = { \
62 .type = (TYPE), \
63 }, \
64 .module = (MODULE), \
65 .index = (INDEX), \
66 .nclks = (NCLKS), \
67 .clkids = {__VA_ARGS__}, \
68}
69
70#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
71 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \
72 INDEX, NCLKS, __VA_ARGS__)
73
74struct s32cc_pll {
75 struct s32cc_clk_obj desc;
76 struct s32cc_clk_obj *source;
77 enum s32cc_clk_source instance;
78 unsigned long vco_freq;
79 uint32_t ndividers;
80 uintptr_t base;
81};
82
83#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
84{ \
85 .desc = { \
86 .type = s32cc_pll_t, \
87 }, \
88 .source = &(PLL_MUX_CLK).desc, \
89 .instance = (INSTANCE), \
90 .ndividers = (NDIVIDERS), \
91}
92
93struct s32cc_pll_out_div {
94 struct s32cc_clk_obj desc;
95 struct s32cc_clk_obj *parent;
96 uint32_t index;
97 unsigned long freq;
98};
99
100#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
101{ \
102 .desc = { \
103 .type = s32cc_pll_out_div_t, \
104 }, \
105 .parent = &(PARENT).desc, \
106 .index = (INDEX), \
107}
108
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300109struct s32cc_clk {
110 struct s32cc_clk_obj desc;
111 struct s32cc_clk_obj *module;
112 struct s32cc_clk *pclock;
113 unsigned long min_freq;
114 unsigned long max_freq;
115};
116
117struct s32cc_clk_array {
118 unsigned long type_mask;
119 struct s32cc_clk **clks;
120 size_t n_clks;
121};
122
123#define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
124{ \
125 .desc = { \
126 .type = s32cc_clk_t, \
127 }, \
128 .module = &(PARENT_MODULE).desc, \
129 .min_freq = (MIN_F), \
130 .max_freq = (MAX_F), \
131}
132
133#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
134 S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
135
136#define S32CC_MODULE_CLK(PARENT_MODULE) \
137 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
138
Ghennadi Procopciucd9373512024-06-12 08:09:19 +0300139static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
140{
141 uintptr_t osc_addr;
142
143 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
144 return (struct s32cc_osc *)osc_addr;
145}
146
147static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
148{
149 uintptr_t clk_addr;
150
151 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
152 return (struct s32cc_clk *)clk_addr;
153}
154
Ghennadi Procopciuc12e7a2c2024-06-12 10:02:07 +0300155static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
156{
157 const struct s32cc_clk_obj *module;
158
159 module = clk->module;
160 if (module == NULL) {
161 return false;
162 }
163
164 return (module->type == s32cc_clkmux_t);
165}
166
167static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
168{
169 uintptr_t cmux_addr;
170
171 cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
172 return (struct s32cc_clkmux *)cmux_addr;
173}
174
175static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
176{
177 if (!is_s32cc_clk_mux(clk)) {
178 return NULL;
179 }
180
181 return s32cc_obj2clkmux(clk->module);
182}
183
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300184#endif /* S32CC_CLK_MODULES_H */