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, 213fa91a94SGhennadi Procopciuc s32cc_shared_clkmux_t, 2244e2130aSGhennadi Procopciuc s32cc_fixed_div_t, 237c36209bSGhennadi Procopciuc }; 247c36209bSGhennadi Procopciuc 257c36209bSGhennadi Procopciuc enum s32cc_clk_source { 267c36209bSGhennadi Procopciuc S32CC_FIRC, 277c36209bSGhennadi Procopciuc S32CC_FXOSC, 287c36209bSGhennadi Procopciuc S32CC_SIRC, 29a8be748aSGhennadi Procopciuc S32CC_ARM_PLL, 303fa91a94SGhennadi Procopciuc S32CC_CGM1, 317c36209bSGhennadi Procopciuc }; 327c36209bSGhennadi Procopciuc 337c36209bSGhennadi Procopciuc struct s32cc_clk_obj { 347c36209bSGhennadi Procopciuc enum s32cc_clkm_type type; 357c36209bSGhennadi Procopciuc uint32_t refcount; 367c36209bSGhennadi Procopciuc }; 377c36209bSGhennadi Procopciuc 387c36209bSGhennadi Procopciuc struct s32cc_osc { 397c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 407c36209bSGhennadi Procopciuc enum s32cc_clk_source source; 417c36209bSGhennadi Procopciuc unsigned long freq; 427c36209bSGhennadi Procopciuc void *base; 437c36209bSGhennadi Procopciuc }; 447c36209bSGhennadi Procopciuc 457c36209bSGhennadi Procopciuc #define S32CC_OSC_INIT(SOURCE) \ 467c36209bSGhennadi Procopciuc { \ 477c36209bSGhennadi Procopciuc .desc = { \ 487c36209bSGhennadi Procopciuc .type = s32cc_osc_t, \ 497c36209bSGhennadi Procopciuc }, \ 507c36209bSGhennadi Procopciuc .source = (SOURCE), \ 517c36209bSGhennadi Procopciuc } 527c36209bSGhennadi Procopciuc 53a8be748aSGhennadi Procopciuc struct s32cc_clkmux { 54a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 55a8be748aSGhennadi Procopciuc enum s32cc_clk_source module; 56a8be748aSGhennadi Procopciuc uint8_t index; /* Mux index in parent module */ 57a8be748aSGhennadi Procopciuc unsigned long source_id; /* Selected source */ 58a8be748aSGhennadi Procopciuc uint8_t nclks; /* Number of input clocks */ 59a8be748aSGhennadi Procopciuc unsigned long clkids[5]; /* IDs of the input clocks */ 60a8be748aSGhennadi Procopciuc }; 61a8be748aSGhennadi Procopciuc 62a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \ 63a8be748aSGhennadi Procopciuc { \ 64a8be748aSGhennadi Procopciuc .desc = { \ 65a8be748aSGhennadi Procopciuc .type = (TYPE), \ 66a8be748aSGhennadi Procopciuc }, \ 67a8be748aSGhennadi Procopciuc .module = (MODULE), \ 68a8be748aSGhennadi Procopciuc .index = (INDEX), \ 69a8be748aSGhennadi Procopciuc .nclks = (NCLKS), \ 70a8be748aSGhennadi Procopciuc .clkids = {__VA_ARGS__}, \ 71a8be748aSGhennadi Procopciuc } 72a8be748aSGhennadi Procopciuc 73a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 74a8be748aSGhennadi Procopciuc S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \ 75a8be748aSGhennadi Procopciuc INDEX, NCLKS, __VA_ARGS__) 76a8be748aSGhennadi Procopciuc 773fa91a94SGhennadi Procopciuc #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 783fa91a94SGhennadi Procopciuc S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \ 793fa91a94SGhennadi Procopciuc INDEX, NCLKS, __VA_ARGS__) 803fa91a94SGhennadi Procopciuc 81a8be748aSGhennadi Procopciuc struct s32cc_pll { 82a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 83a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *source; 84a8be748aSGhennadi Procopciuc enum s32cc_clk_source instance; 85a8be748aSGhennadi Procopciuc unsigned long vco_freq; 86a8be748aSGhennadi Procopciuc uint32_t ndividers; 87a8be748aSGhennadi Procopciuc uintptr_t base; 88a8be748aSGhennadi Procopciuc }; 89a8be748aSGhennadi Procopciuc 90a8be748aSGhennadi Procopciuc #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \ 91a8be748aSGhennadi Procopciuc { \ 92a8be748aSGhennadi Procopciuc .desc = { \ 93a8be748aSGhennadi Procopciuc .type = s32cc_pll_t, \ 94a8be748aSGhennadi Procopciuc }, \ 95a8be748aSGhennadi Procopciuc .source = &(PLL_MUX_CLK).desc, \ 96a8be748aSGhennadi Procopciuc .instance = (INSTANCE), \ 97a8be748aSGhennadi Procopciuc .ndividers = (NDIVIDERS), \ 98a8be748aSGhennadi Procopciuc } 99a8be748aSGhennadi Procopciuc 100a8be748aSGhennadi Procopciuc struct s32cc_pll_out_div { 101a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 102a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *parent; 103a8be748aSGhennadi Procopciuc uint32_t index; 104a8be748aSGhennadi Procopciuc unsigned long freq; 105a8be748aSGhennadi Procopciuc }; 106a8be748aSGhennadi Procopciuc 107a8be748aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ 108a8be748aSGhennadi Procopciuc { \ 109a8be748aSGhennadi Procopciuc .desc = { \ 110a8be748aSGhennadi Procopciuc .type = s32cc_pll_out_div_t, \ 111a8be748aSGhennadi Procopciuc }, \ 112a8be748aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 113a8be748aSGhennadi Procopciuc .index = (INDEX), \ 114a8be748aSGhennadi Procopciuc } 115a8be748aSGhennadi Procopciuc 11644e2130aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ 11744e2130aSGhennadi Procopciuc { \ 11844e2130aSGhennadi Procopciuc .desc = { \ 11944e2130aSGhennadi Procopciuc .type = s32cc_pll_out_div_t, \ 12044e2130aSGhennadi Procopciuc }, \ 12144e2130aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 12244e2130aSGhennadi Procopciuc .index = (INDEX), \ 12344e2130aSGhennadi Procopciuc } 12444e2130aSGhennadi Procopciuc 12544e2130aSGhennadi Procopciuc struct s32cc_fixed_div { 12644e2130aSGhennadi Procopciuc struct s32cc_clk_obj desc; 12744e2130aSGhennadi Procopciuc struct s32cc_clk_obj *parent; 12844e2130aSGhennadi Procopciuc uint32_t rate_div; 12944e2130aSGhennadi Procopciuc }; 13044e2130aSGhennadi Procopciuc 13144e2130aSGhennadi Procopciuc #define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \ 13244e2130aSGhennadi Procopciuc { \ 13344e2130aSGhennadi Procopciuc .desc = { \ 13444e2130aSGhennadi Procopciuc .type = s32cc_fixed_div_t, \ 13544e2130aSGhennadi Procopciuc }, \ 13644e2130aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 13744e2130aSGhennadi Procopciuc .rate_div = (RATE_DIV), \ 13844e2130aSGhennadi Procopciuc } 13944e2130aSGhennadi Procopciuc 1407c36209bSGhennadi Procopciuc struct s32cc_clk { 1417c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 1427c36209bSGhennadi Procopciuc struct s32cc_clk_obj *module; 1437c36209bSGhennadi Procopciuc struct s32cc_clk *pclock; 1447c36209bSGhennadi Procopciuc unsigned long min_freq; 1457c36209bSGhennadi Procopciuc unsigned long max_freq; 1467c36209bSGhennadi Procopciuc }; 1477c36209bSGhennadi Procopciuc 1487c36209bSGhennadi Procopciuc struct s32cc_clk_array { 1497c36209bSGhennadi Procopciuc unsigned long type_mask; 1507c36209bSGhennadi Procopciuc struct s32cc_clk **clks; 1517c36209bSGhennadi Procopciuc size_t n_clks; 1527c36209bSGhennadi Procopciuc }; 1537c36209bSGhennadi Procopciuc 1547c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \ 1557c36209bSGhennadi Procopciuc { \ 1567c36209bSGhennadi Procopciuc .desc = { \ 1577c36209bSGhennadi Procopciuc .type = s32cc_clk_t, \ 1587c36209bSGhennadi Procopciuc }, \ 1597c36209bSGhennadi Procopciuc .module = &(PARENT_MODULE).desc, \ 1607c36209bSGhennadi Procopciuc .min_freq = (MIN_F), \ 1617c36209bSGhennadi Procopciuc .max_freq = (MAX_F), \ 1627c36209bSGhennadi Procopciuc } 1637c36209bSGhennadi Procopciuc 1647c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \ 1657c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) 1667c36209bSGhennadi Procopciuc 1677c36209bSGhennadi Procopciuc #define S32CC_MODULE_CLK(PARENT_MODULE) \ 1687c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0) 1697c36209bSGhennadi Procopciuc 170d9373519SGhennadi Procopciuc static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod) 171d9373519SGhennadi Procopciuc { 172d9373519SGhennadi Procopciuc uintptr_t osc_addr; 173d9373519SGhennadi Procopciuc 174d9373519SGhennadi Procopciuc osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc); 175d9373519SGhennadi Procopciuc return (struct s32cc_osc *)osc_addr; 176d9373519SGhennadi Procopciuc } 177d9373519SGhennadi Procopciuc 178d9373519SGhennadi Procopciuc static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod) 179d9373519SGhennadi Procopciuc { 180d9373519SGhennadi Procopciuc uintptr_t clk_addr; 181d9373519SGhennadi Procopciuc 182d9373519SGhennadi Procopciuc clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc); 183d9373519SGhennadi Procopciuc return (struct s32cc_clk *)clk_addr; 184d9373519SGhennadi Procopciuc } 185d9373519SGhennadi Procopciuc 18612e7a2cdSGhennadi Procopciuc static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk) 18712e7a2cdSGhennadi Procopciuc { 18812e7a2cdSGhennadi Procopciuc const struct s32cc_clk_obj *module; 18912e7a2cdSGhennadi Procopciuc 19012e7a2cdSGhennadi Procopciuc module = clk->module; 19112e7a2cdSGhennadi Procopciuc if (module == NULL) { 19212e7a2cdSGhennadi Procopciuc return false; 19312e7a2cdSGhennadi Procopciuc } 19412e7a2cdSGhennadi Procopciuc 1953fa91a94SGhennadi Procopciuc return (module->type == s32cc_clkmux_t) || 1963fa91a94SGhennadi Procopciuc (module->type == s32cc_shared_clkmux_t); 19712e7a2cdSGhennadi Procopciuc } 19812e7a2cdSGhennadi Procopciuc 19912e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod) 20012e7a2cdSGhennadi Procopciuc { 20112e7a2cdSGhennadi Procopciuc uintptr_t cmux_addr; 20212e7a2cdSGhennadi Procopciuc 20312e7a2cdSGhennadi Procopciuc cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc); 20412e7a2cdSGhennadi Procopciuc return (struct s32cc_clkmux *)cmux_addr; 20512e7a2cdSGhennadi Procopciuc } 20612e7a2cdSGhennadi Procopciuc 20712e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk) 20812e7a2cdSGhennadi Procopciuc { 20912e7a2cdSGhennadi Procopciuc if (!is_s32cc_clk_mux(clk)) { 21012e7a2cdSGhennadi Procopciuc return NULL; 21112e7a2cdSGhennadi Procopciuc } 21212e7a2cdSGhennadi Procopciuc 21312e7a2cdSGhennadi Procopciuc return s32cc_obj2clkmux(clk->module); 21412e7a2cdSGhennadi Procopciuc } 21512e7a2cdSGhennadi Procopciuc 2167ad4e231SGhennadi Procopciuc static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod) 2177ad4e231SGhennadi Procopciuc { 2187ad4e231SGhennadi Procopciuc uintptr_t pll_addr; 2197ad4e231SGhennadi Procopciuc 2207ad4e231SGhennadi Procopciuc pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc); 2217ad4e231SGhennadi Procopciuc return (struct s32cc_pll *)pll_addr; 2227ad4e231SGhennadi Procopciuc } 2237ad4e231SGhennadi Procopciuc 224de950ef0SGhennadi Procopciuc static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod) 225de950ef0SGhennadi Procopciuc { 226de950ef0SGhennadi Procopciuc uintptr_t plldiv_addr; 227de950ef0SGhennadi Procopciuc 228de950ef0SGhennadi Procopciuc plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc); 229de950ef0SGhennadi Procopciuc return (struct s32cc_pll_out_div *)plldiv_addr; 230de950ef0SGhennadi Procopciuc } 231de950ef0SGhennadi Procopciuc 232*65739db2SGhennadi Procopciuc static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod) 233*65739db2SGhennadi Procopciuc { 234*65739db2SGhennadi Procopciuc uintptr_t fdiv_addr; 235*65739db2SGhennadi Procopciuc 236*65739db2SGhennadi Procopciuc fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc); 237*65739db2SGhennadi Procopciuc return (struct s32cc_fixed_div *)fdiv_addr; 238*65739db2SGhennadi Procopciuc } 239*65739db2SGhennadi Procopciuc 2407c36209bSGhennadi Procopciuc #endif /* S32CC_CLK_MODULES_H */ 241