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> 97c36209bSGhennadi Procopciuc #include <stddef.h> 107c36209bSGhennadi Procopciuc 117c36209bSGhennadi Procopciuc #define MHZ UL(1000000) 127c36209bSGhennadi Procopciuc #define GHZ (UL(1000) * MHZ) 137c36209bSGhennadi Procopciuc 147c36209bSGhennadi Procopciuc enum s32cc_clkm_type { 157c36209bSGhennadi Procopciuc s32cc_osc_t, 167c36209bSGhennadi Procopciuc s32cc_clk_t, 17*a8be748aSGhennadi Procopciuc s32cc_pll_t, 18*a8be748aSGhennadi Procopciuc s32cc_pll_out_div_t, 19*a8be748aSGhennadi Procopciuc s32cc_clkmux_t, 207c36209bSGhennadi Procopciuc }; 217c36209bSGhennadi Procopciuc 227c36209bSGhennadi Procopciuc enum s32cc_clk_source { 237c36209bSGhennadi Procopciuc S32CC_FIRC, 247c36209bSGhennadi Procopciuc S32CC_FXOSC, 257c36209bSGhennadi Procopciuc S32CC_SIRC, 26*a8be748aSGhennadi Procopciuc S32CC_ARM_PLL, 277c36209bSGhennadi Procopciuc }; 287c36209bSGhennadi Procopciuc 297c36209bSGhennadi Procopciuc struct s32cc_clk_obj { 307c36209bSGhennadi Procopciuc enum s32cc_clkm_type type; 317c36209bSGhennadi Procopciuc uint32_t refcount; 327c36209bSGhennadi Procopciuc }; 337c36209bSGhennadi Procopciuc 347c36209bSGhennadi Procopciuc struct s32cc_osc { 357c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 367c36209bSGhennadi Procopciuc enum s32cc_clk_source source; 377c36209bSGhennadi Procopciuc unsigned long freq; 387c36209bSGhennadi Procopciuc void *base; 397c36209bSGhennadi Procopciuc }; 407c36209bSGhennadi Procopciuc 417c36209bSGhennadi Procopciuc #define S32CC_OSC_INIT(SOURCE) \ 427c36209bSGhennadi Procopciuc { \ 437c36209bSGhennadi Procopciuc .desc = { \ 447c36209bSGhennadi Procopciuc .type = s32cc_osc_t, \ 457c36209bSGhennadi Procopciuc }, \ 467c36209bSGhennadi Procopciuc .source = (SOURCE), \ 477c36209bSGhennadi Procopciuc } 487c36209bSGhennadi Procopciuc 49*a8be748aSGhennadi Procopciuc struct s32cc_clkmux { 50*a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 51*a8be748aSGhennadi Procopciuc enum s32cc_clk_source module; 52*a8be748aSGhennadi Procopciuc uint8_t index; /* Mux index in parent module */ 53*a8be748aSGhennadi Procopciuc unsigned long source_id; /* Selected source */ 54*a8be748aSGhennadi Procopciuc uint8_t nclks; /* Number of input clocks */ 55*a8be748aSGhennadi Procopciuc unsigned long clkids[5]; /* IDs of the input clocks */ 56*a8be748aSGhennadi Procopciuc }; 57*a8be748aSGhennadi Procopciuc 58*a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \ 59*a8be748aSGhennadi Procopciuc { \ 60*a8be748aSGhennadi Procopciuc .desc = { \ 61*a8be748aSGhennadi Procopciuc .type = (TYPE), \ 62*a8be748aSGhennadi Procopciuc }, \ 63*a8be748aSGhennadi Procopciuc .module = (MODULE), \ 64*a8be748aSGhennadi Procopciuc .index = (INDEX), \ 65*a8be748aSGhennadi Procopciuc .nclks = (NCLKS), \ 66*a8be748aSGhennadi Procopciuc .clkids = {__VA_ARGS__}, \ 67*a8be748aSGhennadi Procopciuc } 68*a8be748aSGhennadi Procopciuc 69*a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 70*a8be748aSGhennadi Procopciuc S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \ 71*a8be748aSGhennadi Procopciuc INDEX, NCLKS, __VA_ARGS__) 72*a8be748aSGhennadi Procopciuc 73*a8be748aSGhennadi Procopciuc struct s32cc_pll { 74*a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 75*a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *source; 76*a8be748aSGhennadi Procopciuc enum s32cc_clk_source instance; 77*a8be748aSGhennadi Procopciuc unsigned long vco_freq; 78*a8be748aSGhennadi Procopciuc uint32_t ndividers; 79*a8be748aSGhennadi Procopciuc uintptr_t base; 80*a8be748aSGhennadi Procopciuc }; 81*a8be748aSGhennadi Procopciuc 82*a8be748aSGhennadi Procopciuc #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \ 83*a8be748aSGhennadi Procopciuc { \ 84*a8be748aSGhennadi Procopciuc .desc = { \ 85*a8be748aSGhennadi Procopciuc .type = s32cc_pll_t, \ 86*a8be748aSGhennadi Procopciuc }, \ 87*a8be748aSGhennadi Procopciuc .source = &(PLL_MUX_CLK).desc, \ 88*a8be748aSGhennadi Procopciuc .instance = (INSTANCE), \ 89*a8be748aSGhennadi Procopciuc .ndividers = (NDIVIDERS), \ 90*a8be748aSGhennadi Procopciuc } 91*a8be748aSGhennadi Procopciuc 92*a8be748aSGhennadi Procopciuc struct s32cc_pll_out_div { 93*a8be748aSGhennadi Procopciuc struct s32cc_clk_obj desc; 94*a8be748aSGhennadi Procopciuc struct s32cc_clk_obj *parent; 95*a8be748aSGhennadi Procopciuc uint32_t index; 96*a8be748aSGhennadi Procopciuc unsigned long freq; 97*a8be748aSGhennadi Procopciuc }; 98*a8be748aSGhennadi Procopciuc 99*a8be748aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ 100*a8be748aSGhennadi Procopciuc { \ 101*a8be748aSGhennadi Procopciuc .desc = { \ 102*a8be748aSGhennadi Procopciuc .type = s32cc_pll_out_div_t, \ 103*a8be748aSGhennadi Procopciuc }, \ 104*a8be748aSGhennadi Procopciuc .parent = &(PARENT).desc, \ 105*a8be748aSGhennadi Procopciuc .index = (INDEX), \ 106*a8be748aSGhennadi Procopciuc } 107*a8be748aSGhennadi Procopciuc 1087c36209bSGhennadi Procopciuc struct s32cc_clk { 1097c36209bSGhennadi Procopciuc struct s32cc_clk_obj desc; 1107c36209bSGhennadi Procopciuc struct s32cc_clk_obj *module; 1117c36209bSGhennadi Procopciuc struct s32cc_clk *pclock; 1127c36209bSGhennadi Procopciuc unsigned long min_freq; 1137c36209bSGhennadi Procopciuc unsigned long max_freq; 1147c36209bSGhennadi Procopciuc }; 1157c36209bSGhennadi Procopciuc 1167c36209bSGhennadi Procopciuc struct s32cc_clk_array { 1177c36209bSGhennadi Procopciuc unsigned long type_mask; 1187c36209bSGhennadi Procopciuc struct s32cc_clk **clks; 1197c36209bSGhennadi Procopciuc size_t n_clks; 1207c36209bSGhennadi Procopciuc }; 1217c36209bSGhennadi Procopciuc 1227c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \ 1237c36209bSGhennadi Procopciuc { \ 1247c36209bSGhennadi Procopciuc .desc = { \ 1257c36209bSGhennadi Procopciuc .type = s32cc_clk_t, \ 1267c36209bSGhennadi Procopciuc }, \ 1277c36209bSGhennadi Procopciuc .module = &(PARENT_MODULE).desc, \ 1287c36209bSGhennadi Procopciuc .min_freq = (MIN_F), \ 1297c36209bSGhennadi Procopciuc .max_freq = (MAX_F), \ 1307c36209bSGhennadi Procopciuc } 1317c36209bSGhennadi Procopciuc 1327c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \ 1337c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) 1347c36209bSGhennadi Procopciuc 1357c36209bSGhennadi Procopciuc #define S32CC_MODULE_CLK(PARENT_MODULE) \ 1367c36209bSGhennadi Procopciuc S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0) 1377c36209bSGhennadi Procopciuc 138d9373519SGhennadi Procopciuc static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod) 139d9373519SGhennadi Procopciuc { 140d9373519SGhennadi Procopciuc uintptr_t osc_addr; 141d9373519SGhennadi Procopciuc 142d9373519SGhennadi Procopciuc osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc); 143d9373519SGhennadi Procopciuc return (struct s32cc_osc *)osc_addr; 144d9373519SGhennadi Procopciuc } 145d9373519SGhennadi Procopciuc 146d9373519SGhennadi Procopciuc static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod) 147d9373519SGhennadi Procopciuc { 148d9373519SGhennadi Procopciuc uintptr_t clk_addr; 149d9373519SGhennadi Procopciuc 150d9373519SGhennadi Procopciuc clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc); 151d9373519SGhennadi Procopciuc return (struct s32cc_clk *)clk_addr; 152d9373519SGhennadi Procopciuc } 153d9373519SGhennadi Procopciuc 1547c36209bSGhennadi Procopciuc #endif /* S32CC_CLK_MODULES_H */ 155