1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* 3 * Copyright 2020-2024 NXP 4 */ 5 #ifndef S32CC_CLK_MODULES_H 6 #define S32CC_CLK_MODULES_H 7 8 #include <inttypes.h> 9 #include <stddef.h> 10 11 #define MHZ UL(1000000) 12 #define GHZ (UL(1000) * MHZ) 13 14 enum s32cc_clkm_type { 15 s32cc_osc_t, 16 s32cc_clk_t, 17 s32cc_pll_t, 18 s32cc_pll_out_div_t, 19 s32cc_clkmux_t, 20 }; 21 22 enum s32cc_clk_source { 23 S32CC_FIRC, 24 S32CC_FXOSC, 25 S32CC_SIRC, 26 S32CC_ARM_PLL, 27 }; 28 29 struct s32cc_clk_obj { 30 enum s32cc_clkm_type type; 31 uint32_t refcount; 32 }; 33 34 struct s32cc_osc { 35 struct s32cc_clk_obj desc; 36 enum s32cc_clk_source source; 37 unsigned long freq; 38 void *base; 39 }; 40 41 #define S32CC_OSC_INIT(SOURCE) \ 42 { \ 43 .desc = { \ 44 .type = s32cc_osc_t, \ 45 }, \ 46 .source = (SOURCE), \ 47 } 48 49 struct s32cc_clkmux { 50 struct s32cc_clk_obj desc; 51 enum s32cc_clk_source module; 52 uint8_t index; /* Mux index in parent module */ 53 unsigned long source_id; /* Selected source */ 54 uint8_t nclks; /* Number of input clocks */ 55 unsigned long clkids[5]; /* IDs of the input clocks */ 56 }; 57 58 #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \ 59 { \ 60 .desc = { \ 61 .type = (TYPE), \ 62 }, \ 63 .module = (MODULE), \ 64 .index = (INDEX), \ 65 .nclks = (NCLKS), \ 66 .clkids = {__VA_ARGS__}, \ 67 } 68 69 #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ 70 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \ 71 INDEX, NCLKS, __VA_ARGS__) 72 73 struct s32cc_pll { 74 struct s32cc_clk_obj desc; 75 struct s32cc_clk_obj *source; 76 enum s32cc_clk_source instance; 77 unsigned long vco_freq; 78 uint32_t ndividers; 79 uintptr_t base; 80 }; 81 82 #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \ 83 { \ 84 .desc = { \ 85 .type = s32cc_pll_t, \ 86 }, \ 87 .source = &(PLL_MUX_CLK).desc, \ 88 .instance = (INSTANCE), \ 89 .ndividers = (NDIVIDERS), \ 90 } 91 92 struct s32cc_pll_out_div { 93 struct s32cc_clk_obj desc; 94 struct s32cc_clk_obj *parent; 95 uint32_t index; 96 unsigned long freq; 97 }; 98 99 #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ 100 { \ 101 .desc = { \ 102 .type = s32cc_pll_out_div_t, \ 103 }, \ 104 .parent = &(PARENT).desc, \ 105 .index = (INDEX), \ 106 } 107 108 struct s32cc_clk { 109 struct s32cc_clk_obj desc; 110 struct s32cc_clk_obj *module; 111 struct s32cc_clk *pclock; 112 unsigned long min_freq; 113 unsigned long max_freq; 114 }; 115 116 struct s32cc_clk_array { 117 unsigned long type_mask; 118 struct s32cc_clk **clks; 119 size_t n_clks; 120 }; 121 122 #define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \ 123 { \ 124 .desc = { \ 125 .type = s32cc_clk_t, \ 126 }, \ 127 .module = &(PARENT_MODULE).desc, \ 128 .min_freq = (MIN_F), \ 129 .max_freq = (MAX_F), \ 130 } 131 132 #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \ 133 S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) 134 135 #define S32CC_MODULE_CLK(PARENT_MODULE) \ 136 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0) 137 138 static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod) 139 { 140 uintptr_t osc_addr; 141 142 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc); 143 return (struct s32cc_osc *)osc_addr; 144 } 145 146 static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod) 147 { 148 uintptr_t clk_addr; 149 150 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc); 151 return (struct s32cc_clk *)clk_addr; 152 } 153 154 #endif /* S32CC_CLK_MODULES_H */ 155