17c36209bSGhennadi Procopciuc /* SPDX-License-Identifier: BSD-3-Clause */ 27c36209bSGhennadi Procopciuc /* 37c36209bSGhennadi Procopciuc * Copyright 2020-2024 NXP 47c36209bSGhennadi Procopciuc */ 57c36209bSGhennadi Procopciuc #ifndef S32CC_CLK_MODULES_H 67c36209bSGhennadi Procopciuc #define S32CC_CLK_MODULES_H 77c36209bSGhennadi Procopciuc 87c36209bSGhennadi Procopciuc #include <inttypes.h> 9*12e7a2cdSGhennadi Procopciuc #include <stdbool.h> 107c36209bSGhennadi Procopciuc #include <stddef.h> 117c36209bSGhennadi Procopciuc 127c36209bSGhennadi Procopciuc #define MHZ UL(1000000) 137c36209bSGhennadi Procopciuc #define GHZ (UL(1000) * MHZ) 147c36209bSGhennadi Procopciuc 157c36209bSGhennadi Procopciuc enum s32cc_clkm_type { 167c36209bSGhennadi Procopciuc s32cc_osc_t, 177c36209bSGhennadi Procopciuc s32cc_clk_t, 18a8be748aSGhennadi Procopciuc s32cc_pll_t, 19a8be748aSGhennadi Procopciuc s32cc_pll_out_div_t, 20a8be748aSGhennadi Procopciuc s32cc_clkmux_t, 217c36209bSGhennadi Procopciuc }; 227c36209bSGhennadi Procopciuc 237c36209bSGhennadi Procopciuc enum s32cc_clk_source { 247c36209bSGhennadi Procopciuc S32CC_FIRC, 257c36209bSGhennadi Procopciuc S32CC_FXOSC, 267c36209bSGhennadi Procopciuc S32CC_SIRC, 27a8be748aSGhennadi Procopciuc S32CC_ARM_PLL, 287c36209bSGhennadi Procopciuc }; 297c36209bSGhennadi Procopciuc 307c36209bSGhennadi Procopciuc struct s32cc_clk_obj { 317c36209bSGhennadi Procopciuc enum s32cc_clkm_type type; 327c36209bSGhennadi Procopciuc uint32_t refcount; 337c36209bSGhennadi Procopciuc }; 347c36209bSGhennadi Procopciuc 357c36209bSGhennadi Procopciuc struct s32cc_osc { 367c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 377c36209bSGhennadi Procopciuc enum s32cc_clk_source source; 387c36209bSGhennadi Procopciuc unsigned long freq; 397c36209bSGhennadi Procopciuc void *base; 407c36209bSGhennadi Procopciuc }; 417c36209bSGhennadi Procopciuc 427c36209bSGhennadi Procopciuc #define S32CC_OSC_INIT(SOURCE) \ 437c36209bSGhennadi Procopciuc { \ 447c36209bSGhennadi Procopciuc .desc = { \ 457c36209bSGhennadi Procopciuc .type = s32cc_osc_t, \ 467c36209bSGhennadi Procopciuc }, \ 477c36209bSGhennadi Procopciuc .source = (SOURCE), \ 487c36209bSGhennadi Procopciuc } 497c36209bSGhennadi Procopciuc 50a8be748aSGhennadi Procopciuc struct s32cc_clkmux { 51a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 52a8be748aSGhennadi Procopciuc enum s32cc_clk_source module; 53a8be748aSGhennadi Procopciuc uint8_t index; /* Mux index in parent module */ 54a8be748aSGhennadi Procopciuc unsigned long source_id; /* Selected source */ 55a8be748aSGhennadi Procopciuc uint8_t nclks; /* Number of input clocks */ 56a8be748aSGhennadi Procopciuc unsigned long clkids[5]; /* IDs of the input clocks */ 57a8be748aSGhennadi Procopciuc }; 58a8be748aSGhennadi Procopciuc 59a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \ 60a8be748aSGhennadi Procopciuc { \ 61a8be748aSGhennadi Procopciuc .desc = { \ 62a8be748aSGhennadi Procopciuc .type = (TYPE), \ 63a8be748aSGhennadi Procopciuc }, \ 64a8be748aSGhennadi Procopciuc .module = (MODULE), \ 65a8be748aSGhennadi Procopciuc .index = (INDEX), \ 66a8be748aSGhennadi Procopciuc .nclks = (NCLKS), \ 67a8be748aSGhennadi Procopciuc .clkids = {__VA_ARGS__}, \ 68a8be748aSGhennadi Procopciuc } 69a8be748aSGhennadi Procopciuc 70a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 71a8be748aSGhennadi Procopciuc S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \ 72a8be748aSGhennadi Procopciuc INDEX, NCLKS, __VA_ARGS__) 73a8be748aSGhennadi Procopciuc 74a8be748aSGhennadi Procopciuc struct s32cc_pll { 75a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 76a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *source; 77a8be748aSGhennadi Procopciuc enum s32cc_clk_source instance; 78a8be748aSGhennadi Procopciuc unsigned long vco_freq; 79a8be748aSGhennadi Procopciuc uint32_t ndividers; 80a8be748aSGhennadi Procopciuc uintptr_t base; 81a8be748aSGhennadi Procopciuc }; 82a8be748aSGhennadi Procopciuc 83a8be748aSGhennadi Procopciuc #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \ 84a8be748aSGhennadi Procopciuc { \ 85a8be748aSGhennadi Procopciuc .desc = { \ 86a8be748aSGhennadi Procopciuc .type = s32cc_pll_t, \ 87a8be748aSGhennadi Procopciuc }, \ 88a8be748aSGhennadi Procopciuc .source = &(PLL_MUX_CLK).desc, \ 89a8be748aSGhennadi Procopciuc .instance = (INSTANCE), \ 90a8be748aSGhennadi Procopciuc .ndividers = (NDIVIDERS), \ 91a8be748aSGhennadi Procopciuc } 92a8be748aSGhennadi Procopciuc 93a8be748aSGhennadi Procopciuc struct s32cc_pll_out_div { 94a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 95a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *parent; 96a8be748aSGhennadi Procopciuc uint32_t index; 97a8be748aSGhennadi Procopciuc unsigned long freq; 98a8be748aSGhennadi Procopciuc }; 99a8be748aSGhennadi Procopciuc 100a8be748aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ 101a8be748aSGhennadi Procopciuc { \ 102a8be748aSGhennadi Procopciuc .desc = { \ 103a8be748aSGhennadi Procopciuc .type = s32cc_pll_out_div_t, \ 104a8be748aSGhennadi Procopciuc }, \ 105a8be748aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 106a8be748aSGhennadi Procopciuc .index = (INDEX), \ 107a8be748aSGhennadi Procopciuc } 108a8be748aSGhennadi Procopciuc 1097c36209bSGhennadi Procopciuc struct s32cc_clk { 1107c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 1117c36209bSGhennadi Procopciuc struct s32cc_clk_obj *module; 1127c36209bSGhennadi Procopciuc struct s32cc_clk *pclock; 1137c36209bSGhennadi Procopciuc unsigned long min_freq; 1147c36209bSGhennadi Procopciuc unsigned long max_freq; 1157c36209bSGhennadi Procopciuc }; 1167c36209bSGhennadi Procopciuc 1177c36209bSGhennadi Procopciuc struct s32cc_clk_array { 1187c36209bSGhennadi Procopciuc unsigned long type_mask; 1197c36209bSGhennadi Procopciuc struct s32cc_clk **clks; 1207c36209bSGhennadi Procopciuc size_t n_clks; 1217c36209bSGhennadi Procopciuc }; 1227c36209bSGhennadi Procopciuc 1237c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \ 1247c36209bSGhennadi Procopciuc { \ 1257c36209bSGhennadi Procopciuc .desc = { \ 1267c36209bSGhennadi Procopciuc .type = s32cc_clk_t, \ 1277c36209bSGhennadi Procopciuc }, \ 1287c36209bSGhennadi Procopciuc .module = &(PARENT_MODULE).desc, \ 1297c36209bSGhennadi Procopciuc .min_freq = (MIN_F), \ 1307c36209bSGhennadi Procopciuc .max_freq = (MAX_F), \ 1317c36209bSGhennadi Procopciuc } 1327c36209bSGhennadi Procopciuc 1337c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \ 1347c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) 1357c36209bSGhennadi Procopciuc 1367c36209bSGhennadi Procopciuc #define S32CC_MODULE_CLK(PARENT_MODULE) \ 1377c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0) 1387c36209bSGhennadi Procopciuc 139d9373519SGhennadi Procopciuc static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod) 140d9373519SGhennadi Procopciuc { 141d9373519SGhennadi Procopciuc uintptr_t osc_addr; 142d9373519SGhennadi Procopciuc 143d9373519SGhennadi Procopciuc osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc); 144d9373519SGhennadi Procopciuc return (struct s32cc_osc *)osc_addr; 145d9373519SGhennadi Procopciuc } 146d9373519SGhennadi Procopciuc 147d9373519SGhennadi Procopciuc static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod) 148d9373519SGhennadi Procopciuc { 149d9373519SGhennadi Procopciuc uintptr_t clk_addr; 150d9373519SGhennadi Procopciuc 151d9373519SGhennadi Procopciuc clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc); 152d9373519SGhennadi Procopciuc return (struct s32cc_clk *)clk_addr; 153d9373519SGhennadi Procopciuc } 154d9373519SGhennadi Procopciuc 155*12e7a2cdSGhennadi Procopciuc static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk) 156*12e7a2cdSGhennadi Procopciuc { 157*12e7a2cdSGhennadi Procopciuc const struct s32cc_clk_obj *module; 158*12e7a2cdSGhennadi Procopciuc 159*12e7a2cdSGhennadi Procopciuc module = clk->module; 160*12e7a2cdSGhennadi Procopciuc if (module == NULL) { 161*12e7a2cdSGhennadi Procopciuc return false; 162*12e7a2cdSGhennadi Procopciuc } 163*12e7a2cdSGhennadi Procopciuc 164*12e7a2cdSGhennadi Procopciuc return (module->type == s32cc_clkmux_t); 165*12e7a2cdSGhennadi Procopciuc } 166*12e7a2cdSGhennadi Procopciuc 167*12e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod) 168*12e7a2cdSGhennadi Procopciuc { 169*12e7a2cdSGhennadi Procopciuc uintptr_t cmux_addr; 170*12e7a2cdSGhennadi Procopciuc 171*12e7a2cdSGhennadi Procopciuc cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc); 172*12e7a2cdSGhennadi Procopciuc return (struct s32cc_clkmux *)cmux_addr; 173*12e7a2cdSGhennadi Procopciuc } 174*12e7a2cdSGhennadi Procopciuc 175*12e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk) 176*12e7a2cdSGhennadi Procopciuc { 177*12e7a2cdSGhennadi Procopciuc if (!is_s32cc_clk_mux(clk)) { 178*12e7a2cdSGhennadi Procopciuc return NULL; 179*12e7a2cdSGhennadi Procopciuc } 180*12e7a2cdSGhennadi Procopciuc 181*12e7a2cdSGhennadi Procopciuc return s32cc_obj2clkmux(clk->module); 182*12e7a2cdSGhennadi Procopciuc } 183*12e7a2cdSGhennadi Procopciuc 1847c36209bSGhennadi Procopciuc #endif /* S32CC_CLK_MODULES_H */ 185