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> 912e7a2cdSGhennadi 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, 21*3fa91a94SGhennadi Procopciuc s32cc_shared_clkmux_t, 227c36209bSGhennadi Procopciuc }; 237c36209bSGhennadi Procopciuc 247c36209bSGhennadi Procopciuc enum s32cc_clk_source { 257c36209bSGhennadi Procopciuc S32CC_FIRC, 267c36209bSGhennadi Procopciuc S32CC_FXOSC, 277c36209bSGhennadi Procopciuc S32CC_SIRC, 28a8be748aSGhennadi Procopciuc S32CC_ARM_PLL, 29*3fa91a94SGhennadi Procopciuc S32CC_CGM1, 307c36209bSGhennadi Procopciuc }; 317c36209bSGhennadi Procopciuc 327c36209bSGhennadi Procopciuc struct s32cc_clk_obj { 337c36209bSGhennadi Procopciuc enum s32cc_clkm_type type; 347c36209bSGhennadi Procopciuc uint32_t refcount; 357c36209bSGhennadi Procopciuc }; 367c36209bSGhennadi Procopciuc 377c36209bSGhennadi Procopciuc struct s32cc_osc { 387c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 397c36209bSGhennadi Procopciuc enum s32cc_clk_source source; 407c36209bSGhennadi Procopciuc unsigned long freq; 417c36209bSGhennadi Procopciuc void *base; 427c36209bSGhennadi Procopciuc }; 437c36209bSGhennadi Procopciuc 447c36209bSGhennadi Procopciuc #define S32CC_OSC_INIT(SOURCE) \ 457c36209bSGhennadi Procopciuc { \ 467c36209bSGhennadi Procopciuc .desc = { \ 477c36209bSGhennadi Procopciuc .type = s32cc_osc_t, \ 487c36209bSGhennadi Procopciuc }, \ 497c36209bSGhennadi Procopciuc .source = (SOURCE), \ 507c36209bSGhennadi Procopciuc } 517c36209bSGhennadi Procopciuc 52a8be748aSGhennadi Procopciuc struct s32cc_clkmux { 53a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 54a8be748aSGhennadi Procopciuc enum s32cc_clk_source module; 55a8be748aSGhennadi Procopciuc uint8_t index; /* Mux index in parent module */ 56a8be748aSGhennadi Procopciuc unsigned long source_id; /* Selected source */ 57a8be748aSGhennadi Procopciuc uint8_t nclks; /* Number of input clocks */ 58a8be748aSGhennadi Procopciuc unsigned long clkids[5]; /* IDs of the input clocks */ 59a8be748aSGhennadi Procopciuc }; 60a8be748aSGhennadi Procopciuc 61a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \ 62a8be748aSGhennadi Procopciuc { \ 63a8be748aSGhennadi Procopciuc .desc = { \ 64a8be748aSGhennadi Procopciuc .type = (TYPE), \ 65a8be748aSGhennadi Procopciuc }, \ 66a8be748aSGhennadi Procopciuc .module = (MODULE), \ 67a8be748aSGhennadi Procopciuc .index = (INDEX), \ 68a8be748aSGhennadi Procopciuc .nclks = (NCLKS), \ 69a8be748aSGhennadi Procopciuc .clkids = {__VA_ARGS__}, \ 70a8be748aSGhennadi Procopciuc } 71a8be748aSGhennadi Procopciuc 72a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 73a8be748aSGhennadi Procopciuc S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \ 74a8be748aSGhennadi Procopciuc INDEX, NCLKS, __VA_ARGS__) 75a8be748aSGhennadi Procopciuc 76*3fa91a94SGhennadi Procopciuc #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 77*3fa91a94SGhennadi Procopciuc S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \ 78*3fa91a94SGhennadi Procopciuc INDEX, NCLKS, __VA_ARGS__) 79*3fa91a94SGhennadi Procopciuc 80a8be748aSGhennadi Procopciuc struct s32cc_pll { 81a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 82a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *source; 83a8be748aSGhennadi Procopciuc enum s32cc_clk_source instance; 84a8be748aSGhennadi Procopciuc unsigned long vco_freq; 85a8be748aSGhennadi Procopciuc uint32_t ndividers; 86a8be748aSGhennadi Procopciuc uintptr_t base; 87a8be748aSGhennadi Procopciuc }; 88a8be748aSGhennadi Procopciuc 89a8be748aSGhennadi Procopciuc #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \ 90a8be748aSGhennadi Procopciuc { \ 91a8be748aSGhennadi Procopciuc .desc = { \ 92a8be748aSGhennadi Procopciuc .type = s32cc_pll_t, \ 93a8be748aSGhennadi Procopciuc }, \ 94a8be748aSGhennadi Procopciuc .source = &(PLL_MUX_CLK).desc, \ 95a8be748aSGhennadi Procopciuc .instance = (INSTANCE), \ 96a8be748aSGhennadi Procopciuc .ndividers = (NDIVIDERS), \ 97a8be748aSGhennadi Procopciuc } 98a8be748aSGhennadi Procopciuc 99a8be748aSGhennadi Procopciuc struct s32cc_pll_out_div { 100a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 101a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *parent; 102a8be748aSGhennadi Procopciuc uint32_t index; 103a8be748aSGhennadi Procopciuc unsigned long freq; 104a8be748aSGhennadi Procopciuc }; 105a8be748aSGhennadi Procopciuc 106a8be748aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ 107a8be748aSGhennadi Procopciuc { \ 108a8be748aSGhennadi Procopciuc .desc = { \ 109a8be748aSGhennadi Procopciuc .type = s32cc_pll_out_div_t, \ 110a8be748aSGhennadi Procopciuc }, \ 111a8be748aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 112a8be748aSGhennadi Procopciuc .index = (INDEX), \ 113a8be748aSGhennadi Procopciuc } 114a8be748aSGhennadi Procopciuc 1157c36209bSGhennadi Procopciuc struct s32cc_clk { 1167c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 1177c36209bSGhennadi Procopciuc struct s32cc_clk_obj *module; 1187c36209bSGhennadi Procopciuc struct s32cc_clk *pclock; 1197c36209bSGhennadi Procopciuc unsigned long min_freq; 1207c36209bSGhennadi Procopciuc unsigned long max_freq; 1217c36209bSGhennadi Procopciuc }; 1227c36209bSGhennadi Procopciuc 1237c36209bSGhennadi Procopciuc struct s32cc_clk_array { 1247c36209bSGhennadi Procopciuc unsigned long type_mask; 1257c36209bSGhennadi Procopciuc struct s32cc_clk **clks; 1267c36209bSGhennadi Procopciuc size_t n_clks; 1277c36209bSGhennadi Procopciuc }; 1287c36209bSGhennadi Procopciuc 1297c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \ 1307c36209bSGhennadi Procopciuc { \ 1317c36209bSGhennadi Procopciuc .desc = { \ 1327c36209bSGhennadi Procopciuc .type = s32cc_clk_t, \ 1337c36209bSGhennadi Procopciuc }, \ 1347c36209bSGhennadi Procopciuc .module = &(PARENT_MODULE).desc, \ 1357c36209bSGhennadi Procopciuc .min_freq = (MIN_F), \ 1367c36209bSGhennadi Procopciuc .max_freq = (MAX_F), \ 1377c36209bSGhennadi Procopciuc } 1387c36209bSGhennadi Procopciuc 1397c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \ 1407c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) 1417c36209bSGhennadi Procopciuc 1427c36209bSGhennadi Procopciuc #define S32CC_MODULE_CLK(PARENT_MODULE) \ 1437c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0) 1447c36209bSGhennadi Procopciuc 145d9373519SGhennadi Procopciuc static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod) 146d9373519SGhennadi Procopciuc { 147d9373519SGhennadi Procopciuc uintptr_t osc_addr; 148d9373519SGhennadi Procopciuc 149d9373519SGhennadi Procopciuc osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc); 150d9373519SGhennadi Procopciuc return (struct s32cc_osc *)osc_addr; 151d9373519SGhennadi Procopciuc } 152d9373519SGhennadi Procopciuc 153d9373519SGhennadi Procopciuc static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod) 154d9373519SGhennadi Procopciuc { 155d9373519SGhennadi Procopciuc uintptr_t clk_addr; 156d9373519SGhennadi Procopciuc 157d9373519SGhennadi Procopciuc clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc); 158d9373519SGhennadi Procopciuc return (struct s32cc_clk *)clk_addr; 159d9373519SGhennadi Procopciuc } 160d9373519SGhennadi Procopciuc 16112e7a2cdSGhennadi Procopciuc static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk) 16212e7a2cdSGhennadi Procopciuc { 16312e7a2cdSGhennadi Procopciuc const struct s32cc_clk_obj *module; 16412e7a2cdSGhennadi Procopciuc 16512e7a2cdSGhennadi Procopciuc module = clk->module; 16612e7a2cdSGhennadi Procopciuc if (module == NULL) { 16712e7a2cdSGhennadi Procopciuc return false; 16812e7a2cdSGhennadi Procopciuc } 16912e7a2cdSGhennadi Procopciuc 170*3fa91a94SGhennadi Procopciuc return (module->type == s32cc_clkmux_t) || 171*3fa91a94SGhennadi Procopciuc (module->type == s32cc_shared_clkmux_t); 17212e7a2cdSGhennadi Procopciuc } 17312e7a2cdSGhennadi Procopciuc 17412e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod) 17512e7a2cdSGhennadi Procopciuc { 17612e7a2cdSGhennadi Procopciuc uintptr_t cmux_addr; 17712e7a2cdSGhennadi Procopciuc 17812e7a2cdSGhennadi Procopciuc cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc); 17912e7a2cdSGhennadi Procopciuc return (struct s32cc_clkmux *)cmux_addr; 18012e7a2cdSGhennadi Procopciuc } 18112e7a2cdSGhennadi Procopciuc 18212e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk) 18312e7a2cdSGhennadi Procopciuc { 18412e7a2cdSGhennadi Procopciuc if (!is_s32cc_clk_mux(clk)) { 18512e7a2cdSGhennadi Procopciuc return NULL; 18612e7a2cdSGhennadi Procopciuc } 18712e7a2cdSGhennadi Procopciuc 18812e7a2cdSGhennadi Procopciuc return s32cc_obj2clkmux(clk->module); 18912e7a2cdSGhennadi Procopciuc } 19012e7a2cdSGhennadi Procopciuc 1917c36209bSGhennadi Procopciuc #endif /* S32CC_CLK_MODULES_H */ 192