1 /* 2 * Copyright 2024-2025 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <drivers/clk.h> 7 #include <platform_def.h> 8 #include <s32cc-clk-drv.h> 9 #include <s32cc-clk-ids.h> 10 #include <s32cc-clk-regs.h> 11 #include <s32cc-mc-rgm.h> 12 #include <s32cc-clk-utils.h> 13 14 #define S32CC_FXOSC_FREQ (40U * MHZ) 15 #define S32CC_ARM_PLL_VCO_FREQ (2U * GHZ) 16 #define S32CC_ARM_PLL_PHI0_FREQ (1U * GHZ) 17 #define S32CC_A53_FREQ (1U * GHZ) 18 #define S32CC_XBAR_2X_FREQ (800U * MHZ) 19 #define S32CC_PERIPH_PLL_VCO_FREQ (2U * GHZ) 20 #define S32CC_PERIPH_PLL_PHI3_FREQ UART_CLOCK_HZ 21 #define S32CC_DDR_PLL_VCO_FREQ (1600U * MHZ) 22 #define S32CC_DDR_PLL_PHI0_FREQ (800U * MHZ) 23 #define S32CC_PERIPH_DFS_PHI3_FREQ (800U * MHZ) 24 #define S32CC_USDHC_FREQ (200U * MHZ) 25 26 #define S32CC_DDR_RESET_TIMEOUT_US 1000000U 27 28 static int setup_fxosc(void) 29 { 30 int ret; 31 32 ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL); 33 if (ret != 0) { 34 return ret; 35 } 36 37 return ret; 38 } 39 40 static int setup_arm_pll(void) 41 { 42 int ret; 43 44 ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC); 45 if (ret != 0) { 46 return ret; 47 } 48 49 ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL); 50 if (ret != 0) { 51 return ret; 52 } 53 54 ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL); 55 if (ret != 0) { 56 return ret; 57 } 58 59 return ret; 60 } 61 62 static int setup_periph_pll(void) 63 { 64 int ret; 65 66 ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC); 67 if (ret != 0) { 68 return ret; 69 } 70 71 ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL); 72 if (ret != 0) { 73 return ret; 74 } 75 76 ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL); 77 if (ret != 0) { 78 return ret; 79 } 80 81 return ret; 82 } 83 84 static int enable_a53_clk(void) 85 { 86 int ret; 87 88 ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0); 89 if (ret != 0) { 90 return ret; 91 } 92 93 ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL); 94 if (ret != 0) { 95 return ret; 96 } 97 98 ret = clk_enable(S32CC_CLK_A53_CORE); 99 if (ret != 0) { 100 return ret; 101 } 102 103 return ret; 104 } 105 106 static int enable_xbar_clk(void) 107 { 108 int ret; 109 110 ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1); 111 if (ret != 0) { 112 return ret; 113 } 114 115 ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL); 116 if (ret != 0) { 117 return ret; 118 } 119 120 ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1); 121 if (ret != 0) { 122 return ret; 123 } 124 125 ret = clk_enable(S32CC_CLK_XBAR_2X); 126 if (ret != 0) { 127 return ret; 128 } 129 130 return ret; 131 } 132 133 static int enable_uart_clk(void) 134 { 135 int ret; 136 137 ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3); 138 if (ret != 0) { 139 return ret; 140 } 141 142 ret = clk_enable(S32CC_CLK_LINFLEX_BAUD); 143 if (ret != 0) { 144 return ret; 145 } 146 147 return ret; 148 } 149 150 static int setup_ddr_pll(void) 151 { 152 int ret; 153 154 ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC); 155 if (ret != 0) { 156 return ret; 157 } 158 159 ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL); 160 if (ret != 0) { 161 return ret; 162 } 163 164 ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL); 165 if (ret != 0) { 166 return ret; 167 } 168 169 return ret; 170 } 171 172 static int enable_ddr_clk(void) 173 { 174 int ret; 175 176 ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0); 177 if (ret != 0) { 178 return ret; 179 } 180 181 ret = clk_enable(S32CC_CLK_DDR); 182 if (ret != 0) { 183 return ret; 184 } 185 186 return ret; 187 } 188 189 static int enable_usdhc_clk(void) 190 { 191 int ret; 192 193 ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX14, 194 S32CC_CLK_PERIPH_PLL_DFS3); 195 if (ret != 0) { 196 return ret; 197 } 198 199 ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_DFS3, 200 S32CC_PERIPH_DFS_PHI3_FREQ, NULL); 201 if (ret != 0) { 202 return ret; 203 } 204 205 ret = clk_set_rate(S32CC_CLK_USDHC, S32CC_USDHC_FREQ, NULL); 206 if (ret != 0) { 207 return ret; 208 } 209 210 ret = clk_enable(S32CC_CLK_USDHC); 211 if (ret != 0) { 212 return ret; 213 } 214 215 return ret; 216 } 217 218 int plat_deassert_ddr_reset(void) 219 { 220 int err; 221 222 clk_disable(S32CC_CLK_DDR); 223 224 err = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_FIRC); 225 if (err != 0) { 226 return err; 227 } 228 229 err = clk_enable(S32CC_CLK_DDR); 230 if (err != 0) { 231 return err; 232 } 233 234 err = mc_rgm_ddr_reset(MC_RGM_BASE_ADDR, S32CC_DDR_RESET_TIMEOUT_US); 235 if (err != 0) { 236 return err; 237 } 238 239 return enable_ddr_clk(); 240 } 241 242 int s32cc_init_core_clocks(void) 243 { 244 int ret; 245 246 ret = s32cc_clk_register_drv(false); 247 if (ret != 0) { 248 return ret; 249 } 250 251 ret = setup_fxosc(); 252 if (ret != 0) { 253 return ret; 254 } 255 256 ret = setup_arm_pll(); 257 if (ret != 0) { 258 return ret; 259 } 260 261 ret = enable_a53_clk(); 262 if (ret != 0) { 263 return ret; 264 } 265 266 ret = enable_xbar_clk(); 267 if (ret != 0) { 268 return ret; 269 } 270 271 return ret; 272 } 273 274 int s32cc_init_early_clks(void) 275 { 276 int ret; 277 278 ret = s32cc_clk_register_drv(true); 279 if (ret != 0) { 280 return ret; 281 } 282 283 ret = setup_periph_pll(); 284 if (ret != 0) { 285 return ret; 286 } 287 288 ret = enable_uart_clk(); 289 if (ret != 0) { 290 return ret; 291 } 292 293 ret = setup_ddr_pll(); 294 if (ret != 0) { 295 return ret; 296 } 297 298 ret = enable_ddr_clk(); 299 if (ret != 0) { 300 return ret; 301 } 302 303 ret = enable_usdhc_clk(); 304 if (ret != 0) { 305 return ret; 306 } 307 308 return ret; 309 } 310