From 8ab34357497b454b2f5e505d06ce9437da7772e4 Mon Sep 17 00:00:00 2001 From: Ghennadi Procopciuc Date: Wed, 12 Jun 2024 09:25:17 +0300 Subject: [PATCH 1/5] feat(nxp-clk): add FXOSC clock enablement Add the low-level implementation to enable the FXOSC oscillator, which is disabled by default when booting the SoC. It will be used by PLLs, for which support will be added later. Change-Id: Ie784e4e29b8b4453b39d37594c311af940bebf92 Signed-off-by: Ghennadi Procopciuc --- .../nxp/clk/s32cc/include/s32cc-clk-regs.h | 29 ++++ drivers/nxp/clk/s32cc/s32cc_clk.mk | 1 + drivers/nxp/clk/s32cc/s32cc_clk_drv.c | 138 +++++++++++++++++- drivers/nxp/clk/s32cc/s32cc_early_clks.c | 5 + 4 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h diff --git a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h new file mode 100644 index 000000000..7ae9624dd --- /dev/null +++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright 2020-2021, 2023-2024 NXP + */ +#ifndef S32CC_CLK_REGS_H +#define S32CC_CLK_REGS_H + +#include + +#define FXOSC_BASE_ADDR (0x40050000UL) + +/* FXOSC */ +#define FXOSC_CTRL(FXOSC) ((FXOSC) + 0x0UL) +#define FXOSC_CTRL_OSC_BYP BIT_32(31U) +#define FXOSC_CTRL_COMP_EN BIT_32(24U) +#define FXOSC_CTRL_EOCV_OFFSET 16U +#define FXOSC_CTRL_EOCV_MASK GENMASK_32(23U, FXOSC_CTRL_EOCV_OFFSET) +#define FXOSC_CTRL_EOCV(VAL) (FXOSC_CTRL_EOCV_MASK & \ + ((uint32_t)(VAL) << FXOSC_CTRL_EOCV_OFFSET)) +#define FXOSC_CTRL_GM_SEL_OFFSET 4U +#define FXOSC_CTRL_GM_SEL_MASK GENMASK_32(7U, FXOSC_CTRL_GM_SEL_OFFSET) +#define FXOSC_CTRL_GM_SEL(VAL) (FXOSC_CTRL_GM_SEL_MASK & \ + ((uint32_t)(VAL) << FXOSC_CTRL_GM_SEL_OFFSET)) +#define FXOSC_CTRL_OSCON BIT_32(0U) + +#define FXOSC_STAT(FXOSC) ((FXOSC) + 0x4UL) +#define FXOSC_STAT_OSC_STAT BIT_32(31U) + +#endif /* S32CC_CLK_REGS_H */ diff --git a/drivers/nxp/clk/s32cc/s32cc_clk.mk b/drivers/nxp/clk/s32cc/s32cc_clk.mk index f5279d3a9..7a65ea675 100644 --- a/drivers/nxp/clk/s32cc/s32cc_clk.mk +++ b/drivers/nxp/clk/s32cc/s32cc_clk.mk @@ -6,6 +6,7 @@ PLAT_INCLUDES += \ -I${PLAT_DRIVERS_INCLUDE_PATH}/clk/s32cc \ + -I${PLAT_DRIVERS_PATH}/clk/s32cc/include \ CLK_SOURCES := \ ${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_drv.c \ diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c index e6653bdf4..c331a8282 100644 --- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c +++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c @@ -5,13 +5,20 @@ */ #include +#include + #include #include +#include #include #include #define MAX_STACK_DEPTH (15U) +struct s32cc_clk_drv { + uintptr_t fxosc_base; +}; + static int update_stack_depth(unsigned int *depth) { if (*depth == 0U) { @@ -22,9 +29,138 @@ static int update_stack_depth(unsigned int *depth) return 0; } +static struct s32cc_clk_drv *get_drv(void) +{ + static struct s32cc_clk_drv driver = { + .fxosc_base = FXOSC_BASE_ADDR, + }; + + return &driver; +} + +static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth); + +static int enable_clk_module(const struct s32cc_clk_obj *module, + const struct s32cc_clk_drv *drv, + unsigned int *depth) +{ + const struct s32cc_clk *clk = s32cc_obj2clk(module); + int ret; + + ret = update_stack_depth(depth); + if (ret != 0) { + return ret; + } + + if (clk == NULL) { + return -EINVAL; + } + + if (clk->module != NULL) { + return enable_module(clk->module, depth); + } + + if (clk->pclock != NULL) { + return enable_clk_module(&clk->pclock->desc, drv, depth); + } + + return -EINVAL; +} + +static void enable_fxosc(const struct s32cc_clk_drv *drv) +{ + uintptr_t fxosc_base = drv->fxosc_base; + uint32_t ctrl; + + ctrl = mmio_read_32(FXOSC_CTRL(fxosc_base)); + if ((ctrl & FXOSC_CTRL_OSCON) != U(0)) { + return; + } + + ctrl = FXOSC_CTRL_COMP_EN; + ctrl &= ~FXOSC_CTRL_OSC_BYP; + ctrl |= FXOSC_CTRL_EOCV(0x1); + ctrl |= FXOSC_CTRL_GM_SEL(0x7); + mmio_write_32(FXOSC_CTRL(fxosc_base), ctrl); + + /* Switch ON the crystal oscillator. */ + mmio_setbits_32(FXOSC_CTRL(fxosc_base), FXOSC_CTRL_OSCON); + + /* Wait until the clock is stable. */ + while ((mmio_read_32(FXOSC_STAT(fxosc_base)) & FXOSC_STAT_OSC_STAT) == U(0)) { + } +} + +static int enable_osc(const struct s32cc_clk_obj *module, + const struct s32cc_clk_drv *drv, + unsigned int *depth) +{ + const struct s32cc_osc *osc = s32cc_obj2osc(module); + int ret = 0; + + ret = update_stack_depth(depth); + if (ret != 0) { + return ret; + } + + switch (osc->source) { + case S32CC_FXOSC: + enable_fxosc(drv); + break; + /* FIRC and SIRC oscillators are enabled by default */ + case S32CC_FIRC: + break; + case S32CC_SIRC: + break; + default: + ERROR("Invalid oscillator %d\n", osc->source); + ret = -EINVAL; + break; + }; + + return ret; +} + +static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth) +{ + const struct s32cc_clk_drv *drv = get_drv(); + int ret = 0; + + ret = update_stack_depth(depth); + if (ret != 0) { + return ret; + } + + if (drv == NULL) { + return -EINVAL; + } + + switch (module->type) { + case s32cc_osc_t: + ret = enable_osc(module, drv, depth); + break; + case s32cc_clk_t: + ret = enable_clk_module(module, drv, depth); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + static int s32cc_clk_enable(unsigned long id) { - return -ENOTSUP; + unsigned int depth = MAX_STACK_DEPTH; + const struct s32cc_clk *clk; + + clk = s32cc_get_arch_clk(id); + if (clk == NULL) { + return -EINVAL; + } + + return enable_module(&clk->desc, &depth); } static void s32cc_clk_disable(unsigned long id) diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c index fc1dc020d..8e4e78b79 100644 --- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c +++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c @@ -21,5 +21,10 @@ int s32cc_init_early_clks(void) return ret; } + ret = clk_enable(S32CC_CLK_FXOSC); + if (ret != 0) { + return ret; + } + return ret; } From a8be748a2821355734f603342b2d2cf7105f6a30 Mon Sep 17 00:00:00 2001 From: Ghennadi Procopciuc Date: Wed, 12 Jun 2024 09:53:18 +0300 Subject: [PATCH 2/5] feat(nxp-clk): add clock objects for ARM PLL Add all the clock objects needed to describe the ARM PLL, which can be powered by either FXOSC or FIRC oscillators. Change-Id: I2585ed38178ca1d5c5485adb38af1b3b8d94f1f6 Signed-off-by: Ghennadi Procopciuc --- drivers/nxp/clk/s32cc/s32cc_clk_drv.c | 14 +++++ drivers/nxp/clk/s32cc/s32cc_clk_modules.c | 36 ++++++++++- .../drivers/nxp/clk/s32cc/s32cc-clk-modules.h | 63 +++++++++++++++++++ 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c index c331a8282..c15b03306 100644 --- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c +++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c @@ -142,6 +142,15 @@ static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth case s32cc_clk_t: ret = enable_clk_module(module, drv, depth); break; + case s32cc_clkmux_t: + ret = -ENOTSUP; + break; + case s32cc_pll_t: + ret = -ENOTSUP; + break; + case s32cc_pll_out_div_t: + ret = -ENOTSUP; + break; default: ret = -EINVAL; break; @@ -251,6 +260,11 @@ static int set_module_rate(const struct s32cc_clk_obj *module, case s32cc_osc_t: ret = set_osc_freq(module, rate, orate, depth); break; + case s32cc_clkmux_t: + case s32cc_pll_t: + case s32cc_pll_out_div_t: + ret = -ENOTSUP; + break; default: ret = -EINVAL; break; diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c index f8fc52f1d..b75c3ffe2 100644 --- a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c +++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c @@ -23,11 +23,30 @@ static struct s32cc_osc sirc = static struct s32cc_clk sirc_clk = S32CC_MODULE_CLK(sirc); -static struct s32cc_clk *s32cc_hw_clk_list[3] = { +/* ARM PLL */ +static struct s32cc_clkmux arm_pll_mux = + S32CC_CLKMUX_INIT(S32CC_ARM_PLL, 0, 2, + S32CC_CLK_FIRC, + S32CC_CLK_FXOSC, 0, 0, 0); +static struct s32cc_clk arm_pll_mux_clk = + S32CC_MODULE_CLK(arm_pll_mux); +static struct s32cc_pll armpll = + S32CC_PLL_INIT(arm_pll_mux_clk, S32CC_ARM_PLL, 2); +static struct s32cc_clk arm_pll_vco_clk = + S32CC_FREQ_MODULE_CLK(armpll, 1400 * MHZ, 2000 * MHZ); + +static struct s32cc_pll_out_div arm_pll_phi0_div = + S32CC_PLL_OUT_DIV_INIT(armpll, 0); +static struct s32cc_clk arm_pll_phi0_clk = + S32CC_FREQ_MODULE_CLK(arm_pll_phi0_div, 0, GHZ); + +static struct s32cc_clk *s32cc_hw_clk_list[5] = { /* Oscillators */ [S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk, [S32CC_CLK_ID(S32CC_CLK_SIRC)] = &sirc_clk, [S32CC_CLK_ID(S32CC_CLK_FXOSC)] = &fxosc_clk, + /* ARM PLL */ + [S32CC_CLK_ID(S32CC_CLK_ARM_PLL_PHI0)] = &arm_pll_phi0_clk, }; static struct s32cc_clk_array s32cc_hw_clocks = { @@ -36,10 +55,23 @@ static struct s32cc_clk_array s32cc_hw_clocks = { .n_clks = ARRAY_SIZE(s32cc_hw_clk_list), }; +static struct s32cc_clk *s32cc_arch_clk_list[2] = { + /* ARM PLL */ + [S32CC_CLK_ID(S32CC_CLK_ARM_PLL_MUX)] = &arm_pll_mux_clk, + [S32CC_CLK_ID(S32CC_CLK_ARM_PLL_VCO)] = &arm_pll_vco_clk, +}; + +static struct s32cc_clk_array s32cc_arch_clocks = { + .type_mask = S32CC_CLK_TYPE(S32CC_CLK_ARM_PLL_MUX), + .clks = &s32cc_arch_clk_list[0], + .n_clks = ARRAY_SIZE(s32cc_arch_clk_list), +}; + struct s32cc_clk *s32cc_get_arch_clk(unsigned long id) { - static const struct s32cc_clk_array *clk_table[1] = { + static const struct s32cc_clk_array *clk_table[2] = { &s32cc_hw_clocks, + &s32cc_arch_clocks, }; return s32cc_get_clk_from_table(clk_table, ARRAY_SIZE(clk_table), id); diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h index 9524f72ef..648af6377 100644 --- a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h +++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h @@ -14,12 +14,16 @@ enum s32cc_clkm_type { s32cc_osc_t, s32cc_clk_t, + s32cc_pll_t, + s32cc_pll_out_div_t, + s32cc_clkmux_t, }; enum s32cc_clk_source { S32CC_FIRC, S32CC_FXOSC, S32CC_SIRC, + S32CC_ARM_PLL, }; struct s32cc_clk_obj { @@ -42,6 +46,65 @@ struct s32cc_osc { .source = (SOURCE), \ } +struct s32cc_clkmux { + struct s32cc_clk_obj desc; + enum s32cc_clk_source module; + uint8_t index; /* Mux index in parent module */ + unsigned long source_id; /* Selected source */ + uint8_t nclks; /* Number of input clocks */ + unsigned long clkids[5]; /* IDs of the input clocks */ +}; + +#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \ +{ \ + .desc = { \ + .type = (TYPE), \ + }, \ + .module = (MODULE), \ + .index = (INDEX), \ + .nclks = (NCLKS), \ + .clkids = {__VA_ARGS__}, \ +} + +#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ + S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \ + INDEX, NCLKS, __VA_ARGS__) + +struct s32cc_pll { + struct s32cc_clk_obj desc; + struct s32cc_clk_obj *source; + enum s32cc_clk_source instance; + unsigned long vco_freq; + uint32_t ndividers; + uintptr_t base; +}; + +#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \ +{ \ + .desc = { \ + .type = s32cc_pll_t, \ + }, \ + .source = &(PLL_MUX_CLK).desc, \ + .instance = (INSTANCE), \ + .ndividers = (NDIVIDERS), \ +} + +struct s32cc_pll_out_div { + struct s32cc_clk_obj desc; + struct s32cc_clk_obj *parent; + uint32_t index; + unsigned long freq; +}; + +#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \ +{ \ + .desc = { \ + .type = s32cc_pll_out_div_t, \ + }, \ + .parent = &(PARENT).desc, \ + .index = (INDEX), \ +} + struct s32cc_clk { struct s32cc_clk_obj desc; struct s32cc_clk_obj *module; From 12e7a2cd2f8f535dfd63834ce78e3fc248ff39f2 Mon Sep 17 00:00:00 2001 From: Ghennadi Procopciuc Date: Wed, 12 Jun 2024 10:02:07 +0300 Subject: [PATCH 3/5] feat(nxp-clk): add set_parent callback On S32CC SoCs, the set_parent operation will be used on clock modules that are mux instances in order to establish the clock source. This will be used for PLLs and MC_CGM muxes. Change-Id: I7228d379500ea790459b858da8fc0bdcbed4fd62 Signed-off-by: Ghennadi Procopciuc --- drivers/nxp/clk/s32cc/s32cc_clk_drv.c | 44 ++++++++++++++++++- .../drivers/nxp/clk/s32cc/s32cc-clk-modules.h | 30 +++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c index c15b03306..dd81d6698 100644 --- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c +++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c @@ -301,7 +301,49 @@ static int s32cc_clk_get_parent(unsigned long id) static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id) { - return -ENOTSUP; + const struct s32cc_clk *parent; + const struct s32cc_clk *clk; + bool valid_source = false; + struct s32cc_clkmux *mux; + uint8_t i; + + clk = s32cc_get_arch_clk(id); + if (clk == NULL) { + return -EINVAL; + } + + parent = s32cc_get_arch_clk(parent_id); + if (parent == NULL) { + return -EINVAL; + } + + if (!is_s32cc_clk_mux(clk)) { + ERROR("Clock %lu is not a mux\n", id); + return -EINVAL; + } + + mux = s32cc_clk2mux(clk); + if (mux == NULL) { + ERROR("Failed to cast clock %lu to clock mux\n", id); + return -EINVAL; + } + + for (i = 0; i < mux->nclks; i++) { + if (mux->clkids[i] == parent_id) { + valid_source = true; + break; + } + } + + if (!valid_source) { + ERROR("Clock %lu is not a valid clock for mux %lu\n", + parent_id, id); + return -EINVAL; + } + + mux->source_id = parent_id; + + return 0; } void s32cc_clk_register_drv(void) diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h index 648af6377..23a611c55 100644 --- a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h +++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h @@ -6,6 +6,7 @@ #define S32CC_CLK_MODULES_H #include +#include #include #define MHZ UL(1000000) @@ -151,4 +152,33 @@ static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod) return (struct s32cc_clk *)clk_addr; } +static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk) +{ + const struct s32cc_clk_obj *module; + + module = clk->module; + if (module == NULL) { + return false; + } + + return (module->type == s32cc_clkmux_t); +} + +static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod) +{ + uintptr_t cmux_addr; + + cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc); + return (struct s32cc_clkmux *)cmux_addr; +} + +static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk) +{ + if (!is_s32cc_clk_mux(clk)) { + return NULL; + } + + return s32cc_obj2clkmux(clk->module); +} + #endif /* S32CC_CLK_MODULES_H */ From 3fa91a94501ed13587132f6e2aec66a6c054c61e Mon Sep 17 00:00:00 2001 From: Ghennadi Procopciuc Date: Wed, 12 Jun 2024 10:53:06 +0300 Subject: [PATCH 4/5] feat(nxp-clk): add MC_CGM clock objects The MC_CGM1 clock objects will participate in A53 clocking. Change-Id: I7309b630d72ac0ad66df7c299b678454220e0581 Signed-off-by: Ghennadi Procopciuc --- drivers/nxp/clk/s32cc/s32cc_clk_drv.c | 4 ++++ drivers/nxp/clk/s32cc/s32cc_clk_modules.c | 12 +++++++++++- include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h | 9 ++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c index dd81d6698..69a9d2173 100644 --- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c +++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c @@ -145,6 +145,9 @@ static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth case s32cc_clkmux_t: ret = -ENOTSUP; break; + case s32cc_shared_clkmux_t: + ret = -ENOTSUP; + break; case s32cc_pll_t: ret = -ENOTSUP; break; @@ -261,6 +264,7 @@ static int set_module_rate(const struct s32cc_clk_obj *module, ret = set_osc_freq(module, rate, orate, depth); break; case s32cc_clkmux_t: + case s32cc_shared_clkmux_t: case s32cc_pll_t: case s32cc_pll_out_div_t: ret = -ENOTSUP; diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c index b75c3ffe2..1f381b601 100644 --- a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c +++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c @@ -40,6 +40,14 @@ static struct s32cc_pll_out_div arm_pll_phi0_div = static struct s32cc_clk arm_pll_phi0_clk = S32CC_FREQ_MODULE_CLK(arm_pll_phi0_div, 0, GHZ); +/* MC_CGM1 */ +static struct s32cc_clkmux cgm1_mux0 = + S32CC_SHARED_CLKMUX_INIT(S32CC_CGM1, 0, 3, + S32CC_CLK_FIRC, + S32CC_CLK_ARM_PLL_PHI0, + S32CC_CLK_ARM_PLL_DFS2, 0, 0); +static struct s32cc_clk cgm1_mux0_clk = S32CC_MODULE_CLK(cgm1_mux0); + static struct s32cc_clk *s32cc_hw_clk_list[5] = { /* Oscillators */ [S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk, @@ -55,10 +63,12 @@ static struct s32cc_clk_array s32cc_hw_clocks = { .n_clks = ARRAY_SIZE(s32cc_hw_clk_list), }; -static struct s32cc_clk *s32cc_arch_clk_list[2] = { +static struct s32cc_clk *s32cc_arch_clk_list[3] = { /* ARM PLL */ [S32CC_CLK_ID(S32CC_CLK_ARM_PLL_MUX)] = &arm_pll_mux_clk, [S32CC_CLK_ID(S32CC_CLK_ARM_PLL_VCO)] = &arm_pll_vco_clk, + /* MC_CGM1 */ + [S32CC_CLK_ID(S32CC_CLK_MC_CGM1_MUX0)] = &cgm1_mux0_clk, }; static struct s32cc_clk_array s32cc_arch_clocks = { diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h index 23a611c55..6ffe32185 100644 --- a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h +++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h @@ -18,6 +18,7 @@ enum s32cc_clkm_type { s32cc_pll_t, s32cc_pll_out_div_t, s32cc_clkmux_t, + s32cc_shared_clkmux_t, }; enum s32cc_clk_source { @@ -25,6 +26,7 @@ enum s32cc_clk_source { S32CC_FXOSC, S32CC_SIRC, S32CC_ARM_PLL, + S32CC_CGM1, }; struct s32cc_clk_obj { @@ -71,6 +73,10 @@ struct s32cc_clkmux { S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \ INDEX, NCLKS, __VA_ARGS__) +#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \ + S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \ + INDEX, NCLKS, __VA_ARGS__) + struct s32cc_pll { struct s32cc_clk_obj desc; struct s32cc_clk_obj *source; @@ -161,7 +167,8 @@ static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk) return false; } - return (module->type == s32cc_clkmux_t); + return (module->type == s32cc_clkmux_t) || + (module->type == s32cc_shared_clkmux_t); } static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod) From 83af45042debcaf76f2f898984f1b74dedc477e1 Mon Sep 17 00:00:00 2001 From: Ghennadi Procopciuc Date: Wed, 12 Jun 2024 11:17:37 +0300 Subject: [PATCH 5/5] feat(nxp-clk): set parent for ARM PLL and MC_CGM muxes Set the parent for ARM PLL and MC_CGM muxes as part of the early clocks enablement. Change-Id: If88186caad520c3f7bb1fb602de526d940037a1c Signed-off-by: Ghennadi Procopciuc --- drivers/nxp/clk/s32cc/s32cc_early_clks.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c index 8e4e78b79..98f30d88c 100644 --- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c +++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c @@ -16,6 +16,16 @@ int s32cc_init_early_clks(void) s32cc_clk_register_drv(); + ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC); + if (ret != 0) { + return ret; + } + + ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0); + if (ret != 0) { + return ret; + } + ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL); if (ret != 0) { return ret;