13a580e9eSGhennadi Procopciuc /* 23a580e9eSGhennadi Procopciuc * Copyright 2024 NXP 33a580e9eSGhennadi Procopciuc * 43a580e9eSGhennadi Procopciuc * SPDX-License-Identifier: BSD-3-Clause 53a580e9eSGhennadi Procopciuc */ 63a580e9eSGhennadi Procopciuc #include <errno.h> 73a580e9eSGhennadi Procopciuc 88ab34357SGhennadi Procopciuc #include <s32cc-clk-regs.h> 98ab34357SGhennadi Procopciuc 10d9373519SGhennadi Procopciuc #include <common/debug.h> 113a580e9eSGhennadi Procopciuc #include <drivers/clk.h> 128ab34357SGhennadi Procopciuc #include <lib/mmio.h> 13d9373519SGhennadi Procopciuc #include <s32cc-clk-modules.h> 14d9373519SGhennadi Procopciuc #include <s32cc-clk-utils.h> 15d9373519SGhennadi Procopciuc 16d9373519SGhennadi Procopciuc #define MAX_STACK_DEPTH (15U) 17d9373519SGhennadi Procopciuc 188ab34357SGhennadi Procopciuc struct s32cc_clk_drv { 198ab34357SGhennadi Procopciuc uintptr_t fxosc_base; 208ab34357SGhennadi Procopciuc }; 218ab34357SGhennadi Procopciuc 22d9373519SGhennadi Procopciuc static int update_stack_depth(unsigned int *depth) 23d9373519SGhennadi Procopciuc { 24d9373519SGhennadi Procopciuc if (*depth == 0U) { 25d9373519SGhennadi Procopciuc return -ENOMEM; 26d9373519SGhennadi Procopciuc } 27d9373519SGhennadi Procopciuc 28d9373519SGhennadi Procopciuc (*depth)--; 29d9373519SGhennadi Procopciuc return 0; 30d9373519SGhennadi Procopciuc } 313a580e9eSGhennadi Procopciuc 328ab34357SGhennadi Procopciuc static struct s32cc_clk_drv *get_drv(void) 338ab34357SGhennadi Procopciuc { 348ab34357SGhennadi Procopciuc static struct s32cc_clk_drv driver = { 358ab34357SGhennadi Procopciuc .fxosc_base = FXOSC_BASE_ADDR, 368ab34357SGhennadi Procopciuc }; 378ab34357SGhennadi Procopciuc 388ab34357SGhennadi Procopciuc return &driver; 398ab34357SGhennadi Procopciuc } 408ab34357SGhennadi Procopciuc 418ab34357SGhennadi Procopciuc static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth); 428ab34357SGhennadi Procopciuc 438ab34357SGhennadi Procopciuc static int enable_clk_module(const struct s32cc_clk_obj *module, 448ab34357SGhennadi Procopciuc const struct s32cc_clk_drv *drv, 458ab34357SGhennadi Procopciuc unsigned int *depth) 468ab34357SGhennadi Procopciuc { 478ab34357SGhennadi Procopciuc const struct s32cc_clk *clk = s32cc_obj2clk(module); 488ab34357SGhennadi Procopciuc int ret; 498ab34357SGhennadi Procopciuc 508ab34357SGhennadi Procopciuc ret = update_stack_depth(depth); 518ab34357SGhennadi Procopciuc if (ret != 0) { 528ab34357SGhennadi Procopciuc return ret; 538ab34357SGhennadi Procopciuc } 548ab34357SGhennadi Procopciuc 558ab34357SGhennadi Procopciuc if (clk == NULL) { 568ab34357SGhennadi Procopciuc return -EINVAL; 578ab34357SGhennadi Procopciuc } 588ab34357SGhennadi Procopciuc 598ab34357SGhennadi Procopciuc if (clk->module != NULL) { 608ab34357SGhennadi Procopciuc return enable_module(clk->module, depth); 618ab34357SGhennadi Procopciuc } 628ab34357SGhennadi Procopciuc 638ab34357SGhennadi Procopciuc if (clk->pclock != NULL) { 648ab34357SGhennadi Procopciuc return enable_clk_module(&clk->pclock->desc, drv, depth); 658ab34357SGhennadi Procopciuc } 668ab34357SGhennadi Procopciuc 678ab34357SGhennadi Procopciuc return -EINVAL; 688ab34357SGhennadi Procopciuc } 698ab34357SGhennadi Procopciuc 708ab34357SGhennadi Procopciuc static void enable_fxosc(const struct s32cc_clk_drv *drv) 718ab34357SGhennadi Procopciuc { 728ab34357SGhennadi Procopciuc uintptr_t fxosc_base = drv->fxosc_base; 738ab34357SGhennadi Procopciuc uint32_t ctrl; 748ab34357SGhennadi Procopciuc 758ab34357SGhennadi Procopciuc ctrl = mmio_read_32(FXOSC_CTRL(fxosc_base)); 768ab34357SGhennadi Procopciuc if ((ctrl & FXOSC_CTRL_OSCON) != U(0)) { 778ab34357SGhennadi Procopciuc return; 788ab34357SGhennadi Procopciuc } 798ab34357SGhennadi Procopciuc 808ab34357SGhennadi Procopciuc ctrl = FXOSC_CTRL_COMP_EN; 818ab34357SGhennadi Procopciuc ctrl &= ~FXOSC_CTRL_OSC_BYP; 828ab34357SGhennadi Procopciuc ctrl |= FXOSC_CTRL_EOCV(0x1); 838ab34357SGhennadi Procopciuc ctrl |= FXOSC_CTRL_GM_SEL(0x7); 848ab34357SGhennadi Procopciuc mmio_write_32(FXOSC_CTRL(fxosc_base), ctrl); 858ab34357SGhennadi Procopciuc 868ab34357SGhennadi Procopciuc /* Switch ON the crystal oscillator. */ 878ab34357SGhennadi Procopciuc mmio_setbits_32(FXOSC_CTRL(fxosc_base), FXOSC_CTRL_OSCON); 888ab34357SGhennadi Procopciuc 898ab34357SGhennadi Procopciuc /* Wait until the clock is stable. */ 908ab34357SGhennadi Procopciuc while ((mmio_read_32(FXOSC_STAT(fxosc_base)) & FXOSC_STAT_OSC_STAT) == U(0)) { 918ab34357SGhennadi Procopciuc } 928ab34357SGhennadi Procopciuc } 938ab34357SGhennadi Procopciuc 948ab34357SGhennadi Procopciuc static int enable_osc(const struct s32cc_clk_obj *module, 958ab34357SGhennadi Procopciuc const struct s32cc_clk_drv *drv, 968ab34357SGhennadi Procopciuc unsigned int *depth) 978ab34357SGhennadi Procopciuc { 988ab34357SGhennadi Procopciuc const struct s32cc_osc *osc = s32cc_obj2osc(module); 998ab34357SGhennadi Procopciuc int ret = 0; 1008ab34357SGhennadi Procopciuc 1018ab34357SGhennadi Procopciuc ret = update_stack_depth(depth); 1028ab34357SGhennadi Procopciuc if (ret != 0) { 1038ab34357SGhennadi Procopciuc return ret; 1048ab34357SGhennadi Procopciuc } 1058ab34357SGhennadi Procopciuc 1068ab34357SGhennadi Procopciuc switch (osc->source) { 1078ab34357SGhennadi Procopciuc case S32CC_FXOSC: 1088ab34357SGhennadi Procopciuc enable_fxosc(drv); 1098ab34357SGhennadi Procopciuc break; 1108ab34357SGhennadi Procopciuc /* FIRC and SIRC oscillators are enabled by default */ 1118ab34357SGhennadi Procopciuc case S32CC_FIRC: 1128ab34357SGhennadi Procopciuc break; 1138ab34357SGhennadi Procopciuc case S32CC_SIRC: 1148ab34357SGhennadi Procopciuc break; 1158ab34357SGhennadi Procopciuc default: 1168ab34357SGhennadi Procopciuc ERROR("Invalid oscillator %d\n", osc->source); 1178ab34357SGhennadi Procopciuc ret = -EINVAL; 1188ab34357SGhennadi Procopciuc break; 1198ab34357SGhennadi Procopciuc }; 1208ab34357SGhennadi Procopciuc 1218ab34357SGhennadi Procopciuc return ret; 1228ab34357SGhennadi Procopciuc } 1238ab34357SGhennadi Procopciuc 1248ab34357SGhennadi Procopciuc static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth) 1258ab34357SGhennadi Procopciuc { 1268ab34357SGhennadi Procopciuc const struct s32cc_clk_drv *drv = get_drv(); 1278ab34357SGhennadi Procopciuc int ret = 0; 1288ab34357SGhennadi Procopciuc 1298ab34357SGhennadi Procopciuc ret = update_stack_depth(depth); 1308ab34357SGhennadi Procopciuc if (ret != 0) { 1318ab34357SGhennadi Procopciuc return ret; 1328ab34357SGhennadi Procopciuc } 1338ab34357SGhennadi Procopciuc 1348ab34357SGhennadi Procopciuc if (drv == NULL) { 1358ab34357SGhennadi Procopciuc return -EINVAL; 1368ab34357SGhennadi Procopciuc } 1378ab34357SGhennadi Procopciuc 1388ab34357SGhennadi Procopciuc switch (module->type) { 1398ab34357SGhennadi Procopciuc case s32cc_osc_t: 1408ab34357SGhennadi Procopciuc ret = enable_osc(module, drv, depth); 1418ab34357SGhennadi Procopciuc break; 1428ab34357SGhennadi Procopciuc case s32cc_clk_t: 1438ab34357SGhennadi Procopciuc ret = enable_clk_module(module, drv, depth); 1448ab34357SGhennadi Procopciuc break; 145a8be748aSGhennadi Procopciuc case s32cc_clkmux_t: 146a8be748aSGhennadi Procopciuc ret = -ENOTSUP; 147a8be748aSGhennadi Procopciuc break; 1483fa91a94SGhennadi Procopciuc case s32cc_shared_clkmux_t: 1493fa91a94SGhennadi Procopciuc ret = -ENOTSUP; 1503fa91a94SGhennadi Procopciuc break; 151a8be748aSGhennadi Procopciuc case s32cc_pll_t: 152a8be748aSGhennadi Procopciuc ret = -ENOTSUP; 153a8be748aSGhennadi Procopciuc break; 154a8be748aSGhennadi Procopciuc case s32cc_pll_out_div_t: 155a8be748aSGhennadi Procopciuc ret = -ENOTSUP; 156a8be748aSGhennadi Procopciuc break; 1578ab34357SGhennadi Procopciuc default: 1588ab34357SGhennadi Procopciuc ret = -EINVAL; 1598ab34357SGhennadi Procopciuc break; 1608ab34357SGhennadi Procopciuc } 1618ab34357SGhennadi Procopciuc 1628ab34357SGhennadi Procopciuc return ret; 1638ab34357SGhennadi Procopciuc } 1648ab34357SGhennadi Procopciuc 1653a580e9eSGhennadi Procopciuc static int s32cc_clk_enable(unsigned long id) 1663a580e9eSGhennadi Procopciuc { 1678ab34357SGhennadi Procopciuc unsigned int depth = MAX_STACK_DEPTH; 1688ab34357SGhennadi Procopciuc const struct s32cc_clk *clk; 1698ab34357SGhennadi Procopciuc 1708ab34357SGhennadi Procopciuc clk = s32cc_get_arch_clk(id); 1718ab34357SGhennadi Procopciuc if (clk == NULL) { 1728ab34357SGhennadi Procopciuc return -EINVAL; 1738ab34357SGhennadi Procopciuc } 1748ab34357SGhennadi Procopciuc 1758ab34357SGhennadi Procopciuc return enable_module(&clk->desc, &depth); 1763a580e9eSGhennadi Procopciuc } 1773a580e9eSGhennadi Procopciuc 1783a580e9eSGhennadi Procopciuc static void s32cc_clk_disable(unsigned long id) 1793a580e9eSGhennadi Procopciuc { 1803a580e9eSGhennadi Procopciuc } 1813a580e9eSGhennadi Procopciuc 1823a580e9eSGhennadi Procopciuc static bool s32cc_clk_is_enabled(unsigned long id) 1833a580e9eSGhennadi Procopciuc { 1843a580e9eSGhennadi Procopciuc return false; 1853a580e9eSGhennadi Procopciuc } 1863a580e9eSGhennadi Procopciuc 1873a580e9eSGhennadi Procopciuc static unsigned long s32cc_clk_get_rate(unsigned long id) 1883a580e9eSGhennadi Procopciuc { 1893a580e9eSGhennadi Procopciuc return 0; 1903a580e9eSGhennadi Procopciuc } 1913a580e9eSGhennadi Procopciuc 192d9373519SGhennadi Procopciuc static int set_module_rate(const struct s32cc_clk_obj *module, 193d9373519SGhennadi Procopciuc unsigned long rate, unsigned long *orate, 194d9373519SGhennadi Procopciuc unsigned int *depth); 195d9373519SGhennadi Procopciuc 196d9373519SGhennadi Procopciuc static int set_osc_freq(const struct s32cc_clk_obj *module, unsigned long rate, 197d9373519SGhennadi Procopciuc unsigned long *orate, unsigned int *depth) 198d9373519SGhennadi Procopciuc { 199d9373519SGhennadi Procopciuc struct s32cc_osc *osc = s32cc_obj2osc(module); 200d9373519SGhennadi Procopciuc int ret; 201d9373519SGhennadi Procopciuc 202d9373519SGhennadi Procopciuc ret = update_stack_depth(depth); 203d9373519SGhennadi Procopciuc if (ret != 0) { 204d9373519SGhennadi Procopciuc return ret; 205d9373519SGhennadi Procopciuc } 206d9373519SGhennadi Procopciuc 207d9373519SGhennadi Procopciuc if ((osc->freq != 0UL) && (rate != osc->freq)) { 208d9373519SGhennadi Procopciuc ERROR("Already initialized oscillator. freq = %lu\n", 209d9373519SGhennadi Procopciuc osc->freq); 210d9373519SGhennadi Procopciuc return -EINVAL; 211d9373519SGhennadi Procopciuc } 212d9373519SGhennadi Procopciuc 213d9373519SGhennadi Procopciuc osc->freq = rate; 214d9373519SGhennadi Procopciuc *orate = osc->freq; 215d9373519SGhennadi Procopciuc 216d9373519SGhennadi Procopciuc return 0; 217d9373519SGhennadi Procopciuc } 218d9373519SGhennadi Procopciuc 219d9373519SGhennadi Procopciuc static int set_clk_freq(const struct s32cc_clk_obj *module, unsigned long rate, 220d9373519SGhennadi Procopciuc unsigned long *orate, unsigned int *depth) 221d9373519SGhennadi Procopciuc { 222d9373519SGhennadi Procopciuc const struct s32cc_clk *clk = s32cc_obj2clk(module); 223d9373519SGhennadi Procopciuc int ret; 224d9373519SGhennadi Procopciuc 225d9373519SGhennadi Procopciuc ret = update_stack_depth(depth); 226d9373519SGhennadi Procopciuc if (ret != 0) { 227d9373519SGhennadi Procopciuc return ret; 228d9373519SGhennadi Procopciuc } 229d9373519SGhennadi Procopciuc 230d9373519SGhennadi Procopciuc if ((clk->min_freq != 0UL) && (clk->max_freq != 0UL) && 231d9373519SGhennadi Procopciuc ((rate < clk->min_freq) || (rate > clk->max_freq))) { 232d9373519SGhennadi Procopciuc ERROR("%lu frequency is out of the allowed range: [%lu:%lu]\n", 233d9373519SGhennadi Procopciuc rate, clk->min_freq, clk->max_freq); 234d9373519SGhennadi Procopciuc return -EINVAL; 235d9373519SGhennadi Procopciuc } 236d9373519SGhennadi Procopciuc 237d9373519SGhennadi Procopciuc if (clk->module != NULL) { 238d9373519SGhennadi Procopciuc return set_module_rate(clk->module, rate, orate, depth); 239d9373519SGhennadi Procopciuc } 240d9373519SGhennadi Procopciuc 241d9373519SGhennadi Procopciuc if (clk->pclock != NULL) { 242d9373519SGhennadi Procopciuc return set_clk_freq(&clk->pclock->desc, rate, orate, depth); 243d9373519SGhennadi Procopciuc } 244d9373519SGhennadi Procopciuc 245d9373519SGhennadi Procopciuc return -EINVAL; 246d9373519SGhennadi Procopciuc } 247d9373519SGhennadi Procopciuc 248*7ad4e231SGhennadi Procopciuc static int set_pll_freq(const struct s32cc_clk_obj *module, unsigned long rate, 249*7ad4e231SGhennadi Procopciuc unsigned long *orate, unsigned int *depth) 250*7ad4e231SGhennadi Procopciuc { 251*7ad4e231SGhennadi Procopciuc struct s32cc_pll *pll = s32cc_obj2pll(module); 252*7ad4e231SGhennadi Procopciuc int ret; 253*7ad4e231SGhennadi Procopciuc 254*7ad4e231SGhennadi Procopciuc ret = update_stack_depth(depth); 255*7ad4e231SGhennadi Procopciuc if (ret != 0) { 256*7ad4e231SGhennadi Procopciuc return ret; 257*7ad4e231SGhennadi Procopciuc } 258*7ad4e231SGhennadi Procopciuc 259*7ad4e231SGhennadi Procopciuc if ((pll->vco_freq != 0UL) && (pll->vco_freq != rate)) { 260*7ad4e231SGhennadi Procopciuc ERROR("PLL frequency was already set\n"); 261*7ad4e231SGhennadi Procopciuc return -EINVAL; 262*7ad4e231SGhennadi Procopciuc } 263*7ad4e231SGhennadi Procopciuc 264*7ad4e231SGhennadi Procopciuc pll->vco_freq = rate; 265*7ad4e231SGhennadi Procopciuc *orate = pll->vco_freq; 266*7ad4e231SGhennadi Procopciuc 267*7ad4e231SGhennadi Procopciuc return 0; 268*7ad4e231SGhennadi Procopciuc } 269*7ad4e231SGhennadi Procopciuc 270d9373519SGhennadi Procopciuc static int set_module_rate(const struct s32cc_clk_obj *module, 271d9373519SGhennadi Procopciuc unsigned long rate, unsigned long *orate, 272d9373519SGhennadi Procopciuc unsigned int *depth) 273d9373519SGhennadi Procopciuc { 274d9373519SGhennadi Procopciuc int ret = 0; 275d9373519SGhennadi Procopciuc 276d9373519SGhennadi Procopciuc ret = update_stack_depth(depth); 277d9373519SGhennadi Procopciuc if (ret != 0) { 278d9373519SGhennadi Procopciuc return ret; 279d9373519SGhennadi Procopciuc } 280d9373519SGhennadi Procopciuc 281d9373519SGhennadi Procopciuc switch (module->type) { 282d9373519SGhennadi Procopciuc case s32cc_clk_t: 283d9373519SGhennadi Procopciuc ret = set_clk_freq(module, rate, orate, depth); 284d9373519SGhennadi Procopciuc break; 285d9373519SGhennadi Procopciuc case s32cc_osc_t: 286d9373519SGhennadi Procopciuc ret = set_osc_freq(module, rate, orate, depth); 287d9373519SGhennadi Procopciuc break; 288*7ad4e231SGhennadi Procopciuc case s32cc_pll_t: 289*7ad4e231SGhennadi Procopciuc ret = set_pll_freq(module, rate, orate, depth); 290*7ad4e231SGhennadi Procopciuc break; 291a8be748aSGhennadi Procopciuc case s32cc_clkmux_t: 2923fa91a94SGhennadi Procopciuc case s32cc_shared_clkmux_t: 293a8be748aSGhennadi Procopciuc case s32cc_pll_out_div_t: 294a8be748aSGhennadi Procopciuc ret = -ENOTSUP; 295a8be748aSGhennadi Procopciuc break; 296d9373519SGhennadi Procopciuc default: 297d9373519SGhennadi Procopciuc ret = -EINVAL; 298d9373519SGhennadi Procopciuc break; 299d9373519SGhennadi Procopciuc } 300d9373519SGhennadi Procopciuc 301d9373519SGhennadi Procopciuc return ret; 302d9373519SGhennadi Procopciuc } 303d9373519SGhennadi Procopciuc 3043a580e9eSGhennadi Procopciuc static int s32cc_clk_set_rate(unsigned long id, unsigned long rate, 3053a580e9eSGhennadi Procopciuc unsigned long *orate) 3063a580e9eSGhennadi Procopciuc { 307d9373519SGhennadi Procopciuc unsigned int depth = MAX_STACK_DEPTH; 308d9373519SGhennadi Procopciuc const struct s32cc_clk *clk; 309d9373519SGhennadi Procopciuc int ret; 310d9373519SGhennadi Procopciuc 311d9373519SGhennadi Procopciuc clk = s32cc_get_arch_clk(id); 312d9373519SGhennadi Procopciuc if (clk == NULL) { 313d9373519SGhennadi Procopciuc return -EINVAL; 314d9373519SGhennadi Procopciuc } 315d9373519SGhennadi Procopciuc 316d9373519SGhennadi Procopciuc ret = set_module_rate(&clk->desc, rate, orate, &depth); 317d9373519SGhennadi Procopciuc if (ret != 0) { 318d9373519SGhennadi Procopciuc ERROR("Failed to set frequency (%lu MHz) for clock %lu\n", 319d9373519SGhennadi Procopciuc rate, id); 320d9373519SGhennadi Procopciuc } 321d9373519SGhennadi Procopciuc 322d9373519SGhennadi Procopciuc return ret; 3233a580e9eSGhennadi Procopciuc } 3243a580e9eSGhennadi Procopciuc 3253a580e9eSGhennadi Procopciuc static int s32cc_clk_get_parent(unsigned long id) 3263a580e9eSGhennadi Procopciuc { 3273a580e9eSGhennadi Procopciuc return -ENOTSUP; 3283a580e9eSGhennadi Procopciuc } 3293a580e9eSGhennadi Procopciuc 3303a580e9eSGhennadi Procopciuc static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id) 3313a580e9eSGhennadi Procopciuc { 33212e7a2cdSGhennadi Procopciuc const struct s32cc_clk *parent; 33312e7a2cdSGhennadi Procopciuc const struct s32cc_clk *clk; 33412e7a2cdSGhennadi Procopciuc bool valid_source = false; 33512e7a2cdSGhennadi Procopciuc struct s32cc_clkmux *mux; 33612e7a2cdSGhennadi Procopciuc uint8_t i; 33712e7a2cdSGhennadi Procopciuc 33812e7a2cdSGhennadi Procopciuc clk = s32cc_get_arch_clk(id); 33912e7a2cdSGhennadi Procopciuc if (clk == NULL) { 34012e7a2cdSGhennadi Procopciuc return -EINVAL; 34112e7a2cdSGhennadi Procopciuc } 34212e7a2cdSGhennadi Procopciuc 34312e7a2cdSGhennadi Procopciuc parent = s32cc_get_arch_clk(parent_id); 34412e7a2cdSGhennadi Procopciuc if (parent == NULL) { 34512e7a2cdSGhennadi Procopciuc return -EINVAL; 34612e7a2cdSGhennadi Procopciuc } 34712e7a2cdSGhennadi Procopciuc 34812e7a2cdSGhennadi Procopciuc if (!is_s32cc_clk_mux(clk)) { 34912e7a2cdSGhennadi Procopciuc ERROR("Clock %lu is not a mux\n", id); 35012e7a2cdSGhennadi Procopciuc return -EINVAL; 35112e7a2cdSGhennadi Procopciuc } 35212e7a2cdSGhennadi Procopciuc 35312e7a2cdSGhennadi Procopciuc mux = s32cc_clk2mux(clk); 35412e7a2cdSGhennadi Procopciuc if (mux == NULL) { 35512e7a2cdSGhennadi Procopciuc ERROR("Failed to cast clock %lu to clock mux\n", id); 35612e7a2cdSGhennadi Procopciuc return -EINVAL; 35712e7a2cdSGhennadi Procopciuc } 35812e7a2cdSGhennadi Procopciuc 35912e7a2cdSGhennadi Procopciuc for (i = 0; i < mux->nclks; i++) { 36012e7a2cdSGhennadi Procopciuc if (mux->clkids[i] == parent_id) { 36112e7a2cdSGhennadi Procopciuc valid_source = true; 36212e7a2cdSGhennadi Procopciuc break; 36312e7a2cdSGhennadi Procopciuc } 36412e7a2cdSGhennadi Procopciuc } 36512e7a2cdSGhennadi Procopciuc 36612e7a2cdSGhennadi Procopciuc if (!valid_source) { 36712e7a2cdSGhennadi Procopciuc ERROR("Clock %lu is not a valid clock for mux %lu\n", 36812e7a2cdSGhennadi Procopciuc parent_id, id); 36912e7a2cdSGhennadi Procopciuc return -EINVAL; 37012e7a2cdSGhennadi Procopciuc } 37112e7a2cdSGhennadi Procopciuc 37212e7a2cdSGhennadi Procopciuc mux->source_id = parent_id; 37312e7a2cdSGhennadi Procopciuc 37412e7a2cdSGhennadi Procopciuc return 0; 3753a580e9eSGhennadi Procopciuc } 3763a580e9eSGhennadi Procopciuc 3773a580e9eSGhennadi Procopciuc void s32cc_clk_register_drv(void) 3783a580e9eSGhennadi Procopciuc { 3793a580e9eSGhennadi Procopciuc static const struct clk_ops s32cc_clk_ops = { 3803a580e9eSGhennadi Procopciuc .enable = s32cc_clk_enable, 3813a580e9eSGhennadi Procopciuc .disable = s32cc_clk_disable, 3823a580e9eSGhennadi Procopciuc .is_enabled = s32cc_clk_is_enabled, 3833a580e9eSGhennadi Procopciuc .get_rate = s32cc_clk_get_rate, 3843a580e9eSGhennadi Procopciuc .set_rate = s32cc_clk_set_rate, 3853a580e9eSGhennadi Procopciuc .get_parent = s32cc_clk_get_parent, 3863a580e9eSGhennadi Procopciuc .set_parent = s32cc_clk_set_parent, 3873a580e9eSGhennadi Procopciuc }; 3883a580e9eSGhennadi Procopciuc 3893a580e9eSGhennadi Procopciuc clk_register(&s32cc_clk_ops); 3903a580e9eSGhennadi Procopciuc } 3913a580e9eSGhennadi Procopciuc 392