* [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock @ 2023-08-22 8:27 Yu Tu 2023-08-22 8:27 ` [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller Yu Tu ` (4 more replies) 0 siblings, 5 replies; 21+ messages in thread From: Yu Tu @ 2023-08-22 8:27 UTC (permalink / raw) To: linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan, Yu Tu 1. Add S4 SoC PLLs and Peripheral clock controller dt-bindings. 2. Add PLLs and Peripheral clock controller driver for S4 SOC. Yu Tu (4): dt-bindings: clock: document Amlogic S4 SoC PLL clock controller dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller clk: meson: S4: add support for Amlogic S4 SoC PLL clock driver clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller V9 -> V10: 1. Change the relevant S4 CLK patch based on Neil's recently modified patch. 2. Change patch 0003/0004 clocks comment, format and clock flags suggested by Jerome. V8 -> V9: Add patch 0001/0002 dt-bindings tag. Suggested by Krzysztof. V7 -> V8: 1. Change patch 0001/0002 dt-bindings title description, remove "meson". Suggested by Dmitry, Neil. 2. Change patch 0003/0004 clocks comment, format and clock flags suggested by Dmitry, Neil, Jerome. V6 -> V7: Change send patch series as well change format and clock flags suggested by Jerome. Change dt-bindings suggested by Krzysztof. V5 -> V6: Change send patch series, as well change format and clock flags. V4 -> V5: change format and clock flags and adjust the patch series as suggested by Jerome. V3 -> V4: change format and clock flags. V2 -> V3: Use two clock controller. V1 -> V2: Change format as discussed in the email. Link:https://lore.kernel.org/linux-amlogic/20230517070215.28463-1-yu.tu@amlogic.com/ .../clock/amlogic,s4-peripherals-clkc.yaml | 96 + .../bindings/clock/amlogic,s4-pll-clkc.yaml | 49 + drivers/clk/meson/Kconfig | 23 + drivers/clk/meson/Makefile | 2 + drivers/clk/meson/s4-peripherals.c | 3787 +++++++++++++++++ drivers/clk/meson/s4-peripherals.h | 57 + drivers/clk/meson/s4-pll.c | 867 ++++ drivers/clk/meson/s4-pll.h | 38 + .../clock/amlogic,s4-peripherals-clkc.h | 236 + .../dt-bindings/clock/amlogic,s4-pll-clkc.h | 43 + 10 files changed, 5198 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-pll-clkc.yaml create mode 100644 drivers/clk/meson/s4-peripherals.c create mode 100644 drivers/clk/meson/s4-peripherals.h create mode 100644 drivers/clk/meson/s4-pll.c create mode 100644 drivers/clk/meson/s4-pll.h create mode 100644 include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h create mode 100644 include/dt-bindings/clock/amlogic,s4-pll-clkc.h base-commit: bd0f6c57c2b324b6f92ccfe13a8005ff829287b8 -- 2.33.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller 2023-08-22 8:27 [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Yu Tu @ 2023-08-22 8:27 ` Yu Tu 2023-08-22 16:32 ` Krzysztof Kozlowski 2023-08-22 8:27 ` [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals " Yu Tu ` (3 subsequent siblings) 4 siblings, 1 reply; 21+ messages in thread From: Yu Tu @ 2023-08-22 8:27 UTC (permalink / raw) To: linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan, Yu Tu Add the S4 PLL clock controller dt-bindings in the S4 SoC family. Signed-off-by: Yu Tu <yu.tu@amlogic.com> --- .../bindings/clock/amlogic,s4-pll-clkc.yaml | 49 +++++++++++++++++++ .../dt-bindings/clock/amlogic,s4-pll-clkc.h | 43 ++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-pll-clkc.yaml create mode 100644 include/dt-bindings/clock/amlogic,s4-pll-clkc.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,s4-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s4-pll-clkc.yaml new file mode 100644 index 000000000000..d8932ec26ca8 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,s4-pll-clkc.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,s4-pll-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic S4 PLL Clock Controller + +maintainers: + - Yu Tu <yu.tu@amlogic.com> + +properties: + compatible: + const: amlogic,s4-pll-clkc + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: xtal + + "#clock-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + +additionalProperties: false + +examples: + - | + clkc_pll: clock-controller@fe008000 { + compatible = "amlogic,s4-pll-clkc"; + reg = <0xfe008000 0x1e8>; + clocks = <&xtal>; + clock-names = "xtal"; + #clock-cells = <1>; + }; + +... diff --git a/include/dt-bindings/clock/amlogic,s4-pll-clkc.h b/include/dt-bindings/clock/amlogic,s4-pll-clkc.h new file mode 100644 index 000000000000..af9f110f8b62 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,s4-pll-clkc.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2022-2023 Amlogic, Inc. All rights reserved. + * Author: Yu Tu <yu.tu@amlogic.com> + */ + +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S4_PLL_CLKC_H +#define _DT_BINDINGS_CLOCK_AMLOGIC_S4_PLL_CLKC_H + +#define CLKID_FIXED_PLL_DCO 0 +#define CLKID_FIXED_PLL 1 +#define CLKID_FCLK_DIV2_DIV 2 +#define CLKID_FCLK_DIV2 3 +#define CLKID_FCLK_DIV3_DIV 4 +#define CLKID_FCLK_DIV3 5 +#define CLKID_FCLK_DIV4_DIV 6 +#define CLKID_FCLK_DIV4 7 +#define CLKID_FCLK_DIV5_DIV 8 +#define CLKID_FCLK_DIV5 9 +#define CLKID_FCLK_DIV7_DIV 10 +#define CLKID_FCLK_DIV7 11 +#define CLKID_FCLK_DIV2P5_DIV 12 +#define CLKID_FCLK_DIV2P5 13 +#define CLKID_GP0_PLL_DCO 14 +#define CLKID_GP0_PLL 15 +#define CLKID_HIFI_PLL_DCO 16 +#define CLKID_HIFI_PLL 17 +#define CLKID_HDMI_PLL_DCO 18 +#define CLKID_HDMI_PLL_OD 19 +#define CLKID_HDMI_PLL 20 +#define CLKID_MPLL_50M_DIV 21 +#define CLKID_MPLL_50M 22 +#define CLKID_MPLL_PREDIV 23 +#define CLKID_MPLL0_DIV 24 +#define CLKID_MPLL0 25 +#define CLKID_MPLL1_DIV 26 +#define CLKID_MPLL1 27 +#define CLKID_MPLL2_DIV 28 +#define CLKID_MPLL2 29 +#define CLKID_MPLL3_DIV 30 +#define CLKID_MPLL3 31 + +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PLL_CLKC_H */ -- 2.33.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller 2023-08-22 8:27 ` [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller Yu Tu @ 2023-08-22 16:32 ` Krzysztof Kozlowski 2023-08-23 2:24 ` Yu Tu 0 siblings, 1 reply; 21+ messages in thread From: Krzysztof Kozlowski @ 2023-08-22 16:32 UTC (permalink / raw) To: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 22/08/2023 10:27, Yu Tu wrote: > Add the S4 PLL clock controller dt-bindings in the S4 SoC family. > > Signed-off-by: Yu Tu <yu.tu@amlogic.com> Lovely. I sent youa friendly reminder at v8 which turns our you ignored. You keep ignoring, I will start ignoring as well from now on. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller 2023-08-22 16:32 ` Krzysztof Kozlowski @ 2023-08-23 2:24 ` Yu Tu 2023-08-23 5:43 ` Krzysztof Kozlowski 0 siblings, 1 reply; 21+ messages in thread From: Yu Tu @ 2023-08-23 2:24 UTC (permalink / raw) To: Krzysztof Kozlowski, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 2023/8/23 0:32, Krzysztof Kozlowski wrote: > [ EXTERNAL EMAIL ] > > On 22/08/2023 10:27, Yu Tu wrote: >> Add the S4 PLL clock controller dt-bindings in the S4 SoC family. >> >> Signed-off-by: Yu Tu <yu.tu@amlogic.com> > > Lovely. I sent youa friendly reminder at v8 which turns our you > ignored. You keep ignoring, I will start ignoring as well from now on. Hi Krzysztof, Sorry. I did not forget the friendly reminder in v8, I consulted you for this at the time, so I re-sent V9 after adding the tag. Because it was just "meson" that was removed. But V10 is based on Neil's patch, which I think is a bit of a change. So I didn't dare add it. Instead of forgetting your reminder. So what should I do, I'll follow your advice exactly. > > Best regards, > Krzysztof > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller 2023-08-23 2:24 ` Yu Tu @ 2023-08-23 5:43 ` Krzysztof Kozlowski 2023-08-23 6:20 ` Yu Tu 0 siblings, 1 reply; 21+ messages in thread From: Krzysztof Kozlowski @ 2023-08-23 5:43 UTC (permalink / raw) To: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 23/08/2023 04:24, Yu Tu wrote: > > > On 2023/8/23 0:32, Krzysztof Kozlowski wrote: >> [ EXTERNAL EMAIL ] >>> On 22/08/2023 10:27, Yu Tu wrote: >>> Add the S4 PLL clock controller dt-bindings in the S4 SoC family. >>> >>> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >> >> Lovely. I sent youa friendly reminder at v8 which turns our you >> ignored. You keep ignoring, I will start ignoring as well from now on. > > Hi Krzysztof, > > Sorry. I did not forget the friendly reminder in v8, I consulted you for > this at the time, so I re-sent V9 after adding the tag. Because it was > just "meson" that was removed. But V10 is based on Neil's patch, which I > think is a bit of a change. So I didn't dare add it. Instead of > forgetting your reminder. > > So what should I do, I'll follow your advice exactly. I don't think there was much difference between the version, which received the review, and the current patch. Otherwise your changelog should say that you drop Rb tag. Rebasing of something somewhere is not the reason, so please describe what are the differences in the patch? Best regards, Krzysztof ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller 2023-08-23 5:43 ` Krzysztof Kozlowski @ 2023-08-23 6:20 ` Yu Tu 2023-08-23 6:27 ` Krzysztof Kozlowski 0 siblings, 1 reply; 21+ messages in thread From: Yu Tu @ 2023-08-23 6:20 UTC (permalink / raw) To: Krzysztof Kozlowski, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 2023/8/23 13:43, Krzysztof Kozlowski wrote: > > [ EXTERNAL EMAIL ] > > On 23/08/2023 04:24, Yu Tu wrote: >> >> >> On 2023/8/23 0:32, Krzysztof Kozlowski wrote: >>> [ EXTERNAL EMAIL ] >>>> On 22/08/2023 10:27, Yu Tu wrote: >>>> Add the S4 PLL clock controller dt-bindings in the S4 SoC family. >>>> >>>> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >>> >>> Lovely. I sent youa friendly reminder at v8 which turns our you >>> ignored. You keep ignoring, I will start ignoring as well from now on. >> >> Hi Krzysztof, >> >> Sorry. I did not forget the friendly reminder in v8, I consulted you for >> this at the time, so I re-sent V9 after adding the tag. Because it was >> just "meson" that was removed. But V10 is based on Neil's patch, which I >> think is a bit of a change. So I didn't dare add it. Instead of >> forgetting your reminder. >> >> So what should I do, I'll follow your advice exactly. > > I don't think there was much difference between the version, which > received the review, and the current patch. Otherwise your changelog > should say that you drop Rb tag. Rebasing of something somewhere is not > the reason, so please describe what are the differences in the patch? The current patch and V9 patch difference is mainly based on Neil patch I put "include/dt - bindings/clock/amlogic,s4-pll-clkc.h" this document describes the clock index all exposed. Next, I should add Rob's tag and resend it. If you have any other suggestions, please tell me and I will strictly follow your suggestions. > > Best regards, > Krzysztof > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller 2023-08-23 6:20 ` Yu Tu @ 2023-08-23 6:27 ` Krzysztof Kozlowski 2023-08-23 6:35 ` Yu Tu 0 siblings, 1 reply; 21+ messages in thread From: Krzysztof Kozlowski @ 2023-08-23 6:27 UTC (permalink / raw) To: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 23/08/2023 08:20, Yu Tu wrote: > > > On 2023/8/23 13:43, Krzysztof Kozlowski wrote: >> >> [ EXTERNAL EMAIL ] >> >> On 23/08/2023 04:24, Yu Tu wrote: >>> >>> >>> On 2023/8/23 0:32, Krzysztof Kozlowski wrote: >>>> [ EXTERNAL EMAIL ] >>>>> On 22/08/2023 10:27, Yu Tu wrote: >>>>> Add the S4 PLL clock controller dt-bindings in the S4 SoC family. >>>>> >>>>> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >>>> >>>> Lovely. I sent youa friendly reminder at v8 which turns our you >>>> ignored. You keep ignoring, I will start ignoring as well from now on. >>> >>> Hi Krzysztof, >>> >>> Sorry. I did not forget the friendly reminder in v8, I consulted you for >>> this at the time, so I re-sent V9 after adding the tag. Because it was >>> just "meson" that was removed. But V10 is based on Neil's patch, which I >>> think is a bit of a change. So I didn't dare add it. Instead of >>> forgetting your reminder. >>> >>> So what should I do, I'll follow your advice exactly. >> >> I don't think there was much difference between the version, which >> received the review, and the current patch. Otherwise your changelog >> should say that you drop Rb tag. Rebasing of something somewhere is not >> the reason, so please describe what are the differences in the patch? > > The current patch and V9 patch difference is mainly based on Neil patch > I put "include/dt - bindings/clock/amlogic,s4-pll-clkc.h" this document > describes the clock index all exposed. Adding one include is insignificant change, thus any Rb tags should stay. > > Next, I should add Rob's tag and resend it. If you have any other > suggestions, please tell me and I will strictly follow your suggestions. I cannot add someone's tag, thus on your next version you must include it. I told this last time. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller 2023-08-23 6:27 ` Krzysztof Kozlowski @ 2023-08-23 6:35 ` Yu Tu 0 siblings, 0 replies; 21+ messages in thread From: Yu Tu @ 2023-08-23 6:35 UTC (permalink / raw) To: Krzysztof Kozlowski, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 2023/8/23 14:27, Krzysztof Kozlowski wrote: > [ EXTERNAL EMAIL ] > > On 23/08/2023 08:20, Yu Tu wrote: >> >> >> On 2023/8/23 13:43, Krzysztof Kozlowski wrote: >>> >>> [ EXTERNAL EMAIL ] >>> >>> On 23/08/2023 04:24, Yu Tu wrote: >>>> >>>> >>>> On 2023/8/23 0:32, Krzysztof Kozlowski wrote: >>>>> [ EXTERNAL EMAIL ] >>>>>> On 22/08/2023 10:27, Yu Tu wrote: >>>>>> Add the S4 PLL clock controller dt-bindings in the S4 SoC family. >>>>>> >>>>>> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >>>>> >>>>> Lovely. I sent youa friendly reminder at v8 which turns our you >>>>> ignored. You keep ignoring, I will start ignoring as well from now on. >>>> >>>> Hi Krzysztof, >>>> >>>> Sorry. I did not forget the friendly reminder in v8, I consulted you for >>>> this at the time, so I re-sent V9 after adding the tag. Because it was >>>> just "meson" that was removed. But V10 is based on Neil's patch, which I >>>> think is a bit of a change. So I didn't dare add it. Instead of >>>> forgetting your reminder. >>>> >>>> So what should I do, I'll follow your advice exactly. >>> >>> I don't think there was much difference between the version, which >>> received the review, and the current patch. Otherwise your changelog >>> should say that you drop Rb tag. Rebasing of something somewhere is not >>> the reason, so please describe what are the differences in the patch? >> >> The current patch and V9 patch difference is mainly based on Neil patch >> I put "include/dt - bindings/clock/amlogic,s4-pll-clkc.h" this document >> describes the clock index all exposed. > > Adding one include is insignificant change, thus any Rb tags should stay. I got it. >> >> Next, I should add Rob's tag and resend it. If you have any other >> suggestions, please tell me and I will strictly follow your suggestions. > > I cannot add someone's tag, thus on your next version you must include > it. I told this last time. Well. I remember your advice. Guaranteed no errors in the next version. > > Best regards, > Krzysztof > ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller 2023-08-22 8:27 [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Yu Tu 2023-08-22 8:27 ` [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller Yu Tu @ 2023-08-22 8:27 ` Yu Tu 2023-08-22 16:33 ` Krzysztof Kozlowski 2023-08-23 8:01 ` Jerome Brunet 2023-08-22 8:27 ` [PATCH V10 3/4] clk: meson: S4: add support for Amlogic S4 SoC PLL clock driver Yu Tu ` (2 subsequent siblings) 4 siblings, 2 replies; 21+ messages in thread From: Yu Tu @ 2023-08-22 8:27 UTC (permalink / raw) To: linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan, Yu Tu Add the S4 peripherals clock controller dt-bindings in the S4 SoC family. Signed-off-by: Yu Tu <yu.tu@amlogic.com> --- .../clock/amlogic,s4-peripherals-clkc.yaml | 96 +++++++ .../clock/amlogic,s4-peripherals-clkc.h | 236 ++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml create mode 100644 include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml new file mode 100644 index 000000000000..e166563e7b14 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,s4-peripherals-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic S4 Peripherals Clock Controller + +maintainers: + - Yu Tu <yu.tu@amlogic.com> + +properties: + compatible: + const: amlogic,s4-peripherals-clkc + + reg: + maxItems: 1 + + clocks: + items: + - description: input fixed pll div2 + - description: input fixed pll div2p5 + - description: input fixed pll div3 + - description: input fixed pll div4 + - description: input fixed pll div5 + - description: input fixed pll div7 + - description: input hifi pll + - description: input gp0 pll + - description: input mpll0 + - description: input mpll1 + - description: input mpll2 + - description: input mpll3 + - description: input hdmi pll + - description: input oscillator (usually at 24MHz) + - description: input external 32kHz reference (optional) + + clock-names: + items: + - const: fclk_div2 + - const: fclk_div2p5 + - const: fclk_div3 + - const: fclk_div4 + - const: fclk_div5 + - const: fclk_div7 + - const: hifi_pll + - const: gp0_pll + - const: mpll0 + - const: mpll1 + - const: mpll2 + - const: mpll3 + - const: hdmi_pll + - const: xtal + - const: ext_32k + + "#clock-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h> + + clkc_periphs: clock-controller@fe000000 { + compatible = "amlogic,s4-peripherals-clkc"; + reg = <0xfe000000 0x49c>; + clocks = <&clkc_pll 3>, + <&clkc_pll 13>, + <&clkc_pll 5>, + <&clkc_pll 7>, + <&clkc_pll 9>, + <&clkc_pll 11>, + <&clkc_pll 17>, + <&clkc_pll 15>, + <&clkc_pll 25>, + <&clkc_pll 27>, + <&clkc_pll 29>, + <&clkc_pll 31>, + <&clkc_pll 20>, + <&xtal>, + <&ext_32k>; + clock-names = "fclk_div2", "fclk_div2p5", "fclk_div3", "fclk_div4", + "fclk_div5", "fclk_div7", "hifi_pll", "gp0_pll", + "mpll0", "mpll1", "mpll2", "mpll3", "hdmi_pll", "xtal", + "ext_32k"; + #clock-cells = <1>; + }; +... diff --git a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h new file mode 100644 index 000000000000..861a331963ac --- /dev/null +++ b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h @@ -0,0 +1,236 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2022-2023 Amlogic, Inc. All rights reserved. + * Author: Yu Tu <yu.tu@amlogic.com> + */ + +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H +#define _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H + +#define CLKID_RTC_32K_CLKIN 0 +#define CLKID_RTC_32K_DIV 1 +#define CLKID_RTC_32K_SEL 2 +#define CLKID_RTC_32K_XATL 3 +#define CLKID_RTC 4 +#define CLKID_SYS_CLK_B_SEL 5 +#define CLKID_SYS_CLK_B_DIV 6 +#define CLKID_SYS_CLK_B 7 +#define CLKID_SYS_CLK_A_SEL 8 +#define CLKID_SYS_CLK_A_DIV 9 +#define CLKID_SYS_CLK_A 10 +#define CLKID_SYS 11 +#define CLKID_CECA_32K_CLKIN 12 +#define CLKID_CECA_32K_DIV 13 +#define CLKID_CECA_32K_SEL_PRE 14 +#define CLKID_CECA_32K_SEL 15 +#define CLKID_CECA_32K_CLKOUT 16 +#define CLKID_CECB_32K_CLKIN 17 +#define CLKID_CECB_32K_DIV 18 +#define CLKID_CECB_32K_SEL_PRE 19 +#define CLKID_CECB_32K_SEL 20 +#define CLKID_CECB_32K_CLKOUT 21 +#define CLKID_SC_CLK_SEL 22 +#define CLKID_SC_CLK_DIV 23 +#define CLKID_SC 24 +#define CLKID_12_24M 25 +#define CLKID_12M_CLK_DIV 26 +#define CLKID_12_24M_CLK_SEL 27 +#define CLKID_VID_PLL_DIV 28 +#define CLKID_VID_PLL_SEL 29 +#define CLKID_VID_PLL 30 +#define CLKID_VCLK_SEL 31 +#define CLKID_VCLK2_SEL 32 +#define CLKID_VCLK_INPUT 33 +#define CLKID_VCLK2_INPUT 34 +#define CLKID_VCLK_DIV 35 +#define CLKID_VCLK2_DIV 36 +#define CLKID_VCLK 37 +#define CLKID_VCLK2 38 +#define CLKID_VCLK_DIV1 39 +#define CLKID_VCLK_DIV2_EN 40 +#define CLKID_VCLK_DIV4_EN 41 +#define CLKID_VCLK_DIV6_EN 42 +#define CLKID_VCLK_DIV12_EN 43 +#define CLKID_VCLK2_DIV1 44 +#define CLKID_VCLK2_DIV2_EN 45 +#define CLKID_VCLK2_DIV4_EN 46 +#define CLKID_VCLK2_DIV6_EN 47 +#define CLKID_VCLK2_DIV12_EN 48 +#define CLKID_VCLK_DIV2 49 +#define CLKID_VCLK_DIV4 50 +#define CLKID_VCLK_DIV6 51 +#define CLKID_VCLK_DIV12 52 +#define CLKID_VCLK2_DIV2 53 +#define CLKID_VCLK2_DIV4 54 +#define CLKID_VCLK2_DIV6 55 +#define CLKID_VCLK2_DIV12 56 +#define CLKID_CTS_ENCI_SEL 57 +#define CLKID_CTS_ENCP_SEL 58 +#define CLKID_CTS_VDAC_SEL 59 +#define CLKID_HDMI_TX_SEL 60 +#define CLKID_CTS_ENCI 61 +#define CLKID_CTS_ENCP 62 +#define CLKID_CTS_VDAC 63 +#define CLKID_HDMI_TX 64 +#define CLKID_HDMI_SEL 65 +#define CLKID_HDMI_DIV 66 +#define CLKID_HDMI 67 +#define CLKID_TS_CLK_DIV 68 +#define CLKID_TS 69 +#define CLKID_MALI_0_SEL 70 +#define CLKID_MALI_0_DIV 71 +#define CLKID_MALI_0 72 +#define CLKID_MALI_1_SEL 73 +#define CLKID_MALI_1_DIV 74 +#define CLKID_MALI_1 75 +#define CLKID_MALI_SEL 76 +#define CLKID_VDEC_P0_SEL 77 +#define CLKID_VDEC_P0_DIV 78 +#define CLKID_VDEC_P0 79 +#define CLKID_VDEC_P1_SEL 80 +#define CLKID_VDEC_P1_DIV 81 +#define CLKID_VDEC_P1 82 +#define CLKID_VDEC_SEL 83 +#define CLKID_HEVCF_P0_SEL 84 +#define CLKID_HEVCF_P0_DIV 85 +#define CLKID_HEVCF_P0 86 +#define CLKID_HEVCF_P1_SEL 87 +#define CLKID_HEVCF_P1_DIV 88 +#define CLKID_HEVCF_P1 89 +#define CLKID_HEVCF_SEL 90 +#define CLKID_VPU_0_SEL 91 +#define CLKID_VPU_0_DIV 92 +#define CLKID_VPU_0 93 +#define CLKID_VPU_1_SEL 94 +#define CLKID_VPU_1_DIV 95 +#define CLKID_VPU_1 96 +#define CLKID_VPU 97 +#define CLKID_VPU_CLKB_TMP_SEL 98 +#define CLKID_VPU_CLKB_TMP_DIV 99 +#define CLKID_VPU_CLKB_TMP 100 +#define CLKID_VPU_CLKB_DIV 101 +#define CLKID_VPU_CLKB 102 +#define CLKID_VPU_CLKC_P0_SEL 103 +#define CLKID_VPU_CLKC_P0_DIV 104 +#define CLKID_VPU_CLKC_P0 105 +#define CLKID_VPU_CLKC_P1_SEL 106 +#define CLKID_VPU_CLKC_P1_DIV 107 +#define CLKID_VPU_CLKC_P1 108 +#define CLKID_VPU_CLKC_SEL 109 +#define CLKID_VAPB_0_SEL 110 +#define CLKID_VAPB_0_DIV 111 +#define CLKID_VAPB_0 112 +#define CLKID_VAPB_1_SEL 113 +#define CLKID_VAPB_1_DIV 114 +#define CLKID_VAPB_1 115 +#define CLKID_VAPB 116 +#define CLKID_GE2D 117 +#define CLKID_VDIN_MEAS_SEL 118 +#define CLKID_VDIN_MEAS_DIV 119 +#define CLKID_VDIN_MEAS 120 +#define CLKID_SD_EMMC_C_CLK_SEL 121 +#define CLKID_SD_EMMC_C_CLK_DIV 122 +#define CLKID_SD_EMMC_C 123 +#define CLKID_SD_EMMC_A_CLK_SEL 124 +#define CLKID_SD_EMMC_A_CLK_DIV 125 +#define CLKID_SD_EMMC_A 126 +#define CLKID_SD_EMMC_B_CLK_SEL 127 +#define CLKID_SD_EMMC_B_CLK_DIV 128 +#define CLKID_SD_EMMC_B 129 +#define CLKID_SPICC0_SEL 130 +#define CLKID_SPICC0_DIV 131 +#define CLKID_SPICC0_EN 132 +#define CLKID_PWM_A_SEL 133 +#define CLKID_PWM_A_DIV 134 +#define CLKID_PWM_A 135 +#define CLKID_PWM_B_SEL 136 +#define CLKID_PWM_B_DIV 137 +#define CLKID_PWM_B 138 +#define CLKID_PWM_C_SEL 139 +#define CLKID_PWM_C_DIV 140 +#define CLKID_PWM_C 141 +#define CLKID_PWM_D_SEL 142 +#define CLKID_PWM_D_DIV 143 +#define CLKID_PWM_D 144 +#define CLKID_PWM_E_SEL 145 +#define CLKID_PWM_E_DIV 146 +#define CLKID_PWM_E 147 +#define CLKID_PWM_F_SEL 148 +#define CLKID_PWM_F_DIV 149 +#define CLKID_PWM_F 150 +#define CLKID_PWM_G_SEL 151 +#define CLKID_PWM_G_DIV 152 +#define CLKID_PWM_G 153 +#define CLKID_PWM_H_SEL 154 +#define CLKID_PWM_H_DIV 155 +#define CLKID_PWM_H 156 +#define CLKID_PWM_I_SEL 157 +#define CLKID_PWM_I_DIV 158 +#define CLKID_PWM_I 159 +#define CLKID_PWM_J_SEL 160 +#define CLKID_PWM_J_DIV 161 +#define CLKID_PWM_J 162 +#define CLKID_SARADC_SEL 163 +#define CLKID_SARADC_DIV 164 +#define CLKID_SARADC 165 +#define CLKID_GEN_SEL 166 +#define CLKID_GEN_DIV 167 +#define CLKID_GEN 168 +#define CLKID_DDR 169 +#define CLKID_DOS 170 +#define CLKID_ETHPHY 171 +#define CLKID_MALI 172 +#define CLKID_AOCPU 173 +#define CLKID_AUCPU 174 +#define CLKID_CEC 175 +#define CLKID_SDEMMC_A 176 +#define CLKID_SDEMMC_B 177 +#define CLKID_NAND 178 +#define CLKID_SMARTCARD 179 +#define CLKID_ACODEC 180 +#define CLKID_SPIFC 181 +#define CLKID_MSR 182 +#define CLKID_IR_CTRL 183 +#define CLKID_AUDIO 184 +#define CLKID_ETH 185 +#define CLKID_UART_A 186 +#define CLKID_UART_B 187 +#define CLKID_UART_C 188 +#define CLKID_UART_D 189 +#define CLKID_UART_E 190 +#define CLKID_AIFIFO 191 +#define CLKID_TS_DDR 192 +#define CLKID_TS_PLL 193 +#define CLKID_G2D 194 +#define CLKID_SPICC0 195 +#define CLKID_SPICC1 196 +#define CLKID_USB 197 +#define CLKID_I2C_M_A 198 +#define CLKID_I2C_M_B 199 +#define CLKID_I2C_M_C 200 +#define CLKID_I2C_M_D 201 +#define CLKID_I2C_M_E 202 +#define CLKID_HDMITX_APB 203 +#define CLKID_I2C_S_A 204 +#define CLKID_USB1_TO_DDR 205 +#define CLKID_HDCP22 206 +#define CLKID_MMC_APB 207 +#define CLKID_RSA 208 +#define CLKID_CPU_DEBUG 209 +#define CLKID_VPU_INTR 210 +#define CLKID_DEMOD 211 +#define CLKID_SAR_ADC 212 +#define CLKID_GIC 213 +#define CLKID_PWM_AB 214 +#define CLKID_PWM_CD 215 +#define CLKID_PWM_EF 216 +#define CLKID_PWM_GH 217 +#define CLKID_PWM_IJ 218 +#define CLKID_HDCP22_ESMCLK_SEL 219 +#define CLKID_HDCP22_ESMCLK_DIV 220 +#define CLKID_HDCP22_ESMCLK 221 +#define CLKID_HDCP22_SKPCLK_SEL 222 +#define CLKID_HDCP22_SKPCLK_DIV 223 +#define CLKID_HDCP22_SKPCLK 224 + +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H */ -- 2.33.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller 2023-08-22 8:27 ` [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals " Yu Tu @ 2023-08-22 16:33 ` Krzysztof Kozlowski 2023-08-23 2:29 ` Yu Tu 2023-08-23 8:01 ` Jerome Brunet 1 sibling, 1 reply; 21+ messages in thread From: Krzysztof Kozlowski @ 2023-08-22 16:33 UTC (permalink / raw) To: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 22/08/2023 10:27, Yu Tu wrote: > Add the S4 peripherals clock controller dt-bindings in the S4 SoC > family. > > Signed-off-by: Yu Tu <yu.tu@amlogic.com> > --- As well ignored email from v8 and v7 and earlier versions. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller 2023-08-22 16:33 ` Krzysztof Kozlowski @ 2023-08-23 2:29 ` Yu Tu 0 siblings, 0 replies; 21+ messages in thread From: Yu Tu @ 2023-08-23 2:29 UTC (permalink / raw) To: Krzysztof Kozlowski, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 2023/8/23 0:33, Krzysztof Kozlowski wrote: > > [ EXTERNAL EMAIL ] > > On 22/08/2023 10:27, Yu Tu wrote: >> Add the S4 peripherals clock controller dt-bindings in the S4 SoC >> family. >> >> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >> --- > > As well ignored email from v8 and v7 and earlier versions. Sorry. I did not forget the friendly reminder in v8, I consulted you for this at the time, so I re-sent V9 after adding the tag. Because it was just "meson" that was removed. But V10 is based on Neil's patch, which I think is a bit of a change. So I didn't dare add it. Instead of forgetting your reminder. So here's what to do, and I'll follow your advice to the letter. > > Best regards, > Krzysztof > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller 2023-08-22 8:27 ` [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals " Yu Tu 2023-08-22 16:33 ` Krzysztof Kozlowski @ 2023-08-23 8:01 ` Jerome Brunet 2023-08-23 8:32 ` Yu Tu 1 sibling, 1 reply; 21+ messages in thread From: Jerome Brunet @ 2023-08-23 8:01 UTC (permalink / raw) To: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On Tue 22 Aug 2023 at 16:27, Yu Tu <yu.tu@amlogic.com> wrote: > Add the S4 peripherals clock controller dt-bindings in the S4 SoC > family. > > Signed-off-by: Yu Tu <yu.tu@amlogic.com> > --- > .../clock/amlogic,s4-peripherals-clkc.yaml | 96 +++++++ > .../clock/amlogic,s4-peripherals-clkc.h | 236 ++++++++++++++++++ > 2 files changed, 332 insertions(+) > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml > create mode 100644 include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h > > diff --git a/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml > new file mode 100644 > index 000000000000..e166563e7b14 > --- /dev/null > +++ b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml > @@ -0,0 +1,96 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/clock/amlogic,s4-peripherals-clkc.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Amlogic S4 Peripherals Clock Controller > + > +maintainers: > + - Yu Tu <yu.tu@amlogic.com> > + > +properties: > + compatible: > + const: amlogic,s4-peripherals-clkc > + > + reg: > + maxItems: 1 > + > + clocks: > + items: > + - description: input fixed pll div2 > + - description: input fixed pll div2p5 > + - description: input fixed pll div3 > + - description: input fixed pll div4 > + - description: input fixed pll div5 > + - description: input fixed pll div7 > + - description: input hifi pll > + - description: input gp0 pll > + - description: input mpll0 > + - description: input mpll1 > + - description: input mpll2 > + - description: input mpll3 > + - description: input hdmi pll > + - description: input oscillator (usually at 24MHz) > + - description: input external 32kHz reference (optional) The bindings described here does not make this last clock optional, but requires it. This is going to be a problem since most platforms won't have this clock. You are missing minItems. Same below > + > + clock-names: > + items: > + - const: fclk_div2 > + - const: fclk_div2p5 > + - const: fclk_div3 > + - const: fclk_div4 > + - const: fclk_div5 > + - const: fclk_div7 > + - const: hifi_pll > + - const: gp0_pll > + - const: mpll0 > + - const: mpll1 > + - const: mpll2 > + - const: mpll3 > + - const: hdmi_pll > + - const: xtal > + - const: ext_32k > + > + "#clock-cells": > + const: 1 > + > +required: > + - compatible > + - reg > + - clocks > + - clock-names > + - "#clock-cells" > + > +additionalProperties: false > + > +examples: > + - | > + #include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h> > + > + clkc_periphs: clock-controller@fe000000 { > + compatible = "amlogic,s4-peripherals-clkc"; > + reg = <0xfe000000 0x49c>; > + clocks = <&clkc_pll 3>, > + <&clkc_pll 13>, > + <&clkc_pll 5>, > + <&clkc_pll 7>, > + <&clkc_pll 9>, > + <&clkc_pll 11>, > + <&clkc_pll 17>, > + <&clkc_pll 15>, > + <&clkc_pll 25>, > + <&clkc_pll 27>, > + <&clkc_pll 29>, > + <&clkc_pll 31>, > + <&clkc_pll 20>, > + <&xtal>, > + <&ext_32k>; > + clock-names = "fclk_div2", "fclk_div2p5", "fclk_div3", "fclk_div4", > + "fclk_div5", "fclk_div7", "hifi_pll", "gp0_pll", > + "mpll0", "mpll1", "mpll2", "mpll3", "hdmi_pll", "xtal", > + "ext_32k"; > + #clock-cells = <1>; > + }; > +... > diff --git a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h > new file mode 100644 > index 000000000000..861a331963ac > --- /dev/null > +++ b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h > @@ -0,0 +1,236 @@ > +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ > +/* > + * Copyright (c) 2022-2023 Amlogic, Inc. All rights reserved. > + * Author: Yu Tu <yu.tu@amlogic.com> > + */ > + > +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H > +#define _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H > + > +#define CLKID_RTC_32K_CLKIN 0 > +#define CLKID_RTC_32K_DIV 1 > +#define CLKID_RTC_32K_SEL 2 > +#define CLKID_RTC_32K_XATL 3 > +#define CLKID_RTC 4 > +#define CLKID_SYS_CLK_B_SEL 5 > +#define CLKID_SYS_CLK_B_DIV 6 > +#define CLKID_SYS_CLK_B 7 > +#define CLKID_SYS_CLK_A_SEL 8 > +#define CLKID_SYS_CLK_A_DIV 9 > +#define CLKID_SYS_CLK_A 10 > +#define CLKID_SYS 11 > +#define CLKID_CECA_32K_CLKIN 12 > +#define CLKID_CECA_32K_DIV 13 > +#define CLKID_CECA_32K_SEL_PRE 14 > +#define CLKID_CECA_32K_SEL 15 > +#define CLKID_CECA_32K_CLKOUT 16 > +#define CLKID_CECB_32K_CLKIN 17 > +#define CLKID_CECB_32K_DIV 18 > +#define CLKID_CECB_32K_SEL_PRE 19 > +#define CLKID_CECB_32K_SEL 20 > +#define CLKID_CECB_32K_CLKOUT 21 > +#define CLKID_SC_CLK_SEL 22 > +#define CLKID_SC_CLK_DIV 23 > +#define CLKID_SC 24 > +#define CLKID_12_24M 25 > +#define CLKID_12M_CLK_DIV 26 > +#define CLKID_12_24M_CLK_SEL 27 > +#define CLKID_VID_PLL_DIV 28 > +#define CLKID_VID_PLL_SEL 29 > +#define CLKID_VID_PLL 30 > +#define CLKID_VCLK_SEL 31 > +#define CLKID_VCLK2_SEL 32 > +#define CLKID_VCLK_INPUT 33 > +#define CLKID_VCLK2_INPUT 34 > +#define CLKID_VCLK_DIV 35 > +#define CLKID_VCLK2_DIV 36 > +#define CLKID_VCLK 37 > +#define CLKID_VCLK2 38 > +#define CLKID_VCLK_DIV1 39 > +#define CLKID_VCLK_DIV2_EN 40 > +#define CLKID_VCLK_DIV4_EN 41 > +#define CLKID_VCLK_DIV6_EN 42 > +#define CLKID_VCLK_DIV12_EN 43 > +#define CLKID_VCLK2_DIV1 44 > +#define CLKID_VCLK2_DIV2_EN 45 > +#define CLKID_VCLK2_DIV4_EN 46 > +#define CLKID_VCLK2_DIV6_EN 47 > +#define CLKID_VCLK2_DIV12_EN 48 > +#define CLKID_VCLK_DIV2 49 > +#define CLKID_VCLK_DIV4 50 > +#define CLKID_VCLK_DIV6 51 > +#define CLKID_VCLK_DIV12 52 > +#define CLKID_VCLK2_DIV2 53 > +#define CLKID_VCLK2_DIV4 54 > +#define CLKID_VCLK2_DIV6 55 > +#define CLKID_VCLK2_DIV12 56 > +#define CLKID_CTS_ENCI_SEL 57 > +#define CLKID_CTS_ENCP_SEL 58 > +#define CLKID_CTS_VDAC_SEL 59 > +#define CLKID_HDMI_TX_SEL 60 > +#define CLKID_CTS_ENCI 61 > +#define CLKID_CTS_ENCP 62 > +#define CLKID_CTS_VDAC 63 > +#define CLKID_HDMI_TX 64 > +#define CLKID_HDMI_SEL 65 > +#define CLKID_HDMI_DIV 66 > +#define CLKID_HDMI 67 > +#define CLKID_TS_CLK_DIV 68 > +#define CLKID_TS 69 > +#define CLKID_MALI_0_SEL 70 > +#define CLKID_MALI_0_DIV 71 > +#define CLKID_MALI_0 72 > +#define CLKID_MALI_1_SEL 73 > +#define CLKID_MALI_1_DIV 74 > +#define CLKID_MALI_1 75 > +#define CLKID_MALI_SEL 76 > +#define CLKID_VDEC_P0_SEL 77 > +#define CLKID_VDEC_P0_DIV 78 > +#define CLKID_VDEC_P0 79 > +#define CLKID_VDEC_P1_SEL 80 > +#define CLKID_VDEC_P1_DIV 81 > +#define CLKID_VDEC_P1 82 > +#define CLKID_VDEC_SEL 83 > +#define CLKID_HEVCF_P0_SEL 84 > +#define CLKID_HEVCF_P0_DIV 85 > +#define CLKID_HEVCF_P0 86 > +#define CLKID_HEVCF_P1_SEL 87 > +#define CLKID_HEVCF_P1_DIV 88 > +#define CLKID_HEVCF_P1 89 > +#define CLKID_HEVCF_SEL 90 > +#define CLKID_VPU_0_SEL 91 > +#define CLKID_VPU_0_DIV 92 > +#define CLKID_VPU_0 93 > +#define CLKID_VPU_1_SEL 94 > +#define CLKID_VPU_1_DIV 95 > +#define CLKID_VPU_1 96 > +#define CLKID_VPU 97 > +#define CLKID_VPU_CLKB_TMP_SEL 98 > +#define CLKID_VPU_CLKB_TMP_DIV 99 > +#define CLKID_VPU_CLKB_TMP 100 > +#define CLKID_VPU_CLKB_DIV 101 > +#define CLKID_VPU_CLKB 102 > +#define CLKID_VPU_CLKC_P0_SEL 103 > +#define CLKID_VPU_CLKC_P0_DIV 104 > +#define CLKID_VPU_CLKC_P0 105 > +#define CLKID_VPU_CLKC_P1_SEL 106 > +#define CLKID_VPU_CLKC_P1_DIV 107 > +#define CLKID_VPU_CLKC_P1 108 > +#define CLKID_VPU_CLKC_SEL 109 > +#define CLKID_VAPB_0_SEL 110 > +#define CLKID_VAPB_0_DIV 111 > +#define CLKID_VAPB_0 112 > +#define CLKID_VAPB_1_SEL 113 > +#define CLKID_VAPB_1_DIV 114 > +#define CLKID_VAPB_1 115 > +#define CLKID_VAPB 116 > +#define CLKID_GE2D 117 > +#define CLKID_VDIN_MEAS_SEL 118 > +#define CLKID_VDIN_MEAS_DIV 119 > +#define CLKID_VDIN_MEAS 120 > +#define CLKID_SD_EMMC_C_CLK_SEL 121 > +#define CLKID_SD_EMMC_C_CLK_DIV 122 > +#define CLKID_SD_EMMC_C 123 > +#define CLKID_SD_EMMC_A_CLK_SEL 124 > +#define CLKID_SD_EMMC_A_CLK_DIV 125 > +#define CLKID_SD_EMMC_A 126 > +#define CLKID_SD_EMMC_B_CLK_SEL 127 > +#define CLKID_SD_EMMC_B_CLK_DIV 128 > +#define CLKID_SD_EMMC_B 129 > +#define CLKID_SPICC0_SEL 130 > +#define CLKID_SPICC0_DIV 131 > +#define CLKID_SPICC0_EN 132 > +#define CLKID_PWM_A_SEL 133 > +#define CLKID_PWM_A_DIV 134 > +#define CLKID_PWM_A 135 > +#define CLKID_PWM_B_SEL 136 > +#define CLKID_PWM_B_DIV 137 > +#define CLKID_PWM_B 138 > +#define CLKID_PWM_C_SEL 139 > +#define CLKID_PWM_C_DIV 140 > +#define CLKID_PWM_C 141 > +#define CLKID_PWM_D_SEL 142 > +#define CLKID_PWM_D_DIV 143 > +#define CLKID_PWM_D 144 > +#define CLKID_PWM_E_SEL 145 > +#define CLKID_PWM_E_DIV 146 > +#define CLKID_PWM_E 147 > +#define CLKID_PWM_F_SEL 148 > +#define CLKID_PWM_F_DIV 149 > +#define CLKID_PWM_F 150 > +#define CLKID_PWM_G_SEL 151 > +#define CLKID_PWM_G_DIV 152 > +#define CLKID_PWM_G 153 > +#define CLKID_PWM_H_SEL 154 > +#define CLKID_PWM_H_DIV 155 > +#define CLKID_PWM_H 156 > +#define CLKID_PWM_I_SEL 157 > +#define CLKID_PWM_I_DIV 158 > +#define CLKID_PWM_I 159 > +#define CLKID_PWM_J_SEL 160 > +#define CLKID_PWM_J_DIV 161 > +#define CLKID_PWM_J 162 > +#define CLKID_SARADC_SEL 163 > +#define CLKID_SARADC_DIV 164 > +#define CLKID_SARADC 165 > +#define CLKID_GEN_SEL 166 > +#define CLKID_GEN_DIV 167 > +#define CLKID_GEN 168 > +#define CLKID_DDR 169 > +#define CLKID_DOS 170 > +#define CLKID_ETHPHY 171 > +#define CLKID_MALI 172 > +#define CLKID_AOCPU 173 > +#define CLKID_AUCPU 174 > +#define CLKID_CEC 175 > +#define CLKID_SDEMMC_A 176 > +#define CLKID_SDEMMC_B 177 > +#define CLKID_NAND 178 > +#define CLKID_SMARTCARD 179 > +#define CLKID_ACODEC 180 > +#define CLKID_SPIFC 181 > +#define CLKID_MSR 182 > +#define CLKID_IR_CTRL 183 > +#define CLKID_AUDIO 184 > +#define CLKID_ETH 185 > +#define CLKID_UART_A 186 > +#define CLKID_UART_B 187 > +#define CLKID_UART_C 188 > +#define CLKID_UART_D 189 > +#define CLKID_UART_E 190 > +#define CLKID_AIFIFO 191 > +#define CLKID_TS_DDR 192 > +#define CLKID_TS_PLL 193 > +#define CLKID_G2D 194 > +#define CLKID_SPICC0 195 > +#define CLKID_SPICC1 196 > +#define CLKID_USB 197 > +#define CLKID_I2C_M_A 198 > +#define CLKID_I2C_M_B 199 > +#define CLKID_I2C_M_C 200 > +#define CLKID_I2C_M_D 201 > +#define CLKID_I2C_M_E 202 > +#define CLKID_HDMITX_APB 203 > +#define CLKID_I2C_S_A 204 > +#define CLKID_USB1_TO_DDR 205 > +#define CLKID_HDCP22 206 > +#define CLKID_MMC_APB 207 > +#define CLKID_RSA 208 > +#define CLKID_CPU_DEBUG 209 > +#define CLKID_VPU_INTR 210 > +#define CLKID_DEMOD 211 > +#define CLKID_SAR_ADC 212 > +#define CLKID_GIC 213 > +#define CLKID_PWM_AB 214 > +#define CLKID_PWM_CD 215 > +#define CLKID_PWM_EF 216 > +#define CLKID_PWM_GH 217 > +#define CLKID_PWM_IJ 218 > +#define CLKID_HDCP22_ESMCLK_SEL 219 > +#define CLKID_HDCP22_ESMCLK_DIV 220 > +#define CLKID_HDCP22_ESMCLK 221 > +#define CLKID_HDCP22_SKPCLK_SEL 222 > +#define CLKID_HDCP22_SKPCLK_DIV 223 > +#define CLKID_HDCP22_SKPCLK 224 > + > +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H */ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller 2023-08-23 8:01 ` Jerome Brunet @ 2023-08-23 8:32 ` Yu Tu 2023-08-23 9:14 ` Jerome Brunet 0 siblings, 1 reply; 21+ messages in thread From: Yu Tu @ 2023-08-23 8:32 UTC (permalink / raw) To: Jerome Brunet, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 2023/8/23 16:01, Jerome Brunet wrote: > [ EXTERNAL EMAIL ] > > On Tue 22 Aug 2023 at 16:27, Yu Tu <yu.tu@amlogic.com> wrote: > >> Add the S4 peripherals clock controller dt-bindings in the S4 SoC >> family. >> >> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >> --- >> .../clock/amlogic,s4-peripherals-clkc.yaml | 96 +++++++ >> .../clock/amlogic,s4-peripherals-clkc.h | 236 ++++++++++++++++++ >> 2 files changed, 332 insertions(+) >> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >> create mode 100644 include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >> >> diff --git a/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >> new file mode 100644 >> index 000000000000..e166563e7b14 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >> @@ -0,0 +1,96 @@ >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) >> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved >> +%YAML 1.2 >> +--- >> +$id: http://devicetree.org/schemas/clock/amlogic,s4-peripherals-clkc.yaml# >> +$schema: http://devicetree.org/meta-schemas/core.yaml# >> + >> +title: Amlogic S4 Peripherals Clock Controller >> + >> +maintainers: >> + - Yu Tu <yu.tu@amlogic.com> >> + >> +properties: >> + compatible: >> + const: amlogic,s4-peripherals-clkc >> + >> + reg: >> + maxItems: 1 >> + >> + clocks: >> + items: >> + - description: input fixed pll div2 >> + - description: input fixed pll div2p5 >> + - description: input fixed pll div3 >> + - description: input fixed pll div4 >> + - description: input fixed pll div5 >> + - description: input fixed pll div7 >> + - description: input hifi pll >> + - description: input gp0 pll >> + - description: input mpll0 >> + - description: input mpll1 >> + - description: input mpll2 >> + - description: input mpll3 >> + - description: input hdmi pll >> + - description: input oscillator (usually at 24MHz) >> + - description: input external 32kHz reference (optional) > > The bindings described here does not make this last clock optional, but > requires it. This is going to be a problem since most platforms won't > have this clock. Hi Jerome, Do you mean that we can delete the description of "external 32kHz", because we hardly use it? > > You are missing minItems. > Same below I will add it in next version. > >> + >> + clock-names: >> + items: >> + - const: fclk_div2 >> + - const: fclk_div2p5 >> + - const: fclk_div3 >> + - const: fclk_div4 >> + - const: fclk_div5 >> + - const: fclk_div7 >> + - const: hifi_pll >> + - const: gp0_pll >> + - const: mpll0 >> + - const: mpll1 >> + - const: mpll2 >> + - const: mpll3 >> + - const: hdmi_pll >> + - const: xtal >> + - const: ext_32k >> + >> + "#clock-cells": >> + const: 1 >> + >> +required: >> + - compatible >> + - reg >> + - clocks >> + - clock-names >> + - "#clock-cells" >> + >> +additionalProperties: false >> + >> +examples: >> + - | >> + #include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h> >> + >> + clkc_periphs: clock-controller@fe000000 { >> + compatible = "amlogic,s4-peripherals-clkc"; >> + reg = <0xfe000000 0x49c>; >> + clocks = <&clkc_pll 3>, >> + <&clkc_pll 13>, >> + <&clkc_pll 5>, >> + <&clkc_pll 7>, >> + <&clkc_pll 9>, >> + <&clkc_pll 11>, >> + <&clkc_pll 17>, >> + <&clkc_pll 15>, >> + <&clkc_pll 25>, >> + <&clkc_pll 27>, >> + <&clkc_pll 29>, >> + <&clkc_pll 31>, >> + <&clkc_pll 20>, >> + <&xtal>, >> + <&ext_32k>; >> + clock-names = "fclk_div2", "fclk_div2p5", "fclk_div3", "fclk_div4", >> + "fclk_div5", "fclk_div7", "hifi_pll", "gp0_pll", >> + "mpll0", "mpll1", "mpll2", "mpll3", "hdmi_pll", "xtal", >> + "ext_32k"; >> + #clock-cells = <1>; >> + }; >> +... >> diff --git a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >> new file mode 100644 >> index 000000000000..861a331963ac >> --- /dev/null >> +++ b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >> @@ -0,0 +1,236 @@ >> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >> +/* >> + * Copyright (c) 2022-2023 Amlogic, Inc. All rights reserved. >> + * Author: Yu Tu <yu.tu@amlogic.com> >> + */ >> + >> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H >> +#define _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H >> + >> +#define CLKID_RTC_32K_CLKIN 0 >> +#define CLKID_RTC_32K_DIV 1 >> +#define CLKID_RTC_32K_SEL 2 >> +#define CLKID_RTC_32K_XATL 3 >> +#define CLKID_RTC 4 >> +#define CLKID_SYS_CLK_B_SEL 5 >> +#define CLKID_SYS_CLK_B_DIV 6 >> +#define CLKID_SYS_CLK_B 7 >> +#define CLKID_SYS_CLK_A_SEL 8 >> +#define CLKID_SYS_CLK_A_DIV 9 >> +#define CLKID_SYS_CLK_A 10 >> +#define CLKID_SYS 11 >> +#define CLKID_CECA_32K_CLKIN 12 >> +#define CLKID_CECA_32K_DIV 13 >> +#define CLKID_CECA_32K_SEL_PRE 14 >> +#define CLKID_CECA_32K_SEL 15 >> +#define CLKID_CECA_32K_CLKOUT 16 >> +#define CLKID_CECB_32K_CLKIN 17 >> +#define CLKID_CECB_32K_DIV 18 >> +#define CLKID_CECB_32K_SEL_PRE 19 >> +#define CLKID_CECB_32K_SEL 20 >> +#define CLKID_CECB_32K_CLKOUT 21 >> +#define CLKID_SC_CLK_SEL 22 >> +#define CLKID_SC_CLK_DIV 23 >> +#define CLKID_SC 24 >> +#define CLKID_12_24M 25 >> +#define CLKID_12M_CLK_DIV 26 >> +#define CLKID_12_24M_CLK_SEL 27 >> +#define CLKID_VID_PLL_DIV 28 >> +#define CLKID_VID_PLL_SEL 29 >> +#define CLKID_VID_PLL 30 >> +#define CLKID_VCLK_SEL 31 >> +#define CLKID_VCLK2_SEL 32 >> +#define CLKID_VCLK_INPUT 33 >> +#define CLKID_VCLK2_INPUT 34 >> +#define CLKID_VCLK_DIV 35 >> +#define CLKID_VCLK2_DIV 36 >> +#define CLKID_VCLK 37 >> +#define CLKID_VCLK2 38 >> +#define CLKID_VCLK_DIV1 39 >> +#define CLKID_VCLK_DIV2_EN 40 >> +#define CLKID_VCLK_DIV4_EN 41 >> +#define CLKID_VCLK_DIV6_EN 42 >> +#define CLKID_VCLK_DIV12_EN 43 >> +#define CLKID_VCLK2_DIV1 44 >> +#define CLKID_VCLK2_DIV2_EN 45 >> +#define CLKID_VCLK2_DIV4_EN 46 >> +#define CLKID_VCLK2_DIV6_EN 47 >> +#define CLKID_VCLK2_DIV12_EN 48 >> +#define CLKID_VCLK_DIV2 49 >> +#define CLKID_VCLK_DIV4 50 >> +#define CLKID_VCLK_DIV6 51 >> +#define CLKID_VCLK_DIV12 52 >> +#define CLKID_VCLK2_DIV2 53 >> +#define CLKID_VCLK2_DIV4 54 >> +#define CLKID_VCLK2_DIV6 55 >> +#define CLKID_VCLK2_DIV12 56 >> +#define CLKID_CTS_ENCI_SEL 57 >> +#define CLKID_CTS_ENCP_SEL 58 >> +#define CLKID_CTS_VDAC_SEL 59 >> +#define CLKID_HDMI_TX_SEL 60 >> +#define CLKID_CTS_ENCI 61 >> +#define CLKID_CTS_ENCP 62 >> +#define CLKID_CTS_VDAC 63 >> +#define CLKID_HDMI_TX 64 >> +#define CLKID_HDMI_SEL 65 >> +#define CLKID_HDMI_DIV 66 >> +#define CLKID_HDMI 67 >> +#define CLKID_TS_CLK_DIV 68 >> +#define CLKID_TS 69 >> +#define CLKID_MALI_0_SEL 70 >> +#define CLKID_MALI_0_DIV 71 >> +#define CLKID_MALI_0 72 >> +#define CLKID_MALI_1_SEL 73 >> +#define CLKID_MALI_1_DIV 74 >> +#define CLKID_MALI_1 75 >> +#define CLKID_MALI_SEL 76 >> +#define CLKID_VDEC_P0_SEL 77 >> +#define CLKID_VDEC_P0_DIV 78 >> +#define CLKID_VDEC_P0 79 >> +#define CLKID_VDEC_P1_SEL 80 >> +#define CLKID_VDEC_P1_DIV 81 >> +#define CLKID_VDEC_P1 82 >> +#define CLKID_VDEC_SEL 83 >> +#define CLKID_HEVCF_P0_SEL 84 >> +#define CLKID_HEVCF_P0_DIV 85 >> +#define CLKID_HEVCF_P0 86 >> +#define CLKID_HEVCF_P1_SEL 87 >> +#define CLKID_HEVCF_P1_DIV 88 >> +#define CLKID_HEVCF_P1 89 >> +#define CLKID_HEVCF_SEL 90 >> +#define CLKID_VPU_0_SEL 91 >> +#define CLKID_VPU_0_DIV 92 >> +#define CLKID_VPU_0 93 >> +#define CLKID_VPU_1_SEL 94 >> +#define CLKID_VPU_1_DIV 95 >> +#define CLKID_VPU_1 96 >> +#define CLKID_VPU 97 >> +#define CLKID_VPU_CLKB_TMP_SEL 98 >> +#define CLKID_VPU_CLKB_TMP_DIV 99 >> +#define CLKID_VPU_CLKB_TMP 100 >> +#define CLKID_VPU_CLKB_DIV 101 >> +#define CLKID_VPU_CLKB 102 >> +#define CLKID_VPU_CLKC_P0_SEL 103 >> +#define CLKID_VPU_CLKC_P0_DIV 104 >> +#define CLKID_VPU_CLKC_P0 105 >> +#define CLKID_VPU_CLKC_P1_SEL 106 >> +#define CLKID_VPU_CLKC_P1_DIV 107 >> +#define CLKID_VPU_CLKC_P1 108 >> +#define CLKID_VPU_CLKC_SEL 109 >> +#define CLKID_VAPB_0_SEL 110 >> +#define CLKID_VAPB_0_DIV 111 >> +#define CLKID_VAPB_0 112 >> +#define CLKID_VAPB_1_SEL 113 >> +#define CLKID_VAPB_1_DIV 114 >> +#define CLKID_VAPB_1 115 >> +#define CLKID_VAPB 116 >> +#define CLKID_GE2D 117 >> +#define CLKID_VDIN_MEAS_SEL 118 >> +#define CLKID_VDIN_MEAS_DIV 119 >> +#define CLKID_VDIN_MEAS 120 >> +#define CLKID_SD_EMMC_C_CLK_SEL 121 >> +#define CLKID_SD_EMMC_C_CLK_DIV 122 >> +#define CLKID_SD_EMMC_C 123 >> +#define CLKID_SD_EMMC_A_CLK_SEL 124 >> +#define CLKID_SD_EMMC_A_CLK_DIV 125 >> +#define CLKID_SD_EMMC_A 126 >> +#define CLKID_SD_EMMC_B_CLK_SEL 127 >> +#define CLKID_SD_EMMC_B_CLK_DIV 128 >> +#define CLKID_SD_EMMC_B 129 >> +#define CLKID_SPICC0_SEL 130 >> +#define CLKID_SPICC0_DIV 131 >> +#define CLKID_SPICC0_EN 132 >> +#define CLKID_PWM_A_SEL 133 >> +#define CLKID_PWM_A_DIV 134 >> +#define CLKID_PWM_A 135 >> +#define CLKID_PWM_B_SEL 136 >> +#define CLKID_PWM_B_DIV 137 >> +#define CLKID_PWM_B 138 >> +#define CLKID_PWM_C_SEL 139 >> +#define CLKID_PWM_C_DIV 140 >> +#define CLKID_PWM_C 141 >> +#define CLKID_PWM_D_SEL 142 >> +#define CLKID_PWM_D_DIV 143 >> +#define CLKID_PWM_D 144 >> +#define CLKID_PWM_E_SEL 145 >> +#define CLKID_PWM_E_DIV 146 >> +#define CLKID_PWM_E 147 >> +#define CLKID_PWM_F_SEL 148 >> +#define CLKID_PWM_F_DIV 149 >> +#define CLKID_PWM_F 150 >> +#define CLKID_PWM_G_SEL 151 >> +#define CLKID_PWM_G_DIV 152 >> +#define CLKID_PWM_G 153 >> +#define CLKID_PWM_H_SEL 154 >> +#define CLKID_PWM_H_DIV 155 >> +#define CLKID_PWM_H 156 >> +#define CLKID_PWM_I_SEL 157 >> +#define CLKID_PWM_I_DIV 158 >> +#define CLKID_PWM_I 159 >> +#define CLKID_PWM_J_SEL 160 >> +#define CLKID_PWM_J_DIV 161 >> +#define CLKID_PWM_J 162 >> +#define CLKID_SARADC_SEL 163 >> +#define CLKID_SARADC_DIV 164 >> +#define CLKID_SARADC 165 >> +#define CLKID_GEN_SEL 166 >> +#define CLKID_GEN_DIV 167 >> +#define CLKID_GEN 168 >> +#define CLKID_DDR 169 >> +#define CLKID_DOS 170 >> +#define CLKID_ETHPHY 171 >> +#define CLKID_MALI 172 >> +#define CLKID_AOCPU 173 >> +#define CLKID_AUCPU 174 >> +#define CLKID_CEC 175 >> +#define CLKID_SDEMMC_A 176 >> +#define CLKID_SDEMMC_B 177 >> +#define CLKID_NAND 178 >> +#define CLKID_SMARTCARD 179 >> +#define CLKID_ACODEC 180 >> +#define CLKID_SPIFC 181 >> +#define CLKID_MSR 182 >> +#define CLKID_IR_CTRL 183 >> +#define CLKID_AUDIO 184 >> +#define CLKID_ETH 185 >> +#define CLKID_UART_A 186 >> +#define CLKID_UART_B 187 >> +#define CLKID_UART_C 188 >> +#define CLKID_UART_D 189 >> +#define CLKID_UART_E 190 >> +#define CLKID_AIFIFO 191 >> +#define CLKID_TS_DDR 192 >> +#define CLKID_TS_PLL 193 >> +#define CLKID_G2D 194 >> +#define CLKID_SPICC0 195 >> +#define CLKID_SPICC1 196 >> +#define CLKID_USB 197 >> +#define CLKID_I2C_M_A 198 >> +#define CLKID_I2C_M_B 199 >> +#define CLKID_I2C_M_C 200 >> +#define CLKID_I2C_M_D 201 >> +#define CLKID_I2C_M_E 202 >> +#define CLKID_HDMITX_APB 203 >> +#define CLKID_I2C_S_A 204 >> +#define CLKID_USB1_TO_DDR 205 >> +#define CLKID_HDCP22 206 >> +#define CLKID_MMC_APB 207 >> +#define CLKID_RSA 208 >> +#define CLKID_CPU_DEBUG 209 >> +#define CLKID_VPU_INTR 210 >> +#define CLKID_DEMOD 211 >> +#define CLKID_SAR_ADC 212 >> +#define CLKID_GIC 213 >> +#define CLKID_PWM_AB 214 >> +#define CLKID_PWM_CD 215 >> +#define CLKID_PWM_EF 216 >> +#define CLKID_PWM_GH 217 >> +#define CLKID_PWM_IJ 218 >> +#define CLKID_HDCP22_ESMCLK_SEL 219 >> +#define CLKID_HDCP22_ESMCLK_DIV 220 >> +#define CLKID_HDCP22_ESMCLK 221 >> +#define CLKID_HDCP22_SKPCLK_SEL 222 >> +#define CLKID_HDCP22_SKPCLK_DIV 223 >> +#define CLKID_HDCP22_SKPCLK 224 >> + >> +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H */ > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller 2023-08-23 8:32 ` Yu Tu @ 2023-08-23 9:14 ` Jerome Brunet 2023-08-24 2:35 ` Yu Tu 0 siblings, 1 reply; 21+ messages in thread From: Jerome Brunet @ 2023-08-23 9:14 UTC (permalink / raw) To: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On Wed 23 Aug 2023 at 16:32, Yu Tu <yu.tu@amlogic.com> wrote: > On 2023/8/23 16:01, Jerome Brunet wrote: >> [ EXTERNAL EMAIL ] >> On Tue 22 Aug 2023 at 16:27, Yu Tu <yu.tu@amlogic.com> wrote: >> >>> Add the S4 peripherals clock controller dt-bindings in the S4 SoC >>> family. >>> >>> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >>> --- >>> .../clock/amlogic,s4-peripherals-clkc.yaml | 96 +++++++ >>> .../clock/amlogic,s4-peripherals-clkc.h | 236 ++++++++++++++++++ >>> 2 files changed, 332 insertions(+) >>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >>> create mode 100644 include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >>> >>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >>> new file mode 100644 >>> index 000000000000..e166563e7b14 >>> --- /dev/null >>> +++ b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >>> @@ -0,0 +1,96 @@ >>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) >>> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved >>> +%YAML 1.2 >>> +--- >>> +$id: http://devicetree.org/schemas/clock/amlogic,s4-peripherals-clkc.yaml# >>> +$schema: http://devicetree.org/meta-schemas/core.yaml# >>> + >>> +title: Amlogic S4 Peripherals Clock Controller >>> + >>> +maintainers: >>> + - Yu Tu <yu.tu@amlogic.com> >>> + >>> +properties: >>> + compatible: >>> + const: amlogic,s4-peripherals-clkc >>> + >>> + reg: >>> + maxItems: 1 >>> + >>> + clocks: >>> + items: >>> + - description: input fixed pll div2 >>> + - description: input fixed pll div2p5 >>> + - description: input fixed pll div3 >>> + - description: input fixed pll div4 >>> + - description: input fixed pll div5 >>> + - description: input fixed pll div7 >>> + - description: input hifi pll >>> + - description: input gp0 pll >>> + - description: input mpll0 >>> + - description: input mpll1 >>> + - description: input mpll2 >>> + - description: input mpll3 >>> + - description: input hdmi pll >>> + - description: input oscillator (usually at 24MHz) >>> + - description: input external 32kHz reference (optional) >> The bindings described here does not make this last clock optional, but >> requires it. This is going to be a problem since most platforms won't >> have this clock. > > Hi Jerome, > Do you mean that we can delete the description of "external 32kHz", > because we hardly use it? Absolutely not. Optional ressources need description too. > >> You are missing minItems. >> Same below > > I will add it in next version. > I'm saying that because you did not provide minItems here, it gets implicitly set to the number of clocks you have declared, making the external 32k a required clock, not an optional one. You need to set minItems so the clocks is actually optional. Try removing the 32k in your example below and check how it goes with 'make dt_binding_check' >> >>> + >>> + clock-names: >>> + items: >>> + - const: fclk_div2 >>> + - const: fclk_div2p5 >>> + - const: fclk_div3 >>> + - const: fclk_div4 >>> + - const: fclk_div5 >>> + - const: fclk_div7 >>> + - const: hifi_pll >>> + - const: gp0_pll >>> + - const: mpll0 >>> + - const: mpll1 >>> + - const: mpll2 >>> + - const: mpll3 >>> + - const: hdmi_pll >>> + - const: xtal >>> + - const: ext_32k >>> + >>> + "#clock-cells": >>> + const: 1 >>> + >>> +required: >>> + - compatible >>> + - reg >>> + - clocks >>> + - clock-names >>> + - "#clock-cells" >>> + >>> +additionalProperties: false >>> + >>> +examples: >>> + - | >>> + #include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h> >>> + >>> + clkc_periphs: clock-controller@fe000000 { >>> + compatible = "amlogic,s4-peripherals-clkc"; >>> + reg = <0xfe000000 0x49c>; >>> + clocks = <&clkc_pll 3>, >>> + <&clkc_pll 13>, >>> + <&clkc_pll 5>, >>> + <&clkc_pll 7>, >>> + <&clkc_pll 9>, >>> + <&clkc_pll 11>, >>> + <&clkc_pll 17>, >>> + <&clkc_pll 15>, >>> + <&clkc_pll 25>, >>> + <&clkc_pll 27>, >>> + <&clkc_pll 29>, >>> + <&clkc_pll 31>, >>> + <&clkc_pll 20>, >>> + <&xtal>, >>> + <&ext_32k>; >>> + clock-names = "fclk_div2", "fclk_div2p5", "fclk_div3", "fclk_div4", >>> + "fclk_div5", "fclk_div7", "hifi_pll", "gp0_pll", >>> + "mpll0", "mpll1", "mpll2", "mpll3", "hdmi_pll", "xtal", >>> + "ext_32k"; >>> + #clock-cells = <1>; >>> + }; >>> +... >>> diff --git a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >>> new file mode 100644 >>> index 000000000000..861a331963ac >>> --- /dev/null >>> +++ b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >>> @@ -0,0 +1,236 @@ >>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >>> +/* >>> + * Copyright (c) 2022-2023 Amlogic, Inc. All rights reserved. >>> + * Author: Yu Tu <yu.tu@amlogic.com> >>> + */ >>> + >>> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H >>> +#define _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H >>> + >>> +#define CLKID_RTC_32K_CLKIN 0 >>> +#define CLKID_RTC_32K_DIV 1 >>> +#define CLKID_RTC_32K_SEL 2 >>> +#define CLKID_RTC_32K_XATL 3 >>> +#define CLKID_RTC 4 >>> +#define CLKID_SYS_CLK_B_SEL 5 >>> +#define CLKID_SYS_CLK_B_DIV 6 >>> +#define CLKID_SYS_CLK_B 7 >>> +#define CLKID_SYS_CLK_A_SEL 8 >>> +#define CLKID_SYS_CLK_A_DIV 9 >>> +#define CLKID_SYS_CLK_A 10 >>> +#define CLKID_SYS 11 >>> +#define CLKID_CECA_32K_CLKIN 12 >>> +#define CLKID_CECA_32K_DIV 13 >>> +#define CLKID_CECA_32K_SEL_PRE 14 >>> +#define CLKID_CECA_32K_SEL 15 >>> +#define CLKID_CECA_32K_CLKOUT 16 >>> +#define CLKID_CECB_32K_CLKIN 17 >>> +#define CLKID_CECB_32K_DIV 18 >>> +#define CLKID_CECB_32K_SEL_PRE 19 >>> +#define CLKID_CECB_32K_SEL 20 >>> +#define CLKID_CECB_32K_CLKOUT 21 >>> +#define CLKID_SC_CLK_SEL 22 >>> +#define CLKID_SC_CLK_DIV 23 >>> +#define CLKID_SC 24 >>> +#define CLKID_12_24M 25 >>> +#define CLKID_12M_CLK_DIV 26 >>> +#define CLKID_12_24M_CLK_SEL 27 >>> +#define CLKID_VID_PLL_DIV 28 >>> +#define CLKID_VID_PLL_SEL 29 >>> +#define CLKID_VID_PLL 30 >>> +#define CLKID_VCLK_SEL 31 >>> +#define CLKID_VCLK2_SEL 32 >>> +#define CLKID_VCLK_INPUT 33 >>> +#define CLKID_VCLK2_INPUT 34 >>> +#define CLKID_VCLK_DIV 35 >>> +#define CLKID_VCLK2_DIV 36 >>> +#define CLKID_VCLK 37 >>> +#define CLKID_VCLK2 38 >>> +#define CLKID_VCLK_DIV1 39 >>> +#define CLKID_VCLK_DIV2_EN 40 >>> +#define CLKID_VCLK_DIV4_EN 41 >>> +#define CLKID_VCLK_DIV6_EN 42 >>> +#define CLKID_VCLK_DIV12_EN 43 >>> +#define CLKID_VCLK2_DIV1 44 >>> +#define CLKID_VCLK2_DIV2_EN 45 >>> +#define CLKID_VCLK2_DIV4_EN 46 >>> +#define CLKID_VCLK2_DIV6_EN 47 >>> +#define CLKID_VCLK2_DIV12_EN 48 >>> +#define CLKID_VCLK_DIV2 49 >>> +#define CLKID_VCLK_DIV4 50 >>> +#define CLKID_VCLK_DIV6 51 >>> +#define CLKID_VCLK_DIV12 52 >>> +#define CLKID_VCLK2_DIV2 53 >>> +#define CLKID_VCLK2_DIV4 54 >>> +#define CLKID_VCLK2_DIV6 55 >>> +#define CLKID_VCLK2_DIV12 56 >>> +#define CLKID_CTS_ENCI_SEL 57 >>> +#define CLKID_CTS_ENCP_SEL 58 >>> +#define CLKID_CTS_VDAC_SEL 59 >>> +#define CLKID_HDMI_TX_SEL 60 >>> +#define CLKID_CTS_ENCI 61 >>> +#define CLKID_CTS_ENCP 62 >>> +#define CLKID_CTS_VDAC 63 >>> +#define CLKID_HDMI_TX 64 >>> +#define CLKID_HDMI_SEL 65 >>> +#define CLKID_HDMI_DIV 66 >>> +#define CLKID_HDMI 67 >>> +#define CLKID_TS_CLK_DIV 68 >>> +#define CLKID_TS 69 >>> +#define CLKID_MALI_0_SEL 70 >>> +#define CLKID_MALI_0_DIV 71 >>> +#define CLKID_MALI_0 72 >>> +#define CLKID_MALI_1_SEL 73 >>> +#define CLKID_MALI_1_DIV 74 >>> +#define CLKID_MALI_1 75 >>> +#define CLKID_MALI_SEL 76 >>> +#define CLKID_VDEC_P0_SEL 77 >>> +#define CLKID_VDEC_P0_DIV 78 >>> +#define CLKID_VDEC_P0 79 >>> +#define CLKID_VDEC_P1_SEL 80 >>> +#define CLKID_VDEC_P1_DIV 81 >>> +#define CLKID_VDEC_P1 82 >>> +#define CLKID_VDEC_SEL 83 >>> +#define CLKID_HEVCF_P0_SEL 84 >>> +#define CLKID_HEVCF_P0_DIV 85 >>> +#define CLKID_HEVCF_P0 86 >>> +#define CLKID_HEVCF_P1_SEL 87 >>> +#define CLKID_HEVCF_P1_DIV 88 >>> +#define CLKID_HEVCF_P1 89 >>> +#define CLKID_HEVCF_SEL 90 >>> +#define CLKID_VPU_0_SEL 91 >>> +#define CLKID_VPU_0_DIV 92 >>> +#define CLKID_VPU_0 93 >>> +#define CLKID_VPU_1_SEL 94 >>> +#define CLKID_VPU_1_DIV 95 >>> +#define CLKID_VPU_1 96 >>> +#define CLKID_VPU 97 >>> +#define CLKID_VPU_CLKB_TMP_SEL 98 >>> +#define CLKID_VPU_CLKB_TMP_DIV 99 >>> +#define CLKID_VPU_CLKB_TMP 100 >>> +#define CLKID_VPU_CLKB_DIV 101 >>> +#define CLKID_VPU_CLKB 102 >>> +#define CLKID_VPU_CLKC_P0_SEL 103 >>> +#define CLKID_VPU_CLKC_P0_DIV 104 >>> +#define CLKID_VPU_CLKC_P0 105 >>> +#define CLKID_VPU_CLKC_P1_SEL 106 >>> +#define CLKID_VPU_CLKC_P1_DIV 107 >>> +#define CLKID_VPU_CLKC_P1 108 >>> +#define CLKID_VPU_CLKC_SEL 109 >>> +#define CLKID_VAPB_0_SEL 110 >>> +#define CLKID_VAPB_0_DIV 111 >>> +#define CLKID_VAPB_0 112 >>> +#define CLKID_VAPB_1_SEL 113 >>> +#define CLKID_VAPB_1_DIV 114 >>> +#define CLKID_VAPB_1 115 >>> +#define CLKID_VAPB 116 >>> +#define CLKID_GE2D 117 >>> +#define CLKID_VDIN_MEAS_SEL 118 >>> +#define CLKID_VDIN_MEAS_DIV 119 >>> +#define CLKID_VDIN_MEAS 120 >>> +#define CLKID_SD_EMMC_C_CLK_SEL 121 >>> +#define CLKID_SD_EMMC_C_CLK_DIV 122 >>> +#define CLKID_SD_EMMC_C 123 >>> +#define CLKID_SD_EMMC_A_CLK_SEL 124 >>> +#define CLKID_SD_EMMC_A_CLK_DIV 125 >>> +#define CLKID_SD_EMMC_A 126 >>> +#define CLKID_SD_EMMC_B_CLK_SEL 127 >>> +#define CLKID_SD_EMMC_B_CLK_DIV 128 >>> +#define CLKID_SD_EMMC_B 129 >>> +#define CLKID_SPICC0_SEL 130 >>> +#define CLKID_SPICC0_DIV 131 >>> +#define CLKID_SPICC0_EN 132 >>> +#define CLKID_PWM_A_SEL 133 >>> +#define CLKID_PWM_A_DIV 134 >>> +#define CLKID_PWM_A 135 >>> +#define CLKID_PWM_B_SEL 136 >>> +#define CLKID_PWM_B_DIV 137 >>> +#define CLKID_PWM_B 138 >>> +#define CLKID_PWM_C_SEL 139 >>> +#define CLKID_PWM_C_DIV 140 >>> +#define CLKID_PWM_C 141 >>> +#define CLKID_PWM_D_SEL 142 >>> +#define CLKID_PWM_D_DIV 143 >>> +#define CLKID_PWM_D 144 >>> +#define CLKID_PWM_E_SEL 145 >>> +#define CLKID_PWM_E_DIV 146 >>> +#define CLKID_PWM_E 147 >>> +#define CLKID_PWM_F_SEL 148 >>> +#define CLKID_PWM_F_DIV 149 >>> +#define CLKID_PWM_F 150 >>> +#define CLKID_PWM_G_SEL 151 >>> +#define CLKID_PWM_G_DIV 152 >>> +#define CLKID_PWM_G 153 >>> +#define CLKID_PWM_H_SEL 154 >>> +#define CLKID_PWM_H_DIV 155 >>> +#define CLKID_PWM_H 156 >>> +#define CLKID_PWM_I_SEL 157 >>> +#define CLKID_PWM_I_DIV 158 >>> +#define CLKID_PWM_I 159 >>> +#define CLKID_PWM_J_SEL 160 >>> +#define CLKID_PWM_J_DIV 161 >>> +#define CLKID_PWM_J 162 >>> +#define CLKID_SARADC_SEL 163 >>> +#define CLKID_SARADC_DIV 164 >>> +#define CLKID_SARADC 165 >>> +#define CLKID_GEN_SEL 166 >>> +#define CLKID_GEN_DIV 167 >>> +#define CLKID_GEN 168 >>> +#define CLKID_DDR 169 >>> +#define CLKID_DOS 170 >>> +#define CLKID_ETHPHY 171 >>> +#define CLKID_MALI 172 >>> +#define CLKID_AOCPU 173 >>> +#define CLKID_AUCPU 174 >>> +#define CLKID_CEC 175 >>> +#define CLKID_SDEMMC_A 176 >>> +#define CLKID_SDEMMC_B 177 >>> +#define CLKID_NAND 178 >>> +#define CLKID_SMARTCARD 179 >>> +#define CLKID_ACODEC 180 >>> +#define CLKID_SPIFC 181 >>> +#define CLKID_MSR 182 >>> +#define CLKID_IR_CTRL 183 >>> +#define CLKID_AUDIO 184 >>> +#define CLKID_ETH 185 >>> +#define CLKID_UART_A 186 >>> +#define CLKID_UART_B 187 >>> +#define CLKID_UART_C 188 >>> +#define CLKID_UART_D 189 >>> +#define CLKID_UART_E 190 >>> +#define CLKID_AIFIFO 191 >>> +#define CLKID_TS_DDR 192 >>> +#define CLKID_TS_PLL 193 >>> +#define CLKID_G2D 194 >>> +#define CLKID_SPICC0 195 >>> +#define CLKID_SPICC1 196 >>> +#define CLKID_USB 197 >>> +#define CLKID_I2C_M_A 198 >>> +#define CLKID_I2C_M_B 199 >>> +#define CLKID_I2C_M_C 200 >>> +#define CLKID_I2C_M_D 201 >>> +#define CLKID_I2C_M_E 202 >>> +#define CLKID_HDMITX_APB 203 >>> +#define CLKID_I2C_S_A 204 >>> +#define CLKID_USB1_TO_DDR 205 >>> +#define CLKID_HDCP22 206 >>> +#define CLKID_MMC_APB 207 >>> +#define CLKID_RSA 208 >>> +#define CLKID_CPU_DEBUG 209 >>> +#define CLKID_VPU_INTR 210 >>> +#define CLKID_DEMOD 211 >>> +#define CLKID_SAR_ADC 212 >>> +#define CLKID_GIC 213 >>> +#define CLKID_PWM_AB 214 >>> +#define CLKID_PWM_CD 215 >>> +#define CLKID_PWM_EF 216 >>> +#define CLKID_PWM_GH 217 >>> +#define CLKID_PWM_IJ 218 >>> +#define CLKID_HDCP22_ESMCLK_SEL 219 >>> +#define CLKID_HDCP22_ESMCLK_DIV 220 >>> +#define CLKID_HDCP22_ESMCLK 221 >>> +#define CLKID_HDCP22_SKPCLK_SEL 222 >>> +#define CLKID_HDCP22_SKPCLK_DIV 223 >>> +#define CLKID_HDCP22_SKPCLK 224 >>> + >>> +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H */ >> ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller 2023-08-23 9:14 ` Jerome Brunet @ 2023-08-24 2:35 ` Yu Tu 0 siblings, 0 replies; 21+ messages in thread From: Yu Tu @ 2023-08-24 2:35 UTC (permalink / raw) To: Jerome Brunet, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 2023/8/23 17:14, Jerome Brunet wrote: > [ EXTERNAL EMAIL ] > > On Wed 23 Aug 2023 at 16:32, Yu Tu <yu.tu@amlogic.com> wrote: > >> On 2023/8/23 16:01, Jerome Brunet wrote: >>> [ EXTERNAL EMAIL ] >>> On Tue 22 Aug 2023 at 16:27, Yu Tu <yu.tu@amlogic.com> wrote: >>> >>>> Add the S4 peripherals clock controller dt-bindings in the S4 SoC >>>> family. >>>> >>>> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >>>> --- >>>> .../clock/amlogic,s4-peripherals-clkc.yaml | 96 +++++++ >>>> .../clock/amlogic,s4-peripherals-clkc.h | 236 ++++++++++++++++++ >>>> 2 files changed, 332 insertions(+) >>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >>>> create mode 100644 include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >>>> >>>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >>>> new file mode 100644 >>>> index 000000000000..e166563e7b14 >>>> --- /dev/null >>>> +++ b/Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml >>>> @@ -0,0 +1,96 @@ >>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) >>>> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved >>>> +%YAML 1.2 >>>> +--- >>>> +$id: http://devicetree.org/schemas/clock/amlogic,s4-peripherals-clkc.yaml# >>>> +$schema: http://devicetree.org/meta-schemas/core.yaml# >>>> + >>>> +title: Amlogic S4 Peripherals Clock Controller >>>> + >>>> +maintainers: >>>> + - Yu Tu <yu.tu@amlogic.com> >>>> + >>>> +properties: >>>> + compatible: >>>> + const: amlogic,s4-peripherals-clkc >>>> + >>>> + reg: >>>> + maxItems: 1 >>>> + >>>> + clocks: >>>> + items: >>>> + - description: input fixed pll div2 >>>> + - description: input fixed pll div2p5 >>>> + - description: input fixed pll div3 >>>> + - description: input fixed pll div4 >>>> + - description: input fixed pll div5 >>>> + - description: input fixed pll div7 >>>> + - description: input hifi pll >>>> + - description: input gp0 pll >>>> + - description: input mpll0 >>>> + - description: input mpll1 >>>> + - description: input mpll2 >>>> + - description: input mpll3 >>>> + - description: input hdmi pll >>>> + - description: input oscillator (usually at 24MHz) >>>> + - description: input external 32kHz reference (optional) >>> The bindings described here does not make this last clock optional, but >>> requires it. This is going to be a problem since most platforms won't >>> have this clock. >> >> Hi Jerome, >> Do you mean that we can delete the description of "external 32kHz", >> because we hardly use it? > > Absolutely not. > Optional ressources need description too. OKay. I got it. > >> >>> You are missing minItems. >>> Same below >> >> I will add it in next version. >> > > I'm saying that because you did not provide minItems here, it gets > implicitly set to the number of clocks you have declared, making the > external 32k a required clock, not an optional one. > > You need to set minItems so the clocks is actually optional. > Try removing the 32k in your example below and check how it goes with > 'make dt_binding_check' thank you I see. I tried. I had to follow your advice, or there'd be a warning. > >>> >>>> + >>>> + clock-names: >>>> + items: >>>> + - const: fclk_div2 >>>> + - const: fclk_div2p5 >>>> + - const: fclk_div3 >>>> + - const: fclk_div4 >>>> + - const: fclk_div5 >>>> + - const: fclk_div7 >>>> + - const: hifi_pll >>>> + - const: gp0_pll >>>> + - const: mpll0 >>>> + - const: mpll1 >>>> + - const: mpll2 >>>> + - const: mpll3 >>>> + - const: hdmi_pll >>>> + - const: xtal >>>> + - const: ext_32k >>>> + >>>> + "#clock-cells": >>>> + const: 1 >>>> + >>>> +required: >>>> + - compatible >>>> + - reg >>>> + - clocks >>>> + - clock-names >>>> + - "#clock-cells" >>>> + >>>> +additionalProperties: false >>>> + >>>> +examples: >>>> + - | >>>> + #include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h> >>>> + >>>> + clkc_periphs: clock-controller@fe000000 { >>>> + compatible = "amlogic,s4-peripherals-clkc"; >>>> + reg = <0xfe000000 0x49c>; >>>> + clocks = <&clkc_pll 3>, >>>> + <&clkc_pll 13>, >>>> + <&clkc_pll 5>, >>>> + <&clkc_pll 7>, >>>> + <&clkc_pll 9>, >>>> + <&clkc_pll 11>, >>>> + <&clkc_pll 17>, >>>> + <&clkc_pll 15>, >>>> + <&clkc_pll 25>, >>>> + <&clkc_pll 27>, >>>> + <&clkc_pll 29>, >>>> + <&clkc_pll 31>, >>>> + <&clkc_pll 20>, >>>> + <&xtal>, >>>> + <&ext_32k>; >>>> + clock-names = "fclk_div2", "fclk_div2p5", "fclk_div3", "fclk_div4", >>>> + "fclk_div5", "fclk_div7", "hifi_pll", "gp0_pll", >>>> + "mpll0", "mpll1", "mpll2", "mpll3", "hdmi_pll", "xtal", >>>> + "ext_32k"; >>>> + #clock-cells = <1>; >>>> + }; >>>> +... >>>> diff --git a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >>>> new file mode 100644 >>>> index 000000000000..861a331963ac >>>> --- /dev/null >>>> +++ b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h >>>> @@ -0,0 +1,236 @@ >>>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >>>> +/* >>>> + * Copyright (c) 2022-2023 Amlogic, Inc. All rights reserved. >>>> + * Author: Yu Tu <yu.tu@amlogic.com> >>>> + */ >>>> + >>>> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H >>>> +#define _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H >>>> + >>>> +#define CLKID_RTC_32K_CLKIN 0 >>>> +#define CLKID_RTC_32K_DIV 1 >>>> +#define CLKID_RTC_32K_SEL 2 >>>> +#define CLKID_RTC_32K_XATL 3 >>>> +#define CLKID_RTC 4 >>>> +#define CLKID_SYS_CLK_B_SEL 5 >>>> +#define CLKID_SYS_CLK_B_DIV 6 >>>> +#define CLKID_SYS_CLK_B 7 >>>> +#define CLKID_SYS_CLK_A_SEL 8 >>>> +#define CLKID_SYS_CLK_A_DIV 9 >>>> +#define CLKID_SYS_CLK_A 10 >>>> +#define CLKID_SYS 11 >>>> +#define CLKID_CECA_32K_CLKIN 12 >>>> +#define CLKID_CECA_32K_DIV 13 >>>> +#define CLKID_CECA_32K_SEL_PRE 14 >>>> +#define CLKID_CECA_32K_SEL 15 >>>> +#define CLKID_CECA_32K_CLKOUT 16 >>>> +#define CLKID_CECB_32K_CLKIN 17 >>>> +#define CLKID_CECB_32K_DIV 18 >>>> +#define CLKID_CECB_32K_SEL_PRE 19 >>>> +#define CLKID_CECB_32K_SEL 20 >>>> +#define CLKID_CECB_32K_CLKOUT 21 >>>> +#define CLKID_SC_CLK_SEL 22 >>>> +#define CLKID_SC_CLK_DIV 23 >>>> +#define CLKID_SC 24 >>>> +#define CLKID_12_24M 25 >>>> +#define CLKID_12M_CLK_DIV 26 >>>> +#define CLKID_12_24M_CLK_SEL 27 >>>> +#define CLKID_VID_PLL_DIV 28 >>>> +#define CLKID_VID_PLL_SEL 29 >>>> +#define CLKID_VID_PLL 30 >>>> +#define CLKID_VCLK_SEL 31 >>>> +#define CLKID_VCLK2_SEL 32 >>>> +#define CLKID_VCLK_INPUT 33 >>>> +#define CLKID_VCLK2_INPUT 34 >>>> +#define CLKID_VCLK_DIV 35 >>>> +#define CLKID_VCLK2_DIV 36 >>>> +#define CLKID_VCLK 37 >>>> +#define CLKID_VCLK2 38 >>>> +#define CLKID_VCLK_DIV1 39 >>>> +#define CLKID_VCLK_DIV2_EN 40 >>>> +#define CLKID_VCLK_DIV4_EN 41 >>>> +#define CLKID_VCLK_DIV6_EN 42 >>>> +#define CLKID_VCLK_DIV12_EN 43 >>>> +#define CLKID_VCLK2_DIV1 44 >>>> +#define CLKID_VCLK2_DIV2_EN 45 >>>> +#define CLKID_VCLK2_DIV4_EN 46 >>>> +#define CLKID_VCLK2_DIV6_EN 47 >>>> +#define CLKID_VCLK2_DIV12_EN 48 >>>> +#define CLKID_VCLK_DIV2 49 >>>> +#define CLKID_VCLK_DIV4 50 >>>> +#define CLKID_VCLK_DIV6 51 >>>> +#define CLKID_VCLK_DIV12 52 >>>> +#define CLKID_VCLK2_DIV2 53 >>>> +#define CLKID_VCLK2_DIV4 54 >>>> +#define CLKID_VCLK2_DIV6 55 >>>> +#define CLKID_VCLK2_DIV12 56 >>>> +#define CLKID_CTS_ENCI_SEL 57 >>>> +#define CLKID_CTS_ENCP_SEL 58 >>>> +#define CLKID_CTS_VDAC_SEL 59 >>>> +#define CLKID_HDMI_TX_SEL 60 >>>> +#define CLKID_CTS_ENCI 61 >>>> +#define CLKID_CTS_ENCP 62 >>>> +#define CLKID_CTS_VDAC 63 >>>> +#define CLKID_HDMI_TX 64 >>>> +#define CLKID_HDMI_SEL 65 >>>> +#define CLKID_HDMI_DIV 66 >>>> +#define CLKID_HDMI 67 >>>> +#define CLKID_TS_CLK_DIV 68 >>>> +#define CLKID_TS 69 >>>> +#define CLKID_MALI_0_SEL 70 >>>> +#define CLKID_MALI_0_DIV 71 >>>> +#define CLKID_MALI_0 72 >>>> +#define CLKID_MALI_1_SEL 73 >>>> +#define CLKID_MALI_1_DIV 74 >>>> +#define CLKID_MALI_1 75 >>>> +#define CLKID_MALI_SEL 76 >>>> +#define CLKID_VDEC_P0_SEL 77 >>>> +#define CLKID_VDEC_P0_DIV 78 >>>> +#define CLKID_VDEC_P0 79 >>>> +#define CLKID_VDEC_P1_SEL 80 >>>> +#define CLKID_VDEC_P1_DIV 81 >>>> +#define CLKID_VDEC_P1 82 >>>> +#define CLKID_VDEC_SEL 83 >>>> +#define CLKID_HEVCF_P0_SEL 84 >>>> +#define CLKID_HEVCF_P0_DIV 85 >>>> +#define CLKID_HEVCF_P0 86 >>>> +#define CLKID_HEVCF_P1_SEL 87 >>>> +#define CLKID_HEVCF_P1_DIV 88 >>>> +#define CLKID_HEVCF_P1 89 >>>> +#define CLKID_HEVCF_SEL 90 >>>> +#define CLKID_VPU_0_SEL 91 >>>> +#define CLKID_VPU_0_DIV 92 >>>> +#define CLKID_VPU_0 93 >>>> +#define CLKID_VPU_1_SEL 94 >>>> +#define CLKID_VPU_1_DIV 95 >>>> +#define CLKID_VPU_1 96 >>>> +#define CLKID_VPU 97 >>>> +#define CLKID_VPU_CLKB_TMP_SEL 98 >>>> +#define CLKID_VPU_CLKB_TMP_DIV 99 >>>> +#define CLKID_VPU_CLKB_TMP 100 >>>> +#define CLKID_VPU_CLKB_DIV 101 >>>> +#define CLKID_VPU_CLKB 102 >>>> +#define CLKID_VPU_CLKC_P0_SEL 103 >>>> +#define CLKID_VPU_CLKC_P0_DIV 104 >>>> +#define CLKID_VPU_CLKC_P0 105 >>>> +#define CLKID_VPU_CLKC_P1_SEL 106 >>>> +#define CLKID_VPU_CLKC_P1_DIV 107 >>>> +#define CLKID_VPU_CLKC_P1 108 >>>> +#define CLKID_VPU_CLKC_SEL 109 >>>> +#define CLKID_VAPB_0_SEL 110 >>>> +#define CLKID_VAPB_0_DIV 111 >>>> +#define CLKID_VAPB_0 112 >>>> +#define CLKID_VAPB_1_SEL 113 >>>> +#define CLKID_VAPB_1_DIV 114 >>>> +#define CLKID_VAPB_1 115 >>>> +#define CLKID_VAPB 116 >>>> +#define CLKID_GE2D 117 >>>> +#define CLKID_VDIN_MEAS_SEL 118 >>>> +#define CLKID_VDIN_MEAS_DIV 119 >>>> +#define CLKID_VDIN_MEAS 120 >>>> +#define CLKID_SD_EMMC_C_CLK_SEL 121 >>>> +#define CLKID_SD_EMMC_C_CLK_DIV 122 >>>> +#define CLKID_SD_EMMC_C 123 >>>> +#define CLKID_SD_EMMC_A_CLK_SEL 124 >>>> +#define CLKID_SD_EMMC_A_CLK_DIV 125 >>>> +#define CLKID_SD_EMMC_A 126 >>>> +#define CLKID_SD_EMMC_B_CLK_SEL 127 >>>> +#define CLKID_SD_EMMC_B_CLK_DIV 128 >>>> +#define CLKID_SD_EMMC_B 129 >>>> +#define CLKID_SPICC0_SEL 130 >>>> +#define CLKID_SPICC0_DIV 131 >>>> +#define CLKID_SPICC0_EN 132 >>>> +#define CLKID_PWM_A_SEL 133 >>>> +#define CLKID_PWM_A_DIV 134 >>>> +#define CLKID_PWM_A 135 >>>> +#define CLKID_PWM_B_SEL 136 >>>> +#define CLKID_PWM_B_DIV 137 >>>> +#define CLKID_PWM_B 138 >>>> +#define CLKID_PWM_C_SEL 139 >>>> +#define CLKID_PWM_C_DIV 140 >>>> +#define CLKID_PWM_C 141 >>>> +#define CLKID_PWM_D_SEL 142 >>>> +#define CLKID_PWM_D_DIV 143 >>>> +#define CLKID_PWM_D 144 >>>> +#define CLKID_PWM_E_SEL 145 >>>> +#define CLKID_PWM_E_DIV 146 >>>> +#define CLKID_PWM_E 147 >>>> +#define CLKID_PWM_F_SEL 148 >>>> +#define CLKID_PWM_F_DIV 149 >>>> +#define CLKID_PWM_F 150 >>>> +#define CLKID_PWM_G_SEL 151 >>>> +#define CLKID_PWM_G_DIV 152 >>>> +#define CLKID_PWM_G 153 >>>> +#define CLKID_PWM_H_SEL 154 >>>> +#define CLKID_PWM_H_DIV 155 >>>> +#define CLKID_PWM_H 156 >>>> +#define CLKID_PWM_I_SEL 157 >>>> +#define CLKID_PWM_I_DIV 158 >>>> +#define CLKID_PWM_I 159 >>>> +#define CLKID_PWM_J_SEL 160 >>>> +#define CLKID_PWM_J_DIV 161 >>>> +#define CLKID_PWM_J 162 >>>> +#define CLKID_SARADC_SEL 163 >>>> +#define CLKID_SARADC_DIV 164 >>>> +#define CLKID_SARADC 165 >>>> +#define CLKID_GEN_SEL 166 >>>> +#define CLKID_GEN_DIV 167 >>>> +#define CLKID_GEN 168 >>>> +#define CLKID_DDR 169 >>>> +#define CLKID_DOS 170 >>>> +#define CLKID_ETHPHY 171 >>>> +#define CLKID_MALI 172 >>>> +#define CLKID_AOCPU 173 >>>> +#define CLKID_AUCPU 174 >>>> +#define CLKID_CEC 175 >>>> +#define CLKID_SDEMMC_A 176 >>>> +#define CLKID_SDEMMC_B 177 >>>> +#define CLKID_NAND 178 >>>> +#define CLKID_SMARTCARD 179 >>>> +#define CLKID_ACODEC 180 >>>> +#define CLKID_SPIFC 181 >>>> +#define CLKID_MSR 182 >>>> +#define CLKID_IR_CTRL 183 >>>> +#define CLKID_AUDIO 184 >>>> +#define CLKID_ETH 185 >>>> +#define CLKID_UART_A 186 >>>> +#define CLKID_UART_B 187 >>>> +#define CLKID_UART_C 188 >>>> +#define CLKID_UART_D 189 >>>> +#define CLKID_UART_E 190 >>>> +#define CLKID_AIFIFO 191 >>>> +#define CLKID_TS_DDR 192 >>>> +#define CLKID_TS_PLL 193 >>>> +#define CLKID_G2D 194 >>>> +#define CLKID_SPICC0 195 >>>> +#define CLKID_SPICC1 196 >>>> +#define CLKID_USB 197 >>>> +#define CLKID_I2C_M_A 198 >>>> +#define CLKID_I2C_M_B 199 >>>> +#define CLKID_I2C_M_C 200 >>>> +#define CLKID_I2C_M_D 201 >>>> +#define CLKID_I2C_M_E 202 >>>> +#define CLKID_HDMITX_APB 203 >>>> +#define CLKID_I2C_S_A 204 >>>> +#define CLKID_USB1_TO_DDR 205 >>>> +#define CLKID_HDCP22 206 >>>> +#define CLKID_MMC_APB 207 >>>> +#define CLKID_RSA 208 >>>> +#define CLKID_CPU_DEBUG 209 >>>> +#define CLKID_VPU_INTR 210 >>>> +#define CLKID_DEMOD 211 >>>> +#define CLKID_SAR_ADC 212 >>>> +#define CLKID_GIC 213 >>>> +#define CLKID_PWM_AB 214 >>>> +#define CLKID_PWM_CD 215 >>>> +#define CLKID_PWM_EF 216 >>>> +#define CLKID_PWM_GH 217 >>>> +#define CLKID_PWM_IJ 218 >>>> +#define CLKID_HDCP22_ESMCLK_SEL 219 >>>> +#define CLKID_HDCP22_ESMCLK_DIV 220 >>>> +#define CLKID_HDCP22_ESMCLK 221 >>>> +#define CLKID_HDCP22_SKPCLK_SEL 222 >>>> +#define CLKID_HDCP22_SKPCLK_DIV 223 >>>> +#define CLKID_HDCP22_SKPCLK 224 >>>> + >>>> +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H */ >>> > ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH V10 3/4] clk: meson: S4: add support for Amlogic S4 SoC PLL clock driver 2023-08-22 8:27 [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Yu Tu 2023-08-22 8:27 ` [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller Yu Tu 2023-08-22 8:27 ` [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals " Yu Tu @ 2023-08-22 8:27 ` Yu Tu 2023-08-22 8:27 ` [PATCH V10 4/4] clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller Yu Tu 2023-08-27 17:04 ` [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Lucas Tanure 4 siblings, 0 replies; 21+ messages in thread From: Yu Tu @ 2023-08-22 8:27 UTC (permalink / raw) To: linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan, Yu Tu Add the S4 PLL clock controller driver in the S4 SoC family. Signed-off-by: Yu Tu <yu.tu@amlogic.com> --- drivers/clk/meson/Kconfig | 12 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/s4-pll.c | 867 +++++++++++++++++++++++++++++++++++++ drivers/clk/meson/s4-pll.h | 38 ++ 4 files changed, 918 insertions(+) create mode 100644 drivers/clk/meson/s4-pll.c create mode 100644 drivers/clk/meson/s4-pll.h diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 135da8f2d0b1..e90982d77598 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -144,4 +144,16 @@ config COMMON_CLK_G12A help Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2 devices, aka g12a. Say Y if you want peripherals to work. + +config COMMON_CLK_S4_PLL + tristate "S4 SoC PLL clock controllers support" + depends on ARM64 + default y + select COMMON_CLK_MESON_MPLL + select COMMON_CLK_MESON_PLL + select COMMON_CLK_MESON_REGMAP + help + Support for the PLL clock controller on Amlogic S805X2 and S905Y4 devices, + AKA S4. Say Y if you want the board to work, because PLLs are the parent of + most peripherals. endmenu diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index cd961cc4f4db..612cee923890 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o +obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o diff --git a/drivers/clk/meson/s4-pll.c b/drivers/clk/meson/s4-pll.c new file mode 100644 index 000000000000..8dfaeccaadc2 --- /dev/null +++ b/drivers/clk/meson/s4-pll.c @@ -0,0 +1,867 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Amlogic S4 PLL Clock Controller Driver + * + * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved + * Author: Yu Tu <yu.tu@amlogic.com> + */ + +#include <linux/clk-provider.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mpll.h" +#include "clk-pll.h" +#include "clk-regmap.h" +#include "s4-pll.h" +#include "meson-clkc-utils.h" +#include <dt-bindings/clock/amlogic,s4-pll-clkc.h> + +static DEFINE_SPINLOCK(meson_clk_lock); + +/* + * These clock are a fixed value (fixed_pll is 2GHz) that is initialized by ROMcode. + * The chip was changed fixed pll for security reasons. Fixed PLL registers are not writable + * in the kernel phase. Write of fixed PLL-related register will cause the system to crash. + * Meanwhile, these clock won't ever change at runtime. + * For the above reasons, we can only use ro_ops for fixed PLL related clocks. + */ +static struct clk_regmap s4_fixed_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = ANACTRL_FIXPLL_CTRL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_fixed_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = ANACTRL_FIXPLL_CTRL0, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fixed_pll_dco.hw + }, + .num_parents = 1, + /* + * This clock won't ever change at runtime so + * CLK_SET_RATE_PARENT is not required + */ + }, +}; + +static struct clk_fixed_factor s4_fclk_div2_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_fclk_div2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL1, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fclk_div2_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor s4_fclk_div3_div = { + .mult = 1, + .div = 3, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_fclk_div3 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL1, + .bit_idx = 20, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fclk_div3_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor s4_fclk_div4_div = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div4_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_fclk_div4 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL1, + .bit_idx = 21, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div4", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fclk_div4_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor s4_fclk_div5_div = { + .mult = 1, + .div = 5, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div5_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_fclk_div5 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL1, + .bit_idx = 22, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div5", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fclk_div5_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor s4_fclk_div7_div = { + .mult = 1, + .div = 7, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div7_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_fclk_div7 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL1, + .bit_idx = 23, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div7", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fclk_div7_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor s4_fclk_div2p5_div = { + .mult = 2, + .div = 5, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2p5_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fixed_pll.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_fclk_div2p5 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_FIXPLL_CTRL1, + .bit_idx = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2p5", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fclk_div2p5_div.hw + }, + .num_parents = 1, + }, +}; + +static const struct pll_mult_range s4_gp0_pll_mult_range = { + .min = 125, + .max = 250, +}; + +/* + * Internal gp0 pll emulation configuration parameters + */ +static const struct reg_sequence s4_gp0_init_regs[] = { + { .reg = ANACTRL_GP0PLL_CTRL1, .def = 0x00000000 }, + { .reg = ANACTRL_GP0PLL_CTRL2, .def = 0x00000000 }, + { .reg = ANACTRL_GP0PLL_CTRL3, .def = 0x48681c00 }, + { .reg = ANACTRL_GP0PLL_CTRL4, .def = 0x88770290 }, + { .reg = ANACTRL_GP0PLL_CTRL5, .def = 0x39272000 }, + { .reg = ANACTRL_GP0PLL_CTRL6, .def = 0x56540000 } +}; + +static struct clk_regmap s4_gp0_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = ANACTRL_GP0PLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &s4_gp0_pll_mult_range, + .init_regs = s4_gp0_init_regs, + .init_count = ARRAY_SIZE(s4_gp0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_gp0_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = ANACTRL_GP0PLL_CTRL0, + .shift = 16, + .width = 3, + .flags = (CLK_DIVIDER_POWER_OF_TWO | + CLK_DIVIDER_ROUND_CLOSEST), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_gp0_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * Internal hifi pll emulation configuration parameters + */ +static const struct reg_sequence s4_hifi_init_regs[] = { + { .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x00010e56 }, + { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00000000 }, + { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 }, + { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 }, + { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x39272000 }, + { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000 } +}; + +static struct clk_regmap s4_hifi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = ANACTRL_HIFIPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &s4_gp0_pll_mult_range, + .init_regs = s4_hifi_init_regs, + .init_count = ARRAY_SIZE(s4_hifi_init_regs), + .flags = CLK_MESON_PLL_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_hifi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = ANACTRL_HIFIPLL_CTRL0, + .shift = 16, + .width = 2, + .flags = (CLK_DIVIDER_POWER_OF_TWO | + CLK_DIVIDER_ROUND_CLOSEST), + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hifi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdmi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = ANACTRL_HDMIPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = ANACTRL_HDMIPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = ANACTRL_HDMIPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = ANACTRL_HDMIPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = ANACTRL_HDMIPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &s4_gp0_pll_mult_range, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_hdmi_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = ANACTRL_HDMIPLL_CTRL0, + .shift = 16, + .width = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hdmi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdmi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = ANACTRL_HDMIPLL_CTRL0, + .shift = 20, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hdmi_pll_od.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_mpll_50m_div = { + .mult = 1, + .div = 80, + .hw.init = &(struct clk_init_data){ + .name = "mpll_50m_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fixed_pll_dco.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_mpll_50m = { + .data = &(struct clk_regmap_mux_data){ + .offset = ANACTRL_FIXPLL_CTRL3, + .mask = 0x1, + .shift = 5, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll_50m", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &s4_mpll_50m_div.hw }, + }, + .num_parents = 2, + }, +}; + +static struct clk_fixed_factor s4_mpll_prediv = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mpll_prediv", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_fixed_pll_dco.hw + }, + .num_parents = 1, + }, +}; + +static const struct reg_sequence s4_mpll0_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL2, .def = 0x40000033 } +}; + +static struct clk_regmap s4_mpll0_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = ANACTRL_MPLL_CTRL1, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = ANACTRL_MPLL_CTRL1, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = ANACTRL_MPLL_CTRL1, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = ANACTRL_MPLL_CTRL1, + .shift = 29, + .width = 1, + }, + .lock = &meson_clk_lock, + .init_regs = s4_mpll0_init_regs, + .init_count = ARRAY_SIZE(s4_mpll0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_mpll0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_MPLL_CTRL1, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_mpll0_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence s4_mpll1_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL4, .def = 0x40000033 } +}; + +static struct clk_regmap s4_mpll1_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = ANACTRL_MPLL_CTRL3, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = ANACTRL_MPLL_CTRL3, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = ANACTRL_MPLL_CTRL3, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = ANACTRL_MPLL_CTRL3, + .shift = 29, + .width = 1, + }, + .lock = &meson_clk_lock, + .init_regs = s4_mpll1_init_regs, + .init_count = ARRAY_SIZE(s4_mpll1_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_mpll1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_MPLL_CTRL3, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_mpll1_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence s4_mpll2_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL6, .def = 0x40000033 } +}; + +static struct clk_regmap s4_mpll2_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = ANACTRL_MPLL_CTRL5, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = ANACTRL_MPLL_CTRL5, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = ANACTRL_MPLL_CTRL5, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = ANACTRL_MPLL_CTRL5, + .shift = 29, + .width = 1, + }, + .lock = &meson_clk_lock, + .init_regs = s4_mpll2_init_regs, + .init_count = ARRAY_SIZE(s4_mpll2_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_mpll2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_MPLL_CTRL5, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_mpll2_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence s4_mpll3_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL8, .def = 0x40000033 } +}; + +static struct clk_regmap s4_mpll3_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = ANACTRL_MPLL_CTRL7, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = ANACTRL_MPLL_CTRL7, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = ANACTRL_MPLL_CTRL7, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = ANACTRL_MPLL_CTRL7, + .shift = 29, + .width = 1, + }, + .lock = &meson_clk_lock, + .init_regs = s4_mpll3_init_regs, + .init_count = ARRAY_SIZE(s4_mpll3_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_mpll3 = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANACTRL_MPLL_CTRL7, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_mpll3_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* Array of all clocks provided by this provider */ +static struct clk_hw *s4_pll_hw_clks[] = { + [CLKID_FIXED_PLL_DCO] = &s4_fixed_pll_dco.hw, + [CLKID_FIXED_PLL] = &s4_fixed_pll.hw, + [CLKID_FCLK_DIV2_DIV] = &s4_fclk_div2_div.hw, + [CLKID_FCLK_DIV2] = &s4_fclk_div2.hw, + [CLKID_FCLK_DIV3_DIV] = &s4_fclk_div3_div.hw, + [CLKID_FCLK_DIV3] = &s4_fclk_div3.hw, + [CLKID_FCLK_DIV4_DIV] = &s4_fclk_div4_div.hw, + [CLKID_FCLK_DIV4] = &s4_fclk_div4.hw, + [CLKID_FCLK_DIV5_DIV] = &s4_fclk_div5_div.hw, + [CLKID_FCLK_DIV5] = &s4_fclk_div5.hw, + [CLKID_FCLK_DIV7_DIV] = &s4_fclk_div7_div.hw, + [CLKID_FCLK_DIV7] = &s4_fclk_div7.hw, + [CLKID_FCLK_DIV2P5_DIV] = &s4_fclk_div2p5_div.hw, + [CLKID_FCLK_DIV2P5] = &s4_fclk_div2p5.hw, + [CLKID_GP0_PLL_DCO] = &s4_gp0_pll_dco.hw, + [CLKID_GP0_PLL] = &s4_gp0_pll.hw, + [CLKID_HIFI_PLL_DCO] = &s4_hifi_pll_dco.hw, + [CLKID_HIFI_PLL] = &s4_hifi_pll.hw, + [CLKID_HDMI_PLL_DCO] = &s4_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &s4_hdmi_pll_od.hw, + [CLKID_HDMI_PLL] = &s4_hdmi_pll.hw, + [CLKID_MPLL_50M_DIV] = &s4_mpll_50m_div.hw, + [CLKID_MPLL_50M] = &s4_mpll_50m.hw, + [CLKID_MPLL_PREDIV] = &s4_mpll_prediv.hw, + [CLKID_MPLL0_DIV] = &s4_mpll0_div.hw, + [CLKID_MPLL0] = &s4_mpll0.hw, + [CLKID_MPLL1_DIV] = &s4_mpll1_div.hw, + [CLKID_MPLL1] = &s4_mpll1.hw, + [CLKID_MPLL2_DIV] = &s4_mpll2_div.hw, + [CLKID_MPLL2] = &s4_mpll2.hw, + [CLKID_MPLL3_DIV] = &s4_mpll3_div.hw, + [CLKID_MPLL3] = &s4_mpll3.hw, +}; + +static struct clk_regmap *const s4_pll_clk_regmaps[] = { + &s4_fixed_pll_dco, + &s4_fixed_pll, + &s4_fclk_div2, + &s4_fclk_div3, + &s4_fclk_div4, + &s4_fclk_div5, + &s4_fclk_div7, + &s4_fclk_div2p5, + &s4_gp0_pll_dco, + &s4_gp0_pll, + &s4_hifi_pll_dco, + &s4_hifi_pll, + &s4_hdmi_pll_dco, + &s4_hdmi_pll_od, + &s4_hdmi_pll, + &s4_mpll_50m, + &s4_mpll0_div, + &s4_mpll0, + &s4_mpll1_div, + &s4_mpll1, + &s4_mpll2_div, + &s4_mpll2, + &s4_mpll3_div, + &s4_mpll3, +}; + +static const struct reg_sequence s4_init_regs[] = { + { .reg = ANACTRL_MPLL_CTRL0, .def = 0x00000543 }, +}; + +static struct regmap_config clkc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +static struct meson_clk_hw_data s4_pll_clks = { + .hws = s4_pll_hw_clks, + .num = ARRAY_SIZE(s4_pll_hw_clks), +}; + +static int meson_s4_pll_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *regmap; + void __iomem *base; + int ret, i; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return dev_err_probe(dev, PTR_ERR(base), + "can't ioremap resource\n"); + + regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "can't init regmap mmio region\n"); + + ret = regmap_multi_reg_write(regmap, s4_init_regs, ARRAY_SIZE(s4_init_regs)); + if (ret) + return dev_err_probe(dev, ret, + "Failed to init registers\n"); + + /* Populate regmap for the regmap backed clocks */ + for (i = 0; i < ARRAY_SIZE(s4_pll_clk_regmaps); i++) + s4_pll_clk_regmaps[i]->map = regmap; + + /* Register clocks */ + for (i = 0; i < s4_pll_clks.num; i++) { + /* array might be sparse */ + if (!s4_pll_clks.hws[i]) + continue; + + ret = devm_clk_hw_register(dev, s4_pll_clks.hws[i]); + if (ret) + return dev_err_probe(dev, ret, + "clock[%d] registration failed\n", i); + } + + return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, + &s4_pll_clks); +} + +static const struct of_device_id clkc_match_table[] = { + { + .compatible = "amlogic,s4-pll-clkc", + }, + {} +}; + +static struct platform_driver s4_driver = { + .probe = meson_s4_pll_probe, + .driver = { + .name = "s4-pll-clkc", + .of_match_table = clkc_match_table, + }, +}; + +module_platform_driver(s4_driver); +MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/s4-pll.h b/drivers/clk/meson/s4-pll.h new file mode 100644 index 000000000000..ff7d58302f2a --- /dev/null +++ b/drivers/clk/meson/s4-pll.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved + * Author: Yu Tu <yu.tu@amlogic.com> + */ + +#ifndef __MESON_S4_PLL_H__ +#define __MESON_S4_PLL_H__ + +#define ANACTRL_FIXPLL_CTRL0 0x040 +#define ANACTRL_FIXPLL_CTRL1 0x044 +#define ANACTRL_FIXPLL_CTRL3 0x04c +#define ANACTRL_GP0PLL_CTRL0 0x080 +#define ANACTRL_GP0PLL_CTRL1 0x084 +#define ANACTRL_GP0PLL_CTRL2 0x088 +#define ANACTRL_GP0PLL_CTRL3 0x08c +#define ANACTRL_GP0PLL_CTRL4 0x090 +#define ANACTRL_GP0PLL_CTRL5 0x094 +#define ANACTRL_GP0PLL_CTRL6 0x098 +#define ANACTRL_HIFIPLL_CTRL0 0x100 +#define ANACTRL_HIFIPLL_CTRL1 0x104 +#define ANACTRL_HIFIPLL_CTRL2 0x108 +#define ANACTRL_HIFIPLL_CTRL3 0x10c +#define ANACTRL_HIFIPLL_CTRL4 0x110 +#define ANACTRL_HIFIPLL_CTRL5 0x114 +#define ANACTRL_HIFIPLL_CTRL6 0x118 +#define ANACTRL_MPLL_CTRL0 0x180 +#define ANACTRL_MPLL_CTRL1 0x184 +#define ANACTRL_MPLL_CTRL2 0x188 +#define ANACTRL_MPLL_CTRL3 0x18c +#define ANACTRL_MPLL_CTRL4 0x190 +#define ANACTRL_MPLL_CTRL5 0x194 +#define ANACTRL_MPLL_CTRL6 0x198 +#define ANACTRL_MPLL_CTRL7 0x19c +#define ANACTRL_MPLL_CTRL8 0x1a0 +#define ANACTRL_HDMIPLL_CTRL0 0x1c0 + +#endif /* __MESON_S4_PLL_H__ */ -- 2.33.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH V10 4/4] clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller 2023-08-22 8:27 [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Yu Tu ` (2 preceding siblings ...) 2023-08-22 8:27 ` [PATCH V10 3/4] clk: meson: S4: add support for Amlogic S4 SoC PLL clock driver Yu Tu @ 2023-08-22 8:27 ` Yu Tu 2023-08-23 8:13 ` Jerome Brunet 2023-08-27 17:04 ` [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Lucas Tanure 4 siblings, 1 reply; 21+ messages in thread From: Yu Tu @ 2023-08-22 8:27 UTC (permalink / raw) To: linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan, Yu Tu Add the peripherals clock controller driver in the S4 SoC family. Signed-off-by: Yu Tu <yu.tu@amlogic.com> --- drivers/clk/meson/Kconfig | 11 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/s4-peripherals.c | 3787 ++++++++++++++++++++++++++++ drivers/clk/meson/s4-peripherals.h | 57 + 4 files changed, 3856 insertions(+) create mode 100644 drivers/clk/meson/s4-peripherals.c create mode 100644 drivers/clk/meson/s4-peripherals.h diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index e90982d77598..c5303e4c1604 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -156,4 +156,15 @@ config COMMON_CLK_S4_PLL Support for the PLL clock controller on Amlogic S805X2 and S905Y4 devices, AKA S4. Say Y if you want the board to work, because PLLs are the parent of most peripherals. + +config COMMON_CLK_S4_PERIPHERALS + tristate "S4 SoC peripherals clock controllers support" + depends on ARM64 + default y + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_DUALDIV + select COMMON_CLK_MESON_VID_PLL_DIV + help + Support for the peripherals clock controller on Amlogic S805X2 and S905Y4 + devices, AKA S4. Say Y if you want S4 peripherals clock controller to work. endmenu diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 612cee923890..9ee4b954c896 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o +obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c new file mode 100644 index 000000000000..60de4beb1561 --- /dev/null +++ b/drivers/clk/meson/s4-peripherals.c @@ -0,0 +1,3787 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Amlogic S4 Peripherals Clock Controller Driver + * + * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved + * Author: Yu Tu <yu.tu@amlogic.com> + */ + +#include <linux/clk-provider.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-regmap.h" +#include "vid-pll-div.h" +#include "clk-dualdiv.h" +#include "s4-peripherals.h" +#include "meson-clkc-utils.h" +#include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h> + +static struct clk_regmap s4_rtc_32k_by_oscin_clkin = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_32k_by_oscin_clkin", + .ops = &clk_regmap_gate_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", } + }, + .num_parents = 1, + }, +}; + +static const struct meson_clk_dualdiv_param s4_32k_div_table[] = { + { + .dual = 1, + .n1 = 733, + .m1 = 8, + .n2 = 732, + .m2 = 11, + }, + {} +}; + +static struct clk_regmap s4_rtc_32k_by_oscin_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .shift = 28, + .width = 1, + }, + .table = s4_32k_div_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_32k_by_oscin_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_rtc_32k_by_oscin_clkin.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_rtc_32k_by_oscin_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL1, + .mask = 0x1, + .shift = 24, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_32k_by_oscin_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_rtc_32k_by_oscin_div.hw, + &s4_rtc_32k_by_oscin_clkin.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_rtc_32k_by_oscin = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_32k_by_oscin", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_rtc_32k_by_oscin_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_rtc_clk = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_RTC_CTRL, + .mask = 0x3, + .shift = 0, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_clk_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_rtc_32k_by_oscin.hw, + &s4_rtc_32k_by_oscin_div.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* The index 5 is AXI_CLK, which is dedicated to AXI. So skip it. */ +static u32 mux_table_sys_ab_clk_sel[] = { 0, 1, 2, 3, 4, 6, 7 }; +static const struct clk_parent_data sys_ab_clk_parent_data[] = { + { .fw_name = "xtal" }, + { .fw_name = "fclk_div2" }, + { .fw_name = "fclk_div3" }, + { .fw_name = "fclk_div4" }, + { .fw_name = "fclk_div5" }, + { .fw_name = "fclk_div7" }, + { .hw = &s4_rtc_clk.hw } +}; + +/* + * This clock is initialized by ROMcode. + * The chip was changed SYS CLK for security reasons. SYS CLK registers are not writable + * in the kernel phase. Write of SYS related register will cause the system to crash. + * Meanwhile, these clock won't ever change at runtime. + * For the above reasons, we can only use ro_ops for SYS related clocks. + */ +static struct clk_regmap s4_sysclk_b_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_SYS_CLK_CTRL0, + .mask = 0x7, + .shift = 26, + .table = mux_table_sys_ab_clk_sel, + }, + .hw.init = &(struct clk_init_data){ + .name = "sysclk_b_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = sys_ab_clk_parent_data, + .num_parents = ARRAY_SIZE(sys_ab_clk_parent_data), + }, +}; + +static struct clk_regmap s4_sysclk_b_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_SYS_CLK_CTRL0, + .shift = 16, + .width = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "sysclk_b_div", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sysclk_b_sel.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_sysclk_b = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_SYS_CLK_CTRL0, + .bit_idx = 29, + }, + .hw.init = &(struct clk_init_data) { + .name = "sysclk_b", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sysclk_b_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_sysclk_a_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_SYS_CLK_CTRL0, + .mask = 0x7, + .shift = 10, + .table = mux_table_sys_ab_clk_sel, + }, + .hw.init = &(struct clk_init_data){ + .name = "sysclk_a_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = sys_ab_clk_parent_data, + .num_parents = ARRAY_SIZE(sys_ab_clk_parent_data), + }, +}; + +static struct clk_regmap s4_sysclk_a_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_SYS_CLK_CTRL0, + .shift = 0, + .width = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "sysclk_a_div", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sysclk_a_sel.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_sysclk_a = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_SYS_CLK_CTRL0, + .bit_idx = 13, + }, + .hw.init = &(struct clk_init_data) { + .name = "sysclk_a", + .ops = &clk_regmap_gate_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sysclk_a_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_sys_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_SYS_CLK_CTRL0, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_clk", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sysclk_a.hw, + &s4_sysclk_b.hw + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap s4_ceca_32k_clkin = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_CECA_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "ceca_32k_clkin", + .ops = &clk_regmap_gate_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_ceca_32k_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CLKCTRL_CECA_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CLKCTRL_CECA_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CLKCTRL_CECA_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CLKCTRL_CECA_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CLKCTRL_CECA_CTRL0, + .shift = 28, + .width = 1, + }, + .table = s4_32k_div_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_32k_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_ceca_32k_clkin.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_ceca_32k_sel_pre = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_CECA_CTRL1, + .mask = 0x1, + .shift = 24, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_32k_sel_pre", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_ceca_32k_div.hw, + &s4_ceca_32k_clkin.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_ceca_32k_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_CECA_CTRL1, + .mask = 0x1, + .shift = 31, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_32k_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_ceca_32k_sel_pre.hw, + &s4_rtc_clk.hw + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap s4_ceca_32k_clkout = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_CECA_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_32k_clkout", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_ceca_32k_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cecb_32k_clkin = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_CECB_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "cecb_32k_clkin", + .ops = &clk_regmap_gate_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_cecb_32k_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CLKCTRL_CECB_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CLKCTRL_CECB_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CLKCTRL_CECB_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CLKCTRL_CECB_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CLKCTRL_CECB_CTRL0, + .shift = 28, + .width = 1, + }, + .table = s4_32k_div_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_32k_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cecb_32k_clkin.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_cecb_32k_sel_pre = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_CECB_CTRL1, + .mask = 0x1, + .shift = 24, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_32k_sel_pre", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cecb_32k_div.hw, + &s4_cecb_32k_clkin.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cecb_32k_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_CECB_CTRL1, + .mask = 0x1, + .shift = 31, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_32k_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cecb_32k_sel_pre.hw, + &s4_rtc_clk.hw + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap s4_cecb_32k_clkout = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_CECB_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_32k_clkout", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cecb_32k_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data s4_sc_parent_data[] = { + { .fw_name = "fclk_div4" }, + { .fw_name = "fclk_div3" }, + { .fw_name = "fclk_div5" }, + { .fw_name = "xtal", } +}; + +static struct clk_regmap s4_sc_clk_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_SC_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "sc_clk_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_sc_parent_data, + .num_parents = ARRAY_SIZE(s4_sc_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_sc_clk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_SC_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "sc_clk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sc_clk_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_sc_clk_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_SC_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "sc_clk_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sc_clk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_12_24M_clk_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_CLK12_24_CTRL, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "12_24m_gate", + .ops = &clk_regmap_gate_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", } + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor s4_12M_clk_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "12M", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_12_24M_clk_gate.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_12_24M_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_CLK12_24_CTRL, + .mask = 0x1, + .shift = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "12_24m", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_12_24M_clk_gate.hw, + &s4_12M_clk_div.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* Video Clocks */ +static struct clk_regmap s4_vid_pll_div = { + .data = &(struct meson_vid_pll_div_data){ + .val = { + .reg_off = CLKCTRL_VID_PLL_CLK_DIV, + .shift = 0, + .width = 15, + }, + .sel = { + .reg_off = CLKCTRL_VID_PLL_CLK_DIV, + .shift = 16, + .width = 2, + }, + }, + .hw.init = &(struct clk_init_data) { + .name = "vid_pll_div", + /* + * TODO meson_vid_pll_div_ro_ops to meson_vid_pll_div_ops + */ + .ops = &meson_vid_pll_div_ro_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "hdmi_pll", } + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vid_pll_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VID_PLL_CLK_DIV, + .mask = 0x1, + .shift = 18, + }, + .hw.init = &(struct clk_init_data){ + .name = "vid_pll_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &s4_vid_pll_div.hw }, + { .fw_name = "hdmi_pll", } + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vid_pll = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_PLL_CLK_DIV, + .bit_idx = 19, + }, + .hw.init = &(struct clk_init_data) { + .name = "vid_pll", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vid_pll_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data s4_vclk_parent_data[] = { + { .hw = &s4_vid_pll.hw }, + { .fw_name = "gp0_pll", }, + { .fw_name = "hifi_pll", }, + { .fw_name = "mpll1", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, +}; + +static struct clk_regmap s4_vclk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VID_CLK_CTRL, + .mask = 0x7, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vclk_parent_data, + .num_parents = ARRAY_SIZE(s4_vclk_parent_data), + }, +}; + +static struct clk_regmap s4_vclk2_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VIID_CLK_CTRL, + .mask = 0x7, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk2_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vclk_parent_data, + .num_parents = ARRAY_SIZE(s4_vclk_parent_data), + }, +}; + +static struct clk_regmap s4_vclk_input = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_DIV, + .bit_idx = 16, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk_input", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk2_input = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VIID_CLK_DIV, + .bit_idx = 16, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk2_input", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VID_CLK_DIV, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk_input.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk2_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VIID_CLK_DIV, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk2_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk2_input.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL, + .bit_idx = 19, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VIID_CLK_CTRL, + .bit_idx = 19, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk2", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk_div1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL, + .bit_idx = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk_div1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk_div2_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL, + .bit_idx = 1, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk_div2_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk_div4_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL, + .bit_idx = 2, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk_div4_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk_div6_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL, + .bit_idx = 3, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk_div6_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk_div12_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL, + .bit_idx = 4, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk_div12_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk2_div1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VIID_CLK_CTRL, + .bit_idx = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk2_div1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk2_div2_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VIID_CLK_CTRL, + .bit_idx = 1, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk2_div2_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk2_div4_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VIID_CLK_CTRL, + .bit_idx = 2, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk2_div4_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk2_div6_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VIID_CLK_CTRL, + .bit_idx = 3, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk2_div6_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vclk2_div12_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VIID_CLK_CTRL, + .bit_idx = 4, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk2_div12_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_vclk_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "vclk_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk_div2_en.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_vclk_div4 = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "vclk_div4", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk_div4_en.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_vclk_div6 = { + .mult = 1, + .div = 6, + .hw.init = &(struct clk_init_data){ + .name = "vclk_div6", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk_div6_en.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_vclk_div12 = { + .mult = 1, + .div = 12, + .hw.init = &(struct clk_init_data){ + .name = "vclk_div12", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk_div12_en.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_vclk2_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "vclk2_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk2_div2_en.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_vclk2_div4 = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "vclk2_div4", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk2_div4_en.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_vclk2_div6 = { + .mult = 1, + .div = 6, + .hw.init = &(struct clk_init_data){ + .name = "vclk2_div6", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk2_div6_en.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor s4_vclk2_div12 = { + .mult = 1, + .div = 12, + .hw.init = &(struct clk_init_data){ + .name = "vclk2_div12", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vclk2_div12_en.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* The 5,6,7 indexes corresponds to no real clock, so there are not used. */ +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *s4_cts_parent_hws[] = { + &s4_vclk_div1.hw, + &s4_vclk_div2.hw, + &s4_vclk_div4.hw, + &s4_vclk_div6.hw, + &s4_vclk_div12.hw, + &s4_vclk2_div1.hw, + &s4_vclk2_div2.hw, + &s4_vclk2_div4.hw, + &s4_vclk2_div6.hw, + &s4_vclk2_div12.hw +}; + +static struct clk_regmap s4_cts_enci_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VID_CLK_DIV, + .mask = 0xf, + .shift = 28, + .table = mux_table_cts_sel, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_enci_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_cts_parent_hws, + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cts_encp_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VID_CLK_DIV, + .mask = 0xf, + .shift = 20, + .table = mux_table_cts_sel, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_encp_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_cts_parent_hws, + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cts_vdac_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VIID_CLK_DIV, + .mask = 0xf, + .shift = 28, + .table = mux_table_cts_sel, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_vdac_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_cts_parent_hws, + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* The 5,6,7 indexes corresponds to no real clock, so there are not used. */ +static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *s4_cts_hdmi_tx_parent_hws[] = { + &s4_vclk_div1.hw, + &s4_vclk_div2.hw, + &s4_vclk_div4.hw, + &s4_vclk_div6.hw, + &s4_vclk_div12.hw, + &s4_vclk2_div1.hw, + &s4_vclk2_div2.hw, + &s4_vclk2_div4.hw, + &s4_vclk2_div6.hw, + &s4_vclk2_div12.hw +}; + +static struct clk_regmap s4_hdmi_tx_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_HDMI_CLK_CTRL, + .mask = 0xf, + .shift = 16, + .table = mux_table_hdmi_tx_sel, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_tx_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_cts_hdmi_tx_parent_hws, + .num_parents = ARRAY_SIZE(s4_cts_hdmi_tx_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cts_enci = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL2, + .bit_idx = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "cts_enci", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cts_enci_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cts_encp = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL2, + .bit_idx = 2, + }, + .hw.init = &(struct clk_init_data) { + .name = "cts_encp", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cts_encp_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cts_vdac = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL2, + .bit_idx = 4, + }, + .hw.init = &(struct clk_init_data) { + .name = "cts_vdac", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cts_vdac_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdmi_tx = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL2, + .bit_idx = 5, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdmi_tx", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hdmi_tx_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* HDMI Clocks */ +static const struct clk_parent_data s4_hdmi_parent_data[] = { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", } +}; + +static struct clk_regmap s4_hdmi_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_HDMI_CLK_CTRL, + .mask = 0x3, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_hdmi_parent_data, + .num_parents = ARRAY_SIZE(s4_hdmi_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdmi_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_HDMI_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_hdmi_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdmi = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_HDMI_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdmi", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_hdmi_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_ts_clk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_TS_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ts_clk_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_ts_clk_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_TS_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ts_clk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_ts_clk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * The MALI IP is clocked by two identical clocks (mali_0 and mali_1) + * muxed by a glitch-free switch. The CCF can manage this glitch-free + * mux because it does top-to-bottom updates the each clock tree and + * switches to the "inactive" one when CLK_SET_RATE_GATE is set. + */ +static const struct clk_parent_data s4_mali_0_1_parent_data[] = { + { .fw_name = "xtal", }, + { .fw_name = "gp0_pll", }, + { .fw_name = "hifi_pll", }, + { .fw_name = "fclk_div2p5", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", } +}; + +static struct clk_regmap s4_mali_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_MALI_CLK_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_mali_0_1_parent_data, + .num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data), + /* + * Don't request the parent to change the rate because + * all GPU frequencies can be derived from the fclk_* + * clocks and one special GP0_PLL setting. This is + * important because we need the MPLL clocks for audio. + */ + .flags = 0, + }, +}; + +static struct clk_regmap s4_mali_0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_MALI_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_mali_0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_mali_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_MALI_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_mali_0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_mali_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_MALI_CLK_CTRL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_mali_0_1_parent_data, + .num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data), + .flags = 0, + }, +}; + +static struct clk_regmap s4_mali_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_MALI_CLK_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_mali_1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_mali_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_MALI_CLK_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_mali_1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_hw *s4_mali_parent_hws[] = { + &s4_mali_0.hw, + &s4_mali_1.hw +}; + +static struct clk_regmap s4_mali_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_MALI_CLK_CTRL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_mali_parent_hws, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* VDEC clocks */ +static const struct clk_parent_data s4_dec_parent_data[] = { + { .fw_name = "fclk_div2p5", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, + { .fw_name = "hifi_pll", }, + { .fw_name = "gp0_pll", }, + { .fw_name = "xtal", } +}; + +static struct clk_regmap s4_vdec_p0_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VDEC_CLK_CTRL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_p0_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_dec_parent_data, + .num_parents = ARRAY_SIZE(s4_dec_parent_data), + }, +}; + +static struct clk_regmap s4_vdec_p0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VDEC_CLK_CTRL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_p0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vdec_p0_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vdec_p0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VDEC_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_p0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vdec_p0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vdec_p1_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VDEC3_CLK_CTRL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_p1_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_dec_parent_data, + .num_parents = ARRAY_SIZE(s4_dec_parent_data), + }, +}; + +static struct clk_regmap s4_vdec_p1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VDEC3_CLK_CTRL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_p1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vdec_p1_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vdec_p1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VDEC3_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_p1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vdec_p1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_hw *s4_vdec_mux_parent_hws[] = { + &s4_vdec_p0.hw, + &s4_vdec_p1.hw +}; + +static struct clk_regmap s4_vdec_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VDEC3_CLK_CTRL, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_mux", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_vdec_mux_parent_hws, + .num_parents = ARRAY_SIZE(s4_vdec_mux_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hevcf_p0_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VDEC2_CLK_CTRL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "hevcf_p0_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_dec_parent_data, + .num_parents = ARRAY_SIZE(s4_dec_parent_data), + }, +}; + +static struct clk_regmap s4_hevcf_p0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VDEC2_CLK_CTRL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "hevcf_p0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hevcf_p0_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hevcf_p0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VDEC2_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "hevcf_p0_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hevcf_p0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hevcf_p1_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VDEC4_CLK_CTRL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "hevcf_p1_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_dec_parent_data, + .num_parents = ARRAY_SIZE(s4_dec_parent_data), + }, +}; + +static struct clk_regmap s4_hevcf_p1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VDEC4_CLK_CTRL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "hevcf_p1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hevcf_p1_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hevcf_p1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VDEC4_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "hevcf_p1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hevcf_p1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_hw *s4_hevcf_mux_parent_hws[] = { + &s4_hevcf_p0.hw, + &s4_hevcf_p1.hw +}; + +static struct clk_regmap s4_hevcf_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VDEC4_CLK_CTRL, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data) { + .name = "hevcf", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_hevcf_mux_parent_hws, + .num_parents = ARRAY_SIZE(s4_hevcf_mux_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* VPU Clock */ +static const struct clk_parent_data s4_vpu_parent_data[] = { + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, + { .fw_name = "mpll1", }, + { .hw = &s4_vid_pll.hw }, + { .fw_name = "hifi_pll", }, + { .fw_name = "gp0_pll", }, +}; + +static struct clk_regmap s4_vpu_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VPU_CLK_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vpu_parent_data, + .num_parents = ARRAY_SIZE(s4_vpu_parent_data), + }, +}; + +static struct clk_regmap s4_vpu_0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VPU_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VPU_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VPU_CLK_CTRL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vpu_parent_data, + .num_parents = ARRAY_SIZE(s4_vpu_parent_data), + }, +}; + +static struct clk_regmap s4_vpu_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VPU_CLK_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VPU_CLK_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VPU_CLK_CTRL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_0.hw, + &s4_vpu_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data vpu_clkb_tmp_parent_data[] = { + { .hw = &s4_vpu.hw }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", } +}; + +static struct clk_regmap s4_vpu_clkb_tmp_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VPU_CLKB_CTRL, + .mask = 0x3, + .shift = 20, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkb_tmp_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = vpu_clkb_tmp_parent_data, + .num_parents = ARRAY_SIZE(vpu_clkb_tmp_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_clkb_tmp_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VPU_CLKB_CTRL, + .shift = 16, + .width = 4, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkb_tmp_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkb_tmp_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_clkb_tmp = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VPU_CLKB_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_clkb_tmp", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkb_tmp_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_clkb_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VPU_CLKB_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkb_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkb_tmp.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_clkb = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VPU_CLKB_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_clkb", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkb_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data s4_vpu_clkc_parent_data[] = { + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, + { .fw_name = "mpll1", }, + { .hw = &s4_vid_pll.hw }, + { .fw_name = "mpll2", }, + { .fw_name = "gp0_pll", }, +}; + +static struct clk_regmap s4_vpu_clkc_p0_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VPU_CLKC_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkc_p0_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vpu_clkc_parent_data, + .num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data), + }, +}; + +static struct clk_regmap s4_vpu_clkc_p0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VPU_CLKC_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkc_p0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkc_p0_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_clkc_p0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VPU_CLKC_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_clkc_p0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkc_p0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_clkc_p1_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VPU_CLKC_CTRL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkc_p1_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vpu_clkc_parent_data, + .num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data), + }, +}; + +static struct clk_regmap s4_vpu_clkc_p1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VPU_CLKC_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkc_p1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkc_p1_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vpu_clkc_p1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VPU_CLKC_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_clkc_p1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkc_p1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_hw *s4_vpu_mux_parent_hws[] = { + &s4_vpu_clkc_p0.hw, + &s4_vpu_clkc_p1.hw +}; + +static struct clk_regmap s4_vpu_clkc_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VPU_CLKC_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkc_mux", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_vpu_mux_parent_hws, + .num_parents = ARRAY_SIZE(s4_vpu_mux_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* VAPB Clock */ +static const struct clk_parent_data s4_vapb_parent_data[] = { + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, + { .fw_name = "mpll1", }, + { .hw = &s4_vid_pll.hw }, + { .fw_name = "mpll2", }, + { .fw_name = "fclk_div2p5", }, +}; + +static struct clk_regmap s4_vapb_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VAPBCLK_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vapb_parent_data, + .num_parents = ARRAY_SIZE(s4_vapb_parent_data), + }, +}; + +static struct clk_regmap s4_vapb_0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VAPBCLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vapb_0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vapb_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VAPBCLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vapb_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vapb_0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vapb_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VAPBCLK_CTRL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vapb_parent_data, + .num_parents = ARRAY_SIZE(s4_vapb_parent_data), + }, +}; + +static struct clk_regmap s4_vapb_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VAPBCLK_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vapb_1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vapb_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VAPBCLK_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vapb_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vapb_1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vapb = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VAPBCLK_CTRL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vapb_0.hw, + &s4_vapb_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_ge2d_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VAPBCLK_CTRL, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "ge2d_clk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &s4_vapb.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data s4_esmclk_parent_data[] = { + { .fw_name = "fclk_div7", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, +}; + +static struct clk_regmap s4_hdcp22_esmclk_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_HDCP22_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdcp22_esmclk_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_esmclk_parent_data, + .num_parents = ARRAY_SIZE(s4_esmclk_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdcp22_esmclk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_HDCP22_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdcp22_esmclk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hdcp22_esmclk_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdcp22_esmclk_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_HDCP22_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdcp22_esmclk_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hdcp22_esmclk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data s4_skpclk_parent_data[] = { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, +}; + +static struct clk_regmap s4_hdcp22_skpclk_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_HDCP22_CTRL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdcp22_skpclk_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_skpclk_parent_data, + .num_parents = ARRAY_SIZE(s4_skpclk_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdcp22_skpclk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_HDCP22_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdcp22_skpclk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hdcp22_skpclk_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_hdcp22_skpclk_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_HDCP22_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdcp22_skpclk_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_hdcp22_skpclk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data s4_vdin_parent_data[] = { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, + { .hw = &s4_vid_pll.hw } +}; + +static struct clk_regmap s4_vdin_meas_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdin_meas_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_vdin_parent_data, + .num_parents = ARRAY_SIZE(s4_vdin_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vdin_meas_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdin_meas_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vdin_meas_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_vdin_meas_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdin_meas_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_vdin_meas_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* EMMC/NAND clock */ +static const struct clk_parent_data s4_sd_emmc_clk0_parent_data[] = { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div2", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "hifi_pll", }, + { .fw_name = "fclk_div2p5", }, + { .fw_name = "mpll2", }, + { .fw_name = "mpll3", }, + { .fw_name = "gp0_pll", }, +}; + +static struct clk_regmap s4_sd_emmc_c_clk0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_NAND_CLK_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_c_clk0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), + }, +}; + +static struct clk_regmap s4_sd_emmc_c_clk0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_NAND_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_c_clk0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sd_emmc_c_clk0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_sd_emmc_c_clk0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_NAND_CLK_CTRL, + .bit_idx = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_c_clk0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sd_emmc_c_clk0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_sd_emmc_a_clk0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_a_clk0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), + }, +}; + +static struct clk_regmap s4_sd_emmc_a_clk0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_a_clk0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sd_emmc_a_clk0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_sd_emmc_a_clk0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .bit_idx = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_a_clk0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sd_emmc_a_clk0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_sd_emmc_b_clk0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_b_clk0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), + }, +}; + +static struct clk_regmap s4_sd_emmc_b_clk0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_b_clk0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sd_emmc_b_clk0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_sd_emmc_b_clk0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, + .bit_idx = 23, + }, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_b_clk0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_sd_emmc_b_clk0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* SPICC Clock */ +static const struct clk_parent_data s4_spicc_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &s4_sys_clk.hw }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div2", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, +}; + +static struct clk_regmap s4_spicc0_mux = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_SPICC_CLK_CTRL, + .mask = 0x7, + .shift = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc0_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_spicc_parent_data, + .num_parents = ARRAY_SIZE(s4_spicc_parent_data), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_spicc0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_SPICC_CLK_CTRL, + .shift = 0, + .width = 6, + }, + .hw.init = &(struct clk_init_data) { + .name = "spicc0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_spicc0_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_spicc0_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_SPICC_CLK_CTRL, + .bit_idx = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_spicc0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* PWM Clock */ +static const struct clk_parent_data s4_pwm_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &s4_vid_pll.hw }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, +}; + +static struct clk_regmap s4_pwm_a_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_AB_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_a_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_a_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_AB_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_a_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_a_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_a_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_AB_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_a_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_a_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_b_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_AB_CTRL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_b_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_b_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_AB_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_b_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_b_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_b_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_AB_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_b_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_b_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_c_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_CD_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_c_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_c_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_CD_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_c_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_c_mux.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap s4_pwm_c_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_CD_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_c_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_c_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_d_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_CD_CTRL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_d_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_d_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_CD_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_d_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_d_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_d_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_CD_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_d_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_d_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_e_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_EF_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_e_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_e_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_EF_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_e_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_e_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_e_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_EF_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_e_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_e_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_f_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_EF_CTRL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_f_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_f_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_EF_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_f_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_f_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_f_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_EF_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_f_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_f_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_g_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_GH_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_g_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_g_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_GH_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_g_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_g_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_g_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_GH_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_g_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_g_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_h_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_GH_CTRL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_h_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_h_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_GH_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_h_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_h_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_h_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_GH_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_h_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_h_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_i_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_i_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_i_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_i_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_i_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_i_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_i_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_i_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_j_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_j_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_pwm_parent_data, + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), + }, +}; + +static struct clk_regmap s4_pwm_j_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_j_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_h_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_pwm_j_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "pwm_j_gate", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_pwm_j_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_saradc_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_SAR_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "saradc_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &s4_sys_clk.hw }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_saradc_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_SAR_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "saradc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_saradc_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_saradc_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_SAR_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "saradc_clk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_saradc_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * gen clk is designed for debug/monitor some internal clock quality. Some of the + * corresponding clock sources are not described in the clock tree and internal clock + * for debug, so they are skipped. + */ +static u32 s4_gen_clk_mux_table[] = { 0, 4, 5, 7, 19, 21, 22, + 23, 24, 25, 26, 27, 28 }; +static const struct clk_parent_data s4_gen_clk_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &s4_vid_pll.hw }, + { .fw_name = "gp0_pll", }, + { .fw_name = "hifi_pll", }, + { .fw_name = "fclk_div2", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, + { .fw_name = "mpll0", }, + { .fw_name = "mpll1", }, + { .fw_name = "mpll2", }, + { .fw_name = "mpll3", }, +}; + +static struct clk_regmap s4_gen_clk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_GEN_CLK_CTRL, + .mask = 0x1f, + .shift = 12, + .table = s4_gen_clk_mux_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "gen_clk_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_gen_clk_parent_data, + .num_parents = ARRAY_SIZE(s4_gen_clk_parent_data), + /* + * Because the GEN clock can be connected to an external pad + * and may be set up directly from the device tree. Don't + * really want to automatically reparent. + */ + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap s4_gen_clk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLKCTRL_GEN_CLK_CTRL, + .shift = 0, + .width = 11, + }, + .hw.init = &(struct clk_init_data){ + .name = "gen_clk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_gen_clk_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_gen_clk = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_GEN_CLK_CTRL, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "gen_clk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_gen_clk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data s4_adc_extclk_in_parent_data[] = { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div4", }, + { .fw_name = "fclk_div3", }, + { .fw_name = "fclk_div5", }, + { .fw_name = "fclk_div7", }, + { .fw_name = "mpll2", }, + { .fw_name = "gp0_pll", }, + { .fw_name = "hifi_pll", }, +}; + +static struct clk_regmap s4_adc_extclk_in_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = s4_adc_extclk_in_parent_data, + .num_parents = ARRAY_SIZE(s4_adc_extclk_in_parent_data), + }, +}; + +static struct clk_regmap s4_adc_extclk_in_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_adc_extclk_in_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_adc_extclk_in_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_adc_extclk_in_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_demod_core_clk_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core_clk_mux", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div7", }, + { .fw_name = "fclk_div4", }, + { .hw = &s4_adc_extclk_in_gate.hw } + }, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_demod_core_clk_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core_clk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_demod_core_clk_mux.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_demod_core_clk_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core_clk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_demod_core_clk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &s4_sys_clk.hw) + +static MESON_GATE(s4_ddr, CLKCTRL_SYS_CLK_EN0_REG0, 0); +static MESON_GATE(s4_dos, CLKCTRL_SYS_CLK_EN0_REG0, 1); +static MESON_GATE(s4_ethphy, CLKCTRL_SYS_CLK_EN0_REG0, 4); +static MESON_GATE(s4_mali, CLKCTRL_SYS_CLK_EN0_REG0, 6); +static MESON_GATE(s4_aocpu, CLKCTRL_SYS_CLK_EN0_REG0, 13); +static MESON_GATE(s4_aucpu, CLKCTRL_SYS_CLK_EN0_REG0, 14); +static MESON_GATE(s4_cec, CLKCTRL_SYS_CLK_EN0_REG0, 16); +static MESON_GATE(s4_sdemmca, CLKCTRL_SYS_CLK_EN0_REG0, 24); +static MESON_GATE(s4_sdemmcb, CLKCTRL_SYS_CLK_EN0_REG0, 25); +static MESON_GATE(s4_nand, CLKCTRL_SYS_CLK_EN0_REG0, 26); +static MESON_GATE(s4_smartcard, CLKCTRL_SYS_CLK_EN0_REG0, 27); +static MESON_GATE(s4_acodec, CLKCTRL_SYS_CLK_EN0_REG0, 28); +static MESON_GATE(s4_spifc, CLKCTRL_SYS_CLK_EN0_REG0, 29); +static MESON_GATE(s4_msr_clk, CLKCTRL_SYS_CLK_EN0_REG0, 30); +static MESON_GATE(s4_ir_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 31); +static MESON_GATE(s4_audio, CLKCTRL_SYS_CLK_EN0_REG1, 0); +static MESON_GATE(s4_eth, CLKCTRL_SYS_CLK_EN0_REG1, 3); +static MESON_GATE(s4_uart_a, CLKCTRL_SYS_CLK_EN0_REG1, 5); +static MESON_GATE(s4_uart_b, CLKCTRL_SYS_CLK_EN0_REG1, 6); +static MESON_GATE(s4_uart_c, CLKCTRL_SYS_CLK_EN0_REG1, 7); +static MESON_GATE(s4_uart_d, CLKCTRL_SYS_CLK_EN0_REG1, 8); +static MESON_GATE(s4_uart_e, CLKCTRL_SYS_CLK_EN0_REG1, 9); +static MESON_GATE(s4_aififo, CLKCTRL_SYS_CLK_EN0_REG1, 11); +static MESON_GATE(s4_ts_ddr, CLKCTRL_SYS_CLK_EN0_REG1, 15); +static MESON_GATE(s4_ts_pll, CLKCTRL_SYS_CLK_EN0_REG1, 16); +static MESON_GATE(s4_g2d, CLKCTRL_SYS_CLK_EN0_REG1, 20); +static MESON_GATE(s4_spicc0, CLKCTRL_SYS_CLK_EN0_REG1, 21); +static MESON_GATE(s4_usb, CLKCTRL_SYS_CLK_EN0_REG1, 26); +static MESON_GATE(s4_i2c_m_a, CLKCTRL_SYS_CLK_EN0_REG1, 30); +static MESON_GATE(s4_i2c_m_b, CLKCTRL_SYS_CLK_EN0_REG1, 31); +static MESON_GATE(s4_i2c_m_c, CLKCTRL_SYS_CLK_EN0_REG2, 0); +static MESON_GATE(s4_i2c_m_d, CLKCTRL_SYS_CLK_EN0_REG2, 1); +static MESON_GATE(s4_i2c_m_e, CLKCTRL_SYS_CLK_EN0_REG2, 2); +static MESON_GATE(s4_hdmitx_apb, CLKCTRL_SYS_CLK_EN0_REG2, 4); +static MESON_GATE(s4_i2c_s_a, CLKCTRL_SYS_CLK_EN0_REG2, 5); +static MESON_GATE(s4_usb1_to_ddr, CLKCTRL_SYS_CLK_EN0_REG2, 8); +static MESON_GATE(s4_hdcp22, CLKCTRL_SYS_CLK_EN0_REG2, 10); +static MESON_GATE(s4_mmc_apb, CLKCTRL_SYS_CLK_EN0_REG2, 11); +static MESON_GATE(s4_rsa, CLKCTRL_SYS_CLK_EN0_REG2, 18); +static MESON_GATE(s4_cpu_debug, CLKCTRL_SYS_CLK_EN0_REG2, 19); +static MESON_GATE(s4_vpu_intr, CLKCTRL_SYS_CLK_EN0_REG2, 25); +static MESON_GATE(s4_demod, CLKCTRL_SYS_CLK_EN0_REG2, 27); +static MESON_GATE(s4_sar_adc, CLKCTRL_SYS_CLK_EN0_REG2, 28); +static MESON_GATE(s4_gic, CLKCTRL_SYS_CLK_EN0_REG2, 30); +static MESON_GATE(s4_pwm_ab, CLKCTRL_SYS_CLK_EN0_REG3, 7); +static MESON_GATE(s4_pwm_cd, CLKCTRL_SYS_CLK_EN0_REG3, 8); +static MESON_GATE(s4_pwm_ef, CLKCTRL_SYS_CLK_EN0_REG3, 9); +static MESON_GATE(s4_pwm_gh, CLKCTRL_SYS_CLK_EN0_REG3, 10); +static MESON_GATE(s4_pwm_ij, CLKCTRL_SYS_CLK_EN0_REG3, 11); + +/* Array of all clocks provided by this provider */ +static struct clk_hw *s4_periphs_hw_clks[] = { + [CLKID_RTC_32K_CLKIN] = &s4_rtc_32k_by_oscin_clkin.hw, + [CLKID_RTC_32K_DIV] = &s4_rtc_32k_by_oscin_div.hw, + [CLKID_RTC_32K_SEL] = &s4_rtc_32k_by_oscin_sel.hw, + [CLKID_RTC_32K_XATL] = &s4_rtc_32k_by_oscin.hw, + [CLKID_RTC] = &s4_rtc_clk.hw, + [CLKID_SYS_CLK_B_SEL] = &s4_sysclk_b_sel.hw, + [CLKID_SYS_CLK_B_DIV] = &s4_sysclk_b_div.hw, + [CLKID_SYS_CLK_B] = &s4_sysclk_b.hw, + [CLKID_SYS_CLK_A_SEL] = &s4_sysclk_a_sel.hw, + [CLKID_SYS_CLK_A_DIV] = &s4_sysclk_a_div.hw, + [CLKID_SYS_CLK_A] = &s4_sysclk_a.hw, + [CLKID_SYS] = &s4_sys_clk.hw, + [CLKID_CECA_32K_CLKIN] = &s4_ceca_32k_clkin.hw, + [CLKID_CECA_32K_DIV] = &s4_ceca_32k_div.hw, + [CLKID_CECA_32K_SEL_PRE] = &s4_ceca_32k_sel_pre.hw, + [CLKID_CECA_32K_SEL] = &s4_ceca_32k_sel.hw, + [CLKID_CECA_32K_CLKOUT] = &s4_ceca_32k_clkout.hw, + [CLKID_CECB_32K_CLKIN] = &s4_cecb_32k_clkin.hw, + [CLKID_CECB_32K_DIV] = &s4_cecb_32k_div.hw, + [CLKID_CECB_32K_SEL_PRE] = &s4_cecb_32k_sel_pre.hw, + [CLKID_CECB_32K_SEL] = &s4_cecb_32k_sel.hw, + [CLKID_CECB_32K_CLKOUT] = &s4_cecb_32k_clkout.hw, + [CLKID_SC_CLK_SEL] = &s4_sc_clk_mux.hw, + [CLKID_SC_CLK_DIV] = &s4_sc_clk_div.hw, + [CLKID_SC] = &s4_sc_clk_gate.hw, + [CLKID_12_24M] = &s4_12_24M_clk_gate.hw, + [CLKID_12M_CLK_DIV] = &s4_12M_clk_div.hw, + [CLKID_12_24M_CLK_SEL] = &s4_12_24M_clk.hw, + [CLKID_VID_PLL_DIV] = &s4_vid_pll_div.hw, + [CLKID_VID_PLL_SEL] = &s4_vid_pll_sel.hw, + [CLKID_VID_PLL] = &s4_vid_pll.hw, + [CLKID_VCLK_SEL] = &s4_vclk_sel.hw, + [CLKID_VCLK2_SEL] = &s4_vclk2_sel.hw, + [CLKID_VCLK_INPUT] = &s4_vclk_input.hw, + [CLKID_VCLK2_INPUT] = &s4_vclk2_input.hw, + [CLKID_VCLK_DIV] = &s4_vclk_div.hw, + [CLKID_VCLK2_DIV] = &s4_vclk2_div.hw, + [CLKID_VCLK] = &s4_vclk.hw, + [CLKID_VCLK2] = &s4_vclk2.hw, + [CLKID_VCLK_DIV1] = &s4_vclk_div1.hw, + [CLKID_VCLK_DIV2_EN] = &s4_vclk_div2_en.hw, + [CLKID_VCLK_DIV4_EN] = &s4_vclk_div4_en.hw, + [CLKID_VCLK_DIV6_EN] = &s4_vclk_div6_en.hw, + [CLKID_VCLK_DIV12_EN] = &s4_vclk_div12_en.hw, + [CLKID_VCLK2_DIV1] = &s4_vclk2_div1.hw, + [CLKID_VCLK2_DIV2_EN] = &s4_vclk2_div2_en.hw, + [CLKID_VCLK2_DIV4_EN] = &s4_vclk2_div4_en.hw, + [CLKID_VCLK2_DIV6_EN] = &s4_vclk2_div6_en.hw, + [CLKID_VCLK2_DIV12_EN] = &s4_vclk2_div12_en.hw, + [CLKID_VCLK_DIV2] = &s4_vclk_div2.hw, + [CLKID_VCLK_DIV4] = &s4_vclk_div4.hw, + [CLKID_VCLK_DIV6] = &s4_vclk_div6.hw, + [CLKID_VCLK_DIV12] = &s4_vclk_div12.hw, + [CLKID_VCLK2_DIV2] = &s4_vclk2_div2.hw, + [CLKID_VCLK2_DIV4] = &s4_vclk2_div4.hw, + [CLKID_VCLK2_DIV6] = &s4_vclk2_div6.hw, + [CLKID_VCLK2_DIV12] = &s4_vclk2_div12.hw, + [CLKID_CTS_ENCI_SEL] = &s4_cts_enci_sel.hw, + [CLKID_CTS_ENCP_SEL] = &s4_cts_encp_sel.hw, + [CLKID_CTS_VDAC_SEL] = &s4_cts_vdac_sel.hw, + [CLKID_HDMI_TX_SEL] = &s4_hdmi_tx_sel.hw, + [CLKID_CTS_ENCI] = &s4_cts_enci.hw, + [CLKID_CTS_ENCP] = &s4_cts_encp.hw, + [CLKID_CTS_VDAC] = &s4_cts_vdac.hw, + [CLKID_HDMI_TX] = &s4_hdmi_tx.hw, + [CLKID_HDMI_SEL] = &s4_hdmi_sel.hw, + [CLKID_HDMI_DIV] = &s4_hdmi_div.hw, + [CLKID_HDMI] = &s4_hdmi.hw, + [CLKID_TS_CLK_DIV] = &s4_ts_clk_div.hw, + [CLKID_TS] = &s4_ts_clk_gate.hw, + [CLKID_MALI_0_SEL] = &s4_mali_0_sel.hw, + [CLKID_MALI_0_DIV] = &s4_mali_0_div.hw, + [CLKID_MALI_0] = &s4_mali_0.hw, + [CLKID_MALI_1_SEL] = &s4_mali_1_sel.hw, + [CLKID_MALI_1_DIV] = &s4_mali_1_div.hw, + [CLKID_MALI_1] = &s4_mali_1.hw, + [CLKID_MALI_SEL] = &s4_mali_mux.hw, + [CLKID_VDEC_P0_SEL] = &s4_vdec_p0_mux.hw, + [CLKID_VDEC_P0_DIV] = &s4_vdec_p0_div.hw, + [CLKID_VDEC_P0] = &s4_vdec_p0.hw, + [CLKID_VDEC_P1_SEL] = &s4_vdec_p1_mux.hw, + [CLKID_VDEC_P1_DIV] = &s4_vdec_p1_div.hw, + [CLKID_VDEC_P1] = &s4_vdec_p1.hw, + [CLKID_VDEC_SEL] = &s4_vdec_mux.hw, + [CLKID_HEVCF_P0_SEL] = &s4_hevcf_p0_mux.hw, + [CLKID_HEVCF_P0_DIV] = &s4_hevcf_p0_div.hw, + [CLKID_HEVCF_P0] = &s4_hevcf_p0.hw, + [CLKID_HEVCF_P1_SEL] = &s4_hevcf_p1_mux.hw, + [CLKID_HEVCF_P1_DIV] = &s4_hevcf_p1_div.hw, + [CLKID_HEVCF_P1] = &s4_hevcf_p1.hw, + [CLKID_HEVCF_SEL] = &s4_hevcf_mux.hw, + [CLKID_VPU_0_SEL] = &s4_vpu_0_sel.hw, + [CLKID_VPU_0_DIV] = &s4_vpu_0_div.hw, + [CLKID_VPU_0] = &s4_vpu_0.hw, + [CLKID_VPU_1_SEL] = &s4_vpu_1_sel.hw, + [CLKID_VPU_1_DIV] = &s4_vpu_1_div.hw, + [CLKID_VPU_1] = &s4_vpu_1.hw, + [CLKID_VPU] = &s4_vpu.hw, + [CLKID_VPU_CLKB_TMP_SEL] = &s4_vpu_clkb_tmp_mux.hw, + [CLKID_VPU_CLKB_TMP_DIV] = &s4_vpu_clkb_tmp_div.hw, + [CLKID_VPU_CLKB_TMP] = &s4_vpu_clkb_tmp.hw, + [CLKID_VPU_CLKB_DIV] = &s4_vpu_clkb_div.hw, + [CLKID_VPU_CLKB] = &s4_vpu_clkb.hw, + [CLKID_VPU_CLKC_P0_SEL] = &s4_vpu_clkc_p0_mux.hw, + [CLKID_VPU_CLKC_P0_DIV] = &s4_vpu_clkc_p0_div.hw, + [CLKID_VPU_CLKC_P0] = &s4_vpu_clkc_p0.hw, + [CLKID_VPU_CLKC_P1_SEL] = &s4_vpu_clkc_p1_mux.hw, + [CLKID_VPU_CLKC_P1_DIV] = &s4_vpu_clkc_p1_div.hw, + [CLKID_VPU_CLKC_P1] = &s4_vpu_clkc_p1.hw, + [CLKID_VPU_CLKC_SEL] = &s4_vpu_clkc_mux.hw, + [CLKID_VAPB_0_SEL] = &s4_vapb_0_sel.hw, + [CLKID_VAPB_0_DIV] = &s4_vapb_0_div.hw, + [CLKID_VAPB_0] = &s4_vapb_0.hw, + [CLKID_VAPB_1_SEL] = &s4_vapb_1_sel.hw, + [CLKID_VAPB_1_DIV] = &s4_vapb_1_div.hw, + [CLKID_VAPB_1] = &s4_vapb_1.hw, + [CLKID_VAPB] = &s4_vapb.hw, + [CLKID_GE2D] = &s4_ge2d_gate.hw, + [CLKID_VDIN_MEAS_SEL] = &s4_vdin_meas_mux.hw, + [CLKID_VDIN_MEAS_DIV] = &s4_vdin_meas_div.hw, + [CLKID_VDIN_MEAS] = &s4_vdin_meas_gate.hw, + [CLKID_SD_EMMC_C_CLK_SEL] = &s4_sd_emmc_c_clk0_sel.hw, + [CLKID_SD_EMMC_C_CLK_DIV] = &s4_sd_emmc_c_clk0_div.hw, + [CLKID_SD_EMMC_C] = &s4_sd_emmc_c_clk0.hw, + [CLKID_SD_EMMC_A_CLK_SEL] = &s4_sd_emmc_a_clk0_sel.hw, + [CLKID_SD_EMMC_A_CLK_DIV] = &s4_sd_emmc_a_clk0_div.hw, + [CLKID_SD_EMMC_A] = &s4_sd_emmc_a_clk0.hw, + [CLKID_SD_EMMC_B_CLK_SEL] = &s4_sd_emmc_b_clk0_sel.hw, + [CLKID_SD_EMMC_B_CLK_DIV] = &s4_sd_emmc_b_clk0_div.hw, + [CLKID_SD_EMMC_B] = &s4_sd_emmc_b_clk0.hw, + [CLKID_SPICC0_SEL] = &s4_spicc0_mux.hw, + [CLKID_SPICC0_DIV] = &s4_spicc0_div.hw, + [CLKID_SPICC0_EN] = &s4_spicc0_gate.hw, + [CLKID_PWM_A_SEL] = &s4_pwm_a_mux.hw, + [CLKID_PWM_A_DIV] = &s4_pwm_a_div.hw, + [CLKID_PWM_A] = &s4_pwm_a_gate.hw, + [CLKID_PWM_B_SEL] = &s4_pwm_b_mux.hw, + [CLKID_PWM_B_DIV] = &s4_pwm_b_div.hw, + [CLKID_PWM_B] = &s4_pwm_b_gate.hw, + [CLKID_PWM_C_SEL] = &s4_pwm_c_mux.hw, + [CLKID_PWM_C_DIV] = &s4_pwm_c_div.hw, + [CLKID_PWM_C] = &s4_pwm_c_gate.hw, + [CLKID_PWM_D_SEL] = &s4_pwm_d_mux.hw, + [CLKID_PWM_D_DIV] = &s4_pwm_d_div.hw, + [CLKID_PWM_D] = &s4_pwm_d_gate.hw, + [CLKID_PWM_E_SEL] = &s4_pwm_e_mux.hw, + [CLKID_PWM_E_DIV] = &s4_pwm_e_div.hw, + [CLKID_PWM_E] = &s4_pwm_e_gate.hw, + [CLKID_PWM_F_SEL] = &s4_pwm_f_mux.hw, + [CLKID_PWM_F_DIV] = &s4_pwm_f_div.hw, + [CLKID_PWM_F] = &s4_pwm_f_gate.hw, + [CLKID_PWM_G_SEL] = &s4_pwm_g_mux.hw, + [CLKID_PWM_G_DIV] = &s4_pwm_g_div.hw, + [CLKID_PWM_G] = &s4_pwm_g_gate.hw, + [CLKID_PWM_H_SEL] = &s4_pwm_h_mux.hw, + [CLKID_PWM_H_DIV] = &s4_pwm_h_div.hw, + [CLKID_PWM_H] = &s4_pwm_h_gate.hw, + [CLKID_PWM_I_SEL] = &s4_pwm_i_mux.hw, + [CLKID_PWM_I_DIV] = &s4_pwm_i_div.hw, + [CLKID_PWM_I] = &s4_pwm_i_gate.hw, + [CLKID_PWM_J_SEL] = &s4_pwm_j_mux.hw, + [CLKID_PWM_J_DIV] = &s4_pwm_j_div.hw, + [CLKID_PWM_J] = &s4_pwm_j_gate.hw, + [CLKID_SARADC_SEL] = &s4_saradc_mux.hw, + [CLKID_SARADC_DIV] = &s4_saradc_div.hw, + [CLKID_SARADC] = &s4_saradc_gate.hw, + [CLKID_GEN_SEL] = &s4_gen_clk_sel.hw, + [CLKID_GEN_DIV] = &s4_gen_clk_div.hw, + [CLKID_GEN] = &s4_gen_clk.hw, + [CLKID_DDR] = &s4_ddr.hw, + [CLKID_DOS] = &s4_dos.hw, + [CLKID_ETHPHY] = &s4_ethphy.hw, + [CLKID_MALI] = &s4_mali.hw, + [CLKID_AOCPU] = &s4_aocpu.hw, + [CLKID_AUCPU] = &s4_aucpu.hw, + [CLKID_CEC] = &s4_cec.hw, + [CLKID_SDEMMC_A] = &s4_sdemmca.hw, + [CLKID_SDEMMC_B] = &s4_sdemmcb.hw, + [CLKID_NAND] = &s4_nand.hw, + [CLKID_SMARTCARD] = &s4_smartcard.hw, + [CLKID_ACODEC] = &s4_acodec.hw, + [CLKID_SPIFC] = &s4_spifc.hw, + [CLKID_MSR] = &s4_msr_clk.hw, + [CLKID_IR_CTRL] = &s4_ir_ctrl.hw, + [CLKID_AUDIO] = &s4_audio.hw, + [CLKID_ETH] = &s4_eth.hw, + [CLKID_UART_A] = &s4_uart_a.hw, + [CLKID_UART_B] = &s4_uart_b.hw, + [CLKID_UART_C] = &s4_uart_c.hw, + [CLKID_UART_D] = &s4_uart_d.hw, + [CLKID_UART_E] = &s4_uart_e.hw, + [CLKID_AIFIFO] = &s4_aififo.hw, + [CLKID_TS_DDR] = &s4_ts_ddr.hw, + [CLKID_TS_PLL] = &s4_ts_pll.hw, + [CLKID_G2D] = &s4_g2d.hw, + [CLKID_SPICC0] = &s4_spicc0.hw, + [CLKID_USB] = &s4_usb.hw, + [CLKID_I2C_M_A] = &s4_i2c_m_a.hw, + [CLKID_I2C_M_B] = &s4_i2c_m_b.hw, + [CLKID_I2C_M_C] = &s4_i2c_m_c.hw, + [CLKID_I2C_M_D] = &s4_i2c_m_d.hw, + [CLKID_I2C_M_E] = &s4_i2c_m_e.hw, + [CLKID_HDMITX_APB] = &s4_hdmitx_apb.hw, + [CLKID_I2C_S_A] = &s4_i2c_s_a.hw, + [CLKID_USB1_TO_DDR] = &s4_usb1_to_ddr.hw, + [CLKID_HDCP22] = &s4_hdcp22.hw, + [CLKID_MMC_APB] = &s4_mmc_apb.hw, + [CLKID_RSA] = &s4_rsa.hw, + [CLKID_CPU_DEBUG] = &s4_cpu_debug.hw, + [CLKID_VPU_INTR] = &s4_vpu_intr.hw, + [CLKID_DEMOD] = &s4_demod.hw, + [CLKID_SAR_ADC] = &s4_sar_adc.hw, + [CLKID_GIC] = &s4_gic.hw, + [CLKID_PWM_AB] = &s4_pwm_ab.hw, + [CLKID_PWM_CD] = &s4_pwm_cd.hw, + [CLKID_PWM_EF] = &s4_pwm_ef.hw, + [CLKID_PWM_GH] = &s4_pwm_gh.hw, + [CLKID_PWM_IJ] = &s4_pwm_ij.hw, + [CLKID_HDCP22_ESMCLK_SEL] = &s4_hdcp22_esmclk_mux.hw, + [CLKID_HDCP22_ESMCLK_DIV] = &s4_hdcp22_esmclk_div.hw, + [CLKID_HDCP22_ESMCLK] = &s4_hdcp22_esmclk_gate.hw, + [CLKID_HDCP22_SKPCLK_SEL] = &s4_hdcp22_skpclk_mux.hw, + [CLKID_HDCP22_SKPCLK_DIV] = &s4_hdcp22_skpclk_div.hw, + [CLKID_HDCP22_SKPCLK] = &s4_hdcp22_skpclk_gate.hw, +}; + +/* Convenience table to populate regmap in .probe */ +static struct clk_regmap *const s4_periphs_clk_regmaps[] = { + &s4_rtc_32k_by_oscin_clkin, + &s4_rtc_32k_by_oscin_div, + &s4_rtc_32k_by_oscin_sel, + &s4_rtc_32k_by_oscin, + &s4_rtc_clk, + &s4_sysclk_b_sel, + &s4_sysclk_b_div, + &s4_sysclk_b, + &s4_sysclk_a_sel, + &s4_sysclk_a_div, + &s4_sysclk_a, + &s4_sys_clk, + &s4_ceca_32k_clkin, + &s4_ceca_32k_div, + &s4_ceca_32k_sel_pre, + &s4_ceca_32k_sel, + &s4_ceca_32k_clkout, + &s4_cecb_32k_clkin, + &s4_cecb_32k_div, + &s4_cecb_32k_sel_pre, + &s4_cecb_32k_sel, + &s4_cecb_32k_clkout, + &s4_sc_clk_mux, + &s4_sc_clk_div, + &s4_sc_clk_gate, + &s4_12_24M_clk_gate, + &s4_12_24M_clk, + &s4_vid_pll_div, + &s4_vid_pll_sel, + &s4_vid_pll, + &s4_vclk_sel, + &s4_vclk2_sel, + &s4_vclk_input, + &s4_vclk2_input, + &s4_vclk_div, + &s4_vclk2_div, + &s4_vclk, + &s4_vclk2, + &s4_vclk_div1, + &s4_vclk_div2_en, + &s4_vclk_div4_en, + &s4_vclk_div6_en, + &s4_vclk_div12_en, + &s4_vclk2_div1, + &s4_vclk2_div2_en, + &s4_vclk2_div4_en, + &s4_vclk2_div6_en, + &s4_vclk2_div12_en, + &s4_cts_enci_sel, + &s4_cts_encp_sel, + &s4_cts_vdac_sel, + &s4_hdmi_tx_sel, + &s4_cts_enci, + &s4_cts_encp, + &s4_cts_vdac, + &s4_hdmi_tx, + &s4_hdmi_sel, + &s4_hdmi_div, + &s4_hdmi, + &s4_ts_clk_div, + &s4_ts_clk_gate, + &s4_mali_0_sel, + &s4_mali_0_div, + &s4_mali_0, + &s4_mali_1_sel, + &s4_mali_1_div, + &s4_mali_1, + &s4_mali_mux, + &s4_vdec_p0_mux, + &s4_vdec_p0_div, + &s4_vdec_p0, + &s4_vdec_p1_mux, + &s4_vdec_p1_div, + &s4_vdec_p1, + &s4_vdec_mux, + &s4_hevcf_p0_mux, + &s4_hevcf_p0_div, + &s4_hevcf_p0, + &s4_hevcf_p1_mux, + &s4_hevcf_p1_div, + &s4_hevcf_p1, + &s4_hevcf_mux, + &s4_vpu_0_sel, + &s4_vpu_0_div, + &s4_vpu_0, + &s4_vpu_1_sel, + &s4_vpu_1_div, + &s4_vpu_1, + &s4_vpu, + &s4_vpu_clkb_tmp_mux, + &s4_vpu_clkb_tmp_div, + &s4_vpu_clkb_tmp, + &s4_vpu_clkb_div, + &s4_vpu_clkb, + &s4_vpu_clkc_p0_mux, + &s4_vpu_clkc_p0_div, + &s4_vpu_clkc_p0, + &s4_vpu_clkc_p1_mux, + &s4_vpu_clkc_p1_div, + &s4_vpu_clkc_p1, + &s4_vpu_clkc_mux, + &s4_vapb_0_sel, + &s4_vapb_0_div, + &s4_vapb_0, + &s4_vapb_1_sel, + &s4_vapb_1_div, + &s4_vapb_1, + &s4_vapb, + &s4_ge2d_gate, + &s4_hdcp22_esmclk_mux, + &s4_hdcp22_esmclk_div, + &s4_hdcp22_esmclk_gate, + &s4_hdcp22_skpclk_mux, + &s4_hdcp22_skpclk_div, + &s4_hdcp22_skpclk_gate, + &s4_vdin_meas_mux, + &s4_vdin_meas_div, + &s4_vdin_meas_gate, + &s4_sd_emmc_c_clk0_sel, + &s4_sd_emmc_c_clk0_div, + &s4_sd_emmc_c_clk0, + &s4_sd_emmc_a_clk0_sel, + &s4_sd_emmc_a_clk0_div, + &s4_sd_emmc_a_clk0, + &s4_sd_emmc_b_clk0_sel, + &s4_sd_emmc_b_clk0_div, + &s4_sd_emmc_b_clk0, + &s4_spicc0_mux, + &s4_spicc0_div, + &s4_spicc0_gate, + &s4_pwm_a_mux, + &s4_pwm_a_div, + &s4_pwm_a_gate, + &s4_pwm_b_mux, + &s4_pwm_b_div, + &s4_pwm_b_gate, + &s4_pwm_c_mux, + &s4_pwm_c_div, + &s4_pwm_c_gate, + &s4_pwm_d_mux, + &s4_pwm_d_div, + &s4_pwm_d_gate, + &s4_pwm_e_mux, + &s4_pwm_e_div, + &s4_pwm_e_gate, + &s4_pwm_f_mux, + &s4_pwm_f_div, + &s4_pwm_f_gate, + &s4_pwm_g_mux, + &s4_pwm_g_div, + &s4_pwm_g_gate, + &s4_pwm_h_mux, + &s4_pwm_h_div, + &s4_pwm_h_gate, + &s4_pwm_i_mux, + &s4_pwm_i_div, + &s4_pwm_i_gate, + &s4_pwm_j_mux, + &s4_pwm_j_div, + &s4_pwm_j_gate, + &s4_saradc_mux, + &s4_saradc_div, + &s4_saradc_gate, + &s4_gen_clk_sel, + &s4_gen_clk_div, + &s4_gen_clk, + &s4_ddr, + &s4_dos, + &s4_ethphy, + &s4_mali, + &s4_aocpu, + &s4_aucpu, + &s4_cec, + &s4_sdemmca, + &s4_sdemmcb, + &s4_nand, + &s4_smartcard, + &s4_acodec, + &s4_spifc, + &s4_msr_clk, + &s4_ir_ctrl, + &s4_audio, + &s4_eth, + &s4_uart_a, + &s4_uart_b, + &s4_uart_c, + &s4_uart_d, + &s4_uart_e, + &s4_aififo, + &s4_ts_ddr, + &s4_ts_pll, + &s4_g2d, + &s4_spicc0, + &s4_usb, + &s4_i2c_m_a, + &s4_i2c_m_b, + &s4_i2c_m_c, + &s4_i2c_m_d, + &s4_i2c_m_e, + &s4_hdmitx_apb, + &s4_i2c_s_a, + &s4_usb1_to_ddr, + &s4_hdcp22, + &s4_mmc_apb, + &s4_rsa, + &s4_cpu_debug, + &s4_vpu_intr, + &s4_demod, + &s4_sar_adc, + &s4_gic, + &s4_pwm_ab, + &s4_pwm_cd, + &s4_pwm_ef, + &s4_pwm_gh, + &s4_pwm_ij, + &s4_demod_core_clk_mux, + &s4_demod_core_clk_div, + &s4_demod_core_clk_gate, + &s4_adc_extclk_in_mux, + &s4_adc_extclk_in_div, + &s4_adc_extclk_in_gate, +}; + +static struct regmap_config clkc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +static struct meson_clk_hw_data s4_periphs_clks = { + .hws = s4_periphs_hw_clks, + .num = ARRAY_SIZE(s4_periphs_hw_clks), +}; + +static int meson_s4_periphs_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *regmap; + void __iomem *base; + int ret, i; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return dev_err_probe(dev, PTR_ERR(base), + "can't ioremap resource\n"); + + regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "can't init regmap mmio region\n"); + + /* Populate regmap for the regmap backed clocks */ + for (i = 0; i < ARRAY_SIZE(s4_periphs_clk_regmaps); i++) + s4_periphs_clk_regmaps[i]->map = regmap; + + for (i = 0; i < s4_periphs_clks.num; i++) { + /* array might be sparse */ + if (!s4_periphs_clks.hws[i]) + continue; + + ret = devm_clk_hw_register(dev, s4_periphs_clks.hws[i]); + if (ret) + return dev_err_probe(dev, ret, + "clock[%d] registration failed\n", i); + } + + return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &s4_periphs_clks); +} + +static const struct of_device_id clkc_match_table[] = { + { + .compatible = "amlogic,s4-peripherals-clkc", + }, + {} +}; + +static struct platform_driver s4_driver = { + .probe = meson_s4_periphs_probe, + .driver = { + .name = "s4-periphs-clkc", + .of_match_table = clkc_match_table, + }, +}; + +module_platform_driver(s4_driver); +MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/s4-peripherals.h b/drivers/clk/meson/s4-peripherals.h new file mode 100644 index 000000000000..56f8f28a913e --- /dev/null +++ b/drivers/clk/meson/s4-peripherals.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved + * Author: Yu Tu <yu.tu@amlogic.com> + */ + +#ifndef __MESON_S4_PERIPHERALS_H__ +#define __MESON_S4_PERIPHERALS_H__ + +#define CLKCTRL_RTC_BY_OSCIN_CTRL0 0x008 +#define CLKCTRL_RTC_BY_OSCIN_CTRL1 0x00c +#define CLKCTRL_RTC_CTRL 0x010 +#define CLKCTRL_SYS_CLK_CTRL0 0x040 +#define CLKCTRL_SYS_CLK_EN0_REG0 0x044 +#define CLKCTRL_SYS_CLK_EN0_REG1 0x048 +#define CLKCTRL_SYS_CLK_EN0_REG2 0x04c +#define CLKCTRL_SYS_CLK_EN0_REG3 0x050 +#define CLKCTRL_CECA_CTRL0 0x088 +#define CLKCTRL_CECA_CTRL1 0x08c +#define CLKCTRL_CECB_CTRL0 0x090 +#define CLKCTRL_CECB_CTRL1 0x094 +#define CLKCTRL_SC_CLK_CTRL 0x098 +#define CLKCTRL_CLK12_24_CTRL 0x0a8 +#define CLKCTRL_VID_CLK_CTRL 0x0c0 +#define CLKCTRL_VID_CLK_CTRL2 0x0c4 +#define CLKCTRL_VID_CLK_DIV 0x0c8 +#define CLKCTRL_VIID_CLK_DIV 0x0cc +#define CLKCTRL_VIID_CLK_CTRL 0x0d0 +#define CLKCTRL_HDMI_CLK_CTRL 0x0e0 +#define CLKCTRL_VID_PLL_CLK_DIV 0x0e4 +#define CLKCTRL_VPU_CLK_CTRL 0x0e8 +#define CLKCTRL_VPU_CLKB_CTRL 0x0ec +#define CLKCTRL_VPU_CLKC_CTRL 0x0f0 +#define CLKCTRL_VID_LOCK_CLK_CTRL 0x0f4 +#define CLKCTRL_VDIN_MEAS_CLK_CTRL 0x0f8 +#define CLKCTRL_VAPBCLK_CTRL 0x0fc +#define CLKCTRL_HDCP22_CTRL 0x100 +#define CLKCTRL_VDEC_CLK_CTRL 0x140 +#define CLKCTRL_VDEC2_CLK_CTRL 0x144 +#define CLKCTRL_VDEC3_CLK_CTRL 0x148 +#define CLKCTRL_VDEC4_CLK_CTRL 0x14c +#define CLKCTRL_TS_CLK_CTRL 0x158 +#define CLKCTRL_MALI_CLK_CTRL 0x15c +#define CLKCTRL_NAND_CLK_CTRL 0x168 +#define CLKCTRL_SD_EMMC_CLK_CTRL 0x16c +#define CLKCTRL_SPICC_CLK_CTRL 0x174 +#define CLKCTRL_GEN_CLK_CTRL 0x178 +#define CLKCTRL_SAR_CLK_CTRL 0x17c +#define CLKCTRL_PWM_CLK_AB_CTRL 0x180 +#define CLKCTRL_PWM_CLK_CD_CTRL 0x184 +#define CLKCTRL_PWM_CLK_EF_CTRL 0x188 +#define CLKCTRL_PWM_CLK_GH_CTRL 0x18c +#define CLKCTRL_PWM_CLK_IJ_CTRL 0x190 +#define CLKCTRL_DEMOD_CLK_CTRL 0x200 + +#endif /* __MESON_S4_PERIPHERALS_H__ */ + -- 2.33.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH V10 4/4] clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller 2023-08-22 8:27 ` [PATCH V10 4/4] clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller Yu Tu @ 2023-08-23 8:13 ` Jerome Brunet 2023-08-23 8:41 ` Yu Tu 0 siblings, 1 reply; 21+ messages in thread From: Jerome Brunet @ 2023-08-23 8:13 UTC (permalink / raw) To: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On Tue 22 Aug 2023 at 16:27, Yu Tu <yu.tu@amlogic.com> wrote: > Add the peripherals clock controller driver in the S4 SoC family. > > Signed-off-by: Yu Tu <yu.tu@amlogic.com> > --- > drivers/clk/meson/Kconfig | 11 + > drivers/clk/meson/Makefile | 1 + > drivers/clk/meson/s4-peripherals.c | 3787 ++++++++++++++++++++++++++++ > drivers/clk/meson/s4-peripherals.h | 57 + > 4 files changed, 3856 insertions(+) > create mode 100644 drivers/clk/meson/s4-peripherals.c > create mode 100644 drivers/clk/meson/s4-peripherals.h > > diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig > index e90982d77598..c5303e4c1604 100644 > --- a/drivers/clk/meson/Kconfig > +++ b/drivers/clk/meson/Kconfig > @@ -156,4 +156,15 @@ config COMMON_CLK_S4_PLL > Support for the PLL clock controller on Amlogic S805X2 and S905Y4 devices, > AKA S4. Say Y if you want the board to work, because PLLs are the parent of > most peripherals. > + > +config COMMON_CLK_S4_PERIPHERALS > + tristate "S4 SoC peripherals clock controllers support" > + depends on ARM64 > + default y > + select COMMON_CLK_MESON_REGMAP > + select COMMON_CLK_MESON_DUALDIV > + select COMMON_CLK_MESON_VID_PLL_DIV > + help > + Support for the peripherals clock controller on Amlogic S805X2 and S905Y4 > + devices, AKA S4. Say Y if you want S4 peripherals clock controller to work. > endmenu > diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile > index 612cee923890..9ee4b954c896 100644 > --- a/drivers/clk/meson/Makefile > +++ b/drivers/clk/meson/Makefile > @@ -23,3 +23,4 @@ obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o > obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o > obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o > obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o > +obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o > diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c > new file mode 100644 > index 000000000000..60de4beb1561 > --- /dev/null > +++ b/drivers/clk/meson/s4-peripherals.c > @@ -0,0 +1,3787 @@ > +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) > +/* > + * Amlogic S4 Peripherals Clock Controller Driver > + * > + * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved > + * Author: Yu Tu <yu.tu@amlogic.com> > + */ > + > +#include <linux/clk-provider.h> > +#include <linux/of_device.h> > +#include <linux/platform_device.h> > + > +#include "clk-regmap.h" > +#include "vid-pll-div.h" > +#include "clk-dualdiv.h" > +#include "s4-peripherals.h" > +#include "meson-clkc-utils.h" > +#include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h> > + > +static struct clk_regmap s4_rtc_32k_by_oscin_clkin = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, > + .bit_idx = 31, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "rtc_32k_by_oscin_clkin", > + .ops = &clk_regmap_gate_ops, > + .parent_data = (const struct clk_parent_data []) { > + { .fw_name = "xtal", } > + }, > + .num_parents = 1, > + }, > +}; > + > +static const struct meson_clk_dualdiv_param s4_32k_div_table[] = { > + { > + .dual = 1, > + .n1 = 733, > + .m1 = 8, > + .n2 = 732, > + .m2 = 11, > + }, > + {} > +}; > + > +static struct clk_regmap s4_rtc_32k_by_oscin_div = { > + .data = &(struct meson_clk_dualdiv_data){ > + .n1 = { > + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, > + .shift = 0, > + .width = 12, > + }, > + .n2 = { > + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, > + .shift = 12, > + .width = 12, > + }, > + .m1 = { > + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1, > + .shift = 0, > + .width = 12, > + }, > + .m2 = { > + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1, > + .shift = 12, > + .width = 12, > + }, > + .dual = { > + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, > + .shift = 28, > + .width = 1, > + }, > + .table = s4_32k_div_table, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "rtc_32k_by_oscin_div", > + .ops = &meson_clk_dualdiv_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_rtc_32k_by_oscin_clkin.hw > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_rtc_32k_by_oscin_sel = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL1, > + .mask = 0x1, > + .shift = 24, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "rtc_32k_by_oscin_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_rtc_32k_by_oscin_div.hw, > + &s4_rtc_32k_by_oscin_clkin.hw, > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_rtc_32k_by_oscin = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, > + .bit_idx = 30, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "rtc_32k_by_oscin", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_rtc_32k_by_oscin_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_rtc_clk = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_RTC_CTRL, > + .mask = 0x3, > + .shift = 0, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "rtc_clk_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_rtc_32k_by_oscin.hw, > + &s4_rtc_32k_by_oscin_div.hw, > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* The index 5 is AXI_CLK, which is dedicated to AXI. So skip it. */ > +static u32 mux_table_sys_ab_clk_sel[] = { 0, 1, 2, 3, 4, 6, 7 }; > +static const struct clk_parent_data sys_ab_clk_parent_data[] = { > + { .fw_name = "xtal" }, > + { .fw_name = "fclk_div2" }, > + { .fw_name = "fclk_div3" }, > + { .fw_name = "fclk_div4" }, > + { .fw_name = "fclk_div5" }, > + { .fw_name = "fclk_div7" }, > + { .hw = &s4_rtc_clk.hw } > +}; > + > +/* > + * This clock is initialized by ROMcode. > + * The chip was changed SYS CLK for security reasons. SYS CLK registers are not writable > + * in the kernel phase. Write of SYS related register will cause the system to crash. > + * Meanwhile, these clock won't ever change at runtime. > + * For the above reasons, we can only use ro_ops for SYS related clocks. > + */ > +static struct clk_regmap s4_sysclk_b_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_SYS_CLK_CTRL0, > + .mask = 0x7, > + .shift = 26, > + .table = mux_table_sys_ab_clk_sel, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sysclk_b_sel", > + .ops = &clk_regmap_mux_ro_ops, > + .parent_data = sys_ab_clk_parent_data, > + .num_parents = ARRAY_SIZE(sys_ab_clk_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_sysclk_b_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_SYS_CLK_CTRL0, > + .shift = 16, > + .width = 10, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sysclk_b_div", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sysclk_b_sel.hw > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_sysclk_b = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_SYS_CLK_CTRL0, > + .bit_idx = 29, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sysclk_b", > + .ops = &clk_regmap_gate_ro_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sysclk_b_div.hw > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_sysclk_a_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_SYS_CLK_CTRL0, > + .mask = 0x7, > + .shift = 10, > + .table = mux_table_sys_ab_clk_sel, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sysclk_a_sel", > + .ops = &clk_regmap_mux_ro_ops, > + .parent_data = sys_ab_clk_parent_data, > + .num_parents = ARRAY_SIZE(sys_ab_clk_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_sysclk_a_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_SYS_CLK_CTRL0, > + .shift = 0, > + .width = 10, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sysclk_a_div", > + .ops = &clk_regmap_divider_ro_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sysclk_a_sel.hw > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_sysclk_a = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_SYS_CLK_CTRL0, > + .bit_idx = 13, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sysclk_a", > + .ops = &clk_regmap_gate_ro_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sysclk_a_div.hw > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_sys_clk = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_SYS_CLK_CTRL0, > + .mask = 0x1, > + .shift = 31, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sys_clk", > + .ops = &clk_regmap_mux_ro_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sysclk_a.hw, > + &s4_sysclk_b.hw > + }, > + .num_parents = 2, > + }, > +}; > + > +static struct clk_regmap s4_ceca_32k_clkin = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_CECA_CTRL0, > + .bit_idx = 31, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "ceca_32k_clkin", > + .ops = &clk_regmap_gate_ops, > + .parent_data = (const struct clk_parent_data []) { > + { .fw_name = "xtal", } > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_ceca_32k_div = { > + .data = &(struct meson_clk_dualdiv_data){ > + .n1 = { > + .reg_off = CLKCTRL_CECA_CTRL0, > + .shift = 0, > + .width = 12, > + }, > + .n2 = { > + .reg_off = CLKCTRL_CECA_CTRL0, > + .shift = 12, > + .width = 12, > + }, > + .m1 = { > + .reg_off = CLKCTRL_CECA_CTRL1, > + .shift = 0, > + .width = 12, > + }, > + .m2 = { > + .reg_off = CLKCTRL_CECA_CTRL1, > + .shift = 12, > + .width = 12, > + }, > + .dual = { > + .reg_off = CLKCTRL_CECA_CTRL0, > + .shift = 28, > + .width = 1, > + }, > + .table = s4_32k_div_table, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "ceca_32k_div", > + .ops = &meson_clk_dualdiv_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_ceca_32k_clkin.hw > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_ceca_32k_sel_pre = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_CECA_CTRL1, > + .mask = 0x1, > + .shift = 24, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "ceca_32k_sel_pre", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_ceca_32k_div.hw, > + &s4_ceca_32k_clkin.hw > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_ceca_32k_sel = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_CECA_CTRL1, > + .mask = 0x1, > + .shift = 31, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "ceca_32k_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_ceca_32k_sel_pre.hw, > + &s4_rtc_clk.hw > + }, > + .num_parents = 2, > + }, > +}; > + > +static struct clk_regmap s4_ceca_32k_clkout = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_CECA_CTRL0, > + .bit_idx = 30, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "ceca_32k_clkout", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_ceca_32k_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_cecb_32k_clkin = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_CECB_CTRL0, > + .bit_idx = 31, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "cecb_32k_clkin", > + .ops = &clk_regmap_gate_ops, > + .parent_data = (const struct clk_parent_data []) { > + { .fw_name = "xtal", } > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_cecb_32k_div = { > + .data = &(struct meson_clk_dualdiv_data){ > + .n1 = { > + .reg_off = CLKCTRL_CECB_CTRL0, > + .shift = 0, > + .width = 12, > + }, > + .n2 = { > + .reg_off = CLKCTRL_CECB_CTRL0, > + .shift = 12, > + .width = 12, > + }, > + .m1 = { > + .reg_off = CLKCTRL_CECB_CTRL1, > + .shift = 0, > + .width = 12, > + }, > + .m2 = { > + .reg_off = CLKCTRL_CECB_CTRL1, > + .shift = 12, > + .width = 12, > + }, > + .dual = { > + .reg_off = CLKCTRL_CECB_CTRL0, > + .shift = 28, > + .width = 1, > + }, > + .table = s4_32k_div_table, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "cecb_32k_div", > + .ops = &meson_clk_dualdiv_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_cecb_32k_clkin.hw > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_cecb_32k_sel_pre = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_CECB_CTRL1, > + .mask = 0x1, > + .shift = 24, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "cecb_32k_sel_pre", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_cecb_32k_div.hw, > + &s4_cecb_32k_clkin.hw > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_cecb_32k_sel = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_CECB_CTRL1, > + .mask = 0x1, > + .shift = 31, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "cecb_32k_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_cecb_32k_sel_pre.hw, > + &s4_rtc_clk.hw > + }, > + .num_parents = 2, > + }, > +}; > + > +static struct clk_regmap s4_cecb_32k_clkout = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_CECB_CTRL0, > + .bit_idx = 30, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "cecb_32k_clkout", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_cecb_32k_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_parent_data s4_sc_parent_data[] = { > + { .fw_name = "fclk_div4" }, > + { .fw_name = "fclk_div3" }, > + { .fw_name = "fclk_div5" }, > + { .fw_name = "xtal", } > +}; > + > +static struct clk_regmap s4_sc_clk_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_SC_CLK_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sc_clk_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_sc_parent_data, > + .num_parents = ARRAY_SIZE(s4_sc_parent_data), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_sc_clk_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_SC_CLK_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sc_clk_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sc_clk_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_sc_clk_gate = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_SC_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sc_clk_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sc_clk_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_12_24M_clk_gate = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_CLK12_24_CTRL, > + .bit_idx = 11, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "12_24m_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_data = (const struct clk_parent_data []) { > + { .fw_name = "xtal", } > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_fixed_factor s4_12M_clk_div = { > + .mult = 1, > + .div = 2, > + .hw.init = &(struct clk_init_data){ > + .name = "12M", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_12_24M_clk_gate.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_12_24M_clk = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_CLK12_24_CTRL, > + .mask = 0x1, > + .shift = 10, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "12_24m", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_12_24M_clk_gate.hw, > + &s4_12M_clk_div.hw, > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* Video Clocks */ > +static struct clk_regmap s4_vid_pll_div = { > + .data = &(struct meson_vid_pll_div_data){ > + .val = { > + .reg_off = CLKCTRL_VID_PLL_CLK_DIV, > + .shift = 0, > + .width = 15, > + }, > + .sel = { > + .reg_off = CLKCTRL_VID_PLL_CLK_DIV, > + .shift = 16, > + .width = 2, > + }, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vid_pll_div", > + /* > + * TODO meson_vid_pll_div_ro_ops to meson_vid_pll_div_ops > + */ > + .ops = &meson_vid_pll_div_ro_ops, > + .parent_data = (const struct clk_parent_data []) { > + { .fw_name = "hdmi_pll", } > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vid_pll_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VID_PLL_CLK_DIV, > + .mask = 0x1, > + .shift = 18, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vid_pll_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = (const struct clk_parent_data []) { > + { .hw = &s4_vid_pll_div.hw }, > + { .fw_name = "hdmi_pll", } > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vid_pll = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_PLL_CLK_DIV, > + .bit_idx = 19, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vid_pll", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vid_pll_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_parent_data s4_vclk_parent_data[] = { > + { .hw = &s4_vid_pll.hw }, > + { .fw_name = "gp0_pll", }, > + { .fw_name = "hifi_pll", }, > + { .fw_name = "mpll1", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", }, > +}; > + > +static struct clk_regmap s4_vclk_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VID_CLK_CTRL, > + .mask = 0x7, > + .shift = 16, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vclk_parent_data, > + .num_parents = ARRAY_SIZE(s4_vclk_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_vclk2_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VIID_CLK_CTRL, > + .mask = 0x7, > + .shift = 16, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk2_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vclk_parent_data, > + .num_parents = ARRAY_SIZE(s4_vclk_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_vclk_input = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_DIV, > + .bit_idx = 16, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk_input", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk_sel.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk2_input = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VIID_CLK_DIV, > + .bit_idx = 16, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk2_input", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2_sel.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VID_CLK_DIV, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk_input.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk2_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VIID_CLK_DIV, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk2_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk2_input.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL, > + .bit_idx = 19, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk_div.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk2 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VIID_CLK_CTRL, > + .bit_idx = 19, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk2", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2_div.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk_div1 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL, > + .bit_idx = 0, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk_div1", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk_div2_en = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL, > + .bit_idx = 1, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk_div2_en", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk_div4_en = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL, > + .bit_idx = 2, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk_div4_en", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk_div6_en = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL, > + .bit_idx = 3, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk_div6_en", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk_div12_en = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL, > + .bit_idx = 4, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk_div12_en", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk2_div1 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VIID_CLK_CTRL, > + .bit_idx = 0, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk2_div1", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk2_div2_en = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VIID_CLK_CTRL, > + .bit_idx = 1, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk2_div2_en", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk2_div4_en = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VIID_CLK_CTRL, > + .bit_idx = 2, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk2_div4_en", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk2_div6_en = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VIID_CLK_CTRL, > + .bit_idx = 3, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk2_div6_en", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vclk2_div12_en = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VIID_CLK_CTRL, > + .bit_idx = 4, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vclk2_div12_en", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_fixed_factor s4_vclk_div2 = { > + .mult = 1, > + .div = 2, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk_div2", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk_div2_en.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_fixed_factor s4_vclk_div4 = { > + .mult = 1, > + .div = 4, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk_div4", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk_div4_en.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_fixed_factor s4_vclk_div6 = { > + .mult = 1, > + .div = 6, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk_div6", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk_div6_en.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_fixed_factor s4_vclk_div12 = { > + .mult = 1, > + .div = 12, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk_div12", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk_div12_en.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_fixed_factor s4_vclk2_div2 = { > + .mult = 1, > + .div = 2, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk2_div2", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk2_div2_en.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_fixed_factor s4_vclk2_div4 = { > + .mult = 1, > + .div = 4, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk2_div4", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk2_div4_en.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_fixed_factor s4_vclk2_div6 = { > + .mult = 1, > + .div = 6, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk2_div6", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk2_div6_en.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_fixed_factor s4_vclk2_div12 = { > + .mult = 1, > + .div = 12, > + .hw.init = &(struct clk_init_data){ > + .name = "vclk2_div12", > + .ops = &clk_fixed_factor_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vclk2_div12_en.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* The 5,6,7 indexes corresponds to no real clock, so there are not used. */ > +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; > +static const struct clk_hw *s4_cts_parent_hws[] = { > + &s4_vclk_div1.hw, > + &s4_vclk_div2.hw, > + &s4_vclk_div4.hw, > + &s4_vclk_div6.hw, > + &s4_vclk_div12.hw, > + &s4_vclk2_div1.hw, > + &s4_vclk2_div2.hw, > + &s4_vclk2_div4.hw, > + &s4_vclk2_div6.hw, > + &s4_vclk2_div12.hw > +}; > + > +static struct clk_regmap s4_cts_enci_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VID_CLK_DIV, > + .mask = 0xf, > + .shift = 28, > + .table = mux_table_cts_sel, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "cts_enci_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = s4_cts_parent_hws, > + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_cts_encp_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VID_CLK_DIV, > + .mask = 0xf, > + .shift = 20, > + .table = mux_table_cts_sel, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "cts_encp_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = s4_cts_parent_hws, > + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_cts_vdac_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VIID_CLK_DIV, > + .mask = 0xf, > + .shift = 28, > + .table = mux_table_cts_sel, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "cts_vdac_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = s4_cts_parent_hws, > + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* The 5,6,7 indexes corresponds to no real clock, so there are not used. */ > +static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; > +static const struct clk_hw *s4_cts_hdmi_tx_parent_hws[] = { > + &s4_vclk_div1.hw, > + &s4_vclk_div2.hw, > + &s4_vclk_div4.hw, > + &s4_vclk_div6.hw, > + &s4_vclk_div12.hw, > + &s4_vclk2_div1.hw, > + &s4_vclk2_div2.hw, > + &s4_vclk2_div4.hw, > + &s4_vclk2_div6.hw, > + &s4_vclk2_div12.hw > +}; > + > +static struct clk_regmap s4_hdmi_tx_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_HDMI_CLK_CTRL, > + .mask = 0xf, > + .shift = 16, > + .table = mux_table_hdmi_tx_sel, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_tx_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = s4_cts_hdmi_tx_parent_hws, > + .num_parents = ARRAY_SIZE(s4_cts_hdmi_tx_parent_hws), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_cts_enci = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL2, > + .bit_idx = 0, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "cts_enci", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_cts_enci_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_cts_encp = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL2, > + .bit_idx = 2, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "cts_encp", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_cts_encp_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_cts_vdac = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL2, > + .bit_idx = 4, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "cts_vdac", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_cts_vdac_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hdmi_tx = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VID_CLK_CTRL2, > + .bit_idx = 5, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hdmi_tx", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hdmi_tx_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* HDMI Clocks */ > +static const struct clk_parent_data s4_hdmi_parent_data[] = { > + { .fw_name = "xtal", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div5", } > +}; > + > +static struct clk_regmap s4_hdmi_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_HDMI_CLK_CTRL, > + .mask = 0x3, > + .shift = 9, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_hdmi_parent_data, > + .num_parents = ARRAY_SIZE(s4_hdmi_parent_data), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hdmi_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_HDMI_CLK_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdmi_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_hdmi_sel.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hdmi = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_HDMI_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hdmi", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_hdmi_div.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_ts_clk_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_TS_CLK_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "ts_clk_div", > + .ops = &clk_regmap_divider_ops, > + .parent_data = &(const struct clk_parent_data) { > + .fw_name = "xtal", > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_ts_clk_gate = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_TS_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "ts_clk", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_ts_clk_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* > + * The MALI IP is clocked by two identical clocks (mali_0 and mali_1) > + * muxed by a glitch-free switch. The CCF can manage this glitch-free > + * mux because it does top-to-bottom updates the each clock tree and > + * switches to the "inactive" one when CLK_SET_RATE_GATE is set. > + */ > +static const struct clk_parent_data s4_mali_0_1_parent_data[] = { > + { .fw_name = "xtal", }, > + { .fw_name = "gp0_pll", }, > + { .fw_name = "hifi_pll", }, > + { .fw_name = "fclk_div2p5", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", } > +}; > + > +static struct clk_regmap s4_mali_0_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_MALI_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "mali_0_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_mali_0_1_parent_data, > + .num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data), > + /* > + * Don't request the parent to change the rate because > + * all GPU frequencies can be derived from the fclk_* > + * clocks and one special GP0_PLL setting. This is > + * important because we need the MPLL clocks for audio. The last part of this comment does not make a lot of sense to me. MPLLs are not among the possible parent of this clock, did you mean HiFi ? > + */ > + .flags = 0, > + }, > +}; > + > +static struct clk_regmap s4_mali_0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_MALI_CLK_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "mali_0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_mali_0_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_mali_0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_MALI_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "mali_0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_mali_0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_mali_1_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_MALI_CLK_CTRL, > + .mask = 0x7, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "mali_1_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_mali_0_1_parent_data, > + .num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data), > + .flags = 0, > + }, > +}; > + > +static struct clk_regmap s4_mali_1_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_MALI_CLK_CTRL, > + .shift = 16, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "mali_1_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_mali_1_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_mali_1 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_MALI_CLK_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "mali_1", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_mali_1_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_hw *s4_mali_parent_hws[] = { > + &s4_mali_0.hw, > + &s4_mali_1.hw > +}; > + > +static struct clk_regmap s4_mali_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_MALI_CLK_CTRL, > + .mask = 1, > + .shift = 31, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "mali", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = s4_mali_parent_hws, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* VDEC clocks */ > +static const struct clk_parent_data s4_dec_parent_data[] = { > + { .fw_name = "fclk_div2p5", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", }, > + { .fw_name = "hifi_pll", }, > + { .fw_name = "gp0_pll", }, > + { .fw_name = "xtal", } > +}; > + > +static struct clk_regmap s4_vdec_p0_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VDEC_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vdec_p0_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_dec_parent_data, > + .num_parents = ARRAY_SIZE(s4_dec_parent_data), Nitpick: .flags = 0; to clearly show that you stopping rate propagation here too (like you did on s4_mali_0_sel - no need to copy the comment though) > + }, > +}; > + > +static struct clk_regmap s4_vdec_p0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VDEC_CLK_CTRL, > + .shift = 0, > + .width = 7, > + .flags = CLK_DIVIDER_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vdec_p0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vdec_p0_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vdec_p0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VDEC_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vdec_p0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vdec_p0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vdec_p1_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VDEC3_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vdec_p1_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_dec_parent_data, > + .num_parents = ARRAY_SIZE(s4_dec_parent_data), Same here and also where applicable in the rest of the driver. > + }, > +}; > + > +static struct clk_regmap s4_vdec_p1_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VDEC3_CLK_CTRL, > + .shift = 0, > + .width = 7, > + .flags = CLK_DIVIDER_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vdec_p1_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vdec_p1_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vdec_p1 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VDEC3_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vdec_p1", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vdec_p1_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_hw *s4_vdec_mux_parent_hws[] = { > + &s4_vdec_p0.hw, > + &s4_vdec_p1.hw > +}; > + > +static struct clk_regmap s4_vdec_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VDEC3_CLK_CTRL, > + .mask = 0x1, > + .shift = 15, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vdec_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = s4_vdec_mux_parent_hws, > + .num_parents = ARRAY_SIZE(s4_vdec_mux_parent_hws), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hevcf_p0_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VDEC2_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hevcf_p0_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_dec_parent_data, > + .num_parents = ARRAY_SIZE(s4_dec_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_hevcf_p0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VDEC2_CLK_CTRL, > + .shift = 0, > + .width = 7, > + .flags = CLK_DIVIDER_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hevcf_p0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hevcf_p0_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hevcf_p0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VDEC2_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hevcf_p0_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hevcf_p0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hevcf_p1_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VDEC4_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + .flags = CLK_MUX_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hevcf_p1_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_dec_parent_data, > + .num_parents = ARRAY_SIZE(s4_dec_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_hevcf_p1_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VDEC4_CLK_CTRL, > + .shift = 0, > + .width = 7, > + .flags = CLK_DIVIDER_ROUND_CLOSEST, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hevcf_p1_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hevcf_p1_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hevcf_p1 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VDEC4_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hevcf_p1", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hevcf_p1_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_hw *s4_hevcf_mux_parent_hws[] = { > + &s4_hevcf_p0.hw, > + &s4_hevcf_p1.hw > +}; > + > +static struct clk_regmap s4_hevcf_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VDEC4_CLK_CTRL, > + .mask = 0x1, > + .shift = 15, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hevcf", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = s4_hevcf_mux_parent_hws, > + .num_parents = ARRAY_SIZE(s4_hevcf_mux_parent_hws), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* VPU Clock */ > +static const struct clk_parent_data s4_vpu_parent_data[] = { > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", }, > + { .fw_name = "mpll1", }, > + { .hw = &s4_vid_pll.hw }, > + { .fw_name = "hifi_pll", }, > + { .fw_name = "gp0_pll", }, > +}; > + > +static struct clk_regmap s4_vpu_0_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VPU_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu_0_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vpu_parent_data, > + .num_parents = ARRAY_SIZE(s4_vpu_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_vpu_0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VPU_CLK_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu_0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_sel.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VPU_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_div.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_1_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VPU_CLK_CTRL, > + .mask = 0x7, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu_1_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vpu_parent_data, > + .num_parents = ARRAY_SIZE(s4_vpu_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_vpu_1_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VPU_CLK_CTRL, > + .shift = 16, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu_1_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_sel.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_1 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VPU_CLK_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_1", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_div.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VPU_CLK_CTRL, > + .mask = 1, > + .shift = 31, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_0.hw, > + &s4_vpu_1.hw, > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_parent_data vpu_clkb_tmp_parent_data[] = { > + { .hw = &s4_vpu.hw }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", } > +}; > + > +static struct clk_regmap s4_vpu_clkb_tmp_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VPU_CLKB_CTRL, > + .mask = 0x3, > + .shift = 20, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_clkb_tmp_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = vpu_clkb_tmp_parent_data, > + .num_parents = ARRAY_SIZE(vpu_clkb_tmp_parent_data), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkb_tmp_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VPU_CLKB_CTRL, > + .shift = 16, > + .width = 4, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_clkb_tmp_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_clkb_tmp_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkb_tmp = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VPU_CLKB_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu_clkb_tmp", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_clkb_tmp_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkb_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VPU_CLKB_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_clkb_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_clkb_tmp.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkb = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VPU_CLKB_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu_clkb", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_clkb_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_parent_data s4_vpu_clkc_parent_data[] = { > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", }, > + { .fw_name = "mpll1", }, > + { .hw = &s4_vid_pll.hw }, > + { .fw_name = "mpll2", }, > + { .fw_name = "gp0_pll", }, > +}; > + > +static struct clk_regmap s4_vpu_clkc_p0_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VPU_CLKC_CTRL, > + .mask = 0x7, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_clkc_p0_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vpu_clkc_parent_data, > + .num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkc_p0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VPU_CLKC_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_clkc_p0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_clkc_p0_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkc_p0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VPU_CLKC_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu_clkc_p0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_clkc_p0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkc_p1_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VPU_CLKC_CTRL, > + .mask = 0x7, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_clkc_p1_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vpu_clkc_parent_data, > + .num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkc_p1_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VPU_CLKC_CTRL, > + .shift = 16, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_clkc_p1_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_clkc_p1_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vpu_clkc_p1 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VPU_CLKC_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vpu_clkc_p1", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vpu_clkc_p1_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_hw *s4_vpu_mux_parent_hws[] = { > + &s4_vpu_clkc_p0.hw, > + &s4_vpu_clkc_p1.hw > +}; > + > +static struct clk_regmap s4_vpu_clkc_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VPU_CLKC_CTRL, > + .mask = 0x1, > + .shift = 31, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vpu_clkc_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = s4_vpu_mux_parent_hws, > + .num_parents = ARRAY_SIZE(s4_vpu_mux_parent_hws), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* VAPB Clock */ > +static const struct clk_parent_data s4_vapb_parent_data[] = { > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", }, > + { .fw_name = "mpll1", }, > + { .hw = &s4_vid_pll.hw }, > + { .fw_name = "mpll2", }, > + { .fw_name = "fclk_div2p5", }, > +}; > + > +static struct clk_regmap s4_vapb_0_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VAPBCLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vapb_0_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vapb_parent_data, > + .num_parents = ARRAY_SIZE(s4_vapb_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_vapb_0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VAPBCLK_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vapb_0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vapb_0_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vapb_0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VAPBCLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vapb_0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vapb_0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vapb_1_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VAPBCLK_CTRL, > + .mask = 0x7, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vapb_1_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vapb_parent_data, > + .num_parents = ARRAY_SIZE(s4_vapb_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_vapb_1_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VAPBCLK_CTRL, > + .shift = 16, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vapb_1_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vapb_1_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vapb_1 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VAPBCLK_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vapb_1", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vapb_1_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vapb = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VAPBCLK_CTRL, > + .mask = 1, > + .shift = 31, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vapb_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vapb_0.hw, > + &s4_vapb_1.hw > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_ge2d_gate = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VAPBCLK_CTRL, > + .bit_idx = 30, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "ge2d_clk", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { &s4_vapb.hw }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_parent_data s4_esmclk_parent_data[] = { > + { .fw_name = "fclk_div7", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div5", }, > +}; > + > +static struct clk_regmap s4_hdcp22_esmclk_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_HDCP22_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hdcp22_esmclk_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_esmclk_parent_data, > + .num_parents = ARRAY_SIZE(s4_esmclk_parent_data), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hdcp22_esmclk_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_HDCP22_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hdcp22_esmclk_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hdcp22_esmclk_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hdcp22_esmclk_gate = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_HDCP22_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdcp22_esmclk_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hdcp22_esmclk_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_parent_data s4_skpclk_parent_data[] = { > + { .fw_name = "xtal", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div5", }, > +}; > + > +static struct clk_regmap s4_hdcp22_skpclk_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_HDCP22_CTRL, > + .mask = 0x3, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hdcp22_skpclk_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_skpclk_parent_data, > + .num_parents = ARRAY_SIZE(s4_skpclk_parent_data), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hdcp22_skpclk_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_HDCP22_CTRL, > + .shift = 16, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "hdcp22_skpclk_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hdcp22_skpclk_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_hdcp22_skpclk_gate = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_HDCP22_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "hdcp22_skpclk_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_hdcp22_skpclk_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_parent_data s4_vdin_parent_data[] = { > + { .fw_name = "xtal", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div5", }, > + { .hw = &s4_vid_pll.hw } > +}; > + > +static struct clk_regmap s4_vdin_meas_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vdin_meas_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_vdin_parent_data, > + .num_parents = ARRAY_SIZE(s4_vdin_parent_data), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vdin_meas_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "vdin_meas_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vdin_meas_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_vdin_meas_gate = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "vdin_meas_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_vdin_meas_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* EMMC/NAND clock */ > +static const struct clk_parent_data s4_sd_emmc_clk0_parent_data[] = { > + { .fw_name = "xtal", }, > + { .fw_name = "fclk_div2", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "hifi_pll", }, > + { .fw_name = "fclk_div2p5", }, > + { .fw_name = "mpll2", }, > + { .fw_name = "mpll3", }, > + { .fw_name = "gp0_pll", }, > +}; > + > +static struct clk_regmap s4_sd_emmc_c_clk0_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_NAND_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sd_emmc_c_clk0_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_sd_emmc_clk0_parent_data, > + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_sd_emmc_c_clk0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_NAND_CLK_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sd_emmc_c_clk0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sd_emmc_c_clk0_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_sd_emmc_c_clk0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_NAND_CLK_CTRL, > + .bit_idx = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sd_emmc_c_clk0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sd_emmc_c_clk0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_sd_emmc_a_clk0_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, > + .mask = 0x7, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sd_emmc_a_clk0_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_sd_emmc_clk0_parent_data, > + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_sd_emmc_a_clk0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sd_emmc_a_clk0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sd_emmc_a_clk0_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_sd_emmc_a_clk0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, > + .bit_idx = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sd_emmc_a_clk0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sd_emmc_a_clk0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_sd_emmc_b_clk0_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, > + .mask = 0x7, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sd_emmc_b_clk0_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_sd_emmc_clk0_parent_data, > + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_sd_emmc_b_clk0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, > + .shift = 16, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "sd_emmc_b_clk0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sd_emmc_b_clk0_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_sd_emmc_b_clk0 = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, > + .bit_idx = 23, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "sd_emmc_b_clk0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_sd_emmc_b_clk0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* SPICC Clock */ > +static const struct clk_parent_data s4_spicc_parent_data[] = { > + { .fw_name = "xtal", }, > + { .hw = &s4_sys_clk.hw }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div2", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", }, > +}; > + > +static struct clk_regmap s4_spicc0_mux = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_SPICC_CLK_CTRL, > + .mask = 0x7, > + .shift = 7, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "spicc0_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_spicc_parent_data, > + .num_parents = ARRAY_SIZE(s4_spicc_parent_data), > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_spicc0_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_SPICC_CLK_CTRL, > + .shift = 0, > + .width = 6, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "spicc0_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_spicc0_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_spicc0_gate = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_SPICC_CLK_CTRL, > + .bit_idx = 6, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "spicc0", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_spicc0_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* PWM Clock */ > +static const struct clk_parent_data s4_pwm_parent_data[] = { > + { .fw_name = "xtal", }, > + { .hw = &s4_vid_pll.hw }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > +}; > + > +static struct clk_regmap s4_pwm_a_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_AB_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_a_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_a_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_AB_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_a_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_a_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_a_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_AB_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_a_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_a_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_b_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_AB_CTRL, > + .mask = 0x3, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_b_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_b_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_AB_CTRL, > + .shift = 16, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_b_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_b_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_b_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_AB_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_b_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_b_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_c_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_CD_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_c_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_c_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_CD_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_c_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_c_mux.hw > + }, > + .num_parents = 1, > + }, > +}; > + > +static struct clk_regmap s4_pwm_c_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_CD_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_c_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_c_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_d_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_CD_CTRL, > + .mask = 0x3, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_d_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_d_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_CD_CTRL, > + .shift = 16, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_d_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_d_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_d_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_CD_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_d_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_d_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_e_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_EF_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_e_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_e_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_EF_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_e_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_e_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_e_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_EF_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_e_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_e_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_f_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_EF_CTRL, > + .mask = 0x3, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_f_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_f_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_EF_CTRL, > + .shift = 16, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_f_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_f_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_f_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_EF_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_f_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_f_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_g_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_GH_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_g_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_g_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_GH_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_g_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_g_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_g_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_GH_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_g_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_g_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_h_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_GH_CTRL, > + .mask = 0x3, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_h_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_h_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_GH_CTRL, > + .shift = 16, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_h_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_h_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_h_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_GH_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_h_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_h_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_i_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_i_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_i_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_i_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_i_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_i_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_i_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_i_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_j_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, > + .mask = 0x3, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_j_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_pwm_parent_data, > + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_pwm_j_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, > + .shift = 16, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_j_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_h_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_pwm_j_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "pwm_j_gate", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_pwm_j_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_saradc_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_SAR_CLK_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "saradc_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = (const struct clk_parent_data []) { > + { .fw_name = "xtal", }, > + { .hw = &s4_sys_clk.hw }, > + }, > + .num_parents = 2, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_saradc_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_SAR_CLK_CTRL, > + .shift = 0, > + .width = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "saradc_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_saradc_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_saradc_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_SAR_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "saradc_clk", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_saradc_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +/* > + * gen clk is designed for debug/monitor some internal clock quality. Some of the > + * corresponding clock sources are not described in the clock tree and internal clock > + * for debug, so they are skipped. > + */ > +static u32 s4_gen_clk_mux_table[] = { 0, 4, 5, 7, 19, 21, 22, > + 23, 24, 25, 26, 27, 28 }; > +static const struct clk_parent_data s4_gen_clk_parent_data[] = { > + { .fw_name = "xtal", }, > + { .hw = &s4_vid_pll.hw }, > + { .fw_name = "gp0_pll", }, > + { .fw_name = "hifi_pll", }, > + { .fw_name = "fclk_div2", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", }, > + { .fw_name = "mpll0", }, > + { .fw_name = "mpll1", }, > + { .fw_name = "mpll2", }, > + { .fw_name = "mpll3", }, > +}; > + > +static struct clk_regmap s4_gen_clk_sel = { > + .data = &(struct clk_regmap_mux_data){ > + .offset = CLKCTRL_GEN_CLK_CTRL, > + .mask = 0x1f, > + .shift = 12, > + .table = s4_gen_clk_mux_table, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "gen_clk_sel", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_gen_clk_parent_data, > + .num_parents = ARRAY_SIZE(s4_gen_clk_parent_data), > + /* > + * Because the GEN clock can be connected to an external pad > + * and may be set up directly from the device tree. Don't > + * really want to automatically reparent. > + */ > + .flags = CLK_SET_RATE_NO_REPARENT, > + }, > +}; > + > +static struct clk_regmap s4_gen_clk_div = { > + .data = &(struct clk_regmap_div_data){ > + .offset = CLKCTRL_GEN_CLK_CTRL, > + .shift = 0, > + .width = 11, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "gen_clk_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_gen_clk_sel.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_gen_clk = { > + .data = &(struct clk_regmap_gate_data){ > + .offset = CLKCTRL_GEN_CLK_CTRL, > + .bit_idx = 11, > + }, > + .hw.init = &(struct clk_init_data) { > + .name = "gen_clk", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_gen_clk_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static const struct clk_parent_data s4_adc_extclk_in_parent_data[] = { > + { .fw_name = "xtal", }, > + { .fw_name = "fclk_div4", }, > + { .fw_name = "fclk_div3", }, > + { .fw_name = "fclk_div5", }, > + { .fw_name = "fclk_div7", }, > + { .fw_name = "mpll2", }, > + { .fw_name = "gp0_pll", }, > + { .fw_name = "hifi_pll", }, > +}; > + > +static struct clk_regmap s4_adc_extclk_in_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_DEMOD_CLK_CTRL, > + .mask = 0x7, > + .shift = 25, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "adc_extclk_in_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = s4_adc_extclk_in_parent_data, > + .num_parents = ARRAY_SIZE(s4_adc_extclk_in_parent_data), > + }, > +}; > + > +static struct clk_regmap s4_adc_extclk_in_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_DEMOD_CLK_CTRL, > + .shift = 16, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "adc_extclk_in_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_adc_extclk_in_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_adc_extclk_in_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_DEMOD_CLK_CTRL, > + .bit_idx = 24, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "adc_extclk_in", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_adc_extclk_in_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_demod_core_clk_mux = { > + .data = &(struct clk_regmap_mux_data) { > + .offset = CLKCTRL_DEMOD_CLK_CTRL, > + .mask = 0x3, > + .shift = 9, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "demod_core_clk_mux", > + .ops = &clk_regmap_mux_ops, > + .parent_data = (const struct clk_parent_data []) { > + { .fw_name = "xtal", }, > + { .fw_name = "fclk_div7", }, > + { .fw_name = "fclk_div4", }, > + { .hw = &s4_adc_extclk_in_gate.hw } > + }, > + .num_parents = 4, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_demod_core_clk_div = { > + .data = &(struct clk_regmap_div_data) { > + .offset = CLKCTRL_DEMOD_CLK_CTRL, > + .shift = 0, > + .width = 7, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "demod_core_clk_div", > + .ops = &clk_regmap_divider_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_demod_core_clk_mux.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +static struct clk_regmap s4_demod_core_clk_gate = { > + .data = &(struct clk_regmap_gate_data) { > + .offset = CLKCTRL_DEMOD_CLK_CTRL, > + .bit_idx = 8, > + }, > + .hw.init = &(struct clk_init_data){ > + .name = "demod_core_clk", > + .ops = &clk_regmap_gate_ops, > + .parent_hws = (const struct clk_hw *[]) { > + &s4_demod_core_clk_div.hw > + }, > + .num_parents = 1, > + .flags = CLK_SET_RATE_PARENT, > + }, > +}; > + > +#define MESON_GATE(_name, _reg, _bit) \ > + MESON_PCLK(_name, _reg, _bit, &s4_sys_clk.hw) > + > +static MESON_GATE(s4_ddr, CLKCTRL_SYS_CLK_EN0_REG0, 0); > +static MESON_GATE(s4_dos, CLKCTRL_SYS_CLK_EN0_REG0, 1); > +static MESON_GATE(s4_ethphy, CLKCTRL_SYS_CLK_EN0_REG0, 4); > +static MESON_GATE(s4_mali, CLKCTRL_SYS_CLK_EN0_REG0, 6); > +static MESON_GATE(s4_aocpu, CLKCTRL_SYS_CLK_EN0_REG0, 13); > +static MESON_GATE(s4_aucpu, CLKCTRL_SYS_CLK_EN0_REG0, 14); > +static MESON_GATE(s4_cec, CLKCTRL_SYS_CLK_EN0_REG0, 16); > +static MESON_GATE(s4_sdemmca, CLKCTRL_SYS_CLK_EN0_REG0, 24); > +static MESON_GATE(s4_sdemmcb, CLKCTRL_SYS_CLK_EN0_REG0, 25); > +static MESON_GATE(s4_nand, CLKCTRL_SYS_CLK_EN0_REG0, 26); > +static MESON_GATE(s4_smartcard, CLKCTRL_SYS_CLK_EN0_REG0, 27); > +static MESON_GATE(s4_acodec, CLKCTRL_SYS_CLK_EN0_REG0, 28); > +static MESON_GATE(s4_spifc, CLKCTRL_SYS_CLK_EN0_REG0, 29); > +static MESON_GATE(s4_msr_clk, CLKCTRL_SYS_CLK_EN0_REG0, 30); > +static MESON_GATE(s4_ir_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 31); > +static MESON_GATE(s4_audio, CLKCTRL_SYS_CLK_EN0_REG1, 0); > +static MESON_GATE(s4_eth, CLKCTRL_SYS_CLK_EN0_REG1, 3); > +static MESON_GATE(s4_uart_a, CLKCTRL_SYS_CLK_EN0_REG1, 5); > +static MESON_GATE(s4_uart_b, CLKCTRL_SYS_CLK_EN0_REG1, 6); > +static MESON_GATE(s4_uart_c, CLKCTRL_SYS_CLK_EN0_REG1, 7); > +static MESON_GATE(s4_uart_d, CLKCTRL_SYS_CLK_EN0_REG1, 8); > +static MESON_GATE(s4_uart_e, CLKCTRL_SYS_CLK_EN0_REG1, 9); > +static MESON_GATE(s4_aififo, CLKCTRL_SYS_CLK_EN0_REG1, 11); > +static MESON_GATE(s4_ts_ddr, CLKCTRL_SYS_CLK_EN0_REG1, 15); > +static MESON_GATE(s4_ts_pll, CLKCTRL_SYS_CLK_EN0_REG1, 16); > +static MESON_GATE(s4_g2d, CLKCTRL_SYS_CLK_EN0_REG1, 20); > +static MESON_GATE(s4_spicc0, CLKCTRL_SYS_CLK_EN0_REG1, 21); > +static MESON_GATE(s4_usb, CLKCTRL_SYS_CLK_EN0_REG1, 26); > +static MESON_GATE(s4_i2c_m_a, CLKCTRL_SYS_CLK_EN0_REG1, 30); > +static MESON_GATE(s4_i2c_m_b, CLKCTRL_SYS_CLK_EN0_REG1, 31); > +static MESON_GATE(s4_i2c_m_c, CLKCTRL_SYS_CLK_EN0_REG2, 0); > +static MESON_GATE(s4_i2c_m_d, CLKCTRL_SYS_CLK_EN0_REG2, 1); > +static MESON_GATE(s4_i2c_m_e, CLKCTRL_SYS_CLK_EN0_REG2, 2); > +static MESON_GATE(s4_hdmitx_apb, CLKCTRL_SYS_CLK_EN0_REG2, 4); > +static MESON_GATE(s4_i2c_s_a, CLKCTRL_SYS_CLK_EN0_REG2, 5); > +static MESON_GATE(s4_usb1_to_ddr, CLKCTRL_SYS_CLK_EN0_REG2, 8); > +static MESON_GATE(s4_hdcp22, CLKCTRL_SYS_CLK_EN0_REG2, 10); > +static MESON_GATE(s4_mmc_apb, CLKCTRL_SYS_CLK_EN0_REG2, 11); > +static MESON_GATE(s4_rsa, CLKCTRL_SYS_CLK_EN0_REG2, 18); > +static MESON_GATE(s4_cpu_debug, CLKCTRL_SYS_CLK_EN0_REG2, 19); > +static MESON_GATE(s4_vpu_intr, CLKCTRL_SYS_CLK_EN0_REG2, 25); > +static MESON_GATE(s4_demod, CLKCTRL_SYS_CLK_EN0_REG2, 27); > +static MESON_GATE(s4_sar_adc, CLKCTRL_SYS_CLK_EN0_REG2, 28); > +static MESON_GATE(s4_gic, CLKCTRL_SYS_CLK_EN0_REG2, 30); > +static MESON_GATE(s4_pwm_ab, CLKCTRL_SYS_CLK_EN0_REG3, 7); > +static MESON_GATE(s4_pwm_cd, CLKCTRL_SYS_CLK_EN0_REG3, 8); > +static MESON_GATE(s4_pwm_ef, CLKCTRL_SYS_CLK_EN0_REG3, 9); > +static MESON_GATE(s4_pwm_gh, CLKCTRL_SYS_CLK_EN0_REG3, 10); > +static MESON_GATE(s4_pwm_ij, CLKCTRL_SYS_CLK_EN0_REG3, 11); > + > +/* Array of all clocks provided by this provider */ > +static struct clk_hw *s4_periphs_hw_clks[] = { > + [CLKID_RTC_32K_CLKIN] = &s4_rtc_32k_by_oscin_clkin.hw, > + [CLKID_RTC_32K_DIV] = &s4_rtc_32k_by_oscin_div.hw, > + [CLKID_RTC_32K_SEL] = &s4_rtc_32k_by_oscin_sel.hw, > + [CLKID_RTC_32K_XATL] = &s4_rtc_32k_by_oscin.hw, > + [CLKID_RTC] = &s4_rtc_clk.hw, > + [CLKID_SYS_CLK_B_SEL] = &s4_sysclk_b_sel.hw, > + [CLKID_SYS_CLK_B_DIV] = &s4_sysclk_b_div.hw, > + [CLKID_SYS_CLK_B] = &s4_sysclk_b.hw, > + [CLKID_SYS_CLK_A_SEL] = &s4_sysclk_a_sel.hw, > + [CLKID_SYS_CLK_A_DIV] = &s4_sysclk_a_div.hw, > + [CLKID_SYS_CLK_A] = &s4_sysclk_a.hw, > + [CLKID_SYS] = &s4_sys_clk.hw, > + [CLKID_CECA_32K_CLKIN] = &s4_ceca_32k_clkin.hw, > + [CLKID_CECA_32K_DIV] = &s4_ceca_32k_div.hw, > + [CLKID_CECA_32K_SEL_PRE] = &s4_ceca_32k_sel_pre.hw, > + [CLKID_CECA_32K_SEL] = &s4_ceca_32k_sel.hw, > + [CLKID_CECA_32K_CLKOUT] = &s4_ceca_32k_clkout.hw, > + [CLKID_CECB_32K_CLKIN] = &s4_cecb_32k_clkin.hw, > + [CLKID_CECB_32K_DIV] = &s4_cecb_32k_div.hw, > + [CLKID_CECB_32K_SEL_PRE] = &s4_cecb_32k_sel_pre.hw, > + [CLKID_CECB_32K_SEL] = &s4_cecb_32k_sel.hw, > + [CLKID_CECB_32K_CLKOUT] = &s4_cecb_32k_clkout.hw, > + [CLKID_SC_CLK_SEL] = &s4_sc_clk_mux.hw, > + [CLKID_SC_CLK_DIV] = &s4_sc_clk_div.hw, > + [CLKID_SC] = &s4_sc_clk_gate.hw, > + [CLKID_12_24M] = &s4_12_24M_clk_gate.hw, > + [CLKID_12M_CLK_DIV] = &s4_12M_clk_div.hw, > + [CLKID_12_24M_CLK_SEL] = &s4_12_24M_clk.hw, > + [CLKID_VID_PLL_DIV] = &s4_vid_pll_div.hw, > + [CLKID_VID_PLL_SEL] = &s4_vid_pll_sel.hw, > + [CLKID_VID_PLL] = &s4_vid_pll.hw, > + [CLKID_VCLK_SEL] = &s4_vclk_sel.hw, > + [CLKID_VCLK2_SEL] = &s4_vclk2_sel.hw, > + [CLKID_VCLK_INPUT] = &s4_vclk_input.hw, > + [CLKID_VCLK2_INPUT] = &s4_vclk2_input.hw, > + [CLKID_VCLK_DIV] = &s4_vclk_div.hw, > + [CLKID_VCLK2_DIV] = &s4_vclk2_div.hw, > + [CLKID_VCLK] = &s4_vclk.hw, > + [CLKID_VCLK2] = &s4_vclk2.hw, > + [CLKID_VCLK_DIV1] = &s4_vclk_div1.hw, > + [CLKID_VCLK_DIV2_EN] = &s4_vclk_div2_en.hw, > + [CLKID_VCLK_DIV4_EN] = &s4_vclk_div4_en.hw, > + [CLKID_VCLK_DIV6_EN] = &s4_vclk_div6_en.hw, > + [CLKID_VCLK_DIV12_EN] = &s4_vclk_div12_en.hw, > + [CLKID_VCLK2_DIV1] = &s4_vclk2_div1.hw, > + [CLKID_VCLK2_DIV2_EN] = &s4_vclk2_div2_en.hw, > + [CLKID_VCLK2_DIV4_EN] = &s4_vclk2_div4_en.hw, > + [CLKID_VCLK2_DIV6_EN] = &s4_vclk2_div6_en.hw, > + [CLKID_VCLK2_DIV12_EN] = &s4_vclk2_div12_en.hw, > + [CLKID_VCLK_DIV2] = &s4_vclk_div2.hw, > + [CLKID_VCLK_DIV4] = &s4_vclk_div4.hw, > + [CLKID_VCLK_DIV6] = &s4_vclk_div6.hw, > + [CLKID_VCLK_DIV12] = &s4_vclk_div12.hw, > + [CLKID_VCLK2_DIV2] = &s4_vclk2_div2.hw, > + [CLKID_VCLK2_DIV4] = &s4_vclk2_div4.hw, > + [CLKID_VCLK2_DIV6] = &s4_vclk2_div6.hw, > + [CLKID_VCLK2_DIV12] = &s4_vclk2_div12.hw, > + [CLKID_CTS_ENCI_SEL] = &s4_cts_enci_sel.hw, > + [CLKID_CTS_ENCP_SEL] = &s4_cts_encp_sel.hw, > + [CLKID_CTS_VDAC_SEL] = &s4_cts_vdac_sel.hw, > + [CLKID_HDMI_TX_SEL] = &s4_hdmi_tx_sel.hw, > + [CLKID_CTS_ENCI] = &s4_cts_enci.hw, > + [CLKID_CTS_ENCP] = &s4_cts_encp.hw, > + [CLKID_CTS_VDAC] = &s4_cts_vdac.hw, > + [CLKID_HDMI_TX] = &s4_hdmi_tx.hw, > + [CLKID_HDMI_SEL] = &s4_hdmi_sel.hw, > + [CLKID_HDMI_DIV] = &s4_hdmi_div.hw, > + [CLKID_HDMI] = &s4_hdmi.hw, > + [CLKID_TS_CLK_DIV] = &s4_ts_clk_div.hw, > + [CLKID_TS] = &s4_ts_clk_gate.hw, > + [CLKID_MALI_0_SEL] = &s4_mali_0_sel.hw, > + [CLKID_MALI_0_DIV] = &s4_mali_0_div.hw, > + [CLKID_MALI_0] = &s4_mali_0.hw, > + [CLKID_MALI_1_SEL] = &s4_mali_1_sel.hw, > + [CLKID_MALI_1_DIV] = &s4_mali_1_div.hw, > + [CLKID_MALI_1] = &s4_mali_1.hw, > + [CLKID_MALI_SEL] = &s4_mali_mux.hw, > + [CLKID_VDEC_P0_SEL] = &s4_vdec_p0_mux.hw, > + [CLKID_VDEC_P0_DIV] = &s4_vdec_p0_div.hw, > + [CLKID_VDEC_P0] = &s4_vdec_p0.hw, > + [CLKID_VDEC_P1_SEL] = &s4_vdec_p1_mux.hw, > + [CLKID_VDEC_P1_DIV] = &s4_vdec_p1_div.hw, > + [CLKID_VDEC_P1] = &s4_vdec_p1.hw, > + [CLKID_VDEC_SEL] = &s4_vdec_mux.hw, > + [CLKID_HEVCF_P0_SEL] = &s4_hevcf_p0_mux.hw, > + [CLKID_HEVCF_P0_DIV] = &s4_hevcf_p0_div.hw, > + [CLKID_HEVCF_P0] = &s4_hevcf_p0.hw, > + [CLKID_HEVCF_P1_SEL] = &s4_hevcf_p1_mux.hw, > + [CLKID_HEVCF_P1_DIV] = &s4_hevcf_p1_div.hw, > + [CLKID_HEVCF_P1] = &s4_hevcf_p1.hw, > + [CLKID_HEVCF_SEL] = &s4_hevcf_mux.hw, > + [CLKID_VPU_0_SEL] = &s4_vpu_0_sel.hw, > + [CLKID_VPU_0_DIV] = &s4_vpu_0_div.hw, > + [CLKID_VPU_0] = &s4_vpu_0.hw, > + [CLKID_VPU_1_SEL] = &s4_vpu_1_sel.hw, > + [CLKID_VPU_1_DIV] = &s4_vpu_1_div.hw, > + [CLKID_VPU_1] = &s4_vpu_1.hw, > + [CLKID_VPU] = &s4_vpu.hw, > + [CLKID_VPU_CLKB_TMP_SEL] = &s4_vpu_clkb_tmp_mux.hw, > + [CLKID_VPU_CLKB_TMP_DIV] = &s4_vpu_clkb_tmp_div.hw, > + [CLKID_VPU_CLKB_TMP] = &s4_vpu_clkb_tmp.hw, > + [CLKID_VPU_CLKB_DIV] = &s4_vpu_clkb_div.hw, > + [CLKID_VPU_CLKB] = &s4_vpu_clkb.hw, > + [CLKID_VPU_CLKC_P0_SEL] = &s4_vpu_clkc_p0_mux.hw, > + [CLKID_VPU_CLKC_P0_DIV] = &s4_vpu_clkc_p0_div.hw, > + [CLKID_VPU_CLKC_P0] = &s4_vpu_clkc_p0.hw, > + [CLKID_VPU_CLKC_P1_SEL] = &s4_vpu_clkc_p1_mux.hw, > + [CLKID_VPU_CLKC_P1_DIV] = &s4_vpu_clkc_p1_div.hw, > + [CLKID_VPU_CLKC_P1] = &s4_vpu_clkc_p1.hw, > + [CLKID_VPU_CLKC_SEL] = &s4_vpu_clkc_mux.hw, > + [CLKID_VAPB_0_SEL] = &s4_vapb_0_sel.hw, > + [CLKID_VAPB_0_DIV] = &s4_vapb_0_div.hw, > + [CLKID_VAPB_0] = &s4_vapb_0.hw, > + [CLKID_VAPB_1_SEL] = &s4_vapb_1_sel.hw, > + [CLKID_VAPB_1_DIV] = &s4_vapb_1_div.hw, > + [CLKID_VAPB_1] = &s4_vapb_1.hw, > + [CLKID_VAPB] = &s4_vapb.hw, > + [CLKID_GE2D] = &s4_ge2d_gate.hw, > + [CLKID_VDIN_MEAS_SEL] = &s4_vdin_meas_mux.hw, > + [CLKID_VDIN_MEAS_DIV] = &s4_vdin_meas_div.hw, > + [CLKID_VDIN_MEAS] = &s4_vdin_meas_gate.hw, > + [CLKID_SD_EMMC_C_CLK_SEL] = &s4_sd_emmc_c_clk0_sel.hw, > + [CLKID_SD_EMMC_C_CLK_DIV] = &s4_sd_emmc_c_clk0_div.hw, > + [CLKID_SD_EMMC_C] = &s4_sd_emmc_c_clk0.hw, > + [CLKID_SD_EMMC_A_CLK_SEL] = &s4_sd_emmc_a_clk0_sel.hw, > + [CLKID_SD_EMMC_A_CLK_DIV] = &s4_sd_emmc_a_clk0_div.hw, > + [CLKID_SD_EMMC_A] = &s4_sd_emmc_a_clk0.hw, > + [CLKID_SD_EMMC_B_CLK_SEL] = &s4_sd_emmc_b_clk0_sel.hw, > + [CLKID_SD_EMMC_B_CLK_DIV] = &s4_sd_emmc_b_clk0_div.hw, > + [CLKID_SD_EMMC_B] = &s4_sd_emmc_b_clk0.hw, > + [CLKID_SPICC0_SEL] = &s4_spicc0_mux.hw, > + [CLKID_SPICC0_DIV] = &s4_spicc0_div.hw, > + [CLKID_SPICC0_EN] = &s4_spicc0_gate.hw, > + [CLKID_PWM_A_SEL] = &s4_pwm_a_mux.hw, > + [CLKID_PWM_A_DIV] = &s4_pwm_a_div.hw, > + [CLKID_PWM_A] = &s4_pwm_a_gate.hw, > + [CLKID_PWM_B_SEL] = &s4_pwm_b_mux.hw, > + [CLKID_PWM_B_DIV] = &s4_pwm_b_div.hw, > + [CLKID_PWM_B] = &s4_pwm_b_gate.hw, > + [CLKID_PWM_C_SEL] = &s4_pwm_c_mux.hw, > + [CLKID_PWM_C_DIV] = &s4_pwm_c_div.hw, > + [CLKID_PWM_C] = &s4_pwm_c_gate.hw, > + [CLKID_PWM_D_SEL] = &s4_pwm_d_mux.hw, > + [CLKID_PWM_D_DIV] = &s4_pwm_d_div.hw, > + [CLKID_PWM_D] = &s4_pwm_d_gate.hw, > + [CLKID_PWM_E_SEL] = &s4_pwm_e_mux.hw, > + [CLKID_PWM_E_DIV] = &s4_pwm_e_div.hw, > + [CLKID_PWM_E] = &s4_pwm_e_gate.hw, > + [CLKID_PWM_F_SEL] = &s4_pwm_f_mux.hw, > + [CLKID_PWM_F_DIV] = &s4_pwm_f_div.hw, > + [CLKID_PWM_F] = &s4_pwm_f_gate.hw, > + [CLKID_PWM_G_SEL] = &s4_pwm_g_mux.hw, > + [CLKID_PWM_G_DIV] = &s4_pwm_g_div.hw, > + [CLKID_PWM_G] = &s4_pwm_g_gate.hw, > + [CLKID_PWM_H_SEL] = &s4_pwm_h_mux.hw, > + [CLKID_PWM_H_DIV] = &s4_pwm_h_div.hw, > + [CLKID_PWM_H] = &s4_pwm_h_gate.hw, > + [CLKID_PWM_I_SEL] = &s4_pwm_i_mux.hw, > + [CLKID_PWM_I_DIV] = &s4_pwm_i_div.hw, > + [CLKID_PWM_I] = &s4_pwm_i_gate.hw, > + [CLKID_PWM_J_SEL] = &s4_pwm_j_mux.hw, > + [CLKID_PWM_J_DIV] = &s4_pwm_j_div.hw, > + [CLKID_PWM_J] = &s4_pwm_j_gate.hw, > + [CLKID_SARADC_SEL] = &s4_saradc_mux.hw, > + [CLKID_SARADC_DIV] = &s4_saradc_div.hw, > + [CLKID_SARADC] = &s4_saradc_gate.hw, > + [CLKID_GEN_SEL] = &s4_gen_clk_sel.hw, > + [CLKID_GEN_DIV] = &s4_gen_clk_div.hw, > + [CLKID_GEN] = &s4_gen_clk.hw, > + [CLKID_DDR] = &s4_ddr.hw, > + [CLKID_DOS] = &s4_dos.hw, > + [CLKID_ETHPHY] = &s4_ethphy.hw, > + [CLKID_MALI] = &s4_mali.hw, > + [CLKID_AOCPU] = &s4_aocpu.hw, > + [CLKID_AUCPU] = &s4_aucpu.hw, > + [CLKID_CEC] = &s4_cec.hw, > + [CLKID_SDEMMC_A] = &s4_sdemmca.hw, > + [CLKID_SDEMMC_B] = &s4_sdemmcb.hw, > + [CLKID_NAND] = &s4_nand.hw, > + [CLKID_SMARTCARD] = &s4_smartcard.hw, > + [CLKID_ACODEC] = &s4_acodec.hw, > + [CLKID_SPIFC] = &s4_spifc.hw, > + [CLKID_MSR] = &s4_msr_clk.hw, > + [CLKID_IR_CTRL] = &s4_ir_ctrl.hw, > + [CLKID_AUDIO] = &s4_audio.hw, > + [CLKID_ETH] = &s4_eth.hw, > + [CLKID_UART_A] = &s4_uart_a.hw, > + [CLKID_UART_B] = &s4_uart_b.hw, > + [CLKID_UART_C] = &s4_uart_c.hw, > + [CLKID_UART_D] = &s4_uart_d.hw, > + [CLKID_UART_E] = &s4_uart_e.hw, > + [CLKID_AIFIFO] = &s4_aififo.hw, > + [CLKID_TS_DDR] = &s4_ts_ddr.hw, > + [CLKID_TS_PLL] = &s4_ts_pll.hw, > + [CLKID_G2D] = &s4_g2d.hw, > + [CLKID_SPICC0] = &s4_spicc0.hw, > + [CLKID_USB] = &s4_usb.hw, > + [CLKID_I2C_M_A] = &s4_i2c_m_a.hw, > + [CLKID_I2C_M_B] = &s4_i2c_m_b.hw, > + [CLKID_I2C_M_C] = &s4_i2c_m_c.hw, > + [CLKID_I2C_M_D] = &s4_i2c_m_d.hw, > + [CLKID_I2C_M_E] = &s4_i2c_m_e.hw, > + [CLKID_HDMITX_APB] = &s4_hdmitx_apb.hw, > + [CLKID_I2C_S_A] = &s4_i2c_s_a.hw, > + [CLKID_USB1_TO_DDR] = &s4_usb1_to_ddr.hw, > + [CLKID_HDCP22] = &s4_hdcp22.hw, > + [CLKID_MMC_APB] = &s4_mmc_apb.hw, > + [CLKID_RSA] = &s4_rsa.hw, > + [CLKID_CPU_DEBUG] = &s4_cpu_debug.hw, > + [CLKID_VPU_INTR] = &s4_vpu_intr.hw, > + [CLKID_DEMOD] = &s4_demod.hw, > + [CLKID_SAR_ADC] = &s4_sar_adc.hw, > + [CLKID_GIC] = &s4_gic.hw, > + [CLKID_PWM_AB] = &s4_pwm_ab.hw, > + [CLKID_PWM_CD] = &s4_pwm_cd.hw, > + [CLKID_PWM_EF] = &s4_pwm_ef.hw, > + [CLKID_PWM_GH] = &s4_pwm_gh.hw, > + [CLKID_PWM_IJ] = &s4_pwm_ij.hw, > + [CLKID_HDCP22_ESMCLK_SEL] = &s4_hdcp22_esmclk_mux.hw, > + [CLKID_HDCP22_ESMCLK_DIV] = &s4_hdcp22_esmclk_div.hw, > + [CLKID_HDCP22_ESMCLK] = &s4_hdcp22_esmclk_gate.hw, > + [CLKID_HDCP22_SKPCLK_SEL] = &s4_hdcp22_skpclk_mux.hw, > + [CLKID_HDCP22_SKPCLK_DIV] = &s4_hdcp22_skpclk_div.hw, > + [CLKID_HDCP22_SKPCLK] = &s4_hdcp22_skpclk_gate.hw, > +}; > + > +/* Convenience table to populate regmap in .probe */ > +static struct clk_regmap *const s4_periphs_clk_regmaps[] = { > + &s4_rtc_32k_by_oscin_clkin, > + &s4_rtc_32k_by_oscin_div, > + &s4_rtc_32k_by_oscin_sel, > + &s4_rtc_32k_by_oscin, > + &s4_rtc_clk, > + &s4_sysclk_b_sel, > + &s4_sysclk_b_div, > + &s4_sysclk_b, > + &s4_sysclk_a_sel, > + &s4_sysclk_a_div, > + &s4_sysclk_a, > + &s4_sys_clk, > + &s4_ceca_32k_clkin, > + &s4_ceca_32k_div, > + &s4_ceca_32k_sel_pre, > + &s4_ceca_32k_sel, > + &s4_ceca_32k_clkout, > + &s4_cecb_32k_clkin, > + &s4_cecb_32k_div, > + &s4_cecb_32k_sel_pre, > + &s4_cecb_32k_sel, > + &s4_cecb_32k_clkout, > + &s4_sc_clk_mux, > + &s4_sc_clk_div, > + &s4_sc_clk_gate, > + &s4_12_24M_clk_gate, > + &s4_12_24M_clk, > + &s4_vid_pll_div, > + &s4_vid_pll_sel, > + &s4_vid_pll, > + &s4_vclk_sel, > + &s4_vclk2_sel, > + &s4_vclk_input, > + &s4_vclk2_input, > + &s4_vclk_div, > + &s4_vclk2_div, > + &s4_vclk, > + &s4_vclk2, > + &s4_vclk_div1, > + &s4_vclk_div2_en, > + &s4_vclk_div4_en, > + &s4_vclk_div6_en, > + &s4_vclk_div12_en, > + &s4_vclk2_div1, > + &s4_vclk2_div2_en, > + &s4_vclk2_div4_en, > + &s4_vclk2_div6_en, > + &s4_vclk2_div12_en, > + &s4_cts_enci_sel, > + &s4_cts_encp_sel, > + &s4_cts_vdac_sel, > + &s4_hdmi_tx_sel, > + &s4_cts_enci, > + &s4_cts_encp, > + &s4_cts_vdac, > + &s4_hdmi_tx, > + &s4_hdmi_sel, > + &s4_hdmi_div, > + &s4_hdmi, > + &s4_ts_clk_div, > + &s4_ts_clk_gate, > + &s4_mali_0_sel, > + &s4_mali_0_div, > + &s4_mali_0, > + &s4_mali_1_sel, > + &s4_mali_1_div, > + &s4_mali_1, > + &s4_mali_mux, > + &s4_vdec_p0_mux, > + &s4_vdec_p0_div, > + &s4_vdec_p0, > + &s4_vdec_p1_mux, > + &s4_vdec_p1_div, > + &s4_vdec_p1, > + &s4_vdec_mux, > + &s4_hevcf_p0_mux, > + &s4_hevcf_p0_div, > + &s4_hevcf_p0, > + &s4_hevcf_p1_mux, > + &s4_hevcf_p1_div, > + &s4_hevcf_p1, > + &s4_hevcf_mux, > + &s4_vpu_0_sel, > + &s4_vpu_0_div, > + &s4_vpu_0, > + &s4_vpu_1_sel, > + &s4_vpu_1_div, > + &s4_vpu_1, > + &s4_vpu, > + &s4_vpu_clkb_tmp_mux, > + &s4_vpu_clkb_tmp_div, > + &s4_vpu_clkb_tmp, > + &s4_vpu_clkb_div, > + &s4_vpu_clkb, > + &s4_vpu_clkc_p0_mux, > + &s4_vpu_clkc_p0_div, > + &s4_vpu_clkc_p0, > + &s4_vpu_clkc_p1_mux, > + &s4_vpu_clkc_p1_div, > + &s4_vpu_clkc_p1, > + &s4_vpu_clkc_mux, > + &s4_vapb_0_sel, > + &s4_vapb_0_div, > + &s4_vapb_0, > + &s4_vapb_1_sel, > + &s4_vapb_1_div, > + &s4_vapb_1, > + &s4_vapb, > + &s4_ge2d_gate, > + &s4_hdcp22_esmclk_mux, > + &s4_hdcp22_esmclk_div, > + &s4_hdcp22_esmclk_gate, > + &s4_hdcp22_skpclk_mux, > + &s4_hdcp22_skpclk_div, > + &s4_hdcp22_skpclk_gate, > + &s4_vdin_meas_mux, > + &s4_vdin_meas_div, > + &s4_vdin_meas_gate, > + &s4_sd_emmc_c_clk0_sel, > + &s4_sd_emmc_c_clk0_div, > + &s4_sd_emmc_c_clk0, > + &s4_sd_emmc_a_clk0_sel, > + &s4_sd_emmc_a_clk0_div, > + &s4_sd_emmc_a_clk0, > + &s4_sd_emmc_b_clk0_sel, > + &s4_sd_emmc_b_clk0_div, > + &s4_sd_emmc_b_clk0, > + &s4_spicc0_mux, > + &s4_spicc0_div, > + &s4_spicc0_gate, > + &s4_pwm_a_mux, > + &s4_pwm_a_div, > + &s4_pwm_a_gate, > + &s4_pwm_b_mux, > + &s4_pwm_b_div, > + &s4_pwm_b_gate, > + &s4_pwm_c_mux, > + &s4_pwm_c_div, > + &s4_pwm_c_gate, > + &s4_pwm_d_mux, > + &s4_pwm_d_div, > + &s4_pwm_d_gate, > + &s4_pwm_e_mux, > + &s4_pwm_e_div, > + &s4_pwm_e_gate, > + &s4_pwm_f_mux, > + &s4_pwm_f_div, > + &s4_pwm_f_gate, > + &s4_pwm_g_mux, > + &s4_pwm_g_div, > + &s4_pwm_g_gate, > + &s4_pwm_h_mux, > + &s4_pwm_h_div, > + &s4_pwm_h_gate, > + &s4_pwm_i_mux, > + &s4_pwm_i_div, > + &s4_pwm_i_gate, > + &s4_pwm_j_mux, > + &s4_pwm_j_div, > + &s4_pwm_j_gate, > + &s4_saradc_mux, > + &s4_saradc_div, > + &s4_saradc_gate, > + &s4_gen_clk_sel, > + &s4_gen_clk_div, > + &s4_gen_clk, > + &s4_ddr, > + &s4_dos, > + &s4_ethphy, > + &s4_mali, > + &s4_aocpu, > + &s4_aucpu, > + &s4_cec, > + &s4_sdemmca, > + &s4_sdemmcb, > + &s4_nand, > + &s4_smartcard, > + &s4_acodec, > + &s4_spifc, > + &s4_msr_clk, > + &s4_ir_ctrl, > + &s4_audio, > + &s4_eth, > + &s4_uart_a, > + &s4_uart_b, > + &s4_uart_c, > + &s4_uart_d, > + &s4_uart_e, > + &s4_aififo, > + &s4_ts_ddr, > + &s4_ts_pll, > + &s4_g2d, > + &s4_spicc0, > + &s4_usb, > + &s4_i2c_m_a, > + &s4_i2c_m_b, > + &s4_i2c_m_c, > + &s4_i2c_m_d, > + &s4_i2c_m_e, > + &s4_hdmitx_apb, > + &s4_i2c_s_a, > + &s4_usb1_to_ddr, > + &s4_hdcp22, > + &s4_mmc_apb, > + &s4_rsa, > + &s4_cpu_debug, > + &s4_vpu_intr, > + &s4_demod, > + &s4_sar_adc, > + &s4_gic, > + &s4_pwm_ab, > + &s4_pwm_cd, > + &s4_pwm_ef, > + &s4_pwm_gh, > + &s4_pwm_ij, > + &s4_demod_core_clk_mux, > + &s4_demod_core_clk_div, > + &s4_demod_core_clk_gate, > + &s4_adc_extclk_in_mux, > + &s4_adc_extclk_in_div, > + &s4_adc_extclk_in_gate, > +}; > + > +static struct regmap_config clkc_regmap_config = { > + .reg_bits = 32, > + .val_bits = 32, > + .reg_stride = 4, > +}; > + > +static struct meson_clk_hw_data s4_periphs_clks = { > + .hws = s4_periphs_hw_clks, > + .num = ARRAY_SIZE(s4_periphs_hw_clks), > +}; > + > +static int meson_s4_periphs_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct regmap *regmap; > + void __iomem *base; > + int ret, i; > + > + base = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(base)) > + return dev_err_probe(dev, PTR_ERR(base), > + "can't ioremap resource\n"); > + > + regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); > + if (IS_ERR(regmap)) > + return dev_err_probe(dev, PTR_ERR(regmap), > + "can't init regmap mmio region\n"); > + > + /* Populate regmap for the regmap backed clocks */ > + for (i = 0; i < ARRAY_SIZE(s4_periphs_clk_regmaps); i++) > + s4_periphs_clk_regmaps[i]->map = regmap; > + > + for (i = 0; i < s4_periphs_clks.num; i++) { > + /* array might be sparse */ > + if (!s4_periphs_clks.hws[i]) > + continue; > + > + ret = devm_clk_hw_register(dev, s4_periphs_clks.hws[i]); > + if (ret) > + return dev_err_probe(dev, ret, > + "clock[%d] registration failed\n", i); > + } > + > + return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &s4_periphs_clks); > +} > + > +static const struct of_device_id clkc_match_table[] = { > + { > + .compatible = "amlogic,s4-peripherals-clkc", > + }, > + {} > +}; > + > +static struct platform_driver s4_driver = { > + .probe = meson_s4_periphs_probe, > + .driver = { > + .name = "s4-periphs-clkc", > + .of_match_table = clkc_match_table, > + }, > +}; > + > +module_platform_driver(s4_driver); > +MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>"); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/clk/meson/s4-peripherals.h b/drivers/clk/meson/s4-peripherals.h > new file mode 100644 > index 000000000000..56f8f28a913e > --- /dev/null > +++ b/drivers/clk/meson/s4-peripherals.h > @@ -0,0 +1,57 @@ > +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ > +/* > + * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved > + * Author: Yu Tu <yu.tu@amlogic.com> > + */ > + > +#ifndef __MESON_S4_PERIPHERALS_H__ > +#define __MESON_S4_PERIPHERALS_H__ > + > +#define CLKCTRL_RTC_BY_OSCIN_CTRL0 0x008 > +#define CLKCTRL_RTC_BY_OSCIN_CTRL1 0x00c > +#define CLKCTRL_RTC_CTRL 0x010 > +#define CLKCTRL_SYS_CLK_CTRL0 0x040 > +#define CLKCTRL_SYS_CLK_EN0_REG0 0x044 > +#define CLKCTRL_SYS_CLK_EN0_REG1 0x048 > +#define CLKCTRL_SYS_CLK_EN0_REG2 0x04c > +#define CLKCTRL_SYS_CLK_EN0_REG3 0x050 > +#define CLKCTRL_CECA_CTRL0 0x088 > +#define CLKCTRL_CECA_CTRL1 0x08c > +#define CLKCTRL_CECB_CTRL0 0x090 > +#define CLKCTRL_CECB_CTRL1 0x094 > +#define CLKCTRL_SC_CLK_CTRL 0x098 > +#define CLKCTRL_CLK12_24_CTRL 0x0a8 > +#define CLKCTRL_VID_CLK_CTRL 0x0c0 > +#define CLKCTRL_VID_CLK_CTRL2 0x0c4 > +#define CLKCTRL_VID_CLK_DIV 0x0c8 > +#define CLKCTRL_VIID_CLK_DIV 0x0cc > +#define CLKCTRL_VIID_CLK_CTRL 0x0d0 > +#define CLKCTRL_HDMI_CLK_CTRL 0x0e0 > +#define CLKCTRL_VID_PLL_CLK_DIV 0x0e4 > +#define CLKCTRL_VPU_CLK_CTRL 0x0e8 > +#define CLKCTRL_VPU_CLKB_CTRL 0x0ec > +#define CLKCTRL_VPU_CLKC_CTRL 0x0f0 > +#define CLKCTRL_VID_LOCK_CLK_CTRL 0x0f4 > +#define CLKCTRL_VDIN_MEAS_CLK_CTRL 0x0f8 > +#define CLKCTRL_VAPBCLK_CTRL 0x0fc > +#define CLKCTRL_HDCP22_CTRL 0x100 > +#define CLKCTRL_VDEC_CLK_CTRL 0x140 > +#define CLKCTRL_VDEC2_CLK_CTRL 0x144 > +#define CLKCTRL_VDEC3_CLK_CTRL 0x148 > +#define CLKCTRL_VDEC4_CLK_CTRL 0x14c > +#define CLKCTRL_TS_CLK_CTRL 0x158 > +#define CLKCTRL_MALI_CLK_CTRL 0x15c > +#define CLKCTRL_NAND_CLK_CTRL 0x168 > +#define CLKCTRL_SD_EMMC_CLK_CTRL 0x16c > +#define CLKCTRL_SPICC_CLK_CTRL 0x174 > +#define CLKCTRL_GEN_CLK_CTRL 0x178 > +#define CLKCTRL_SAR_CLK_CTRL 0x17c > +#define CLKCTRL_PWM_CLK_AB_CTRL 0x180 > +#define CLKCTRL_PWM_CLK_CD_CTRL 0x184 > +#define CLKCTRL_PWM_CLK_EF_CTRL 0x188 > +#define CLKCTRL_PWM_CLK_GH_CTRL 0x18c > +#define CLKCTRL_PWM_CLK_IJ_CTRL 0x190 > +#define CLKCTRL_DEMOD_CLK_CTRL 0x200 > + > +#endif /* __MESON_S4_PERIPHERALS_H__ */ > + ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 4/4] clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller 2023-08-23 8:13 ` Jerome Brunet @ 2023-08-23 8:41 ` Yu Tu 0 siblings, 0 replies; 21+ messages in thread From: Yu Tu @ 2023-08-23 8:41 UTC (permalink / raw) To: Jerome Brunet, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 2023/8/23 16:13, Jerome Brunet wrote: > [ EXTERNAL EMAIL ] > > On Tue 22 Aug 2023 at 16:27, Yu Tu <yu.tu@amlogic.com> wrote: > >> Add the peripherals clock controller driver in the S4 SoC family. >> >> Signed-off-by: Yu Tu <yu.tu@amlogic.com> >> --- >> drivers/clk/meson/Kconfig | 11 + >> drivers/clk/meson/Makefile | 1 + >> drivers/clk/meson/s4-peripherals.c | 3787 ++++++++++++++++++++++++++++ >> drivers/clk/meson/s4-peripherals.h | 57 + >> 4 files changed, 3856 insertions(+) >> create mode 100644 drivers/clk/meson/s4-peripherals.c >> create mode 100644 drivers/clk/meson/s4-peripherals.h >> >> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig >> index e90982d77598..c5303e4c1604 100644 >> --- a/drivers/clk/meson/Kconfig >> +++ b/drivers/clk/meson/Kconfig >> @@ -156,4 +156,15 @@ config COMMON_CLK_S4_PLL >> Support for the PLL clock controller on Amlogic S805X2 and S905Y4 devices, >> AKA S4. Say Y if you want the board to work, because PLLs are the parent of >> most peripherals. >> + >> +config COMMON_CLK_S4_PERIPHERALS >> + tristate "S4 SoC peripherals clock controllers support" >> + depends on ARM64 >> + default y >> + select COMMON_CLK_MESON_REGMAP >> + select COMMON_CLK_MESON_DUALDIV >> + select COMMON_CLK_MESON_VID_PLL_DIV >> + help >> + Support for the peripherals clock controller on Amlogic S805X2 and S905Y4 >> + devices, AKA S4. Say Y if you want S4 peripherals clock controller to work. >> endmenu >> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile >> index 612cee923890..9ee4b954c896 100644 >> --- a/drivers/clk/meson/Makefile >> +++ b/drivers/clk/meson/Makefile >> @@ -23,3 +23,4 @@ obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o >> obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o >> obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o >> obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o >> +obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o >> diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c >> new file mode 100644 >> index 000000000000..60de4beb1561 >> --- /dev/null >> +++ b/drivers/clk/meson/s4-peripherals.c >> @@ -0,0 +1,3787 @@ >> +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) >> +/* >> + * Amlogic S4 Peripherals Clock Controller Driver >> + * >> + * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved >> + * Author: Yu Tu <yu.tu@amlogic.com> >> + */ >> + >> +#include <linux/clk-provider.h> >> +#include <linux/of_device.h> >> +#include <linux/platform_device.h> >> + >> +#include "clk-regmap.h" >> +#include "vid-pll-div.h" >> +#include "clk-dualdiv.h" >> +#include "s4-peripherals.h" >> +#include "meson-clkc-utils.h" >> +#include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h> >> + >> +static struct clk_regmap s4_rtc_32k_by_oscin_clkin = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, >> + .bit_idx = 31, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "rtc_32k_by_oscin_clkin", >> + .ops = &clk_regmap_gate_ops, >> + .parent_data = (const struct clk_parent_data []) { >> + { .fw_name = "xtal", } >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static const struct meson_clk_dualdiv_param s4_32k_div_table[] = { >> + { >> + .dual = 1, >> + .n1 = 733, >> + .m1 = 8, >> + .n2 = 732, >> + .m2 = 11, >> + }, >> + {} >> +}; >> + >> +static struct clk_regmap s4_rtc_32k_by_oscin_div = { >> + .data = &(struct meson_clk_dualdiv_data){ >> + .n1 = { >> + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, >> + .shift = 0, >> + .width = 12, >> + }, >> + .n2 = { >> + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, >> + .shift = 12, >> + .width = 12, >> + }, >> + .m1 = { >> + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1, >> + .shift = 0, >> + .width = 12, >> + }, >> + .m2 = { >> + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1, >> + .shift = 12, >> + .width = 12, >> + }, >> + .dual = { >> + .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0, >> + .shift = 28, >> + .width = 1, >> + }, >> + .table = s4_32k_div_table, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "rtc_32k_by_oscin_div", >> + .ops = &meson_clk_dualdiv_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_rtc_32k_by_oscin_clkin.hw >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_rtc_32k_by_oscin_sel = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL1, >> + .mask = 0x1, >> + .shift = 24, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "rtc_32k_by_oscin_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_rtc_32k_by_oscin_div.hw, >> + &s4_rtc_32k_by_oscin_clkin.hw, >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_rtc_32k_by_oscin = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, >> + .bit_idx = 30, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "rtc_32k_by_oscin", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_rtc_32k_by_oscin_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_rtc_clk = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_RTC_CTRL, >> + .mask = 0x3, >> + .shift = 0, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "rtc_clk_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_rtc_32k_by_oscin.hw, >> + &s4_rtc_32k_by_oscin_div.hw, >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* The index 5 is AXI_CLK, which is dedicated to AXI. So skip it. */ >> +static u32 mux_table_sys_ab_clk_sel[] = { 0, 1, 2, 3, 4, 6, 7 }; >> +static const struct clk_parent_data sys_ab_clk_parent_data[] = { >> + { .fw_name = "xtal" }, >> + { .fw_name = "fclk_div2" }, >> + { .fw_name = "fclk_div3" }, >> + { .fw_name = "fclk_div4" }, >> + { .fw_name = "fclk_div5" }, >> + { .fw_name = "fclk_div7" }, >> + { .hw = &s4_rtc_clk.hw } >> +}; >> + >> +/* >> + * This clock is initialized by ROMcode. >> + * The chip was changed SYS CLK for security reasons. SYS CLK registers are not writable >> + * in the kernel phase. Write of SYS related register will cause the system to crash. >> + * Meanwhile, these clock won't ever change at runtime. >> + * For the above reasons, we can only use ro_ops for SYS related clocks. >> + */ >> +static struct clk_regmap s4_sysclk_b_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_SYS_CLK_CTRL0, >> + .mask = 0x7, >> + .shift = 26, >> + .table = mux_table_sys_ab_clk_sel, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sysclk_b_sel", >> + .ops = &clk_regmap_mux_ro_ops, >> + .parent_data = sys_ab_clk_parent_data, >> + .num_parents = ARRAY_SIZE(sys_ab_clk_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_sysclk_b_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_SYS_CLK_CTRL0, >> + .shift = 16, >> + .width = 10, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sysclk_b_div", >> + .ops = &clk_regmap_divider_ro_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sysclk_b_sel.hw >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sysclk_b = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_SYS_CLK_CTRL0, >> + .bit_idx = 29, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sysclk_b", >> + .ops = &clk_regmap_gate_ro_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sysclk_b_div.hw >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sysclk_a_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_SYS_CLK_CTRL0, >> + .mask = 0x7, >> + .shift = 10, >> + .table = mux_table_sys_ab_clk_sel, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sysclk_a_sel", >> + .ops = &clk_regmap_mux_ro_ops, >> + .parent_data = sys_ab_clk_parent_data, >> + .num_parents = ARRAY_SIZE(sys_ab_clk_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_sysclk_a_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_SYS_CLK_CTRL0, >> + .shift = 0, >> + .width = 10, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sysclk_a_div", >> + .ops = &clk_regmap_divider_ro_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sysclk_a_sel.hw >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sysclk_a = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_SYS_CLK_CTRL0, >> + .bit_idx = 13, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sysclk_a", >> + .ops = &clk_regmap_gate_ro_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sysclk_a_div.hw >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sys_clk = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_SYS_CLK_CTRL0, >> + .mask = 0x1, >> + .shift = 31, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sys_clk", >> + .ops = &clk_regmap_mux_ro_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sysclk_a.hw, >> + &s4_sysclk_b.hw >> + }, >> + .num_parents = 2, >> + }, >> +}; >> + >> +static struct clk_regmap s4_ceca_32k_clkin = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_CECA_CTRL0, >> + .bit_idx = 31, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "ceca_32k_clkin", >> + .ops = &clk_regmap_gate_ops, >> + .parent_data = (const struct clk_parent_data []) { >> + { .fw_name = "xtal", } >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_ceca_32k_div = { >> + .data = &(struct meson_clk_dualdiv_data){ >> + .n1 = { >> + .reg_off = CLKCTRL_CECA_CTRL0, >> + .shift = 0, >> + .width = 12, >> + }, >> + .n2 = { >> + .reg_off = CLKCTRL_CECA_CTRL0, >> + .shift = 12, >> + .width = 12, >> + }, >> + .m1 = { >> + .reg_off = CLKCTRL_CECA_CTRL1, >> + .shift = 0, >> + .width = 12, >> + }, >> + .m2 = { >> + .reg_off = CLKCTRL_CECA_CTRL1, >> + .shift = 12, >> + .width = 12, >> + }, >> + .dual = { >> + .reg_off = CLKCTRL_CECA_CTRL0, >> + .shift = 28, >> + .width = 1, >> + }, >> + .table = s4_32k_div_table, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "ceca_32k_div", >> + .ops = &meson_clk_dualdiv_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_ceca_32k_clkin.hw >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_ceca_32k_sel_pre = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_CECA_CTRL1, >> + .mask = 0x1, >> + .shift = 24, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "ceca_32k_sel_pre", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_ceca_32k_div.hw, >> + &s4_ceca_32k_clkin.hw >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_ceca_32k_sel = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_CECA_CTRL1, >> + .mask = 0x1, >> + .shift = 31, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "ceca_32k_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_ceca_32k_sel_pre.hw, >> + &s4_rtc_clk.hw >> + }, >> + .num_parents = 2, >> + }, >> +}; >> + >> +static struct clk_regmap s4_ceca_32k_clkout = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_CECA_CTRL0, >> + .bit_idx = 30, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "ceca_32k_clkout", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_ceca_32k_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cecb_32k_clkin = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_CECB_CTRL0, >> + .bit_idx = 31, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "cecb_32k_clkin", >> + .ops = &clk_regmap_gate_ops, >> + .parent_data = (const struct clk_parent_data []) { >> + { .fw_name = "xtal", } >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cecb_32k_div = { >> + .data = &(struct meson_clk_dualdiv_data){ >> + .n1 = { >> + .reg_off = CLKCTRL_CECB_CTRL0, >> + .shift = 0, >> + .width = 12, >> + }, >> + .n2 = { >> + .reg_off = CLKCTRL_CECB_CTRL0, >> + .shift = 12, >> + .width = 12, >> + }, >> + .m1 = { >> + .reg_off = CLKCTRL_CECB_CTRL1, >> + .shift = 0, >> + .width = 12, >> + }, >> + .m2 = { >> + .reg_off = CLKCTRL_CECB_CTRL1, >> + .shift = 12, >> + .width = 12, >> + }, >> + .dual = { >> + .reg_off = CLKCTRL_CECB_CTRL0, >> + .shift = 28, >> + .width = 1, >> + }, >> + .table = s4_32k_div_table, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "cecb_32k_div", >> + .ops = &meson_clk_dualdiv_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_cecb_32k_clkin.hw >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cecb_32k_sel_pre = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_CECB_CTRL1, >> + .mask = 0x1, >> + .shift = 24, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "cecb_32k_sel_pre", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_cecb_32k_div.hw, >> + &s4_cecb_32k_clkin.hw >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cecb_32k_sel = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_CECB_CTRL1, >> + .mask = 0x1, >> + .shift = 31, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "cecb_32k_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_cecb_32k_sel_pre.hw, >> + &s4_rtc_clk.hw >> + }, >> + .num_parents = 2, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cecb_32k_clkout = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_CECB_CTRL0, >> + .bit_idx = 30, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "cecb_32k_clkout", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_cecb_32k_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_parent_data s4_sc_parent_data[] = { >> + { .fw_name = "fclk_div4" }, >> + { .fw_name = "fclk_div3" }, >> + { .fw_name = "fclk_div5" }, >> + { .fw_name = "xtal", } >> +}; >> + >> +static struct clk_regmap s4_sc_clk_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_SC_CLK_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sc_clk_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_sc_parent_data, >> + .num_parents = ARRAY_SIZE(s4_sc_parent_data), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sc_clk_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_SC_CLK_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sc_clk_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sc_clk_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sc_clk_gate = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_SC_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sc_clk_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sc_clk_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_12_24M_clk_gate = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_CLK12_24_CTRL, >> + .bit_idx = 11, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "12_24m_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_data = (const struct clk_parent_data []) { >> + { .fw_name = "xtal", } >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_12M_clk_div = { >> + .mult = 1, >> + .div = 2, >> + .hw.init = &(struct clk_init_data){ >> + .name = "12M", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_12_24M_clk_gate.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_12_24M_clk = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_CLK12_24_CTRL, >> + .mask = 0x1, >> + .shift = 10, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "12_24m", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_12_24M_clk_gate.hw, >> + &s4_12M_clk_div.hw, >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* Video Clocks */ >> +static struct clk_regmap s4_vid_pll_div = { >> + .data = &(struct meson_vid_pll_div_data){ >> + .val = { >> + .reg_off = CLKCTRL_VID_PLL_CLK_DIV, >> + .shift = 0, >> + .width = 15, >> + }, >> + .sel = { >> + .reg_off = CLKCTRL_VID_PLL_CLK_DIV, >> + .shift = 16, >> + .width = 2, >> + }, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vid_pll_div", >> + /* >> + * TODO meson_vid_pll_div_ro_ops to meson_vid_pll_div_ops >> + */ >> + .ops = &meson_vid_pll_div_ro_ops, >> + .parent_data = (const struct clk_parent_data []) { >> + { .fw_name = "hdmi_pll", } >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vid_pll_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VID_PLL_CLK_DIV, >> + .mask = 0x1, >> + .shift = 18, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vid_pll_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = (const struct clk_parent_data []) { >> + { .hw = &s4_vid_pll_div.hw }, >> + { .fw_name = "hdmi_pll", } >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vid_pll = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_PLL_CLK_DIV, >> + .bit_idx = 19, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vid_pll", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vid_pll_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_parent_data s4_vclk_parent_data[] = { >> + { .hw = &s4_vid_pll.hw }, >> + { .fw_name = "gp0_pll", }, >> + { .fw_name = "hifi_pll", }, >> + { .fw_name = "mpll1", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", }, >> +}; >> + >> +static struct clk_regmap s4_vclk_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 16, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vclk_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vclk_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VIID_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 16, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk2_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vclk_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vclk_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk_input = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_DIV, >> + .bit_idx = 16, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk_input", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk_sel.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2_input = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VIID_CLK_DIV, >> + .bit_idx = 16, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk2_input", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2_sel.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VID_CLK_DIV, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk_input.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VIID_CLK_DIV, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk2_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk2_input.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL, >> + .bit_idx = 19, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk_div.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VIID_CLK_CTRL, >> + .bit_idx = 19, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk2", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2_div.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk_div1 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL, >> + .bit_idx = 0, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk_div1", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk_div2_en = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL, >> + .bit_idx = 1, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk_div2_en", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk_div4_en = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL, >> + .bit_idx = 2, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk_div4_en", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk_div6_en = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL, >> + .bit_idx = 3, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk_div6_en", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk_div12_en = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL, >> + .bit_idx = 4, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk_div12_en", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2_div1 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VIID_CLK_CTRL, >> + .bit_idx = 0, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk2_div1", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2_div2_en = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VIID_CLK_CTRL, >> + .bit_idx = 1, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk2_div2_en", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2_div4_en = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VIID_CLK_CTRL, >> + .bit_idx = 2, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk2_div4_en", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2_div6_en = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VIID_CLK_CTRL, >> + .bit_idx = 3, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk2_div6_en", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vclk2_div12_en = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VIID_CLK_CTRL, >> + .bit_idx = 4, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vclk2_div12_en", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_vclk_div2 = { >> + .mult = 1, >> + .div = 2, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk_div2", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk_div2_en.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_vclk_div4 = { >> + .mult = 1, >> + .div = 4, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk_div4", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk_div4_en.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_vclk_div6 = { >> + .mult = 1, >> + .div = 6, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk_div6", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk_div6_en.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_vclk_div12 = { >> + .mult = 1, >> + .div = 12, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk_div12", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk_div12_en.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_vclk2_div2 = { >> + .mult = 1, >> + .div = 2, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk2_div2", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk2_div2_en.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_vclk2_div4 = { >> + .mult = 1, >> + .div = 4, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk2_div4", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk2_div4_en.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_vclk2_div6 = { >> + .mult = 1, >> + .div = 6, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk2_div6", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk2_div6_en.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_fixed_factor s4_vclk2_div12 = { >> + .mult = 1, >> + .div = 12, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vclk2_div12", >> + .ops = &clk_fixed_factor_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vclk2_div12_en.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* The 5,6,7 indexes corresponds to no real clock, so there are not used. */ >> +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; >> +static const struct clk_hw *s4_cts_parent_hws[] = { >> + &s4_vclk_div1.hw, >> + &s4_vclk_div2.hw, >> + &s4_vclk_div4.hw, >> + &s4_vclk_div6.hw, >> + &s4_vclk_div12.hw, >> + &s4_vclk2_div1.hw, >> + &s4_vclk2_div2.hw, >> + &s4_vclk2_div4.hw, >> + &s4_vclk2_div6.hw, >> + &s4_vclk2_div12.hw >> +}; >> + >> +static struct clk_regmap s4_cts_enci_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VID_CLK_DIV, >> + .mask = 0xf, >> + .shift = 28, >> + .table = mux_table_cts_sel, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "cts_enci_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = s4_cts_parent_hws, >> + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cts_encp_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VID_CLK_DIV, >> + .mask = 0xf, >> + .shift = 20, >> + .table = mux_table_cts_sel, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "cts_encp_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = s4_cts_parent_hws, >> + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cts_vdac_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VIID_CLK_DIV, >> + .mask = 0xf, >> + .shift = 28, >> + .table = mux_table_cts_sel, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "cts_vdac_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = s4_cts_parent_hws, >> + .num_parents = ARRAY_SIZE(s4_cts_parent_hws), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* The 5,6,7 indexes corresponds to no real clock, so there are not used. */ >> +static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; >> +static const struct clk_hw *s4_cts_hdmi_tx_parent_hws[] = { >> + &s4_vclk_div1.hw, >> + &s4_vclk_div2.hw, >> + &s4_vclk_div4.hw, >> + &s4_vclk_div6.hw, >> + &s4_vclk_div12.hw, >> + &s4_vclk2_div1.hw, >> + &s4_vclk2_div2.hw, >> + &s4_vclk2_div4.hw, >> + &s4_vclk2_div6.hw, >> + &s4_vclk2_div12.hw >> +}; >> + >> +static struct clk_regmap s4_hdmi_tx_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_HDMI_CLK_CTRL, >> + .mask = 0xf, >> + .shift = 16, >> + .table = mux_table_hdmi_tx_sel, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "hdmi_tx_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = s4_cts_hdmi_tx_parent_hws, >> + .num_parents = ARRAY_SIZE(s4_cts_hdmi_tx_parent_hws), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cts_enci = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL2, >> + .bit_idx = 0, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "cts_enci", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_cts_enci_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cts_encp = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL2, >> + .bit_idx = 2, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "cts_encp", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_cts_encp_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_cts_vdac = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL2, >> + .bit_idx = 4, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "cts_vdac", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_cts_vdac_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hdmi_tx = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VID_CLK_CTRL2, >> + .bit_idx = 5, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hdmi_tx", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hdmi_tx_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* HDMI Clocks */ >> +static const struct clk_parent_data s4_hdmi_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div5", } >> +}; >> + >> +static struct clk_regmap s4_hdmi_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_HDMI_CLK_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "hdmi_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_hdmi_parent_data, >> + .num_parents = ARRAY_SIZE(s4_hdmi_parent_data), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hdmi_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_HDMI_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "hdmi_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_hdmi_sel.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hdmi = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_HDMI_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hdmi", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_hdmi_div.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_ts_clk_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_TS_CLK_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "ts_clk_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_data = &(const struct clk_parent_data) { >> + .fw_name = "xtal", >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_ts_clk_gate = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_TS_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "ts_clk", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_ts_clk_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* >> + * The MALI IP is clocked by two identical clocks (mali_0 and mali_1) >> + * muxed by a glitch-free switch. The CCF can manage this glitch-free >> + * mux because it does top-to-bottom updates the each clock tree and >> + * switches to the "inactive" one when CLK_SET_RATE_GATE is set. >> + */ >> +static const struct clk_parent_data s4_mali_0_1_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .fw_name = "gp0_pll", }, >> + { .fw_name = "hifi_pll", }, >> + { .fw_name = "fclk_div2p5", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", } >> +}; >> + >> +static struct clk_regmap s4_mali_0_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_MALI_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "mali_0_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_mali_0_1_parent_data, >> + .num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data), >> + /* >> + * Don't request the parent to change the rate because >> + * all GPU frequencies can be derived from the fclk_* >> + * clocks and one special GP0_PLL setting. This is >> + * important because we need the MPLL clocks for audio. > > The last part of this comment does not make a lot of sense to me. > MPLLs are not among the possible parent of this clock, did you mean HiFi ? Sorry. It's HIFI PLL, and you're right. Do you suggest that I delete it or change it to HIFI PLL? I will change it in the next edition as you suggested > >> + */ >> + .flags = 0, >> + }, >> +}; >> + >> +static struct clk_regmap s4_mali_0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_MALI_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "mali_0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_mali_0_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_mali_0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_MALI_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "mali_0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_mali_0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_mali_1_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_MALI_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "mali_1_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_mali_0_1_parent_data, >> + .num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data), >> + .flags = 0, >> + }, >> +}; >> + >> +static struct clk_regmap s4_mali_1_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_MALI_CLK_CTRL, >> + .shift = 16, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "mali_1_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_mali_1_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_mali_1 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_MALI_CLK_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "mali_1", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_mali_1_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_hw *s4_mali_parent_hws[] = { >> + &s4_mali_0.hw, >> + &s4_mali_1.hw >> +}; >> + >> +static struct clk_regmap s4_mali_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_MALI_CLK_CTRL, >> + .mask = 1, >> + .shift = 31, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "mali", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = s4_mali_parent_hws, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* VDEC clocks */ >> +static const struct clk_parent_data s4_dec_parent_data[] = { >> + { .fw_name = "fclk_div2p5", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", }, >> + { .fw_name = "hifi_pll", }, >> + { .fw_name = "gp0_pll", }, >> + { .fw_name = "xtal", } >> +}; >> + >> +static struct clk_regmap s4_vdec_p0_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VDEC_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vdec_p0_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_dec_parent_data, >> + .num_parents = ARRAY_SIZE(s4_dec_parent_data), > > Nitpick: .flags = 0; to clearly show that you stopping rate propagation > here too (like you did on s4_mali_0_sel - no need to copy the comment though) I will change it in the next edition as you suggested. > >> + }, >> +}; >> + >> +static struct clk_regmap s4_vdec_p0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VDEC_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + .flags = CLK_DIVIDER_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vdec_p0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vdec_p0_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vdec_p0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VDEC_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vdec_p0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vdec_p0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vdec_p1_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VDEC3_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vdec_p1_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_dec_parent_data, >> + .num_parents = ARRAY_SIZE(s4_dec_parent_data), > > Same here and also where applicable in the rest of the driver. OKay. > >> + }, >> +}; >> + >> +static struct clk_regmap s4_vdec_p1_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VDEC3_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + .flags = CLK_DIVIDER_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vdec_p1_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vdec_p1_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vdec_p1 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VDEC3_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vdec_p1", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vdec_p1_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_hw *s4_vdec_mux_parent_hws[] = { >> + &s4_vdec_p0.hw, >> + &s4_vdec_p1.hw >> +}; >> + >> +static struct clk_regmap s4_vdec_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VDEC3_CLK_CTRL, >> + .mask = 0x1, >> + .shift = 15, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vdec_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = s4_vdec_mux_parent_hws, >> + .num_parents = ARRAY_SIZE(s4_vdec_mux_parent_hws), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hevcf_p0_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VDEC2_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hevcf_p0_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_dec_parent_data, >> + .num_parents = ARRAY_SIZE(s4_dec_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_hevcf_p0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VDEC2_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + .flags = CLK_DIVIDER_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hevcf_p0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hevcf_p0_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hevcf_p0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VDEC2_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "hevcf_p0_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hevcf_p0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hevcf_p1_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VDEC4_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + .flags = CLK_MUX_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hevcf_p1_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_dec_parent_data, >> + .num_parents = ARRAY_SIZE(s4_dec_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_hevcf_p1_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VDEC4_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + .flags = CLK_DIVIDER_ROUND_CLOSEST, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hevcf_p1_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hevcf_p1_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hevcf_p1 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VDEC4_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "hevcf_p1", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hevcf_p1_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_hw *s4_hevcf_mux_parent_hws[] = { >> + &s4_hevcf_p0.hw, >> + &s4_hevcf_p1.hw >> +}; >> + >> +static struct clk_regmap s4_hevcf_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VDEC4_CLK_CTRL, >> + .mask = 0x1, >> + .shift = 15, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hevcf", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = s4_hevcf_mux_parent_hws, >> + .num_parents = ARRAY_SIZE(s4_hevcf_mux_parent_hws), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* VPU Clock */ >> +static const struct clk_parent_data s4_vpu_parent_data[] = { >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", }, >> + { .fw_name = "mpll1", }, >> + { .hw = &s4_vid_pll.hw }, >> + { .fw_name = "hifi_pll", }, >> + { .fw_name = "gp0_pll", }, >> +}; >> + >> +static struct clk_regmap s4_vpu_0_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VPU_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu_0_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vpu_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vpu_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VPU_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu_0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_sel.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VPU_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_div.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_1_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VPU_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu_1_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vpu_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vpu_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_1_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VPU_CLK_CTRL, >> + .shift = 16, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu_1_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_sel.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_1 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VPU_CLK_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_1", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_div.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VPU_CLK_CTRL, >> + .mask = 1, >> + .shift = 31, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_0.hw, >> + &s4_vpu_1.hw, >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_parent_data vpu_clkb_tmp_parent_data[] = { >> + { .hw = &s4_vpu.hw }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", } >> +}; >> + >> +static struct clk_regmap s4_vpu_clkb_tmp_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VPU_CLKB_CTRL, >> + .mask = 0x3, >> + .shift = 20, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_clkb_tmp_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = vpu_clkb_tmp_parent_data, >> + .num_parents = ARRAY_SIZE(vpu_clkb_tmp_parent_data), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkb_tmp_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VPU_CLKB_CTRL, >> + .shift = 16, >> + .width = 4, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_clkb_tmp_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_clkb_tmp_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkb_tmp = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VPU_CLKB_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu_clkb_tmp", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_clkb_tmp_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkb_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VPU_CLKB_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_clkb_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_clkb_tmp.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkb = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VPU_CLKB_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu_clkb", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_clkb_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_parent_data s4_vpu_clkc_parent_data[] = { >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", }, >> + { .fw_name = "mpll1", }, >> + { .hw = &s4_vid_pll.hw }, >> + { .fw_name = "mpll2", }, >> + { .fw_name = "gp0_pll", }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkc_p0_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VPU_CLKC_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_clkc_p0_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vpu_clkc_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkc_p0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VPU_CLKC_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_clkc_p0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_clkc_p0_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkc_p0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VPU_CLKC_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu_clkc_p0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_clkc_p0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkc_p1_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VPU_CLKC_CTRL, >> + .mask = 0x7, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_clkc_p1_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vpu_clkc_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkc_p1_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VPU_CLKC_CTRL, >> + .shift = 16, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_clkc_p1_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_clkc_p1_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vpu_clkc_p1 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VPU_CLKC_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vpu_clkc_p1", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vpu_clkc_p1_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_hw *s4_vpu_mux_parent_hws[] = { >> + &s4_vpu_clkc_p0.hw, >> + &s4_vpu_clkc_p1.hw >> +}; >> + >> +static struct clk_regmap s4_vpu_clkc_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VPU_CLKC_CTRL, >> + .mask = 0x1, >> + .shift = 31, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vpu_clkc_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = s4_vpu_mux_parent_hws, >> + .num_parents = ARRAY_SIZE(s4_vpu_mux_parent_hws), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* VAPB Clock */ >> +static const struct clk_parent_data s4_vapb_parent_data[] = { >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", }, >> + { .fw_name = "mpll1", }, >> + { .hw = &s4_vid_pll.hw }, >> + { .fw_name = "mpll2", }, >> + { .fw_name = "fclk_div2p5", }, >> +}; >> + >> +static struct clk_regmap s4_vapb_0_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VAPBCLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vapb_0_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vapb_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vapb_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_vapb_0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VAPBCLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vapb_0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vapb_0_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vapb_0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VAPBCLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vapb_0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vapb_0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vapb_1_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VAPBCLK_CTRL, >> + .mask = 0x7, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vapb_1_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vapb_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vapb_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_vapb_1_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VAPBCLK_CTRL, >> + .shift = 16, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vapb_1_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vapb_1_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vapb_1 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VAPBCLK_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vapb_1", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vapb_1_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vapb = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VAPBCLK_CTRL, >> + .mask = 1, >> + .shift = 31, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vapb_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vapb_0.hw, >> + &s4_vapb_1.hw >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_ge2d_gate = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VAPBCLK_CTRL, >> + .bit_idx = 30, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "ge2d_clk", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { &s4_vapb.hw }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_parent_data s4_esmclk_parent_data[] = { >> + { .fw_name = "fclk_div7", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div5", }, >> +}; >> + >> +static struct clk_regmap s4_hdcp22_esmclk_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_HDCP22_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hdcp22_esmclk_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_esmclk_parent_data, >> + .num_parents = ARRAY_SIZE(s4_esmclk_parent_data), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hdcp22_esmclk_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_HDCP22_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hdcp22_esmclk_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hdcp22_esmclk_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hdcp22_esmclk_gate = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_HDCP22_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "hdcp22_esmclk_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hdcp22_esmclk_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_parent_data s4_skpclk_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div5", }, >> +}; >> + >> +static struct clk_regmap s4_hdcp22_skpclk_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_HDCP22_CTRL, >> + .mask = 0x3, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hdcp22_skpclk_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_skpclk_parent_data, >> + .num_parents = ARRAY_SIZE(s4_skpclk_parent_data), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hdcp22_skpclk_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_HDCP22_CTRL, >> + .shift = 16, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "hdcp22_skpclk_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hdcp22_skpclk_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_hdcp22_skpclk_gate = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_HDCP22_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "hdcp22_skpclk_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_hdcp22_skpclk_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_parent_data s4_vdin_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div5", }, >> + { .hw = &s4_vid_pll.hw } >> +}; >> + >> +static struct clk_regmap s4_vdin_meas_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vdin_meas_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_vdin_parent_data, >> + .num_parents = ARRAY_SIZE(s4_vdin_parent_data), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vdin_meas_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "vdin_meas_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vdin_meas_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_vdin_meas_gate = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "vdin_meas_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_vdin_meas_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* EMMC/NAND clock */ >> +static const struct clk_parent_data s4_sd_emmc_clk0_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .fw_name = "fclk_div2", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "hifi_pll", }, >> + { .fw_name = "fclk_div2p5", }, >> + { .fw_name = "mpll2", }, >> + { .fw_name = "mpll3", }, >> + { .fw_name = "gp0_pll", }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_c_clk0_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_NAND_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sd_emmc_c_clk0_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_sd_emmc_clk0_parent_data, >> + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_c_clk0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_NAND_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sd_emmc_c_clk0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sd_emmc_c_clk0_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_c_clk0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_NAND_CLK_CTRL, >> + .bit_idx = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sd_emmc_c_clk0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sd_emmc_c_clk0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_a_clk0_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sd_emmc_a_clk0_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_sd_emmc_clk0_parent_data, >> + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_a_clk0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sd_emmc_a_clk0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sd_emmc_a_clk0_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_a_clk0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, >> + .bit_idx = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sd_emmc_a_clk0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sd_emmc_a_clk0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_b_clk0_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sd_emmc_b_clk0_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_sd_emmc_clk0_parent_data, >> + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_b_clk0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, >> + .shift = 16, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "sd_emmc_b_clk0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sd_emmc_b_clk0_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_sd_emmc_b_clk0 = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_SD_EMMC_CLK_CTRL, >> + .bit_idx = 23, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "sd_emmc_b_clk0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_sd_emmc_b_clk0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* SPICC Clock */ >> +static const struct clk_parent_data s4_spicc_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .hw = &s4_sys_clk.hw }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div2", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", }, >> +}; >> + >> +static struct clk_regmap s4_spicc0_mux = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_SPICC_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 7, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "spicc0_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_spicc_parent_data, >> + .num_parents = ARRAY_SIZE(s4_spicc_parent_data), >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_spicc0_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_SPICC_CLK_CTRL, >> + .shift = 0, >> + .width = 6, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "spicc0_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_spicc0_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_spicc0_gate = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_SPICC_CLK_CTRL, >> + .bit_idx = 6, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "spicc0", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_spicc0_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* PWM Clock */ >> +static const struct clk_parent_data s4_pwm_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .hw = &s4_vid_pll.hw }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> +}; >> + >> +static struct clk_regmap s4_pwm_a_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_AB_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_a_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_a_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_AB_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_a_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_a_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_a_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_AB_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_a_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_a_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_b_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_AB_CTRL, >> + .mask = 0x3, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_b_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_b_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_AB_CTRL, >> + .shift = 16, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_b_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_b_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_b_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_AB_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_b_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_b_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_c_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_CD_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_c_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_c_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_CD_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_c_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_c_mux.hw >> + }, >> + .num_parents = 1, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_c_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_CD_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_c_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_c_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_d_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_CD_CTRL, >> + .mask = 0x3, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_d_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_d_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_CD_CTRL, >> + .shift = 16, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_d_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_d_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_d_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_CD_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_d_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_d_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_e_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_EF_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_e_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_e_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_EF_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_e_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_e_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_e_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_EF_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_e_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_e_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_f_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_EF_CTRL, >> + .mask = 0x3, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_f_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_f_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_EF_CTRL, >> + .shift = 16, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_f_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_f_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_f_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_EF_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_f_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_f_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_g_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_GH_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_g_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_g_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_GH_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_g_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_g_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_g_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_GH_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_g_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_g_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_h_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_GH_CTRL, >> + .mask = 0x3, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_h_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_h_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_GH_CTRL, >> + .shift = 16, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_h_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_h_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_h_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_GH_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_h_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_h_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_i_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_i_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_i_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_i_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_i_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_i_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_i_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_i_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_j_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, >> + .mask = 0x3, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_j_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_pwm_parent_data, >> + .num_parents = ARRAY_SIZE(s4_pwm_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_j_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, >> + .shift = 16, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_j_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_h_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_pwm_j_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_PWM_CLK_IJ_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "pwm_j_gate", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_pwm_j_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_saradc_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_SAR_CLK_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "saradc_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = (const struct clk_parent_data []) { >> + { .fw_name = "xtal", }, >> + { .hw = &s4_sys_clk.hw }, >> + }, >> + .num_parents = 2, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_saradc_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_SAR_CLK_CTRL, >> + .shift = 0, >> + .width = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "saradc_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_saradc_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_saradc_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_SAR_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "saradc_clk", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_saradc_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +/* >> + * gen clk is designed for debug/monitor some internal clock quality. Some of the >> + * corresponding clock sources are not described in the clock tree and internal clock >> + * for debug, so they are skipped. >> + */ >> +static u32 s4_gen_clk_mux_table[] = { 0, 4, 5, 7, 19, 21, 22, >> + 23, 24, 25, 26, 27, 28 }; >> +static const struct clk_parent_data s4_gen_clk_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .hw = &s4_vid_pll.hw }, >> + { .fw_name = "gp0_pll", }, >> + { .fw_name = "hifi_pll", }, >> + { .fw_name = "fclk_div2", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", }, >> + { .fw_name = "mpll0", }, >> + { .fw_name = "mpll1", }, >> + { .fw_name = "mpll2", }, >> + { .fw_name = "mpll3", }, >> +}; >> + >> +static struct clk_regmap s4_gen_clk_sel = { >> + .data = &(struct clk_regmap_mux_data){ >> + .offset = CLKCTRL_GEN_CLK_CTRL, >> + .mask = 0x1f, >> + .shift = 12, >> + .table = s4_gen_clk_mux_table, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "gen_clk_sel", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_gen_clk_parent_data, >> + .num_parents = ARRAY_SIZE(s4_gen_clk_parent_data), >> + /* >> + * Because the GEN clock can be connected to an external pad >> + * and may be set up directly from the device tree. Don't >> + * really want to automatically reparent. >> + */ >> + .flags = CLK_SET_RATE_NO_REPARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_gen_clk_div = { >> + .data = &(struct clk_regmap_div_data){ >> + .offset = CLKCTRL_GEN_CLK_CTRL, >> + .shift = 0, >> + .width = 11, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "gen_clk_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_gen_clk_sel.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_gen_clk = { >> + .data = &(struct clk_regmap_gate_data){ >> + .offset = CLKCTRL_GEN_CLK_CTRL, >> + .bit_idx = 11, >> + }, >> + .hw.init = &(struct clk_init_data) { >> + .name = "gen_clk", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_gen_clk_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static const struct clk_parent_data s4_adc_extclk_in_parent_data[] = { >> + { .fw_name = "xtal", }, >> + { .fw_name = "fclk_div4", }, >> + { .fw_name = "fclk_div3", }, >> + { .fw_name = "fclk_div5", }, >> + { .fw_name = "fclk_div7", }, >> + { .fw_name = "mpll2", }, >> + { .fw_name = "gp0_pll", }, >> + { .fw_name = "hifi_pll", }, >> +}; >> + >> +static struct clk_regmap s4_adc_extclk_in_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_DEMOD_CLK_CTRL, >> + .mask = 0x7, >> + .shift = 25, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "adc_extclk_in_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = s4_adc_extclk_in_parent_data, >> + .num_parents = ARRAY_SIZE(s4_adc_extclk_in_parent_data), >> + }, >> +}; >> + >> +static struct clk_regmap s4_adc_extclk_in_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_DEMOD_CLK_CTRL, >> + .shift = 16, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "adc_extclk_in_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_adc_extclk_in_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_adc_extclk_in_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_DEMOD_CLK_CTRL, >> + .bit_idx = 24, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "adc_extclk_in", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_adc_extclk_in_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_demod_core_clk_mux = { >> + .data = &(struct clk_regmap_mux_data) { >> + .offset = CLKCTRL_DEMOD_CLK_CTRL, >> + .mask = 0x3, >> + .shift = 9, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "demod_core_clk_mux", >> + .ops = &clk_regmap_mux_ops, >> + .parent_data = (const struct clk_parent_data []) { >> + { .fw_name = "xtal", }, >> + { .fw_name = "fclk_div7", }, >> + { .fw_name = "fclk_div4", }, >> + { .hw = &s4_adc_extclk_in_gate.hw } >> + }, >> + .num_parents = 4, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_demod_core_clk_div = { >> + .data = &(struct clk_regmap_div_data) { >> + .offset = CLKCTRL_DEMOD_CLK_CTRL, >> + .shift = 0, >> + .width = 7, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "demod_core_clk_div", >> + .ops = &clk_regmap_divider_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_demod_core_clk_mux.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +static struct clk_regmap s4_demod_core_clk_gate = { >> + .data = &(struct clk_regmap_gate_data) { >> + .offset = CLKCTRL_DEMOD_CLK_CTRL, >> + .bit_idx = 8, >> + }, >> + .hw.init = &(struct clk_init_data){ >> + .name = "demod_core_clk", >> + .ops = &clk_regmap_gate_ops, >> + .parent_hws = (const struct clk_hw *[]) { >> + &s4_demod_core_clk_div.hw >> + }, >> + .num_parents = 1, >> + .flags = CLK_SET_RATE_PARENT, >> + }, >> +}; >> + >> +#define MESON_GATE(_name, _reg, _bit) \ >> + MESON_PCLK(_name, _reg, _bit, &s4_sys_clk.hw) >> + >> +static MESON_GATE(s4_ddr, CLKCTRL_SYS_CLK_EN0_REG0, 0); >> +static MESON_GATE(s4_dos, CLKCTRL_SYS_CLK_EN0_REG0, 1); >> +static MESON_GATE(s4_ethphy, CLKCTRL_SYS_CLK_EN0_REG0, 4); >> +static MESON_GATE(s4_mali, CLKCTRL_SYS_CLK_EN0_REG0, 6); >> +static MESON_GATE(s4_aocpu, CLKCTRL_SYS_CLK_EN0_REG0, 13); >> +static MESON_GATE(s4_aucpu, CLKCTRL_SYS_CLK_EN0_REG0, 14); >> +static MESON_GATE(s4_cec, CLKCTRL_SYS_CLK_EN0_REG0, 16); >> +static MESON_GATE(s4_sdemmca, CLKCTRL_SYS_CLK_EN0_REG0, 24); >> +static MESON_GATE(s4_sdemmcb, CLKCTRL_SYS_CLK_EN0_REG0, 25); >> +static MESON_GATE(s4_nand, CLKCTRL_SYS_CLK_EN0_REG0, 26); >> +static MESON_GATE(s4_smartcard, CLKCTRL_SYS_CLK_EN0_REG0, 27); >> +static MESON_GATE(s4_acodec, CLKCTRL_SYS_CLK_EN0_REG0, 28); >> +static MESON_GATE(s4_spifc, CLKCTRL_SYS_CLK_EN0_REG0, 29); >> +static MESON_GATE(s4_msr_clk, CLKCTRL_SYS_CLK_EN0_REG0, 30); >> +static MESON_GATE(s4_ir_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 31); >> +static MESON_GATE(s4_audio, CLKCTRL_SYS_CLK_EN0_REG1, 0); >> +static MESON_GATE(s4_eth, CLKCTRL_SYS_CLK_EN0_REG1, 3); >> +static MESON_GATE(s4_uart_a, CLKCTRL_SYS_CLK_EN0_REG1, 5); >> +static MESON_GATE(s4_uart_b, CLKCTRL_SYS_CLK_EN0_REG1, 6); >> +static MESON_GATE(s4_uart_c, CLKCTRL_SYS_CLK_EN0_REG1, 7); >> +static MESON_GATE(s4_uart_d, CLKCTRL_SYS_CLK_EN0_REG1, 8); >> +static MESON_GATE(s4_uart_e, CLKCTRL_SYS_CLK_EN0_REG1, 9); >> +static MESON_GATE(s4_aififo, CLKCTRL_SYS_CLK_EN0_REG1, 11); >> +static MESON_GATE(s4_ts_ddr, CLKCTRL_SYS_CLK_EN0_REG1, 15); >> +static MESON_GATE(s4_ts_pll, CLKCTRL_SYS_CLK_EN0_REG1, 16); >> +static MESON_GATE(s4_g2d, CLKCTRL_SYS_CLK_EN0_REG1, 20); >> +static MESON_GATE(s4_spicc0, CLKCTRL_SYS_CLK_EN0_REG1, 21); >> +static MESON_GATE(s4_usb, CLKCTRL_SYS_CLK_EN0_REG1, 26); >> +static MESON_GATE(s4_i2c_m_a, CLKCTRL_SYS_CLK_EN0_REG1, 30); >> +static MESON_GATE(s4_i2c_m_b, CLKCTRL_SYS_CLK_EN0_REG1, 31); >> +static MESON_GATE(s4_i2c_m_c, CLKCTRL_SYS_CLK_EN0_REG2, 0); >> +static MESON_GATE(s4_i2c_m_d, CLKCTRL_SYS_CLK_EN0_REG2, 1); >> +static MESON_GATE(s4_i2c_m_e, CLKCTRL_SYS_CLK_EN0_REG2, 2); >> +static MESON_GATE(s4_hdmitx_apb, CLKCTRL_SYS_CLK_EN0_REG2, 4); >> +static MESON_GATE(s4_i2c_s_a, CLKCTRL_SYS_CLK_EN0_REG2, 5); >> +static MESON_GATE(s4_usb1_to_ddr, CLKCTRL_SYS_CLK_EN0_REG2, 8); >> +static MESON_GATE(s4_hdcp22, CLKCTRL_SYS_CLK_EN0_REG2, 10); >> +static MESON_GATE(s4_mmc_apb, CLKCTRL_SYS_CLK_EN0_REG2, 11); >> +static MESON_GATE(s4_rsa, CLKCTRL_SYS_CLK_EN0_REG2, 18); >> +static MESON_GATE(s4_cpu_debug, CLKCTRL_SYS_CLK_EN0_REG2, 19); >> +static MESON_GATE(s4_vpu_intr, CLKCTRL_SYS_CLK_EN0_REG2, 25); >> +static MESON_GATE(s4_demod, CLKCTRL_SYS_CLK_EN0_REG2, 27); >> +static MESON_GATE(s4_sar_adc, CLKCTRL_SYS_CLK_EN0_REG2, 28); >> +static MESON_GATE(s4_gic, CLKCTRL_SYS_CLK_EN0_REG2, 30); >> +static MESON_GATE(s4_pwm_ab, CLKCTRL_SYS_CLK_EN0_REG3, 7); >> +static MESON_GATE(s4_pwm_cd, CLKCTRL_SYS_CLK_EN0_REG3, 8); >> +static MESON_GATE(s4_pwm_ef, CLKCTRL_SYS_CLK_EN0_REG3, 9); >> +static MESON_GATE(s4_pwm_gh, CLKCTRL_SYS_CLK_EN0_REG3, 10); >> +static MESON_GATE(s4_pwm_ij, CLKCTRL_SYS_CLK_EN0_REG3, 11); >> + >> +/* Array of all clocks provided by this provider */ >> +static struct clk_hw *s4_periphs_hw_clks[] = { >> + [CLKID_RTC_32K_CLKIN] = &s4_rtc_32k_by_oscin_clkin.hw, >> + [CLKID_RTC_32K_DIV] = &s4_rtc_32k_by_oscin_div.hw, >> + [CLKID_RTC_32K_SEL] = &s4_rtc_32k_by_oscin_sel.hw, >> + [CLKID_RTC_32K_XATL] = &s4_rtc_32k_by_oscin.hw, >> + [CLKID_RTC] = &s4_rtc_clk.hw, >> + [CLKID_SYS_CLK_B_SEL] = &s4_sysclk_b_sel.hw, >> + [CLKID_SYS_CLK_B_DIV] = &s4_sysclk_b_div.hw, >> + [CLKID_SYS_CLK_B] = &s4_sysclk_b.hw, >> + [CLKID_SYS_CLK_A_SEL] = &s4_sysclk_a_sel.hw, >> + [CLKID_SYS_CLK_A_DIV] = &s4_sysclk_a_div.hw, >> + [CLKID_SYS_CLK_A] = &s4_sysclk_a.hw, >> + [CLKID_SYS] = &s4_sys_clk.hw, >> + [CLKID_CECA_32K_CLKIN] = &s4_ceca_32k_clkin.hw, >> + [CLKID_CECA_32K_DIV] = &s4_ceca_32k_div.hw, >> + [CLKID_CECA_32K_SEL_PRE] = &s4_ceca_32k_sel_pre.hw, >> + [CLKID_CECA_32K_SEL] = &s4_ceca_32k_sel.hw, >> + [CLKID_CECA_32K_CLKOUT] = &s4_ceca_32k_clkout.hw, >> + [CLKID_CECB_32K_CLKIN] = &s4_cecb_32k_clkin.hw, >> + [CLKID_CECB_32K_DIV] = &s4_cecb_32k_div.hw, >> + [CLKID_CECB_32K_SEL_PRE] = &s4_cecb_32k_sel_pre.hw, >> + [CLKID_CECB_32K_SEL] = &s4_cecb_32k_sel.hw, >> + [CLKID_CECB_32K_CLKOUT] = &s4_cecb_32k_clkout.hw, >> + [CLKID_SC_CLK_SEL] = &s4_sc_clk_mux.hw, >> + [CLKID_SC_CLK_DIV] = &s4_sc_clk_div.hw, >> + [CLKID_SC] = &s4_sc_clk_gate.hw, >> + [CLKID_12_24M] = &s4_12_24M_clk_gate.hw, >> + [CLKID_12M_CLK_DIV] = &s4_12M_clk_div.hw, >> + [CLKID_12_24M_CLK_SEL] = &s4_12_24M_clk.hw, >> + [CLKID_VID_PLL_DIV] = &s4_vid_pll_div.hw, >> + [CLKID_VID_PLL_SEL] = &s4_vid_pll_sel.hw, >> + [CLKID_VID_PLL] = &s4_vid_pll.hw, >> + [CLKID_VCLK_SEL] = &s4_vclk_sel.hw, >> + [CLKID_VCLK2_SEL] = &s4_vclk2_sel.hw, >> + [CLKID_VCLK_INPUT] = &s4_vclk_input.hw, >> + [CLKID_VCLK2_INPUT] = &s4_vclk2_input.hw, >> + [CLKID_VCLK_DIV] = &s4_vclk_div.hw, >> + [CLKID_VCLK2_DIV] = &s4_vclk2_div.hw, >> + [CLKID_VCLK] = &s4_vclk.hw, >> + [CLKID_VCLK2] = &s4_vclk2.hw, >> + [CLKID_VCLK_DIV1] = &s4_vclk_div1.hw, >> + [CLKID_VCLK_DIV2_EN] = &s4_vclk_div2_en.hw, >> + [CLKID_VCLK_DIV4_EN] = &s4_vclk_div4_en.hw, >> + [CLKID_VCLK_DIV6_EN] = &s4_vclk_div6_en.hw, >> + [CLKID_VCLK_DIV12_EN] = &s4_vclk_div12_en.hw, >> + [CLKID_VCLK2_DIV1] = &s4_vclk2_div1.hw, >> + [CLKID_VCLK2_DIV2_EN] = &s4_vclk2_div2_en.hw, >> + [CLKID_VCLK2_DIV4_EN] = &s4_vclk2_div4_en.hw, >> + [CLKID_VCLK2_DIV6_EN] = &s4_vclk2_div6_en.hw, >> + [CLKID_VCLK2_DIV12_EN] = &s4_vclk2_div12_en.hw, >> + [CLKID_VCLK_DIV2] = &s4_vclk_div2.hw, >> + [CLKID_VCLK_DIV4] = &s4_vclk_div4.hw, >> + [CLKID_VCLK_DIV6] = &s4_vclk_div6.hw, >> + [CLKID_VCLK_DIV12] = &s4_vclk_div12.hw, >> + [CLKID_VCLK2_DIV2] = &s4_vclk2_div2.hw, >> + [CLKID_VCLK2_DIV4] = &s4_vclk2_div4.hw, >> + [CLKID_VCLK2_DIV6] = &s4_vclk2_div6.hw, >> + [CLKID_VCLK2_DIV12] = &s4_vclk2_div12.hw, >> + [CLKID_CTS_ENCI_SEL] = &s4_cts_enci_sel.hw, >> + [CLKID_CTS_ENCP_SEL] = &s4_cts_encp_sel.hw, >> + [CLKID_CTS_VDAC_SEL] = &s4_cts_vdac_sel.hw, >> + [CLKID_HDMI_TX_SEL] = &s4_hdmi_tx_sel.hw, >> + [CLKID_CTS_ENCI] = &s4_cts_enci.hw, >> + [CLKID_CTS_ENCP] = &s4_cts_encp.hw, >> + [CLKID_CTS_VDAC] = &s4_cts_vdac.hw, >> + [CLKID_HDMI_TX] = &s4_hdmi_tx.hw, >> + [CLKID_HDMI_SEL] = &s4_hdmi_sel.hw, >> + [CLKID_HDMI_DIV] = &s4_hdmi_div.hw, >> + [CLKID_HDMI] = &s4_hdmi.hw, >> + [CLKID_TS_CLK_DIV] = &s4_ts_clk_div.hw, >> + [CLKID_TS] = &s4_ts_clk_gate.hw, >> + [CLKID_MALI_0_SEL] = &s4_mali_0_sel.hw, >> + [CLKID_MALI_0_DIV] = &s4_mali_0_div.hw, >> + [CLKID_MALI_0] = &s4_mali_0.hw, >> + [CLKID_MALI_1_SEL] = &s4_mali_1_sel.hw, >> + [CLKID_MALI_1_DIV] = &s4_mali_1_div.hw, >> + [CLKID_MALI_1] = &s4_mali_1.hw, >> + [CLKID_MALI_SEL] = &s4_mali_mux.hw, >> + [CLKID_VDEC_P0_SEL] = &s4_vdec_p0_mux.hw, >> + [CLKID_VDEC_P0_DIV] = &s4_vdec_p0_div.hw, >> + [CLKID_VDEC_P0] = &s4_vdec_p0.hw, >> + [CLKID_VDEC_P1_SEL] = &s4_vdec_p1_mux.hw, >> + [CLKID_VDEC_P1_DIV] = &s4_vdec_p1_div.hw, >> + [CLKID_VDEC_P1] = &s4_vdec_p1.hw, >> + [CLKID_VDEC_SEL] = &s4_vdec_mux.hw, >> + [CLKID_HEVCF_P0_SEL] = &s4_hevcf_p0_mux.hw, >> + [CLKID_HEVCF_P0_DIV] = &s4_hevcf_p0_div.hw, >> + [CLKID_HEVCF_P0] = &s4_hevcf_p0.hw, >> + [CLKID_HEVCF_P1_SEL] = &s4_hevcf_p1_mux.hw, >> + [CLKID_HEVCF_P1_DIV] = &s4_hevcf_p1_div.hw, >> + [CLKID_HEVCF_P1] = &s4_hevcf_p1.hw, >> + [CLKID_HEVCF_SEL] = &s4_hevcf_mux.hw, >> + [CLKID_VPU_0_SEL] = &s4_vpu_0_sel.hw, >> + [CLKID_VPU_0_DIV] = &s4_vpu_0_div.hw, >> + [CLKID_VPU_0] = &s4_vpu_0.hw, >> + [CLKID_VPU_1_SEL] = &s4_vpu_1_sel.hw, >> + [CLKID_VPU_1_DIV] = &s4_vpu_1_div.hw, >> + [CLKID_VPU_1] = &s4_vpu_1.hw, >> + [CLKID_VPU] = &s4_vpu.hw, >> + [CLKID_VPU_CLKB_TMP_SEL] = &s4_vpu_clkb_tmp_mux.hw, >> + [CLKID_VPU_CLKB_TMP_DIV] = &s4_vpu_clkb_tmp_div.hw, >> + [CLKID_VPU_CLKB_TMP] = &s4_vpu_clkb_tmp.hw, >> + [CLKID_VPU_CLKB_DIV] = &s4_vpu_clkb_div.hw, >> + [CLKID_VPU_CLKB] = &s4_vpu_clkb.hw, >> + [CLKID_VPU_CLKC_P0_SEL] = &s4_vpu_clkc_p0_mux.hw, >> + [CLKID_VPU_CLKC_P0_DIV] = &s4_vpu_clkc_p0_div.hw, >> + [CLKID_VPU_CLKC_P0] = &s4_vpu_clkc_p0.hw, >> + [CLKID_VPU_CLKC_P1_SEL] = &s4_vpu_clkc_p1_mux.hw, >> + [CLKID_VPU_CLKC_P1_DIV] = &s4_vpu_clkc_p1_div.hw, >> + [CLKID_VPU_CLKC_P1] = &s4_vpu_clkc_p1.hw, >> + [CLKID_VPU_CLKC_SEL] = &s4_vpu_clkc_mux.hw, >> + [CLKID_VAPB_0_SEL] = &s4_vapb_0_sel.hw, >> + [CLKID_VAPB_0_DIV] = &s4_vapb_0_div.hw, >> + [CLKID_VAPB_0] = &s4_vapb_0.hw, >> + [CLKID_VAPB_1_SEL] = &s4_vapb_1_sel.hw, >> + [CLKID_VAPB_1_DIV] = &s4_vapb_1_div.hw, >> + [CLKID_VAPB_1] = &s4_vapb_1.hw, >> + [CLKID_VAPB] = &s4_vapb.hw, >> + [CLKID_GE2D] = &s4_ge2d_gate.hw, >> + [CLKID_VDIN_MEAS_SEL] = &s4_vdin_meas_mux.hw, >> + [CLKID_VDIN_MEAS_DIV] = &s4_vdin_meas_div.hw, >> + [CLKID_VDIN_MEAS] = &s4_vdin_meas_gate.hw, >> + [CLKID_SD_EMMC_C_CLK_SEL] = &s4_sd_emmc_c_clk0_sel.hw, >> + [CLKID_SD_EMMC_C_CLK_DIV] = &s4_sd_emmc_c_clk0_div.hw, >> + [CLKID_SD_EMMC_C] = &s4_sd_emmc_c_clk0.hw, >> + [CLKID_SD_EMMC_A_CLK_SEL] = &s4_sd_emmc_a_clk0_sel.hw, >> + [CLKID_SD_EMMC_A_CLK_DIV] = &s4_sd_emmc_a_clk0_div.hw, >> + [CLKID_SD_EMMC_A] = &s4_sd_emmc_a_clk0.hw, >> + [CLKID_SD_EMMC_B_CLK_SEL] = &s4_sd_emmc_b_clk0_sel.hw, >> + [CLKID_SD_EMMC_B_CLK_DIV] = &s4_sd_emmc_b_clk0_div.hw, >> + [CLKID_SD_EMMC_B] = &s4_sd_emmc_b_clk0.hw, >> + [CLKID_SPICC0_SEL] = &s4_spicc0_mux.hw, >> + [CLKID_SPICC0_DIV] = &s4_spicc0_div.hw, >> + [CLKID_SPICC0_EN] = &s4_spicc0_gate.hw, >> + [CLKID_PWM_A_SEL] = &s4_pwm_a_mux.hw, >> + [CLKID_PWM_A_DIV] = &s4_pwm_a_div.hw, >> + [CLKID_PWM_A] = &s4_pwm_a_gate.hw, >> + [CLKID_PWM_B_SEL] = &s4_pwm_b_mux.hw, >> + [CLKID_PWM_B_DIV] = &s4_pwm_b_div.hw, >> + [CLKID_PWM_B] = &s4_pwm_b_gate.hw, >> + [CLKID_PWM_C_SEL] = &s4_pwm_c_mux.hw, >> + [CLKID_PWM_C_DIV] = &s4_pwm_c_div.hw, >> + [CLKID_PWM_C] = &s4_pwm_c_gate.hw, >> + [CLKID_PWM_D_SEL] = &s4_pwm_d_mux.hw, >> + [CLKID_PWM_D_DIV] = &s4_pwm_d_div.hw, >> + [CLKID_PWM_D] = &s4_pwm_d_gate.hw, >> + [CLKID_PWM_E_SEL] = &s4_pwm_e_mux.hw, >> + [CLKID_PWM_E_DIV] = &s4_pwm_e_div.hw, >> + [CLKID_PWM_E] = &s4_pwm_e_gate.hw, >> + [CLKID_PWM_F_SEL] = &s4_pwm_f_mux.hw, >> + [CLKID_PWM_F_DIV] = &s4_pwm_f_div.hw, >> + [CLKID_PWM_F] = &s4_pwm_f_gate.hw, >> + [CLKID_PWM_G_SEL] = &s4_pwm_g_mux.hw, >> + [CLKID_PWM_G_DIV] = &s4_pwm_g_div.hw, >> + [CLKID_PWM_G] = &s4_pwm_g_gate.hw, >> + [CLKID_PWM_H_SEL] = &s4_pwm_h_mux.hw, >> + [CLKID_PWM_H_DIV] = &s4_pwm_h_div.hw, >> + [CLKID_PWM_H] = &s4_pwm_h_gate.hw, >> + [CLKID_PWM_I_SEL] = &s4_pwm_i_mux.hw, >> + [CLKID_PWM_I_DIV] = &s4_pwm_i_div.hw, >> + [CLKID_PWM_I] = &s4_pwm_i_gate.hw, >> + [CLKID_PWM_J_SEL] = &s4_pwm_j_mux.hw, >> + [CLKID_PWM_J_DIV] = &s4_pwm_j_div.hw, >> + [CLKID_PWM_J] = &s4_pwm_j_gate.hw, >> + [CLKID_SARADC_SEL] = &s4_saradc_mux.hw, >> + [CLKID_SARADC_DIV] = &s4_saradc_div.hw, >> + [CLKID_SARADC] = &s4_saradc_gate.hw, >> + [CLKID_GEN_SEL] = &s4_gen_clk_sel.hw, >> + [CLKID_GEN_DIV] = &s4_gen_clk_div.hw, >> + [CLKID_GEN] = &s4_gen_clk.hw, >> + [CLKID_DDR] = &s4_ddr.hw, >> + [CLKID_DOS] = &s4_dos.hw, >> + [CLKID_ETHPHY] = &s4_ethphy.hw, >> + [CLKID_MALI] = &s4_mali.hw, >> + [CLKID_AOCPU] = &s4_aocpu.hw, >> + [CLKID_AUCPU] = &s4_aucpu.hw, >> + [CLKID_CEC] = &s4_cec.hw, >> + [CLKID_SDEMMC_A] = &s4_sdemmca.hw, >> + [CLKID_SDEMMC_B] = &s4_sdemmcb.hw, >> + [CLKID_NAND] = &s4_nand.hw, >> + [CLKID_SMARTCARD] = &s4_smartcard.hw, >> + [CLKID_ACODEC] = &s4_acodec.hw, >> + [CLKID_SPIFC] = &s4_spifc.hw, >> + [CLKID_MSR] = &s4_msr_clk.hw, >> + [CLKID_IR_CTRL] = &s4_ir_ctrl.hw, >> + [CLKID_AUDIO] = &s4_audio.hw, >> + [CLKID_ETH] = &s4_eth.hw, >> + [CLKID_UART_A] = &s4_uart_a.hw, >> + [CLKID_UART_B] = &s4_uart_b.hw, >> + [CLKID_UART_C] = &s4_uart_c.hw, >> + [CLKID_UART_D] = &s4_uart_d.hw, >> + [CLKID_UART_E] = &s4_uart_e.hw, >> + [CLKID_AIFIFO] = &s4_aififo.hw, >> + [CLKID_TS_DDR] = &s4_ts_ddr.hw, >> + [CLKID_TS_PLL] = &s4_ts_pll.hw, >> + [CLKID_G2D] = &s4_g2d.hw, >> + [CLKID_SPICC0] = &s4_spicc0.hw, >> + [CLKID_USB] = &s4_usb.hw, >> + [CLKID_I2C_M_A] = &s4_i2c_m_a.hw, >> + [CLKID_I2C_M_B] = &s4_i2c_m_b.hw, >> + [CLKID_I2C_M_C] = &s4_i2c_m_c.hw, >> + [CLKID_I2C_M_D] = &s4_i2c_m_d.hw, >> + [CLKID_I2C_M_E] = &s4_i2c_m_e.hw, >> + [CLKID_HDMITX_APB] = &s4_hdmitx_apb.hw, >> + [CLKID_I2C_S_A] = &s4_i2c_s_a.hw, >> + [CLKID_USB1_TO_DDR] = &s4_usb1_to_ddr.hw, >> + [CLKID_HDCP22] = &s4_hdcp22.hw, >> + [CLKID_MMC_APB] = &s4_mmc_apb.hw, >> + [CLKID_RSA] = &s4_rsa.hw, >> + [CLKID_CPU_DEBUG] = &s4_cpu_debug.hw, >> + [CLKID_VPU_INTR] = &s4_vpu_intr.hw, >> + [CLKID_DEMOD] = &s4_demod.hw, >> + [CLKID_SAR_ADC] = &s4_sar_adc.hw, >> + [CLKID_GIC] = &s4_gic.hw, >> + [CLKID_PWM_AB] = &s4_pwm_ab.hw, >> + [CLKID_PWM_CD] = &s4_pwm_cd.hw, >> + [CLKID_PWM_EF] = &s4_pwm_ef.hw, >> + [CLKID_PWM_GH] = &s4_pwm_gh.hw, >> + [CLKID_PWM_IJ] = &s4_pwm_ij.hw, >> + [CLKID_HDCP22_ESMCLK_SEL] = &s4_hdcp22_esmclk_mux.hw, >> + [CLKID_HDCP22_ESMCLK_DIV] = &s4_hdcp22_esmclk_div.hw, >> + [CLKID_HDCP22_ESMCLK] = &s4_hdcp22_esmclk_gate.hw, >> + [CLKID_HDCP22_SKPCLK_SEL] = &s4_hdcp22_skpclk_mux.hw, >> + [CLKID_HDCP22_SKPCLK_DIV] = &s4_hdcp22_skpclk_div.hw, >> + [CLKID_HDCP22_SKPCLK] = &s4_hdcp22_skpclk_gate.hw, >> +}; >> + >> +/* Convenience table to populate regmap in .probe */ >> +static struct clk_regmap *const s4_periphs_clk_regmaps[] = { >> + &s4_rtc_32k_by_oscin_clkin, >> + &s4_rtc_32k_by_oscin_div, >> + &s4_rtc_32k_by_oscin_sel, >> + &s4_rtc_32k_by_oscin, >> + &s4_rtc_clk, >> + &s4_sysclk_b_sel, >> + &s4_sysclk_b_div, >> + &s4_sysclk_b, >> + &s4_sysclk_a_sel, >> + &s4_sysclk_a_div, >> + &s4_sysclk_a, >> + &s4_sys_clk, >> + &s4_ceca_32k_clkin, >> + &s4_ceca_32k_div, >> + &s4_ceca_32k_sel_pre, >> + &s4_ceca_32k_sel, >> + &s4_ceca_32k_clkout, >> + &s4_cecb_32k_clkin, >> + &s4_cecb_32k_div, >> + &s4_cecb_32k_sel_pre, >> + &s4_cecb_32k_sel, >> + &s4_cecb_32k_clkout, >> + &s4_sc_clk_mux, >> + &s4_sc_clk_div, >> + &s4_sc_clk_gate, >> + &s4_12_24M_clk_gate, >> + &s4_12_24M_clk, >> + &s4_vid_pll_div, >> + &s4_vid_pll_sel, >> + &s4_vid_pll, >> + &s4_vclk_sel, >> + &s4_vclk2_sel, >> + &s4_vclk_input, >> + &s4_vclk2_input, >> + &s4_vclk_div, >> + &s4_vclk2_div, >> + &s4_vclk, >> + &s4_vclk2, >> + &s4_vclk_div1, >> + &s4_vclk_div2_en, >> + &s4_vclk_div4_en, >> + &s4_vclk_div6_en, >> + &s4_vclk_div12_en, >> + &s4_vclk2_div1, >> + &s4_vclk2_div2_en, >> + &s4_vclk2_div4_en, >> + &s4_vclk2_div6_en, >> + &s4_vclk2_div12_en, >> + &s4_cts_enci_sel, >> + &s4_cts_encp_sel, >> + &s4_cts_vdac_sel, >> + &s4_hdmi_tx_sel, >> + &s4_cts_enci, >> + &s4_cts_encp, >> + &s4_cts_vdac, >> + &s4_hdmi_tx, >> + &s4_hdmi_sel, >> + &s4_hdmi_div, >> + &s4_hdmi, >> + &s4_ts_clk_div, >> + &s4_ts_clk_gate, >> + &s4_mali_0_sel, >> + &s4_mali_0_div, >> + &s4_mali_0, >> + &s4_mali_1_sel, >> + &s4_mali_1_div, >> + &s4_mali_1, >> + &s4_mali_mux, >> + &s4_vdec_p0_mux, >> + &s4_vdec_p0_div, >> + &s4_vdec_p0, >> + &s4_vdec_p1_mux, >> + &s4_vdec_p1_div, >> + &s4_vdec_p1, >> + &s4_vdec_mux, >> + &s4_hevcf_p0_mux, >> + &s4_hevcf_p0_div, >> + &s4_hevcf_p0, >> + &s4_hevcf_p1_mux, >> + &s4_hevcf_p1_div, >> + &s4_hevcf_p1, >> + &s4_hevcf_mux, >> + &s4_vpu_0_sel, >> + &s4_vpu_0_div, >> + &s4_vpu_0, >> + &s4_vpu_1_sel, >> + &s4_vpu_1_div, >> + &s4_vpu_1, >> + &s4_vpu, >> + &s4_vpu_clkb_tmp_mux, >> + &s4_vpu_clkb_tmp_div, >> + &s4_vpu_clkb_tmp, >> + &s4_vpu_clkb_div, >> + &s4_vpu_clkb, >> + &s4_vpu_clkc_p0_mux, >> + &s4_vpu_clkc_p0_div, >> + &s4_vpu_clkc_p0, >> + &s4_vpu_clkc_p1_mux, >> + &s4_vpu_clkc_p1_div, >> + &s4_vpu_clkc_p1, >> + &s4_vpu_clkc_mux, >> + &s4_vapb_0_sel, >> + &s4_vapb_0_div, >> + &s4_vapb_0, >> + &s4_vapb_1_sel, >> + &s4_vapb_1_div, >> + &s4_vapb_1, >> + &s4_vapb, >> + &s4_ge2d_gate, >> + &s4_hdcp22_esmclk_mux, >> + &s4_hdcp22_esmclk_div, >> + &s4_hdcp22_esmclk_gate, >> + &s4_hdcp22_skpclk_mux, >> + &s4_hdcp22_skpclk_div, >> + &s4_hdcp22_skpclk_gate, >> + &s4_vdin_meas_mux, >> + &s4_vdin_meas_div, >> + &s4_vdin_meas_gate, >> + &s4_sd_emmc_c_clk0_sel, >> + &s4_sd_emmc_c_clk0_div, >> + &s4_sd_emmc_c_clk0, >> + &s4_sd_emmc_a_clk0_sel, >> + &s4_sd_emmc_a_clk0_div, >> + &s4_sd_emmc_a_clk0, >> + &s4_sd_emmc_b_clk0_sel, >> + &s4_sd_emmc_b_clk0_div, >> + &s4_sd_emmc_b_clk0, >> + &s4_spicc0_mux, >> + &s4_spicc0_div, >> + &s4_spicc0_gate, >> + &s4_pwm_a_mux, >> + &s4_pwm_a_div, >> + &s4_pwm_a_gate, >> + &s4_pwm_b_mux, >> + &s4_pwm_b_div, >> + &s4_pwm_b_gate, >> + &s4_pwm_c_mux, >> + &s4_pwm_c_div, >> + &s4_pwm_c_gate, >> + &s4_pwm_d_mux, >> + &s4_pwm_d_div, >> + &s4_pwm_d_gate, >> + &s4_pwm_e_mux, >> + &s4_pwm_e_div, >> + &s4_pwm_e_gate, >> + &s4_pwm_f_mux, >> + &s4_pwm_f_div, >> + &s4_pwm_f_gate, >> + &s4_pwm_g_mux, >> + &s4_pwm_g_div, >> + &s4_pwm_g_gate, >> + &s4_pwm_h_mux, >> + &s4_pwm_h_div, >> + &s4_pwm_h_gate, >> + &s4_pwm_i_mux, >> + &s4_pwm_i_div, >> + &s4_pwm_i_gate, >> + &s4_pwm_j_mux, >> + &s4_pwm_j_div, >> + &s4_pwm_j_gate, >> + &s4_saradc_mux, >> + &s4_saradc_div, >> + &s4_saradc_gate, >> + &s4_gen_clk_sel, >> + &s4_gen_clk_div, >> + &s4_gen_clk, >> + &s4_ddr, >> + &s4_dos, >> + &s4_ethphy, >> + &s4_mali, >> + &s4_aocpu, >> + &s4_aucpu, >> + &s4_cec, >> + &s4_sdemmca, >> + &s4_sdemmcb, >> + &s4_nand, >> + &s4_smartcard, >> + &s4_acodec, >> + &s4_spifc, >> + &s4_msr_clk, >> + &s4_ir_ctrl, >> + &s4_audio, >> + &s4_eth, >> + &s4_uart_a, >> + &s4_uart_b, >> + &s4_uart_c, >> + &s4_uart_d, >> + &s4_uart_e, >> + &s4_aififo, >> + &s4_ts_ddr, >> + &s4_ts_pll, >> + &s4_g2d, >> + &s4_spicc0, >> + &s4_usb, >> + &s4_i2c_m_a, >> + &s4_i2c_m_b, >> + &s4_i2c_m_c, >> + &s4_i2c_m_d, >> + &s4_i2c_m_e, >> + &s4_hdmitx_apb, >> + &s4_i2c_s_a, >> + &s4_usb1_to_ddr, >> + &s4_hdcp22, >> + &s4_mmc_apb, >> + &s4_rsa, >> + &s4_cpu_debug, >> + &s4_vpu_intr, >> + &s4_demod, >> + &s4_sar_adc, >> + &s4_gic, >> + &s4_pwm_ab, >> + &s4_pwm_cd, >> + &s4_pwm_ef, >> + &s4_pwm_gh, >> + &s4_pwm_ij, >> + &s4_demod_core_clk_mux, >> + &s4_demod_core_clk_div, >> + &s4_demod_core_clk_gate, >> + &s4_adc_extclk_in_mux, >> + &s4_adc_extclk_in_div, >> + &s4_adc_extclk_in_gate, >> +}; >> + >> +static struct regmap_config clkc_regmap_config = { >> + .reg_bits = 32, >> + .val_bits = 32, >> + .reg_stride = 4, >> +}; >> + >> +static struct meson_clk_hw_data s4_periphs_clks = { >> + .hws = s4_periphs_hw_clks, >> + .num = ARRAY_SIZE(s4_periphs_hw_clks), >> +}; >> + >> +static int meson_s4_periphs_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct regmap *regmap; >> + void __iomem *base; >> + int ret, i; >> + >> + base = devm_platform_ioremap_resource(pdev, 0); >> + if (IS_ERR(base)) >> + return dev_err_probe(dev, PTR_ERR(base), >> + "can't ioremap resource\n"); >> + >> + regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); >> + if (IS_ERR(regmap)) >> + return dev_err_probe(dev, PTR_ERR(regmap), >> + "can't init regmap mmio region\n"); >> + >> + /* Populate regmap for the regmap backed clocks */ >> + for (i = 0; i < ARRAY_SIZE(s4_periphs_clk_regmaps); i++) >> + s4_periphs_clk_regmaps[i]->map = regmap; >> + >> + for (i = 0; i < s4_periphs_clks.num; i++) { >> + /* array might be sparse */ >> + if (!s4_periphs_clks.hws[i]) >> + continue; >> + >> + ret = devm_clk_hw_register(dev, s4_periphs_clks.hws[i]); >> + if (ret) >> + return dev_err_probe(dev, ret, >> + "clock[%d] registration failed\n", i); >> + } >> + >> + return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &s4_periphs_clks); >> +} >> + >> +static const struct of_device_id clkc_match_table[] = { >> + { >> + .compatible = "amlogic,s4-peripherals-clkc", >> + }, >> + {} >> +}; >> + >> +static struct platform_driver s4_driver = { >> + .probe = meson_s4_periphs_probe, >> + .driver = { >> + .name = "s4-periphs-clkc", >> + .of_match_table = clkc_match_table, >> + }, >> +}; >> + >> +module_platform_driver(s4_driver); >> +MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>"); >> +MODULE_LICENSE("GPL"); >> diff --git a/drivers/clk/meson/s4-peripherals.h b/drivers/clk/meson/s4-peripherals.h >> new file mode 100644 >> index 000000000000..56f8f28a913e >> --- /dev/null >> +++ b/drivers/clk/meson/s4-peripherals.h >> @@ -0,0 +1,57 @@ >> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >> +/* >> + * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved >> + * Author: Yu Tu <yu.tu@amlogic.com> >> + */ >> + >> +#ifndef __MESON_S4_PERIPHERALS_H__ >> +#define __MESON_S4_PERIPHERALS_H__ >> + >> +#define CLKCTRL_RTC_BY_OSCIN_CTRL0 0x008 >> +#define CLKCTRL_RTC_BY_OSCIN_CTRL1 0x00c >> +#define CLKCTRL_RTC_CTRL 0x010 >> +#define CLKCTRL_SYS_CLK_CTRL0 0x040 >> +#define CLKCTRL_SYS_CLK_EN0_REG0 0x044 >> +#define CLKCTRL_SYS_CLK_EN0_REG1 0x048 >> +#define CLKCTRL_SYS_CLK_EN0_REG2 0x04c >> +#define CLKCTRL_SYS_CLK_EN0_REG3 0x050 >> +#define CLKCTRL_CECA_CTRL0 0x088 >> +#define CLKCTRL_CECA_CTRL1 0x08c >> +#define CLKCTRL_CECB_CTRL0 0x090 >> +#define CLKCTRL_CECB_CTRL1 0x094 >> +#define CLKCTRL_SC_CLK_CTRL 0x098 >> +#define CLKCTRL_CLK12_24_CTRL 0x0a8 >> +#define CLKCTRL_VID_CLK_CTRL 0x0c0 >> +#define CLKCTRL_VID_CLK_CTRL2 0x0c4 >> +#define CLKCTRL_VID_CLK_DIV 0x0c8 >> +#define CLKCTRL_VIID_CLK_DIV 0x0cc >> +#define CLKCTRL_VIID_CLK_CTRL 0x0d0 >> +#define CLKCTRL_HDMI_CLK_CTRL 0x0e0 >> +#define CLKCTRL_VID_PLL_CLK_DIV 0x0e4 >> +#define CLKCTRL_VPU_CLK_CTRL 0x0e8 >> +#define CLKCTRL_VPU_CLKB_CTRL 0x0ec >> +#define CLKCTRL_VPU_CLKC_CTRL 0x0f0 >> +#define CLKCTRL_VID_LOCK_CLK_CTRL 0x0f4 >> +#define CLKCTRL_VDIN_MEAS_CLK_CTRL 0x0f8 >> +#define CLKCTRL_VAPBCLK_CTRL 0x0fc >> +#define CLKCTRL_HDCP22_CTRL 0x100 >> +#define CLKCTRL_VDEC_CLK_CTRL 0x140 >> +#define CLKCTRL_VDEC2_CLK_CTRL 0x144 >> +#define CLKCTRL_VDEC3_CLK_CTRL 0x148 >> +#define CLKCTRL_VDEC4_CLK_CTRL 0x14c >> +#define CLKCTRL_TS_CLK_CTRL 0x158 >> +#define CLKCTRL_MALI_CLK_CTRL 0x15c >> +#define CLKCTRL_NAND_CLK_CTRL 0x168 >> +#define CLKCTRL_SD_EMMC_CLK_CTRL 0x16c >> +#define CLKCTRL_SPICC_CLK_CTRL 0x174 >> +#define CLKCTRL_GEN_CLK_CTRL 0x178 >> +#define CLKCTRL_SAR_CLK_CTRL 0x17c >> +#define CLKCTRL_PWM_CLK_AB_CTRL 0x180 >> +#define CLKCTRL_PWM_CLK_CD_CTRL 0x184 >> +#define CLKCTRL_PWM_CLK_EF_CTRL 0x188 >> +#define CLKCTRL_PWM_CLK_GH_CTRL 0x18c >> +#define CLKCTRL_PWM_CLK_IJ_CTRL 0x190 >> +#define CLKCTRL_DEMOD_CLK_CTRL 0x200 >> + >> +#endif /* __MESON_S4_PERIPHERALS_H__ */ >> + > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock 2023-08-22 8:27 [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Yu Tu ` (3 preceding siblings ...) 2023-08-22 8:27 ` [PATCH V10 4/4] clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller Yu Tu @ 2023-08-27 17:04 ` Lucas Tanure 2023-08-28 2:24 ` Keguang Zhang 4 siblings, 1 reply; 21+ messages in thread From: Lucas Tanure @ 2023-08-27 17:04 UTC (permalink / raw) To: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl Cc: kelvin.zhang, qi.duan On 22-08-2023 09:27, Yu Tu wrote: > 1. Add S4 SoC PLLs and Peripheral clock controller dt-bindings. > 2. Add PLLs and Peripheral clock controller driver for S4 SOC. > > > Yu Tu (4): > dt-bindings: clock: document Amlogic S4 SoC PLL clock controller > dt-bindings: clock: document Amlogic S4 SoC peripherals clock > controller > clk: meson: S4: add support for Amlogic S4 SoC PLL clock driver > clk: meson: S4: add support for Amlogic S4 SoC peripheral clock > controller > > V9 -> V10: > 1. Change the relevant S4 CLK patch based on Neil's recently modified > patch. > 2. Change patch 0003/0004 clocks comment, format and clock flags suggested > by Jerome. > > V8 -> V9: Add patch 0001/0002 dt-bindings tag. Suggested by Krzysztof. > V7 -> V8: > 1. Change patch 0001/0002 dt-bindings title description, remove "meson". > Suggested by Dmitry, Neil. > 2. Change patch 0003/0004 clocks comment, format and clock flags suggested by > Dmitry, Neil, Jerome. > > V6 -> V7: Change send patch series as well change format and clock flags > suggested by Jerome. Change dt-bindings suggested by Krzysztof. > V5 -> V6: Change send patch series, as well change format and clock flags. > V4 -> V5: change format and clock flags and adjust the patch series > as suggested by Jerome. > V3 -> V4: change format and clock flags. > V2 -> V3: Use two clock controller. > V1 -> V2: Change format as discussed in the email. > > Link:https://lore.kernel.org/linux-amlogic/20230517070215.28463-1-yu.tu@amlogic.com/ > > .../clock/amlogic,s4-peripherals-clkc.yaml | 96 + > .../bindings/clock/amlogic,s4-pll-clkc.yaml | 49 + > drivers/clk/meson/Kconfig | 23 + > drivers/clk/meson/Makefile | 2 + > drivers/clk/meson/s4-peripherals.c | 3787 +++++++++++++++++ > drivers/clk/meson/s4-peripherals.h | 57 + > drivers/clk/meson/s4-pll.c | 867 ++++ > drivers/clk/meson/s4-pll.h | 38 + > .../clock/amlogic,s4-peripherals-clkc.h | 236 + > .../dt-bindings/clock/amlogic,s4-pll-clkc.h | 43 + > 10 files changed, 5198 insertions(+) > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-pll-clkc.yaml > create mode 100644 drivers/clk/meson/s4-peripherals.c > create mode 100644 drivers/clk/meson/s4-peripherals.h > create mode 100644 drivers/clk/meson/s4-pll.c > create mode 100644 drivers/clk/meson/s4-pll.h > create mode 100644 include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h > create mode 100644 include/dt-bindings/clock/amlogic,s4-pll-clkc.h > > > base-commit: bd0f6c57c2b324b6f92ccfe13a8005ff829287b8 How similar is T7 and S4 regarding the clocks? Can S4 clock driver be used by T7 without modifications? Thanks Lucas ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock 2023-08-27 17:04 ` [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Lucas Tanure @ 2023-08-28 2:24 ` Keguang Zhang 0 siblings, 0 replies; 21+ messages in thread From: Keguang Zhang @ 2023-08-28 2:24 UTC (permalink / raw) To: Lucas Tanure Cc: Yu Tu, linux-clk, linux-arm-kernel, linux-amlogic, linux-kernel, devicetree, Rob Herring, Neil Armstrong, Jerome Brunet, Kevin Hilman, Michael Turquette, Stephen Boyd, Krzysztof Kozlowski, Conor Dooley, Martin Blumenstingl, kelvin.zhang, qi.duan On Mon, Aug 28, 2023 at 1:34 AM Lucas Tanure <tanure@linux.com> wrote: > > On 22-08-2023 09:27, Yu Tu wrote: > > 1. Add S4 SoC PLLs and Peripheral clock controller dt-bindings. > > 2. Add PLLs and Peripheral clock controller driver for S4 SOC. > > > > > > Yu Tu (4): > > dt-bindings: clock: document Amlogic S4 SoC PLL clock controller > > dt-bindings: clock: document Amlogic S4 SoC peripherals clock > > controller > > clk: meson: S4: add support for Amlogic S4 SoC PLL clock driver > > clk: meson: S4: add support for Amlogic S4 SoC peripheral clock > > controller > > > > V9 -> V10: > > 1. Change the relevant S4 CLK patch based on Neil's recently modified > > patch. > > 2. Change patch 0003/0004 clocks comment, format and clock flags suggested > > by Jerome. > > > > V8 -> V9: Add patch 0001/0002 dt-bindings tag. Suggested by Krzysztof. > > V7 -> V8: > > 1. Change patch 0001/0002 dt-bindings title description, remove "meson". > > Suggested by Dmitry, Neil. > > 2. Change patch 0003/0004 clocks comment, format and clock flags suggested by > > Dmitry, Neil, Jerome. > > > > V6 -> V7: Change send patch series as well change format and clock flags > > suggested by Jerome. Change dt-bindings suggested by Krzysztof. > > V5 -> V6: Change send patch series, as well change format and clock flags. > > V4 -> V5: change format and clock flags and adjust the patch series > > as suggested by Jerome. > > V3 -> V4: change format and clock flags. > > V2 -> V3: Use two clock controller. > > V1 -> V2: Change format as discussed in the email. > > > > Link:https://lore.kernel.org/linux-amlogic/20230517070215.28463-1-yu.tu@amlogic.com/ > > > > .../clock/amlogic,s4-peripherals-clkc.yaml | 96 + > > .../bindings/clock/amlogic,s4-pll-clkc.yaml | 49 + > > drivers/clk/meson/Kconfig | 23 + > > drivers/clk/meson/Makefile | 2 + > > drivers/clk/meson/s4-peripherals.c | 3787 +++++++++++++++++ > > drivers/clk/meson/s4-peripherals.h | 57 + > > drivers/clk/meson/s4-pll.c | 867 ++++ > > drivers/clk/meson/s4-pll.h | 38 + > > .../clock/amlogic,s4-peripherals-clkc.h | 236 + > > .../dt-bindings/clock/amlogic,s4-pll-clkc.h | 43 + > > 10 files changed, 5198 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-peripherals-clkc.yaml > > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,s4-pll-clkc.yaml > > create mode 100644 drivers/clk/meson/s4-peripherals.c > > create mode 100644 drivers/clk/meson/s4-peripherals.h > > create mode 100644 drivers/clk/meson/s4-pll.c > > create mode 100644 drivers/clk/meson/s4-pll.h > > create mode 100644 include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h > > create mode 100644 include/dt-bindings/clock/amlogic,s4-pll-clkc.h > > > > > > base-commit: bd0f6c57c2b324b6f92ccfe13a8005ff829287b8 > How similar is T7 and S4 regarding the clocks? > Can S4 clock driver be used by T7 without modifications? > Unfortunately not. But don't worry! The T7 clock driver is coming soon. > Thanks > Lucas -- Best regards, Keguang Zhang ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2023-08-28 2:43 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-08-22 8:27 [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Yu Tu 2023-08-22 8:27 ` [PATCH V10 1/4] dt-bindings: clock: document Amlogic S4 SoC PLL clock controller Yu Tu 2023-08-22 16:32 ` Krzysztof Kozlowski 2023-08-23 2:24 ` Yu Tu 2023-08-23 5:43 ` Krzysztof Kozlowski 2023-08-23 6:20 ` Yu Tu 2023-08-23 6:27 ` Krzysztof Kozlowski 2023-08-23 6:35 ` Yu Tu 2023-08-22 8:27 ` [PATCH V10 2/4] dt-bindings: clock: document Amlogic S4 SoC peripherals " Yu Tu 2023-08-22 16:33 ` Krzysztof Kozlowski 2023-08-23 2:29 ` Yu Tu 2023-08-23 8:01 ` Jerome Brunet 2023-08-23 8:32 ` Yu Tu 2023-08-23 9:14 ` Jerome Brunet 2023-08-24 2:35 ` Yu Tu 2023-08-22 8:27 ` [PATCH V10 3/4] clk: meson: S4: add support for Amlogic S4 SoC PLL clock driver Yu Tu 2023-08-22 8:27 ` [PATCH V10 4/4] clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller Yu Tu 2023-08-23 8:13 ` Jerome Brunet 2023-08-23 8:41 ` Yu Tu 2023-08-27 17:04 ` [PATCH V10 0/4] Add S4 SoC PLLs and Peripheral clock Lucas Tanure 2023-08-28 2:24 ` Keguang Zhang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).