blob: 1fe271962cf16e6f94a16b97fd4dd5ae0e98e44c [file] [log] [blame]
Ghennadi Procopciucecc98d22024-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 Procopciucaa45fa92024-06-12 10:02:07 +03009#include <stdbool.h>
Ghennadi Procopciucecc98d22024-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 Procopciuc7277b972024-06-12 09:53:18 +030018 s32cc_pll_t,
19 s32cc_pll_out_div_t,
20 s32cc_clkmux_t,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030021 s32cc_shared_clkmux_t,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030022};
23
24enum s32cc_clk_source {
25 S32CC_FIRC,
26 S32CC_FXOSC,
27 S32CC_SIRC,
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030028 S32CC_ARM_PLL,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030029 S32CC_CGM1,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030030};
31
32struct s32cc_clk_obj {
33 enum s32cc_clkm_type type;
34 uint32_t refcount;
35};
36
37struct s32cc_osc {
38 struct s32cc_clk_obj desc;
39 enum s32cc_clk_source source;
40 unsigned long freq;
41 void *base;
42};
43
44#define S32CC_OSC_INIT(SOURCE) \
45{ \
46 .desc = { \
47 .type = s32cc_osc_t, \
48 }, \
49 .source = (SOURCE), \
50}
51
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030052struct s32cc_clkmux {
53 struct s32cc_clk_obj desc;
54 enum s32cc_clk_source module;
55 uint8_t index; /* Mux index in parent module */
56 unsigned long source_id; /* Selected source */
57 uint8_t nclks; /* Number of input clocks */
58 unsigned long clkids[5]; /* IDs of the input clocks */
59};
60
61#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
62{ \
63 .desc = { \
64 .type = (TYPE), \
65 }, \
66 .module = (MODULE), \
67 .index = (INDEX), \
68 .nclks = (NCLKS), \
69 .clkids = {__VA_ARGS__}, \
70}
71
72#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
73 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \
74 INDEX, NCLKS, __VA_ARGS__)
75
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030076#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
77 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
78 INDEX, NCLKS, __VA_ARGS__)
79
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030080struct s32cc_pll {
81 struct s32cc_clk_obj desc;
82 struct s32cc_clk_obj *source;
83 enum s32cc_clk_source instance;
84 unsigned long vco_freq;
85 uint32_t ndividers;
86 uintptr_t base;
87};
88
89#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
90{ \
91 .desc = { \
92 .type = s32cc_pll_t, \
93 }, \
94 .source = &(PLL_MUX_CLK).desc, \
95 .instance = (INSTANCE), \
96 .ndividers = (NDIVIDERS), \
97}
98
99struct s32cc_pll_out_div {
100 struct s32cc_clk_obj desc;
101 struct s32cc_clk_obj *parent;
102 uint32_t index;
103 unsigned long freq;
104};
105
106#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
107{ \
108 .desc = { \
109 .type = s32cc_pll_out_div_t, \
110 }, \
111 .parent = &(PARENT).desc, \
112 .index = (INDEX), \
113}
114
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300115struct s32cc_clk {
116 struct s32cc_clk_obj desc;
117 struct s32cc_clk_obj *module;
118 struct s32cc_clk *pclock;
119 unsigned long min_freq;
120 unsigned long max_freq;
121};
122
123struct s32cc_clk_array {
124 unsigned long type_mask;
125 struct s32cc_clk **clks;
126 size_t n_clks;
127};
128
129#define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
130{ \
131 .desc = { \
132 .type = s32cc_clk_t, \
133 }, \
134 .module = &(PARENT_MODULE).desc, \
135 .min_freq = (MIN_F), \
136 .max_freq = (MAX_F), \
137}
138
139#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
140 S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
141
142#define S32CC_MODULE_CLK(PARENT_MODULE) \
143 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
144
Ghennadi Procopciuc0d525772024-06-12 08:09:19 +0300145static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
146{
147 uintptr_t osc_addr;
148
149 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
150 return (struct s32cc_osc *)osc_addr;
151}
152
153static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
154{
155 uintptr_t clk_addr;
156
157 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
158 return (struct s32cc_clk *)clk_addr;
159}
160
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300161static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
162{
163 const struct s32cc_clk_obj *module;
164
165 module = clk->module;
166 if (module == NULL) {
167 return false;
168 }
169
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +0300170 return (module->type == s32cc_clkmux_t) ||
171 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300172}
173
174static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
175{
176 uintptr_t cmux_addr;
177
178 cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
179 return (struct s32cc_clkmux *)cmux_addr;
180}
181
182static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
183{
184 if (!is_s32cc_clk_mux(clk)) {
185 return NULL;
186 }
187
188 return s32cc_obj2clkmux(clk->module);
189}
190
Ghennadi Procopciuce18cf332024-06-12 11:55:32 +0300191static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
192{
193 uintptr_t pll_addr;
194
195 pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
196 return (struct s32cc_pll *)pll_addr;
197}
198
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300199#endif /* S32CC_CLK_MODULES_H */