From 6489e47b2eb29e172eab88bbba8ad859263bc146 Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Tue, 4 Aug 2026 13:55:21 +0100 Subject: [PATCH 1/6] clk: adi: sc846: correct driver header The SC846 clock driver was derived from the existing ADI clock support, but its SoC specific clock topology was implemented and is maintained by Analog Devices. Remove the stale Timesys authorship and porting annotations, and describe the file as the SC846 clock driver. Lastly update the Analog Devices copyright year from 2022 to 2026. Signed-off-by: Qasim Ijaz --- drivers/clk/adi/clk-adi-sc846.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clk/adi/clk-adi-sc846.c b/drivers/clk/adi/clk-adi-sc846.c index 05976699997a..d8242ed78a22 100644 --- a/drivers/clk/adi/clk-adi-sc846.c +++ b/drivers/clk/adi/clk-adi-sc846.c @@ -1,12 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * (C) Copyright 2022 - Analog Devices, Inc. + * Clock support for ADI SC846 processor * - * Written and/or maintained by Timesys Corporation - * - * Author: Greg Malysa - * - * Ported from Linux: Nathan Barrett-Morrison + * (C) Copyright 2026 - Analog Devices, Inc. */ #include From 4fc88721260cc46f7d996f0f594d3e4aaf5eaa3c Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Wed, 5 Aug 2026 09:56:16 +0100 Subject: [PATCH 2/6] clk: adi: sc846: correct PLLCLK fixed factor clock div values The PLLCLK fixed factor clock currently divides its VCO parent rate by four. The HRM specifies that PLLCLK divides its parent rate by two. Set the PLLCLK divisor to two. Signed-off-by: Qasim Ijaz --- drivers/clk/adi/clk-adi-sc846.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/adi/clk-adi-sc846.c b/drivers/clk/adi/clk-adi-sc846.c index d8242ed78a22..62f839e345b7 100644 --- a/drivers/clk/adi/clk-adi-sc846.c +++ b/drivers/clk/adi/clk-adi-sc846.c @@ -89,12 +89,11 @@ static int sc846_clock_probe(struct udevice *dev) clks[ADSP_SC846_CLK_CGU0_PLLCLK] = clk_register_fixed_factor(NULL, "cgu0_pllclk", "cgu0_vco", CLK_SET_RATE_PARENT, - 1, 4); + 1, 2); clks[ADSP_SC846_CLK_CGU1_PLLCLK] = clk_register_fixed_factor(NULL, "cgu1_pllclk", "cgu1_vco", CLK_SET_RATE_PARENT, - 1, 4); - + 1, 2); /* CGU0 DIV */ /* Dividers from pll output */ clks[ADSP_SC846_CLK_CGU0_CDIV] = cgu_divider("cgu0_cdiv", "cgu0_pllclk", From 3967c1f183155d73582a99b652e40f8b22f9ad1f Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Wed, 5 Aug 2026 12:23:49 +0100 Subject: [PATCH 3/6] clk: adi: sc846: Add PLLCLK_HALF clock and correct divider clock parents The current driver uses the cguX_pllclk clock as parents for the divider clocks but this is incorrect because the divider clocks should have a parent which divides the rate of pllclk by 2 according to the HRM. To account for this introduce a fixed factor clock cguX_pllclk_half which does that and make that the parent of the divider clocks. As part of this add the needed clock binding IDs: ADSP_SC846_CLK_CGU0_PLLCLK_HALF and ADSP_SC846_CLK_CGU1_PLLCLK_HALF. Signed-off-by: Qasim Ijaz --- drivers/clk/adi/clk-adi-sc846.c | 28 +++++++++++++-------- include/dt-bindings/clock/adi-sc5xx-clock.h | 4 ++- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/clk/adi/clk-adi-sc846.c b/drivers/clk/adi/clk-adi-sc846.c index 62f839e345b7..dcc01aa5cb5f 100644 --- a/drivers/clk/adi/clk-adi-sc846.c +++ b/drivers/clk/adi/clk-adi-sc846.c @@ -94,22 +94,28 @@ static int sc846_clock_probe(struct udevice *dev) "cgu1_vco", CLK_SET_RATE_PARENT, 1, 2); + clks[ADSP_SC846_CLK_CGU0_PLLCLK_HALF] = + clk_register_fixed_factor(NULL, "cgu0_pllclk_half", "cgu0_pllclk", + CLK_SET_RATE_PARENT, 1, 2); + clks[ADSP_SC846_CLK_CGU1_PLLCLK_HALF] = + clk_register_fixed_factor(NULL, "cgu1_pllclk_half", "cgu1_pllclk", + CLK_SET_RATE_PARENT, 1, 2); /* CGU0 DIV */ /* Dividers from pll output */ - clks[ADSP_SC846_CLK_CGU0_CDIV] = cgu_divider("cgu0_cdiv", "cgu0_pllclk", + clks[ADSP_SC846_CLK_CGU0_CDIV] = cgu_divider("cgu0_cdiv", "cgu0_pllclk_half", cgu0 + CGU_DIV, 0, 5, 0); - clks[ADSP_SC846_CLK_CGU0_SYSCLK] = cgu_divider("sysclk_0", "cgu0_pllclk", + clks[ADSP_SC846_CLK_CGU0_SYSCLK] = cgu_divider("sysclk_0", "cgu0_pllclk_half", cgu0 + CGU_DIV, 8, 5, 0); - clks[ADSP_SC846_CLK_CGU0_DDIV] = cgu_divider("cgu0_ddiv", "cgu0_pllclk", + clks[ADSP_SC846_CLK_CGU0_DDIV] = cgu_divider("cgu0_ddiv", "cgu0_pllclk_half", cgu0 + CGU_DIV, 16, 5, 0); - clks[ADSP_SC846_CLK_CGU0_ODIV] = cgu_divider("cgu0_odiv", "cgu0_pllclk", + clks[ADSP_SC846_CLK_CGU0_ODIV] = cgu_divider("cgu0_odiv", "cgu0_pllclk_half", cgu0 + CGU_DIV, 22, 7, 0); clks[ADSP_SC846_CLK_CGU0_S0SELDIV] = cgu_divider("cgu0_s0seldiv", "sysclk_0", cgu0 + CGU_DIV, 5, 3, 0); clks[ADSP_SC846_CLK_CGU0_S1SELDIV] = cgu_divider("cgu0_s1seldiv", "sysclk_0", cgu0 + CGU_DIV, 13, 3, 0); clks[ADSP_SC846_CLK_CGU0_S1SELEXDIV] = cgu_divider("cgu0_s1selexdiv", - "cgu0_pllclk", + "cgu0_pllclk_half", cgu0 + CGU_DIVEX, 16, 8, 0); clks[ADSP_SC846_CLK_CGU0_S1SEL] = clk_register_mux(NULL, "cgu0_sclk1sel", cgu0_s1sels, 2, @@ -132,23 +138,23 @@ static int sc846_clock_probe(struct udevice *dev) 1, 5); /* CGU1 DIV */ - clks[ADSP_SC846_CLK_CGU1_CDIV] = cgu_divider("cgu1_cdiv", "cgu1_pllclk", + clks[ADSP_SC846_CLK_CGU1_CDIV] = cgu_divider("cgu1_cdiv", "cgu1_pllclk_half", cgu1 + CGU_DIV, 0, 5, 0); - clks[ADSP_SC846_CLK_CGU1_SYSCLK] = cgu_divider("sysclk_1", "cgu1_pllclk", + clks[ADSP_SC846_CLK_CGU1_SYSCLK] = cgu_divider("sysclk_1", "cgu1_pllclk_half", cgu1 + CGU_DIV, 8, 5, 0); - clks[ADSP_SC846_CLK_CGU1_DDIV] = cgu_divider("cgu1_ddiv", "cgu1_pllclk", + clks[ADSP_SC846_CLK_CGU1_DDIV] = cgu_divider("cgu1_ddiv", "cgu1_pllclk_half", cgu1 + CGU_DIV, 16, 5, 0); - clks[ADSP_SC846_CLK_CGU1_ODIV] = cgu_divider("cgu1_odiv", "cgu1_pllclk", + clks[ADSP_SC846_CLK_CGU1_ODIV] = cgu_divider("cgu1_odiv", "cgu1_pllclk_half", cgu1 + CGU_DIV, 22, 7, 0); clks[ADSP_SC846_CLK_CGU1_S0SELDIV] = cgu_divider("cgu1_s0seldiv", "sysclk_1", cgu1 + CGU_DIV, 5, 3, 0); clks[ADSP_SC846_CLK_CGU1_S1SELDIV] = cgu_divider("cgu1_s1seldiv", "sysclk_1", cgu1 + CGU_DIV, 13, 3, 0); clks[ADSP_SC846_CLK_CGU1_S0SELEXDIV] = cgu_divider("cgu1_s0selexdiv", - "cgu1_pllclk", + "cgu1_pllclk_half", cgu1 + CGU_DIVEX, 0, 8, 0); clks[ADSP_SC846_CLK_CGU1_S1SELEXDIV] = cgu_divider("cgu1_s1selexdiv", - "cgu1_pllclk", + "cgu1_pllclk_half", cgu1 + CGU_DIVEX, 16, 8, 0); clks[ADSP_SC846_CLK_CGU1_S0SEL] = clk_register_mux(NULL, "cgu1_sclk0sel", cgu1_s0sels, 2, diff --git a/include/dt-bindings/clock/adi-sc5xx-clock.h b/include/dt-bindings/clock/adi-sc5xx-clock.h index 261bb6f9c9f2..7aae4cef663f 100644 --- a/include/dt-bindings/clock/adi-sc5xx-clock.h +++ b/include/dt-bindings/clock/adi-sc5xx-clock.h @@ -79,7 +79,9 @@ #define ADSP_SC846_CLK_TRACE 65 #define ADSP_SC846_CLK_PWM 66 #define ADSP_SC846_CLK_MSHC 67 -#define ADSP_SC846_CLK_END 68 +#define ADSP_SC846_CLK_CGU0_PLLCLK_HALF 68 +#define ADSP_SC846_CLK_CGU1_PLLCLK_HALF 69 +#define ADSP_SC846_CLK_END 70 //ADSP-SC594 #define ADSP_SC594_CLK_DUMMY 0 From e0629f2c03e60e84afa409dc3cb5e1c0fd62d765 Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Wed, 5 Aug 2026 12:52:36 +0100 Subject: [PATCH 4/6] clk: adi: sc846: check input clock lookup errors Check the return values from clk_get_by_name() when obtaining the dummy and sys_clkin0 input clocks. Return the lookup error instead of continuing with invalid clock handles. Signed-off-by: Qasim Ijaz --- drivers/clk/adi/clk-adi-sc846.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/clk/adi/clk-adi-sc846.c b/drivers/clk/adi/clk-adi-sc846.c index dcc01aa5cb5f..2999ebe022b2 100644 --- a/drivers/clk/adi/clk-adi-sc846.c +++ b/drivers/clk/adi/clk-adi-sc846.c @@ -62,8 +62,13 @@ static int sc846_clock_probe(struct udevice *dev) cdu = devm_ioremap(dev, res.start, resource_size(&res)); /* Input clock configuration */ - clk_get_by_name(dev, "dummy", &dummy); - clk_get_by_name(dev, "sys_clkin0", &clkin0); + ret = clk_get_by_name(dev, "dummy", &dummy); + if (ret < 0) + return ret; + + ret = clk_get_by_name(dev, "sys_clkin0", &clkin0); + if (ret < 0) + return ret; clks[ADSP_SC846_CLK_DUMMY] = &dummy; clks[ADSP_SC846_CLK_SYS_CLKIN0] = &clkin0; From 074b4f72118f5d1c96902db8a03c4774167a3a9d Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Wed, 5 Aug 2026 13:02:51 +0100 Subject: [PATCH 5/6] clk: adi: sc846: remove duplicate CCLK2_1 clock CCLK2_1 is registered twice also it is a CGU1 clock not a CGU0 clock. Remove the incorrect CGU0 registration so CCLK2_1. Also remove the unused clock binding and renumber the remaining SC846 clock IDs. Signed-off-by: Qasim Ijaz --- drivers/clk/adi/clk-adi-sc846.c | 4 - include/dt-bindings/clock/adi-sc5xx-clock.h | 87 ++++++++++----------- 2 files changed, 43 insertions(+), 48 deletions(-) diff --git a/drivers/clk/adi/clk-adi-sc846.c b/drivers/clk/adi/clk-adi-sc846.c index 2999ebe022b2..011d579a2a4d 100644 --- a/drivers/clk/adi/clk-adi-sc846.c +++ b/drivers/clk/adi/clk-adi-sc846.c @@ -132,10 +132,6 @@ static int sc846_clock_probe(struct udevice *dev) "cgu0_vco", CLK_SET_RATE_PARENT, 1, 3); - clks[ADSP_SC846_CLK_CGU0_CCLK2_1] = clk_register_fixed_factor(NULL, "cclk2_1", - "cgu0_vco", - CLK_SET_RATE_PARENT, - 1, 3); /* DCLK1_x = VCO/5 */ clks[ADSP_SC846_CLK_CGU0_DCLK1_0] = clk_register_fixed_factor(NULL, "dclk1_0", "cgu0_vco", diff --git a/include/dt-bindings/clock/adi-sc5xx-clock.h b/include/dt-bindings/clock/adi-sc5xx-clock.h index 7aae4cef663f..dd9d4abc2360 100644 --- a/include/dt-bindings/clock/adi-sc5xx-clock.h +++ b/include/dt-bindings/clock/adi-sc5xx-clock.h @@ -38,50 +38,49 @@ #define ADSP_SC846_CLK_CGU1_S0SEL 24 #define ADSP_SC846_CLK_CGU1_S1SEL 25 #define ADSP_SC846_CLK_CGU0_CCLK2_0 26 -#define ADSP_SC846_CLK_CGU0_CCLK2_1 27 -#define ADSP_SC846_CLK_CGU0_DCLK1_0 28 -#define ADSP_SC846_CLK_CGU0_CCLK0 29 -#define ADSP_SC846_CLK_CGU0_OCLK 30 -#define ADSP_SC846_CLK_CGU0_DCLK 31 -#define ADSP_SC846_CLK_CGU0_SCLK1 32 -#define ADSP_SC846_CLK_CGU0_SCLK0 33 -#define ADSP_SC846_CLK_CGU1_CCLK0 34 -#define ADSP_SC846_CLK_CGU1_OCLK 35 -#define ADSP_SC846_CLK_CGU1_DCLK 36 -#define ADSP_SC846_CLK_CGU1_SCLK1 37 -#define ADSP_SC846_CLK_CGU1_SCLK0 38 -#define ADSP_SC846_CLK_CGU1_CCLK2 39 -#define ADSP_SC846_CLK_SHARC0_SEL 40 -#define ADSP_SC846_CLK_ARM0_SEL 41 -#define ADSP_SC846_CLK_ARM1_SEL 42 -#define ADSP_SC846_CLK_CDU_DDR_SEL 43 -#define ADSP_SC846_CLK_CAN_SEL 44 -#define ADSP_SC846_CLK_SPDIF_SEL 45 -#define ADSP_SC846_CLK_SPI_SEL 46 -#define ADSP_SC846_CLK_GIGE_SEL 47 -#define ADSP_SC846_CLK_XSPI2_SEL 48 -#define ADSP_SC846_CLK_LP_SEL 49 -#define ADSP_SC846_CLK_XSPI_SEL 50 -#define ADSP_SC846_CLK_TRACE_SEL 51 -#define ADSP_SC846_CLK_PWM_SEL 52 -#define ADSP_SC846_CLK_MSHC_SEL 53 -#define ADSP_SC846_CLK_SHARC0 54 -#define ADSP_SC846_CLK_ARM0 55 -#define ADSP_SC846_CLK_ARM1 56 -#define ADSP_SC846_CLK_CDU_DDR 57 -#define ADSP_SC846_CLK_CAN 58 -#define ADSP_SC846_CLK_SPDIF 59 -#define ADSP_SC846_CLK_SPI 60 -#define ADSP_SC846_CLK_GIGE 61 -#define ADSP_SC846_CLK_XSPI2 62 -#define ADSP_SC846_CLK_LP 63 -#define ADSP_SC846_CLK_XSPI 64 -#define ADSP_SC846_CLK_TRACE 65 -#define ADSP_SC846_CLK_PWM 66 -#define ADSP_SC846_CLK_MSHC 67 -#define ADSP_SC846_CLK_CGU0_PLLCLK_HALF 68 -#define ADSP_SC846_CLK_CGU1_PLLCLK_HALF 69 -#define ADSP_SC846_CLK_END 70 +#define ADSP_SC846_CLK_CGU0_DCLK1_0 27 +#define ADSP_SC846_CLK_CGU0_CCLK0 28 +#define ADSP_SC846_CLK_CGU0_OCLK 29 +#define ADSP_SC846_CLK_CGU0_DCLK 30 +#define ADSP_SC846_CLK_CGU0_SCLK1 31 +#define ADSP_SC846_CLK_CGU0_SCLK0 32 +#define ADSP_SC846_CLK_CGU1_CCLK0 33 +#define ADSP_SC846_CLK_CGU1_OCLK 34 +#define ADSP_SC846_CLK_CGU1_DCLK 35 +#define ADSP_SC846_CLK_CGU1_SCLK1 36 +#define ADSP_SC846_CLK_CGU1_SCLK0 37 +#define ADSP_SC846_CLK_CGU1_CCLK2 38 +#define ADSP_SC846_CLK_SHARC0_SEL 39 +#define ADSP_SC846_CLK_ARM0_SEL 40 +#define ADSP_SC846_CLK_ARM1_SEL 41 +#define ADSP_SC846_CLK_CDU_DDR_SEL 42 +#define ADSP_SC846_CLK_CAN_SEL 43 +#define ADSP_SC846_CLK_SPDIF_SEL 44 +#define ADSP_SC846_CLK_SPI_SEL 45 +#define ADSP_SC846_CLK_GIGE_SEL 46 +#define ADSP_SC846_CLK_XSPI2_SEL 47 +#define ADSP_SC846_CLK_LP_SEL 48 +#define ADSP_SC846_CLK_XSPI_SEL 49 +#define ADSP_SC846_CLK_TRACE_SEL 50 +#define ADSP_SC846_CLK_PWM_SEL 51 +#define ADSP_SC846_CLK_MSHC_SEL 52 +#define ADSP_SC846_CLK_SHARC0 53 +#define ADSP_SC846_CLK_ARM0 54 +#define ADSP_SC846_CLK_ARM1 55 +#define ADSP_SC846_CLK_CDU_DDR 56 +#define ADSP_SC846_CLK_CAN 57 +#define ADSP_SC846_CLK_SPDIF 58 +#define ADSP_SC846_CLK_SPI 59 +#define ADSP_SC846_CLK_GIGE 60 +#define ADSP_SC846_CLK_XSPI2 61 +#define ADSP_SC846_CLK_LP 62 +#define ADSP_SC846_CLK_XSPI 63 +#define ADSP_SC846_CLK_TRACE 64 +#define ADSP_SC846_CLK_PWM 65 +#define ADSP_SC846_CLK_MSHC 66 +#define ADSP_SC846_CLK_CGU0_PLLCLK_HALF 67 +#define ADSP_SC846_CLK_CGU1_PLLCLK_HALF 68 +#define ADSP_SC846_CLK_END 69 //ADSP-SC594 #define ADSP_SC594_CLK_DUMMY 0 From 1bd7329ca134ce5eddf78a25c2641c7555903f2c Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Wed, 5 Aug 2026 14:15:59 +0100 Subject: [PATCH 6/6] clk: adi: sc846: add CGU1 DCLK1_1 clock The driver registers the CGU0 DCLK1_0 fixed factor clock but is missing the corresponding DCLK1_1 clock from CGU1. Add DCLK1_1 as a fixed factor clock derived directly from the CGU1 VCO with a mult and div value of 1 and 5. Signed-off-by: Qasim Ijaz --- drivers/clk/adi/clk-adi-sc846.c | 3 +++ include/dt-bindings/clock/adi-sc5xx-clock.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/adi/clk-adi-sc846.c b/drivers/clk/adi/clk-adi-sc846.c index 011d579a2a4d..eb4b952adf08 100644 --- a/drivers/clk/adi/clk-adi-sc846.c +++ b/drivers/clk/adi/clk-adi-sc846.c @@ -169,6 +169,9 @@ static int sc846_clock_probe(struct udevice *dev) "cgu1_vco", CLK_SET_RATE_PARENT, 1, 3); + clks[ADSP_SC846_CLK_CGU1_DCLK1_1] = + clk_register_fixed_factor(NULL, "dclk1_1", "cgu1_vco", + CLK_SET_RATE_PARENT, 1, 5); /* Gates to enable CGU outputs */ clks[ADSP_SC846_CLK_CGU0_CCLK0] = cgu_gate("cclk0_0", "cgu0_cdiv", diff --git a/include/dt-bindings/clock/adi-sc5xx-clock.h b/include/dt-bindings/clock/adi-sc5xx-clock.h index dd9d4abc2360..4462a474329b 100644 --- a/include/dt-bindings/clock/adi-sc5xx-clock.h +++ b/include/dt-bindings/clock/adi-sc5xx-clock.h @@ -80,7 +80,8 @@ #define ADSP_SC846_CLK_MSHC 66 #define ADSP_SC846_CLK_CGU0_PLLCLK_HALF 67 #define ADSP_SC846_CLK_CGU1_PLLCLK_HALF 68 -#define ADSP_SC846_CLK_END 69 +#define ADSP_SC846_CLK_CGU1_DCLK1_1 69 +#define ADSP_SC846_CLK_END 70 //ADSP-SC594 #define ADSP_SC594_CLK_DUMMY 0