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, 20*44ae54afSGhennadi Procopciuc s32cc_dfs_t, 21*44ae54afSGhennadi Procopciuc s32cc_dfs_div_t, 22a8be748aSGhennadi Procopciuc s32cc_clkmux_t, 233fa91a94SGhennadi Procopciuc s32cc_shared_clkmux_t, 2444e2130aSGhennadi Procopciuc s32cc_fixed_div_t, 257c36209bSGhennadi Procopciuc }; 267c36209bSGhennadi Procopciuc 277c36209bSGhennadi Procopciuc enum s32cc_clk_source { 287c36209bSGhennadi Procopciuc S32CC_FIRC, 297c36209bSGhennadi Procopciuc S32CC_FXOSC, 307c36209bSGhennadi Procopciuc S32CC_SIRC, 31a8be748aSGhennadi Procopciuc S32CC_ARM_PLL, 32*44ae54afSGhennadi Procopciuc S32CC_ARM_DFS, 333fa91a94SGhennadi Procopciuc S32CC_CGM1, 347c36209bSGhennadi Procopciuc }; 357c36209bSGhennadi Procopciuc 367c36209bSGhennadi Procopciuc struct s32cc_clk_obj { 377c36209bSGhennadi Procopciuc enum s32cc_clkm_type type; 387c36209bSGhennadi Procopciuc uint32_t refcount; 397c36209bSGhennadi Procopciuc }; 407c36209bSGhennadi Procopciuc 417c36209bSGhennadi Procopciuc struct s32cc_osc { 427c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 437c36209bSGhennadi Procopciuc enum s32cc_clk_source source; 447c36209bSGhennadi Procopciuc unsigned long freq; 457c36209bSGhennadi Procopciuc void *base; 467c36209bSGhennadi Procopciuc }; 477c36209bSGhennadi Procopciuc 487c36209bSGhennadi Procopciuc #define S32CC_OSC_INIT(SOURCE) \ 497c36209bSGhennadi Procopciuc { \ 507c36209bSGhennadi Procopciuc .desc = { \ 517c36209bSGhennadi Procopciuc .type = s32cc_osc_t, \ 527c36209bSGhennadi Procopciuc }, \ 537c36209bSGhennadi Procopciuc .source = (SOURCE), \ 547c36209bSGhennadi Procopciuc } 557c36209bSGhennadi Procopciuc 56a8be748aSGhennadi Procopciuc struct s32cc_clkmux { 57a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 58a8be748aSGhennadi Procopciuc enum s32cc_clk_source module; 59a8be748aSGhennadi Procopciuc uint8_t index; /* Mux index in parent module */ 60a8be748aSGhennadi Procopciuc unsigned long source_id; /* Selected source */ 61a8be748aSGhennadi Procopciuc uint8_t nclks; /* Number of input clocks */ 62a8be748aSGhennadi Procopciuc unsigned long clkids[5]; /* IDs of the input clocks */ 63a8be748aSGhennadi Procopciuc }; 64a8be748aSGhennadi Procopciuc 65a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \ 66a8be748aSGhennadi Procopciuc { \ 67a8be748aSGhennadi Procopciuc .desc = { \ 68a8be748aSGhennadi Procopciuc .type = (TYPE), \ 69a8be748aSGhennadi Procopciuc }, \ 70a8be748aSGhennadi Procopciuc .module = (MODULE), \ 71a8be748aSGhennadi Procopciuc .index = (INDEX), \ 72a8be748aSGhennadi Procopciuc .nclks = (NCLKS), \ 73a8be748aSGhennadi Procopciuc .clkids = {__VA_ARGS__}, \ 74a8be748aSGhennadi Procopciuc } 75a8be748aSGhennadi Procopciuc 76a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 77a8be748aSGhennadi Procopciuc S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \ 78a8be748aSGhennadi Procopciuc INDEX, NCLKS, __VA_ARGS__) 79a8be748aSGhennadi Procopciuc 803fa91a94SGhennadi Procopciuc #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 813fa91a94SGhennadi Procopciuc S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \ 823fa91a94SGhennadi Procopciuc INDEX, NCLKS, __VA_ARGS__) 833fa91a94SGhennadi Procopciuc 84a8be748aSGhennadi Procopciuc struct s32cc_pll { 85a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 86a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *source; 87a8be748aSGhennadi Procopciuc enum s32cc_clk_source instance; 88a8be748aSGhennadi Procopciuc unsigned long vco_freq; 89a8be748aSGhennadi Procopciuc uint32_t ndividers; 90a8be748aSGhennadi Procopciuc uintptr_t base; 91a8be748aSGhennadi Procopciuc }; 92a8be748aSGhennadi Procopciuc 93a8be748aSGhennadi Procopciuc #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \ 94a8be748aSGhennadi Procopciuc { \ 95a8be748aSGhennadi Procopciuc .desc = { \ 96a8be748aSGhennadi Procopciuc .type = s32cc_pll_t, \ 97a8be748aSGhennadi Procopciuc }, \ 98a8be748aSGhennadi Procopciuc .source = &(PLL_MUX_CLK).desc, \ 99a8be748aSGhennadi Procopciuc .instance = (INSTANCE), \ 100a8be748aSGhennadi Procopciuc .ndividers = (NDIVIDERS), \ 101a8be748aSGhennadi Procopciuc } 102a8be748aSGhennadi Procopciuc 103a8be748aSGhennadi Procopciuc struct s32cc_pll_out_div { 104a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 105a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *parent; 106a8be748aSGhennadi Procopciuc uint32_t index; 107a8be748aSGhennadi Procopciuc unsigned long freq; 108a8be748aSGhennadi Procopciuc }; 109a8be748aSGhennadi Procopciuc 110a8be748aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ 111a8be748aSGhennadi Procopciuc { \ 112a8be748aSGhennadi Procopciuc .desc = { \ 113a8be748aSGhennadi Procopciuc .type = s32cc_pll_out_div_t, \ 114a8be748aSGhennadi Procopciuc }, \ 115a8be748aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 116a8be748aSGhennadi Procopciuc .index = (INDEX), \ 117a8be748aSGhennadi Procopciuc } 118a8be748aSGhennadi Procopciuc 11944e2130aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ 12044e2130aSGhennadi Procopciuc { \ 12144e2130aSGhennadi Procopciuc .desc = { \ 12244e2130aSGhennadi Procopciuc .type = s32cc_pll_out_div_t, \ 12344e2130aSGhennadi Procopciuc }, \ 12444e2130aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 12544e2130aSGhennadi Procopciuc .index = (INDEX), \ 12644e2130aSGhennadi Procopciuc } 12744e2130aSGhennadi Procopciuc 128*44ae54afSGhennadi Procopciuc struct s32cc_dfs { 129*44ae54afSGhennadi Procopciuc struct s32cc_clk_obj desc; 130*44ae54afSGhennadi Procopciuc struct s32cc_clk_obj *parent; 131*44ae54afSGhennadi Procopciuc enum s32cc_clk_source instance; 132*44ae54afSGhennadi Procopciuc uintptr_t base; 133*44ae54afSGhennadi Procopciuc }; 134*44ae54afSGhennadi Procopciuc 135*44ae54afSGhennadi Procopciuc #define S32CC_DFS_INIT(PARENT, INSTANCE) \ 136*44ae54afSGhennadi Procopciuc { \ 137*44ae54afSGhennadi Procopciuc .desc = { \ 138*44ae54afSGhennadi Procopciuc .type = s32cc_dfs_t, \ 139*44ae54afSGhennadi Procopciuc }, \ 140*44ae54afSGhennadi Procopciuc .parent = &(PARENT).desc, \ 141*44ae54afSGhennadi Procopciuc .instance = (INSTANCE), \ 142*44ae54afSGhennadi Procopciuc } 143*44ae54afSGhennadi Procopciuc 144*44ae54afSGhennadi Procopciuc struct s32cc_dfs_div { 145*44ae54afSGhennadi Procopciuc struct s32cc_clk_obj desc; 146*44ae54afSGhennadi Procopciuc struct s32cc_clk_obj *parent; 147*44ae54afSGhennadi Procopciuc uint32_t index; 148*44ae54afSGhennadi Procopciuc unsigned long freq; 149*44ae54afSGhennadi Procopciuc }; 150*44ae54afSGhennadi Procopciuc 151*44ae54afSGhennadi Procopciuc #define S32CC_DFS_DIV_INIT(PARENT, INDEX) \ 152*44ae54afSGhennadi Procopciuc { \ 153*44ae54afSGhennadi Procopciuc .desc = { \ 154*44ae54afSGhennadi Procopciuc .type = s32cc_dfs_div_t, \ 155*44ae54afSGhennadi Procopciuc }, \ 156*44ae54afSGhennadi Procopciuc .parent = &(PARENT).desc, \ 157*44ae54afSGhennadi Procopciuc .index = (INDEX), \ 158*44ae54afSGhennadi Procopciuc } 159*44ae54afSGhennadi Procopciuc 16044e2130aSGhennadi Procopciuc struct s32cc_fixed_div { 16144e2130aSGhennadi Procopciuc struct s32cc_clk_obj desc; 16244e2130aSGhennadi Procopciuc struct s32cc_clk_obj *parent; 16344e2130aSGhennadi Procopciuc uint32_t rate_div; 16444e2130aSGhennadi Procopciuc }; 16544e2130aSGhennadi Procopciuc 16644e2130aSGhennadi Procopciuc #define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \ 16744e2130aSGhennadi Procopciuc { \ 16844e2130aSGhennadi Procopciuc .desc = { \ 16944e2130aSGhennadi Procopciuc .type = s32cc_fixed_div_t, \ 17044e2130aSGhennadi Procopciuc }, \ 17144e2130aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 17244e2130aSGhennadi Procopciuc .rate_div = (RATE_DIV), \ 17344e2130aSGhennadi Procopciuc } 17444e2130aSGhennadi Procopciuc 1757c36209bSGhennadi Procopciuc struct s32cc_clk { 1767c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 1777c36209bSGhennadi Procopciuc struct s32cc_clk_obj *module; 1787c36209bSGhennadi Procopciuc struct s32cc_clk *pclock; 1797c36209bSGhennadi Procopciuc unsigned long min_freq; 1807c36209bSGhennadi Procopciuc unsigned long max_freq; 1817c36209bSGhennadi Procopciuc }; 1827c36209bSGhennadi Procopciuc 1837c36209bSGhennadi Procopciuc struct s32cc_clk_array { 1847c36209bSGhennadi Procopciuc unsigned long type_mask; 1857c36209bSGhennadi Procopciuc struct s32cc_clk **clks; 1867c36209bSGhennadi Procopciuc size_t n_clks; 1877c36209bSGhennadi Procopciuc }; 1887c36209bSGhennadi Procopciuc 189*44ae54afSGhennadi Procopciuc #define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \ 1907c36209bSGhennadi Procopciuc { \ 1917c36209bSGhennadi Procopciuc .desc = { \ 1927c36209bSGhennadi Procopciuc .type = s32cc_clk_t, \ 1937c36209bSGhennadi Procopciuc }, \ 194*44ae54afSGhennadi Procopciuc .pclock = (PARENT), \ 195*44ae54afSGhennadi Procopciuc .module = (PARENT_MODULE), \ 1967c36209bSGhennadi Procopciuc .min_freq = (MIN_F), \ 1977c36209bSGhennadi Procopciuc .max_freq = (MAX_F), \ 1987c36209bSGhennadi Procopciuc } 1997c36209bSGhennadi Procopciuc 2007c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \ 201*44ae54afSGhennadi Procopciuc S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F) 2027c36209bSGhennadi Procopciuc 2037c36209bSGhennadi Procopciuc #define S32CC_MODULE_CLK(PARENT_MODULE) \ 2047c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0) 2057c36209bSGhennadi Procopciuc 206*44ae54afSGhennadi Procopciuc #define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \ 207*44ae54afSGhennadi Procopciuc S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F) 208*44ae54afSGhennadi Procopciuc 209d9373519SGhennadi Procopciuc static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod) 210d9373519SGhennadi Procopciuc { 211d9373519SGhennadi Procopciuc uintptr_t osc_addr; 212d9373519SGhennadi Procopciuc 213d9373519SGhennadi Procopciuc osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc); 214d9373519SGhennadi Procopciuc return (struct s32cc_osc *)osc_addr; 215d9373519SGhennadi Procopciuc } 216d9373519SGhennadi Procopciuc 217d9373519SGhennadi Procopciuc static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod) 218d9373519SGhennadi Procopciuc { 219d9373519SGhennadi Procopciuc uintptr_t clk_addr; 220d9373519SGhennadi Procopciuc 221d9373519SGhennadi Procopciuc clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc); 222d9373519SGhennadi Procopciuc return (struct s32cc_clk *)clk_addr; 223d9373519SGhennadi Procopciuc } 224d9373519SGhennadi Procopciuc 22512e7a2cdSGhennadi Procopciuc static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk) 22612e7a2cdSGhennadi Procopciuc { 22712e7a2cdSGhennadi Procopciuc const struct s32cc_clk_obj *module; 22812e7a2cdSGhennadi Procopciuc 22912e7a2cdSGhennadi Procopciuc module = clk->module; 23012e7a2cdSGhennadi Procopciuc if (module == NULL) { 23112e7a2cdSGhennadi Procopciuc return false; 23212e7a2cdSGhennadi Procopciuc } 23312e7a2cdSGhennadi Procopciuc 2343fa91a94SGhennadi Procopciuc return (module->type == s32cc_clkmux_t) || 2353fa91a94SGhennadi Procopciuc (module->type == s32cc_shared_clkmux_t); 23612e7a2cdSGhennadi Procopciuc } 23712e7a2cdSGhennadi Procopciuc 23812e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod) 23912e7a2cdSGhennadi Procopciuc { 24012e7a2cdSGhennadi Procopciuc uintptr_t cmux_addr; 24112e7a2cdSGhennadi Procopciuc 24212e7a2cdSGhennadi Procopciuc cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc); 24312e7a2cdSGhennadi Procopciuc return (struct s32cc_clkmux *)cmux_addr; 24412e7a2cdSGhennadi Procopciuc } 24512e7a2cdSGhennadi Procopciuc 24612e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk) 24712e7a2cdSGhennadi Procopciuc { 24812e7a2cdSGhennadi Procopciuc if (!is_s32cc_clk_mux(clk)) { 24912e7a2cdSGhennadi Procopciuc return NULL; 25012e7a2cdSGhennadi Procopciuc } 25112e7a2cdSGhennadi Procopciuc 25212e7a2cdSGhennadi Procopciuc return s32cc_obj2clkmux(clk->module); 25312e7a2cdSGhennadi Procopciuc } 25412e7a2cdSGhennadi Procopciuc 2557ad4e231SGhennadi Procopciuc static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod) 2567ad4e231SGhennadi Procopciuc { 2577ad4e231SGhennadi Procopciuc uintptr_t pll_addr; 2587ad4e231SGhennadi Procopciuc 2597ad4e231SGhennadi Procopciuc pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc); 2607ad4e231SGhennadi Procopciuc return (struct s32cc_pll *)pll_addr; 2617ad4e231SGhennadi Procopciuc } 2627ad4e231SGhennadi Procopciuc 263de950ef0SGhennadi Procopciuc static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod) 264de950ef0SGhennadi Procopciuc { 265de950ef0SGhennadi Procopciuc uintptr_t plldiv_addr; 266de950ef0SGhennadi Procopciuc 267de950ef0SGhennadi Procopciuc plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc); 268de950ef0SGhennadi Procopciuc return (struct s32cc_pll_out_div *)plldiv_addr; 269de950ef0SGhennadi Procopciuc } 270de950ef0SGhennadi Procopciuc 27165739db2SGhennadi Procopciuc static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod) 27265739db2SGhennadi Procopciuc { 27365739db2SGhennadi Procopciuc uintptr_t fdiv_addr; 27465739db2SGhennadi Procopciuc 27565739db2SGhennadi Procopciuc fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc); 27665739db2SGhennadi Procopciuc return (struct s32cc_fixed_div *)fdiv_addr; 27765739db2SGhennadi Procopciuc } 27865739db2SGhennadi Procopciuc 279*44ae54afSGhennadi Procopciuc static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod) 280*44ae54afSGhennadi Procopciuc { 281*44ae54afSGhennadi Procopciuc uintptr_t dfs_addr; 282*44ae54afSGhennadi Procopciuc 283*44ae54afSGhennadi Procopciuc dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc); 284*44ae54afSGhennadi Procopciuc return (struct s32cc_dfs *)dfs_addr; 285*44ae54afSGhennadi Procopciuc } 286*44ae54afSGhennadi Procopciuc 287*44ae54afSGhennadi Procopciuc static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod) 288*44ae54afSGhennadi Procopciuc { 289*44ae54afSGhennadi Procopciuc uintptr_t dfs_div_addr; 290*44ae54afSGhennadi Procopciuc 291*44ae54afSGhennadi Procopciuc dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc); 292*44ae54afSGhennadi Procopciuc return (struct s32cc_dfs_div *)dfs_div_addr; 293*44ae54afSGhennadi Procopciuc } 294*44ae54afSGhennadi Procopciuc 2957c36209bSGhennadi Procopciuc #endif /* S32CC_CLK_MODULES_H */ 296