All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-17 13:33 ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
and Audio. The audio clock controller is different from others, but the
rest are very similar from a functional and regmap point of view.
This patch series add support for Amlogic A1 PLL and Peripherals clock
drivers.
It blocks all A1 peripherals mainline support and a couple of patch series,
which were already reviewed and acked, but weren't merged due to pending
clock controller drivers series, e.g.
https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/

TODO: CPU and Audio clock controllers are not included in this patch
series, it will be sent later. The following clks from these controllers
are not supported for now:
* Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
   pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
   audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
   audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
   audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
   audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
   audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c

* CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
            cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk

Validation:
* to double check all clk flags run below helper script:
    pushd /sys/kernel/debug/clk
    for f in *; do
        if [[ -f "$f/clk_flags" ]]; then
            flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
            echo -e "$f: $flags"
        fi
    done
    popd

* to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
  with jq post-processing:
    $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json

* to debug clk rate propagation, compile kernel with the following
  definition:
    $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
  after that, clk_rate debug node for each clock will be available for
  write operation

Changes v15 since v14 as [15]:
    - rename all dt bindings related to A1 Peripherals Clock Controller
      from "*a1-clkc*" to "*a1-peripherals-clkc*"
    - change COMMON_CLK_A1 config to COMMON_CLK_A1_PERIPHERALS
    - rename compatible string from "a1-clkc" to "a1-peripherals-clkc"
    - open the SD_EMMC_SEL2 clock object to public dt bindings due to
      several hardware issues during auto-reparenting with rate
      propagation; currently, the Meson MMC driver initializes its
      parent using an assigned-clocks mechanism and sets an appropriate
      rate. A related patch for meson-a1.dtsi will be provided after the
      clock patch series is merged
    - remove 'driver' keyword from dt bindings commit msgs and patchsets
    - make English grammar better!

Changes v14 since v13 at [14]:
    - remove the term "Meson" from all patchsets or replace it with
      "Amlogic"
    - purge extra commas as per Martin's suggestion
    - drop the unneeded use of of_match_ptr(), since all Meson clock
      drivers depend on the ARM64 config which selects CONFIG_OF by default

Changes v13 since v12 at [13]:
    - make the clock object registration order from the roots to the leaves
    - rearrange the clkids following above rule

Changes v12 since v11 at [12]:
    - split the DT bindings patchset into two patches: one for the PLL clock
      controller driver, and one for the peripherals clock controller driver
    - to satisfy the DT binding checker, use fake references to the
      peripherals clock controller in the PLL DT bindings schema, and then
      replace them with real references when the peripherals bindings
      become available.
    - remove the public/private clocks concept from both controllers,
      and instead use a linear clkid list with both exposed and internal
      objects, all of which are registered in the clock provider
    - combine all comments about RTC children with the flag
      'CLK_SET_RATE_NO_REPARENT' into a single item with multiple
      references to it

Changes v11 since v10 at [11]:
    - change include/dt-bindings license to proper value required for
      bindings files: 'GPL-2.0-only OR BSD-2-Clause'
    - pll and peripherals clocks are split into public and private parts;
      public clocks are available for external consumers through the DT layer,
      private clocks include internal muxes and dividers of composite clocks,
      they are placed inside clock controller driver without external access
    - make public clks CLKID bindings continuous
    - mark the following clock muxes as NO_REPARENT and add them to
      public clocks list: GEN_SEL, DSPA_A_SEL, DSPA_B_SEL, DSPB_A_SEL,
      DSP_B_B_SEL, PWM_A_SEL, PWM_B_SEL, PWM_C_SEL, PWM_D_SEL,
      PWM_E_SEL, PWM_F_SEL, CECA_32K_SEL, CECB_32K_SEL; each of them can
      be inherited from more accurate RTC clock and sometimes it's
      required to forbid reparenting in such situation; also GEN_SEL can
      be connected to external PAD and should not change parent
      automatically due to rate propagation. For such clocks user must
      setup parents on the DT side

Changes v10 since v9 at [10]:
    - split general clk-pll changes into two different patchsets:
      optional rst usage and new power sequence
    - squash dt bindings patchsets to avoid chicken-or-the-egg problem
      during run dt binding check routines
    - add vendor prefix to PLL and Peripherals clkcs bindings filenames
    - clear managed hifi_pll fields from initial poke table
    - move DSPA_SEL, DSPB_SEL and SARADC_SEL to private clkid table,
      because it should not be opened for direct usage
    - pwm_a clk used for voltage regulation is not critical anymore, it
      must be included to the proper cpu voltage regulation setup (will
      be available in the next patch series)
    - as discussed with Jerome, dspX clks are simple clocks and it
      should be enabled/disabled/ignored/anything else from appropriate
      DSP driver, so remove CLK_IGNORE_UNUSED tags
    - provide more understandable comments and remove irrelevant (I hope so)
    - remove CONFIG_OF usage, because it's redundant
    - fix license issue, it's GPL-2.0+ only in the current version
    - some commit msgs rewording

Changes v9 since v8 at [9]:
    - remove common a1-clkc driver for the first version of a1 clock
      controllers as Jerome suggested (it will be discussed after s4 and
      a1 clks landed, hope so)
    - replace inherited a1-pll clk_pll_ops with common ops and
    оло  introduce custom A1 PLL logic under MESON_PARM_APPLICABLE()
      conditions
    - rename xtal depended clocks in PLL and Peripherals domains
    - remove 'a1_' prefix for all clocks, because they are already
      inside A1 driver, it's redundant
    - change udelay() to usleep_range() as preferred for small msec
      amount
    - purge all double quotes from the yaml schemas
    - use proper dt node names following kernel guidelines
      https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
    - use devm_platform_ioremap_resource() instead of simple
      devm_ioremap_resource()
    - mark all dspX clocks as CLK_IGNORE_UNUSED, because we do not want
      to touch these clocks during CCF initialization due to possible
      workload execution on it started from bootloader; in this case
      bootloader already made all initialization stuff for dspX
    - also mark all dspX with NO_REPARENT tag, because from dspX clocks
      we want to select proper clk source from device tree

Changes v8 since v7 at [8]:
    - introduced a1-clkc common driver for all A1 clock controllers
    - exported meson_clk_pll_wait_lock symbol
    - supported meson-a1-clkc common driver in the a1-pll and a1 clkc
    - inherited a1-pll from the base clk-pll driver, implemented own
      version of init/enable/disable/enabled routines; rate calculating
      logic is fully the same
    - aligned CLKID-related definitions with CLKID list from order
      perspective to remove holes and permutations
    - corrected Kconfig dependencies and types
    - provided correct MODULE_AUTHORs()
    - optimized and fixed up some clock relationships
    - removed unused register offset definitions
    - fixed up A1 PLL and Peripherals clkc dtb_check errors
    - fixed clk_summary kernel panic due to missing a1_pad_ctrl
      clk_regmap definition
    - included PLL and Peripherals clk controllers to the base a1 dts
    - The previous v7 version [8] had several logic and style problems,
      all of them are resolved in this version. Original Jian Hu v7 patches
      are not touched, and all additional fixes are implemented in separate
      patches. Patch "clk: meson: add support for A1 PLL clock ops" is
      removed, because a1-pll clk driver inherits all stuff from clk-pll
      base driver, just implements custom init/enable/disable/is_enabled
      callbacks.

Changes v7 since v6 at [7]:
    - fix 'dt_binding_check' compiling error
    - add acked-by

Changes v6 since v5 at [6]:
    - fix yaml file
    - add rst/current_en/l_detect parm detection
    - remove 'meson_eeclkc_data' in a1.c and a1-pll.c

Changes v5 since v4 at [5]:
    - change yaml GPL
    - drop meson-eeclk.c patch, add probe function in each driver
    - add CLK_IS_CRITICAL for sys_clk clock, drop the flag for sys_a
      and sys_b
    - add new parm for pll, add protection for rst parm
    - drop flag for a1_fixed_pll
    - remove the same comment for fclk_div, add "refer to"
    - add critical flag for a1_sys_clk
    - remove rtc table
    - rename a1_dspa_en_dspa and a1_dspb_en_dspb
    - remove useless comment

Changes v4 since v3 at [3]:
    - fix reparenting orphan failed, it depends on jerome's patch [4]
    - fix changelist in v3 about reparenting orphan
    - remove the dts patch 

Changes v3 since v2 at [2]:
    - add probe function for A1
    - separate the clock driver into two patch
    - change some clock flags and ops
    - add support for a1 PLL ops
    - add A1 clock node
    - fix reparenting orphan clock failed, registering xtal_fixpll
      and xtal_hifipll after the provider registration, it is not
      a best way.

Changes v2 since v1 at [1]:
    - place A1 config alphabetically
    - add actual reason for RO ops, CLK_IS_CRITICAL, CLK_IGNORE_UNUSED
    - separate the driver into two driver: peripheral and pll driver
    - delete CLK_IGNORE_UNUSED flag for pwm b/c/d/e/f clock, dsp clock
    - delete the change in Kconfig.platforms, address to Kevin alone
    - remove the useless comments
    - modify the meson pll driver to support A1 PLLs

Links:
    [1] https://lkml.kernel.org/r/1569411888-98116-1-git-send-email-jian.hu@amlogic.com
    [2] https://lkml.kernel.org/r/1571382865-41978-1-git-send-email-jian.hu@amlogic.com
    [3] https://lkml.kernel.org/r/20191129144605.182774-1-jian.hu@amlogic.com
    [4] https://lkml.kernel.org/r/20191203080805.104628-1-jbrunet@baylibre.com
    [5] https://lkml.kernel.org/r/20191206074052.15557-1-jian.hu@amlogic.com
    [6] https://lkml.kernel.org/r/20191227094606.143637-1-jian.hu@amlogic.com
    [7] https://lkml.kernel.org/r/20200116080440.118679-1-jian.hu@amlogic.com
    [8] https://lore.kernel.org/linux-amlogic/20200120034937.128600-1-jian.hu@amlogic.com/
    [9] https://lore.kernel.org/linux-amlogic/20221201225703.6507-1-ddrokosov@sberdevices.ru/
    [10] https://lore.kernel.org/all/20230301183759.16163-1-ddrokosov@sberdevices.ru/
    [11] https://lore.kernel.org/all/20230313201259.19998-1-ddrokosov@sberdevices.ru/
    [12] https://lore.kernel.org/all/20230321193014.26349-1-ddrokosov@sberdevices.ru/
    [13] https://lore.kernel.org/all/20230404155332.9571-1-ddrokosov@sberdevices.ru/
    [14] https://lore.kernel.org/linux-amlogic/20230405195927.13487-1-ddrokosov@sberdevices.ru/
    [15] https://lore.kernel.org/all/20230426095805.15338-1-ddrokosov@sberdevices.ru/

Dmitry Rokosov (6):
  clk: meson: make pll rst bit as optional
  clk: meson: introduce new pll power-on sequence for A1 SoC family
  dt-bindings: clock: meson: add A1 PLL clock controller bindings
  clk: meson: a1: add Amlogic A1 PLL clock controller driver
  dt-bindings: clock: meson: add A1 Peripherals clock controller
    bindings
  clk: meson: a1: add Amlogic A1 Peripherals clock controller driver

 .../clock/amlogic,a1-peripherals-clkc.yaml    |   73 +
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   |   59 +
 MAINTAINERS                                   |    1 +
 drivers/clk/meson/Kconfig                     |   20 +
 drivers/clk/meson/Makefile                    |    2 +
 drivers/clk/meson/a1-peripherals.c            | 2273 +++++++++++++++++
 drivers/clk/meson/a1-peripherals.h            |  113 +
 drivers/clk/meson/a1-pll.c                    |  356 +++
 drivers/clk/meson/a1-pll.h                    |   47 +
 drivers/clk/meson/clk-pll.c                   |   47 +-
 drivers/clk/meson/clk-pll.h                   |    2 +
 .../clock/amlogic,a1-peripherals-clkc.h       |  115 +
 .../dt-bindings/clock/amlogic,a1-pll-clkc.h   |   20 +
 13 files changed, 3121 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
 create mode 100644 drivers/clk/meson/a1-peripherals.c
 create mode 100644 drivers/clk/meson/a1-peripherals.h
 create mode 100644 drivers/clk/meson/a1-pll.c
 create mode 100644 drivers/clk/meson/a1-pll.h
 create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
 create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h

-- 
2.36.0


^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-17 13:33 ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
and Audio. The audio clock controller is different from others, but the
rest are very similar from a functional and regmap point of view.
This patch series add support for Amlogic A1 PLL and Peripherals clock
drivers.
It blocks all A1 peripherals mainline support and a couple of patch series,
which were already reviewed and acked, but weren't merged due to pending
clock controller drivers series, e.g.
https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/

TODO: CPU and Audio clock controllers are not included in this patch
series, it will be sent later. The following clks from these controllers
are not supported for now:
* Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
   pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
   audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
   audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
   audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
   audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
   audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c

* CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
            cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk

Validation:
* to double check all clk flags run below helper script:
    pushd /sys/kernel/debug/clk
    for f in *; do
        if [[ -f "$f/clk_flags" ]]; then
            flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
            echo -e "$f: $flags"
        fi
    done
    popd

* to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
  with jq post-processing:
    $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json

* to debug clk rate propagation, compile kernel with the following
  definition:
    $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
  after that, clk_rate debug node for each clock will be available for
  write operation

Changes v15 since v14 as [15]:
    - rename all dt bindings related to A1 Peripherals Clock Controller
      from "*a1-clkc*" to "*a1-peripherals-clkc*"
    - change COMMON_CLK_A1 config to COMMON_CLK_A1_PERIPHERALS
    - rename compatible string from "a1-clkc" to "a1-peripherals-clkc"
    - open the SD_EMMC_SEL2 clock object to public dt bindings due to
      several hardware issues during auto-reparenting with rate
      propagation; currently, the Meson MMC driver initializes its
      parent using an assigned-clocks mechanism and sets an appropriate
      rate. A related patch for meson-a1.dtsi will be provided after the
      clock patch series is merged
    - remove 'driver' keyword from dt bindings commit msgs and patchsets
    - make English grammar better!

Changes v14 since v13 at [14]:
    - remove the term "Meson" from all patchsets or replace it with
      "Amlogic"
    - purge extra commas as per Martin's suggestion
    - drop the unneeded use of of_match_ptr(), since all Meson clock
      drivers depend on the ARM64 config which selects CONFIG_OF by default

Changes v13 since v12 at [13]:
    - make the clock object registration order from the roots to the leaves
    - rearrange the clkids following above rule

Changes v12 since v11 at [12]:
    - split the DT bindings patchset into two patches: one for the PLL clock
      controller driver, and one for the peripherals clock controller driver
    - to satisfy the DT binding checker, use fake references to the
      peripherals clock controller in the PLL DT bindings schema, and then
      replace them with real references when the peripherals bindings
      become available.
    - remove the public/private clocks concept from both controllers,
      and instead use a linear clkid list with both exposed and internal
      objects, all of which are registered in the clock provider
    - combine all comments about RTC children with the flag
      'CLK_SET_RATE_NO_REPARENT' into a single item with multiple
      references to it

Changes v11 since v10 at [11]:
    - change include/dt-bindings license to proper value required for
      bindings files: 'GPL-2.0-only OR BSD-2-Clause'
    - pll and peripherals clocks are split into public and private parts;
      public clocks are available for external consumers through the DT layer,
      private clocks include internal muxes and dividers of composite clocks,
      they are placed inside clock controller driver without external access
    - make public clks CLKID bindings continuous
    - mark the following clock muxes as NO_REPARENT and add them to
      public clocks list: GEN_SEL, DSPA_A_SEL, DSPA_B_SEL, DSPB_A_SEL,
      DSP_B_B_SEL, PWM_A_SEL, PWM_B_SEL, PWM_C_SEL, PWM_D_SEL,
      PWM_E_SEL, PWM_F_SEL, CECA_32K_SEL, CECB_32K_SEL; each of them can
      be inherited from more accurate RTC clock and sometimes it's
      required to forbid reparenting in such situation; also GEN_SEL can
      be connected to external PAD and should not change parent
      automatically due to rate propagation. For such clocks user must
      setup parents on the DT side

Changes v10 since v9 at [10]:
    - split general clk-pll changes into two different patchsets:
      optional rst usage and new power sequence
    - squash dt bindings patchsets to avoid chicken-or-the-egg problem
      during run dt binding check routines
    - add vendor prefix to PLL and Peripherals clkcs bindings filenames
    - clear managed hifi_pll fields from initial poke table
    - move DSPA_SEL, DSPB_SEL and SARADC_SEL to private clkid table,
      because it should not be opened for direct usage
    - pwm_a clk used for voltage regulation is not critical anymore, it
      must be included to the proper cpu voltage regulation setup (will
      be available in the next patch series)
    - as discussed with Jerome, dspX clks are simple clocks and it
      should be enabled/disabled/ignored/anything else from appropriate
      DSP driver, so remove CLK_IGNORE_UNUSED tags
    - provide more understandable comments and remove irrelevant (I hope so)
    - remove CONFIG_OF usage, because it's redundant
    - fix license issue, it's GPL-2.0+ only in the current version
    - some commit msgs rewording

Changes v9 since v8 at [9]:
    - remove common a1-clkc driver for the first version of a1 clock
      controllers as Jerome suggested (it will be discussed after s4 and
      a1 clks landed, hope so)
    - replace inherited a1-pll clk_pll_ops with common ops and
    оло  introduce custom A1 PLL logic under MESON_PARM_APPLICABLE()
      conditions
    - rename xtal depended clocks in PLL and Peripherals domains
    - remove 'a1_' prefix for all clocks, because they are already
      inside A1 driver, it's redundant
    - change udelay() to usleep_range() as preferred for small msec
      amount
    - purge all double quotes from the yaml schemas
    - use proper dt node names following kernel guidelines
      https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
    - use devm_platform_ioremap_resource() instead of simple
      devm_ioremap_resource()
    - mark all dspX clocks as CLK_IGNORE_UNUSED, because we do not want
      to touch these clocks during CCF initialization due to possible
      workload execution on it started from bootloader; in this case
      bootloader already made all initialization stuff for dspX
    - also mark all dspX with NO_REPARENT tag, because from dspX clocks
      we want to select proper clk source from device tree

Changes v8 since v7 at [8]:
    - introduced a1-clkc common driver for all A1 clock controllers
    - exported meson_clk_pll_wait_lock symbol
    - supported meson-a1-clkc common driver in the a1-pll and a1 clkc
    - inherited a1-pll from the base clk-pll driver, implemented own
      version of init/enable/disable/enabled routines; rate calculating
      logic is fully the same
    - aligned CLKID-related definitions with CLKID list from order
      perspective to remove holes and permutations
    - corrected Kconfig dependencies and types
    - provided correct MODULE_AUTHORs()
    - optimized and fixed up some clock relationships
    - removed unused register offset definitions
    - fixed up A1 PLL and Peripherals clkc dtb_check errors
    - fixed clk_summary kernel panic due to missing a1_pad_ctrl
      clk_regmap definition
    - included PLL and Peripherals clk controllers to the base a1 dts
    - The previous v7 version [8] had several logic and style problems,
      all of them are resolved in this version. Original Jian Hu v7 patches
      are not touched, and all additional fixes are implemented in separate
      patches. Patch "clk: meson: add support for A1 PLL clock ops" is
      removed, because a1-pll clk driver inherits all stuff from clk-pll
      base driver, just implements custom init/enable/disable/is_enabled
      callbacks.

Changes v7 since v6 at [7]:
    - fix 'dt_binding_check' compiling error
    - add acked-by

Changes v6 since v5 at [6]:
    - fix yaml file
    - add rst/current_en/l_detect parm detection
    - remove 'meson_eeclkc_data' in a1.c and a1-pll.c

Changes v5 since v4 at [5]:
    - change yaml GPL
    - drop meson-eeclk.c patch, add probe function in each driver
    - add CLK_IS_CRITICAL for sys_clk clock, drop the flag for sys_a
      and sys_b
    - add new parm for pll, add protection for rst parm
    - drop flag for a1_fixed_pll
    - remove the same comment for fclk_div, add "refer to"
    - add critical flag for a1_sys_clk
    - remove rtc table
    - rename a1_dspa_en_dspa and a1_dspb_en_dspb
    - remove useless comment

Changes v4 since v3 at [3]:
    - fix reparenting orphan failed, it depends on jerome's patch [4]
    - fix changelist in v3 about reparenting orphan
    - remove the dts patch 

Changes v3 since v2 at [2]:
    - add probe function for A1
    - separate the clock driver into two patch
    - change some clock flags and ops
    - add support for a1 PLL ops
    - add A1 clock node
    - fix reparenting orphan clock failed, registering xtal_fixpll
      and xtal_hifipll after the provider registration, it is not
      a best way.

Changes v2 since v1 at [1]:
    - place A1 config alphabetically
    - add actual reason for RO ops, CLK_IS_CRITICAL, CLK_IGNORE_UNUSED
    - separate the driver into two driver: peripheral and pll driver
    - delete CLK_IGNORE_UNUSED flag for pwm b/c/d/e/f clock, dsp clock
    - delete the change in Kconfig.platforms, address to Kevin alone
    - remove the useless comments
    - modify the meson pll driver to support A1 PLLs

Links:
    [1] https://lkml.kernel.org/r/1569411888-98116-1-git-send-email-jian.hu@amlogic.com
    [2] https://lkml.kernel.org/r/1571382865-41978-1-git-send-email-jian.hu@amlogic.com
    [3] https://lkml.kernel.org/r/20191129144605.182774-1-jian.hu@amlogic.com
    [4] https://lkml.kernel.org/r/20191203080805.104628-1-jbrunet@baylibre.com
    [5] https://lkml.kernel.org/r/20191206074052.15557-1-jian.hu@amlogic.com
    [6] https://lkml.kernel.org/r/20191227094606.143637-1-jian.hu@amlogic.com
    [7] https://lkml.kernel.org/r/20200116080440.118679-1-jian.hu@amlogic.com
    [8] https://lore.kernel.org/linux-amlogic/20200120034937.128600-1-jian.hu@amlogic.com/
    [9] https://lore.kernel.org/linux-amlogic/20221201225703.6507-1-ddrokosov@sberdevices.ru/
    [10] https://lore.kernel.org/all/20230301183759.16163-1-ddrokosov@sberdevices.ru/
    [11] https://lore.kernel.org/all/20230313201259.19998-1-ddrokosov@sberdevices.ru/
    [12] https://lore.kernel.org/all/20230321193014.26349-1-ddrokosov@sberdevices.ru/
    [13] https://lore.kernel.org/all/20230404155332.9571-1-ddrokosov@sberdevices.ru/
    [14] https://lore.kernel.org/linux-amlogic/20230405195927.13487-1-ddrokosov@sberdevices.ru/
    [15] https://lore.kernel.org/all/20230426095805.15338-1-ddrokosov@sberdevices.ru/

Dmitry Rokosov (6):
  clk: meson: make pll rst bit as optional
  clk: meson: introduce new pll power-on sequence for A1 SoC family
  dt-bindings: clock: meson: add A1 PLL clock controller bindings
  clk: meson: a1: add Amlogic A1 PLL clock controller driver
  dt-bindings: clock: meson: add A1 Peripherals clock controller
    bindings
  clk: meson: a1: add Amlogic A1 Peripherals clock controller driver

 .../clock/amlogic,a1-peripherals-clkc.yaml    |   73 +
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   |   59 +
 MAINTAINERS                                   |    1 +
 drivers/clk/meson/Kconfig                     |   20 +
 drivers/clk/meson/Makefile                    |    2 +
 drivers/clk/meson/a1-peripherals.c            | 2273 +++++++++++++++++
 drivers/clk/meson/a1-peripherals.h            |  113 +
 drivers/clk/meson/a1-pll.c                    |  356 +++
 drivers/clk/meson/a1-pll.h                    |   47 +
 drivers/clk/meson/clk-pll.c                   |   47 +-
 drivers/clk/meson/clk-pll.h                   |    2 +
 .../clock/amlogic,a1-peripherals-clkc.h       |  115 +
 .../dt-bindings/clock/amlogic,a1-pll-clkc.h   |   20 +
 13 files changed, 3121 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
 create mode 100644 drivers/clk/meson/a1-peripherals.c
 create mode 100644 drivers/clk/meson/a1-peripherals.h
 create mode 100644 drivers/clk/meson/a1-pll.c
 create mode 100644 drivers/clk/meson/a1-pll.h
 create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
 create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h

-- 
2.36.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-17 13:33 ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
and Audio. The audio clock controller is different from others, but the
rest are very similar from a functional and regmap point of view.
This patch series add support for Amlogic A1 PLL and Peripherals clock
drivers.
It blocks all A1 peripherals mainline support and a couple of patch series,
which were already reviewed and acked, but weren't merged due to pending
clock controller drivers series, e.g.
https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/

TODO: CPU and Audio clock controllers are not included in this patch
series, it will be sent later. The following clks from these controllers
are not supported for now:
* Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
   pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
   audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
   audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
   audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
   audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
   audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c

* CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
            cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk

Validation:
* to double check all clk flags run below helper script:
    pushd /sys/kernel/debug/clk
    for f in *; do
        if [[ -f "$f/clk_flags" ]]; then
            flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
            echo -e "$f: $flags"
        fi
    done
    popd

* to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
  with jq post-processing:
    $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json

* to debug clk rate propagation, compile kernel with the following
  definition:
    $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
  after that, clk_rate debug node for each clock will be available for
  write operation

Changes v15 since v14 as [15]:
    - rename all dt bindings related to A1 Peripherals Clock Controller
      from "*a1-clkc*" to "*a1-peripherals-clkc*"
    - change COMMON_CLK_A1 config to COMMON_CLK_A1_PERIPHERALS
    - rename compatible string from "a1-clkc" to "a1-peripherals-clkc"
    - open the SD_EMMC_SEL2 clock object to public dt bindings due to
      several hardware issues during auto-reparenting with rate
      propagation; currently, the Meson MMC driver initializes its
      parent using an assigned-clocks mechanism and sets an appropriate
      rate. A related patch for meson-a1.dtsi will be provided after the
      clock patch series is merged
    - remove 'driver' keyword from dt bindings commit msgs and patchsets
    - make English grammar better!

Changes v14 since v13 at [14]:
    - remove the term "Meson" from all patchsets or replace it with
      "Amlogic"
    - purge extra commas as per Martin's suggestion
    - drop the unneeded use of of_match_ptr(), since all Meson clock
      drivers depend on the ARM64 config which selects CONFIG_OF by default

Changes v13 since v12 at [13]:
    - make the clock object registration order from the roots to the leaves
    - rearrange the clkids following above rule

Changes v12 since v11 at [12]:
    - split the DT bindings patchset into two patches: one for the PLL clock
      controller driver, and one for the peripherals clock controller driver
    - to satisfy the DT binding checker, use fake references to the
      peripherals clock controller in the PLL DT bindings schema, and then
      replace them with real references when the peripherals bindings
      become available.
    - remove the public/private clocks concept from both controllers,
      and instead use a linear clkid list with both exposed and internal
      objects, all of which are registered in the clock provider
    - combine all comments about RTC children with the flag
      'CLK_SET_RATE_NO_REPARENT' into a single item with multiple
      references to it

Changes v11 since v10 at [11]:
    - change include/dt-bindings license to proper value required for
      bindings files: 'GPL-2.0-only OR BSD-2-Clause'
    - pll and peripherals clocks are split into public and private parts;
      public clocks are available for external consumers through the DT layer,
      private clocks include internal muxes and dividers of composite clocks,
      they are placed inside clock controller driver without external access
    - make public clks CLKID bindings continuous
    - mark the following clock muxes as NO_REPARENT and add them to
      public clocks list: GEN_SEL, DSPA_A_SEL, DSPA_B_SEL, DSPB_A_SEL,
      DSP_B_B_SEL, PWM_A_SEL, PWM_B_SEL, PWM_C_SEL, PWM_D_SEL,
      PWM_E_SEL, PWM_F_SEL, CECA_32K_SEL, CECB_32K_SEL; each of them can
      be inherited from more accurate RTC clock and sometimes it's
      required to forbid reparenting in such situation; also GEN_SEL can
      be connected to external PAD and should not change parent
      automatically due to rate propagation. For such clocks user must
      setup parents on the DT side

Changes v10 since v9 at [10]:
    - split general clk-pll changes into two different patchsets:
      optional rst usage and new power sequence
    - squash dt bindings patchsets to avoid chicken-or-the-egg problem
      during run dt binding check routines
    - add vendor prefix to PLL and Peripherals clkcs bindings filenames
    - clear managed hifi_pll fields from initial poke table
    - move DSPA_SEL, DSPB_SEL and SARADC_SEL to private clkid table,
      because it should not be opened for direct usage
    - pwm_a clk used for voltage regulation is not critical anymore, it
      must be included to the proper cpu voltage regulation setup (will
      be available in the next patch series)
    - as discussed with Jerome, dspX clks are simple clocks and it
      should be enabled/disabled/ignored/anything else from appropriate
      DSP driver, so remove CLK_IGNORE_UNUSED tags
    - provide more understandable comments and remove irrelevant (I hope so)
    - remove CONFIG_OF usage, because it's redundant
    - fix license issue, it's GPL-2.0+ only in the current version
    - some commit msgs rewording

Changes v9 since v8 at [9]:
    - remove common a1-clkc driver for the first version of a1 clock
      controllers as Jerome suggested (it will be discussed after s4 and
      a1 clks landed, hope so)
    - replace inherited a1-pll clk_pll_ops with common ops and
    оло  introduce custom A1 PLL logic under MESON_PARM_APPLICABLE()
      conditions
    - rename xtal depended clocks in PLL and Peripherals domains
    - remove 'a1_' prefix for all clocks, because they are already
      inside A1 driver, it's redundant
    - change udelay() to usleep_range() as preferred for small msec
      amount
    - purge all double quotes from the yaml schemas
    - use proper dt node names following kernel guidelines
      https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
    - use devm_platform_ioremap_resource() instead of simple
      devm_ioremap_resource()
    - mark all dspX clocks as CLK_IGNORE_UNUSED, because we do not want
      to touch these clocks during CCF initialization due to possible
      workload execution on it started from bootloader; in this case
      bootloader already made all initialization stuff for dspX
    - also mark all dspX with NO_REPARENT tag, because from dspX clocks
      we want to select proper clk source from device tree

Changes v8 since v7 at [8]:
    - introduced a1-clkc common driver for all A1 clock controllers
    - exported meson_clk_pll_wait_lock symbol
    - supported meson-a1-clkc common driver in the a1-pll and a1 clkc
    - inherited a1-pll from the base clk-pll driver, implemented own
      version of init/enable/disable/enabled routines; rate calculating
      logic is fully the same
    - aligned CLKID-related definitions with CLKID list from order
      perspective to remove holes and permutations
    - corrected Kconfig dependencies and types
    - provided correct MODULE_AUTHORs()
    - optimized and fixed up some clock relationships
    - removed unused register offset definitions
    - fixed up A1 PLL and Peripherals clkc dtb_check errors
    - fixed clk_summary kernel panic due to missing a1_pad_ctrl
      clk_regmap definition
    - included PLL and Peripherals clk controllers to the base a1 dts
    - The previous v7 version [8] had several logic and style problems,
      all of them are resolved in this version. Original Jian Hu v7 patches
      are not touched, and all additional fixes are implemented in separate
      patches. Patch "clk: meson: add support for A1 PLL clock ops" is
      removed, because a1-pll clk driver inherits all stuff from clk-pll
      base driver, just implements custom init/enable/disable/is_enabled
      callbacks.

Changes v7 since v6 at [7]:
    - fix 'dt_binding_check' compiling error
    - add acked-by

Changes v6 since v5 at [6]:
    - fix yaml file
    - add rst/current_en/l_detect parm detection
    - remove 'meson_eeclkc_data' in a1.c and a1-pll.c

Changes v5 since v4 at [5]:
    - change yaml GPL
    - drop meson-eeclk.c patch, add probe function in each driver
    - add CLK_IS_CRITICAL for sys_clk clock, drop the flag for sys_a
      and sys_b
    - add new parm for pll, add protection for rst parm
    - drop flag for a1_fixed_pll
    - remove the same comment for fclk_div, add "refer to"
    - add critical flag for a1_sys_clk
    - remove rtc table
    - rename a1_dspa_en_dspa and a1_dspb_en_dspb
    - remove useless comment

Changes v4 since v3 at [3]:
    - fix reparenting orphan failed, it depends on jerome's patch [4]
    - fix changelist in v3 about reparenting orphan
    - remove the dts patch 

Changes v3 since v2 at [2]:
    - add probe function for A1
    - separate the clock driver into two patch
    - change some clock flags and ops
    - add support for a1 PLL ops
    - add A1 clock node
    - fix reparenting orphan clock failed, registering xtal_fixpll
      and xtal_hifipll after the provider registration, it is not
      a best way.

Changes v2 since v1 at [1]:
    - place A1 config alphabetically
    - add actual reason for RO ops, CLK_IS_CRITICAL, CLK_IGNORE_UNUSED
    - separate the driver into two driver: peripheral and pll driver
    - delete CLK_IGNORE_UNUSED flag for pwm b/c/d/e/f clock, dsp clock
    - delete the change in Kconfig.platforms, address to Kevin alone
    - remove the useless comments
    - modify the meson pll driver to support A1 PLLs

Links:
    [1] https://lkml.kernel.org/r/1569411888-98116-1-git-send-email-jian.hu@amlogic.com
    [2] https://lkml.kernel.org/r/1571382865-41978-1-git-send-email-jian.hu@amlogic.com
    [3] https://lkml.kernel.org/r/20191129144605.182774-1-jian.hu@amlogic.com
    [4] https://lkml.kernel.org/r/20191203080805.104628-1-jbrunet@baylibre.com
    [5] https://lkml.kernel.org/r/20191206074052.15557-1-jian.hu@amlogic.com
    [6] https://lkml.kernel.org/r/20191227094606.143637-1-jian.hu@amlogic.com
    [7] https://lkml.kernel.org/r/20200116080440.118679-1-jian.hu@amlogic.com
    [8] https://lore.kernel.org/linux-amlogic/20200120034937.128600-1-jian.hu@amlogic.com/
    [9] https://lore.kernel.org/linux-amlogic/20221201225703.6507-1-ddrokosov@sberdevices.ru/
    [10] https://lore.kernel.org/all/20230301183759.16163-1-ddrokosov@sberdevices.ru/
    [11] https://lore.kernel.org/all/20230313201259.19998-1-ddrokosov@sberdevices.ru/
    [12] https://lore.kernel.org/all/20230321193014.26349-1-ddrokosov@sberdevices.ru/
    [13] https://lore.kernel.org/all/20230404155332.9571-1-ddrokosov@sberdevices.ru/
    [14] https://lore.kernel.org/linux-amlogic/20230405195927.13487-1-ddrokosov@sberdevices.ru/
    [15] https://lore.kernel.org/all/20230426095805.15338-1-ddrokosov@sberdevices.ru/

Dmitry Rokosov (6):
  clk: meson: make pll rst bit as optional
  clk: meson: introduce new pll power-on sequence for A1 SoC family
  dt-bindings: clock: meson: add A1 PLL clock controller bindings
  clk: meson: a1: add Amlogic A1 PLL clock controller driver
  dt-bindings: clock: meson: add A1 Peripherals clock controller
    bindings
  clk: meson: a1: add Amlogic A1 Peripherals clock controller driver

 .../clock/amlogic,a1-peripherals-clkc.yaml    |   73 +
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   |   59 +
 MAINTAINERS                                   |    1 +
 drivers/clk/meson/Kconfig                     |   20 +
 drivers/clk/meson/Makefile                    |    2 +
 drivers/clk/meson/a1-peripherals.c            | 2273 +++++++++++++++++
 drivers/clk/meson/a1-peripherals.h            |  113 +
 drivers/clk/meson/a1-pll.c                    |  356 +++
 drivers/clk/meson/a1-pll.h                    |   47 +
 drivers/clk/meson/clk-pll.c                   |   47 +-
 drivers/clk/meson/clk-pll.h                   |    2 +
 .../clock/amlogic,a1-peripherals-clkc.h       |  115 +
 .../dt-bindings/clock/amlogic,a1-pll-clkc.h   |   20 +
 13 files changed, 3121 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
 create mode 100644 drivers/clk/meson/a1-peripherals.c
 create mode 100644 drivers/clk/meson/a1-peripherals.h
 create mode 100644 drivers/clk/meson/a1-pll.c
 create mode 100644 drivers/clk/meson/a1-pll.h
 create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
 create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h

-- 
2.36.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v15 1/6] clk: meson: make pll rst bit as optional
  2023-05-17 13:33 ` Dmitry Rokosov
  (?)
@ 2023-05-17 13:33   ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Compared with the previous SoCs, self-adaption current module
is newly added for A1, and there is no reset parameter except the
fixed pll. Since we use clk-pll generic driver for A1 pll
implementation, rst bit should be optional to support new behavior.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/clk-pll.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index afefeba6e458..314ca945a4d0 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -295,10 +295,14 @@ static int meson_clk_pll_init(struct clk_hw *hw)
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
 	if (pll->init_count) {
-		meson_parm_write(clk->map, &pll->rst, 1);
+		if (MESON_PARM_APPLICABLE(&pll->rst))
+			meson_parm_write(clk->map, &pll->rst, 1);
+
 		regmap_multi_reg_write(clk->map, pll->init_regs,
 				       pll->init_count);
-		meson_parm_write(clk->map, &pll->rst, 0);
+
+		if (MESON_PARM_APPLICABLE(&pll->rst))
+			meson_parm_write(clk->map, &pll->rst, 0);
 	}
 
 	return 0;
@@ -309,8 +313,11 @@ static int meson_clk_pll_is_enabled(struct clk_hw *hw)
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
-	if (meson_parm_read(clk->map, &pll->rst) ||
-	    !meson_parm_read(clk->map, &pll->en) ||
+	if (MESON_PARM_APPLICABLE(&pll->rst) &&
+	    meson_parm_read(clk->map, &pll->rst))
+		return 0;
+
+	if (!meson_parm_read(clk->map, &pll->en) ||
 	    !meson_parm_read(clk->map, &pll->l))
 		return 0;
 
@@ -341,13 +348,15 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
 		return 0;
 
 	/* Make sure the pll is in reset */
-	meson_parm_write(clk->map, &pll->rst, 1);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 1);
 
 	/* Enable the pll */
 	meson_parm_write(clk->map, &pll->en, 1);
 
 	/* Take the pll out reset */
-	meson_parm_write(clk->map, &pll->rst, 0);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 0);
 
 	if (meson_clk_pll_wait_lock(hw))
 		return -EIO;
@@ -361,7 +370,8 @@ static void meson_clk_pll_disable(struct clk_hw *hw)
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
 	/* Put the pll is in reset */
-	meson_parm_write(clk->map, &pll->rst, 1);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 1);
 
 	/* Disable the pll */
 	meson_parm_write(clk->map, &pll->en, 0);
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 1/6] clk: meson: make pll rst bit as optional
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Compared with the previous SoCs, self-adaption current module
is newly added for A1, and there is no reset parameter except the
fixed pll. Since we use clk-pll generic driver for A1 pll
implementation, rst bit should be optional to support new behavior.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/clk-pll.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index afefeba6e458..314ca945a4d0 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -295,10 +295,14 @@ static int meson_clk_pll_init(struct clk_hw *hw)
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
 	if (pll->init_count) {
-		meson_parm_write(clk->map, &pll->rst, 1);
+		if (MESON_PARM_APPLICABLE(&pll->rst))
+			meson_parm_write(clk->map, &pll->rst, 1);
+
 		regmap_multi_reg_write(clk->map, pll->init_regs,
 				       pll->init_count);
-		meson_parm_write(clk->map, &pll->rst, 0);
+
+		if (MESON_PARM_APPLICABLE(&pll->rst))
+			meson_parm_write(clk->map, &pll->rst, 0);
 	}
 
 	return 0;
@@ -309,8 +313,11 @@ static int meson_clk_pll_is_enabled(struct clk_hw *hw)
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
-	if (meson_parm_read(clk->map, &pll->rst) ||
-	    !meson_parm_read(clk->map, &pll->en) ||
+	if (MESON_PARM_APPLICABLE(&pll->rst) &&
+	    meson_parm_read(clk->map, &pll->rst))
+		return 0;
+
+	if (!meson_parm_read(clk->map, &pll->en) ||
 	    !meson_parm_read(clk->map, &pll->l))
 		return 0;
 
@@ -341,13 +348,15 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
 		return 0;
 
 	/* Make sure the pll is in reset */
-	meson_parm_write(clk->map, &pll->rst, 1);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 1);
 
 	/* Enable the pll */
 	meson_parm_write(clk->map, &pll->en, 1);
 
 	/* Take the pll out reset */
-	meson_parm_write(clk->map, &pll->rst, 0);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 0);
 
 	if (meson_clk_pll_wait_lock(hw))
 		return -EIO;
@@ -361,7 +370,8 @@ static void meson_clk_pll_disable(struct clk_hw *hw)
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
 	/* Put the pll is in reset */
-	meson_parm_write(clk->map, &pll->rst, 1);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 1);
 
 	/* Disable the pll */
 	meson_parm_write(clk->map, &pll->en, 0);
-- 
2.36.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 1/6] clk: meson: make pll rst bit as optional
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Compared with the previous SoCs, self-adaption current module
is newly added for A1, and there is no reset parameter except the
fixed pll. Since we use clk-pll generic driver for A1 pll
implementation, rst bit should be optional to support new behavior.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/clk-pll.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index afefeba6e458..314ca945a4d0 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -295,10 +295,14 @@ static int meson_clk_pll_init(struct clk_hw *hw)
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
 	if (pll->init_count) {
-		meson_parm_write(clk->map, &pll->rst, 1);
+		if (MESON_PARM_APPLICABLE(&pll->rst))
+			meson_parm_write(clk->map, &pll->rst, 1);
+
 		regmap_multi_reg_write(clk->map, pll->init_regs,
 				       pll->init_count);
-		meson_parm_write(clk->map, &pll->rst, 0);
+
+		if (MESON_PARM_APPLICABLE(&pll->rst))
+			meson_parm_write(clk->map, &pll->rst, 0);
 	}
 
 	return 0;
@@ -309,8 +313,11 @@ static int meson_clk_pll_is_enabled(struct clk_hw *hw)
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
-	if (meson_parm_read(clk->map, &pll->rst) ||
-	    !meson_parm_read(clk->map, &pll->en) ||
+	if (MESON_PARM_APPLICABLE(&pll->rst) &&
+	    meson_parm_read(clk->map, &pll->rst))
+		return 0;
+
+	if (!meson_parm_read(clk->map, &pll->en) ||
 	    !meson_parm_read(clk->map, &pll->l))
 		return 0;
 
@@ -341,13 +348,15 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
 		return 0;
 
 	/* Make sure the pll is in reset */
-	meson_parm_write(clk->map, &pll->rst, 1);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 1);
 
 	/* Enable the pll */
 	meson_parm_write(clk->map, &pll->en, 1);
 
 	/* Take the pll out reset */
-	meson_parm_write(clk->map, &pll->rst, 0);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 0);
 
 	if (meson_clk_pll_wait_lock(hw))
 		return -EIO;
@@ -361,7 +370,8 @@ static void meson_clk_pll_disable(struct clk_hw *hw)
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
 	/* Put the pll is in reset */
-	meson_parm_write(clk->map, &pll->rst, 1);
+	if (MESON_PARM_APPLICABLE(&pll->rst))
+		meson_parm_write(clk->map, &pll->rst, 1);
 
 	/* Disable the pll */
 	meson_parm_write(clk->map, &pll->en, 0);
-- 
2.36.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 2/6] clk: meson: introduce new pll power-on sequence for A1 SoC family
  2023-05-17 13:33 ` Dmitry Rokosov
  (?)
@ 2023-05-17 13:33   ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Modern meson PLL IPs are a little bit different from early known PLLs.
The main difference is located in the init/enable/disable sequences; the
rate logic is the same.

In A1 PLL, the PLL enable sequence is different, so add new optional pll
reg bits and use the new power-on sequence to enable the PLL:
    1. enable the pll, delay for 10us
    2. enable the pll self-adaption current module, delay for 40us
    3. enable the lock detect module

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/clk-pll.c | 23 +++++++++++++++++++++++
 drivers/clk/meson/clk-pll.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 314ca945a4d0..56ec2210f1ad 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -358,6 +358,25 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
 	if (MESON_PARM_APPLICABLE(&pll->rst))
 		meson_parm_write(clk->map, &pll->rst, 0);
 
+	/*
+	 * Compared with the previous SoCs, self-adaption current module
+	 * is newly added for A1, keep the new power-on sequence to enable the
+	 * PLL. The sequence is:
+	 * 1. enable the pll, delay for 10us
+	 * 2. enable the pll self-adaption current module, delay for 40us
+	 * 3. enable the lock detect module
+	 */
+	if (MESON_PARM_APPLICABLE(&pll->current_en)) {
+		usleep_range(10, 20);
+		meson_parm_write(clk->map, &pll->current_en, 1);
+		usleep_range(40, 50);
+	};
+
+	if (MESON_PARM_APPLICABLE(&pll->l_detect)) {
+		meson_parm_write(clk->map, &pll->l_detect, 1);
+		meson_parm_write(clk->map, &pll->l_detect, 0);
+	}
+
 	if (meson_clk_pll_wait_lock(hw))
 		return -EIO;
 
@@ -375,6 +394,10 @@ static void meson_clk_pll_disable(struct clk_hw *hw)
 
 	/* Disable the pll */
 	meson_parm_write(clk->map, &pll->en, 0);
+
+	/* Disable PLL internal self-adaption current module */
+	if (MESON_PARM_APPLICABLE(&pll->current_en))
+		meson_parm_write(clk->map, &pll->current_en, 0);
 }
 
 static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
index 367efd0f6410..a2228c0fdce5 100644
--- a/drivers/clk/meson/clk-pll.h
+++ b/drivers/clk/meson/clk-pll.h
@@ -36,6 +36,8 @@ struct meson_clk_pll_data {
 	struct parm frac;
 	struct parm l;
 	struct parm rst;
+	struct parm current_en;
+	struct parm l_detect;
 	const struct reg_sequence *init_regs;
 	unsigned int init_count;
 	const struct pll_params_table *table;
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 2/6] clk: meson: introduce new pll power-on sequence for A1 SoC family
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Modern meson PLL IPs are a little bit different from early known PLLs.
The main difference is located in the init/enable/disable sequences; the
rate logic is the same.

In A1 PLL, the PLL enable sequence is different, so add new optional pll
reg bits and use the new power-on sequence to enable the PLL:
    1. enable the pll, delay for 10us
    2. enable the pll self-adaption current module, delay for 40us
    3. enable the lock detect module

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/clk-pll.c | 23 +++++++++++++++++++++++
 drivers/clk/meson/clk-pll.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 314ca945a4d0..56ec2210f1ad 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -358,6 +358,25 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
 	if (MESON_PARM_APPLICABLE(&pll->rst))
 		meson_parm_write(clk->map, &pll->rst, 0);
 
+	/*
+	 * Compared with the previous SoCs, self-adaption current module
+	 * is newly added for A1, keep the new power-on sequence to enable the
+	 * PLL. The sequence is:
+	 * 1. enable the pll, delay for 10us
+	 * 2. enable the pll self-adaption current module, delay for 40us
+	 * 3. enable the lock detect module
+	 */
+	if (MESON_PARM_APPLICABLE(&pll->current_en)) {
+		usleep_range(10, 20);
+		meson_parm_write(clk->map, &pll->current_en, 1);
+		usleep_range(40, 50);
+	};
+
+	if (MESON_PARM_APPLICABLE(&pll->l_detect)) {
+		meson_parm_write(clk->map, &pll->l_detect, 1);
+		meson_parm_write(clk->map, &pll->l_detect, 0);
+	}
+
 	if (meson_clk_pll_wait_lock(hw))
 		return -EIO;
 
@@ -375,6 +394,10 @@ static void meson_clk_pll_disable(struct clk_hw *hw)
 
 	/* Disable the pll */
 	meson_parm_write(clk->map, &pll->en, 0);
+
+	/* Disable PLL internal self-adaption current module */
+	if (MESON_PARM_APPLICABLE(&pll->current_en))
+		meson_parm_write(clk->map, &pll->current_en, 0);
 }
 
 static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
index 367efd0f6410..a2228c0fdce5 100644
--- a/drivers/clk/meson/clk-pll.h
+++ b/drivers/clk/meson/clk-pll.h
@@ -36,6 +36,8 @@ struct meson_clk_pll_data {
 	struct parm frac;
 	struct parm l;
 	struct parm rst;
+	struct parm current_en;
+	struct parm l_detect;
 	const struct reg_sequence *init_regs;
 	unsigned int init_count;
 	const struct pll_params_table *table;
-- 
2.36.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 2/6] clk: meson: introduce new pll power-on sequence for A1 SoC family
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Modern meson PLL IPs are a little bit different from early known PLLs.
The main difference is located in the init/enable/disable sequences; the
rate logic is the same.

In A1 PLL, the PLL enable sequence is different, so add new optional pll
reg bits and use the new power-on sequence to enable the PLL:
    1. enable the pll, delay for 10us
    2. enable the pll self-adaption current module, delay for 40us
    3. enable the lock detect module

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/clk-pll.c | 23 +++++++++++++++++++++++
 drivers/clk/meson/clk-pll.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 314ca945a4d0..56ec2210f1ad 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -358,6 +358,25 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
 	if (MESON_PARM_APPLICABLE(&pll->rst))
 		meson_parm_write(clk->map, &pll->rst, 0);
 
+	/*
+	 * Compared with the previous SoCs, self-adaption current module
+	 * is newly added for A1, keep the new power-on sequence to enable the
+	 * PLL. The sequence is:
+	 * 1. enable the pll, delay for 10us
+	 * 2. enable the pll self-adaption current module, delay for 40us
+	 * 3. enable the lock detect module
+	 */
+	if (MESON_PARM_APPLICABLE(&pll->current_en)) {
+		usleep_range(10, 20);
+		meson_parm_write(clk->map, &pll->current_en, 1);
+		usleep_range(40, 50);
+	};
+
+	if (MESON_PARM_APPLICABLE(&pll->l_detect)) {
+		meson_parm_write(clk->map, &pll->l_detect, 1);
+		meson_parm_write(clk->map, &pll->l_detect, 0);
+	}
+
 	if (meson_clk_pll_wait_lock(hw))
 		return -EIO;
 
@@ -375,6 +394,10 @@ static void meson_clk_pll_disable(struct clk_hw *hw)
 
 	/* Disable the pll */
 	meson_parm_write(clk->map, &pll->en, 0);
+
+	/* Disable PLL internal self-adaption current module */
+	if (MESON_PARM_APPLICABLE(&pll->current_en))
+		meson_parm_write(clk->map, &pll->current_en, 0);
 }
 
 static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
index 367efd0f6410..a2228c0fdce5 100644
--- a/drivers/clk/meson/clk-pll.h
+++ b/drivers/clk/meson/clk-pll.h
@@ -36,6 +36,8 @@ struct meson_clk_pll_data {
 	struct parm frac;
 	struct parm l;
 	struct parm rst;
+	struct parm current_en;
+	struct parm l_detect;
 	const struct reg_sequence *init_regs;
 	unsigned int init_count;
 	const struct pll_params_table *table;
-- 
2.36.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 3/6] dt-bindings: clock: meson: add A1 PLL clock controller bindings
  2023-05-17 13:33 ` Dmitry Rokosov
  (?)
@ 2023-05-17 13:33   ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov, Rob Herring

Add the documentation and dt bindings for Amlogic A1 PLL clock
controller.
Also include new A1 clock controller dt bindings to MAINTAINERS.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   | 58 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 .../dt-bindings/clock/amlogic,a1-pll-clkc.h   | 20 +++++++
 3 files changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
new file mode 100644
index 000000000000..5c6fa620a63c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a1-pll-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A1 PLL Clock Control Unit
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+  - Jerome Brunet <jbrunet@baylibre.com>
+  - Jian Hu <jian.hu@jian.hu.com>
+  - Dmitry Rokosov <ddrokosov@sberdevices.ru>
+
+properties:
+  compatible:
+    const: amlogic,a1-pll-clkc
+
+  '#clock-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: input fixpll_in
+      - description: input hifipll_in
+
+  clock-names:
+    items:
+      - const: fixpll_in
+      - const: hifipll_in
+
+required:
+  - compatible
+  - '#clock-cells'
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@7c80 {
+            compatible = "amlogic,a1-pll-clkc";
+            reg = <0 0x7c80 0 0x18c>;
+            #clock-cells = <1>;
+            clocks = <&clkc_periphs_fixpll_in>,
+                     <&clkc_periphs_hifipll_in>;
+            clock-names = "fixpll_in", "hifipll_in";
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 39ff1a717625..8438bc9bd636 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1895,6 +1895,7 @@ L:	linux-amlogic@lists.infradead.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/amlogic*
 F:	drivers/clk/meson/
+F:	include/dt-bindings/clock/a1*
 F:	include/dt-bindings/clock/gxbb*
 F:	include/dt-bindings/clock/meson*
 
diff --git a/include/dt-bindings/clock/amlogic,a1-pll-clkc.h b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
new file mode 100644
index 000000000000..01fb8164ac29
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PLL_CLKC_H
+#define __A1_PLL_CLKC_H
+
+#define CLKID_FIXED_PLL		1
+#define CLKID_FCLK_DIV2		6
+#define CLKID_FCLK_DIV3		7
+#define CLKID_FCLK_DIV5		8
+#define CLKID_FCLK_DIV7		9
+#define CLKID_HIFI_PLL		10
+
+#endif /* __A1_PLL_CLKC_H */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 3/6] dt-bindings: clock: meson: add A1 PLL clock controller bindings
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov, Rob Herring

Add the documentation and dt bindings for Amlogic A1 PLL clock
controller.
Also include new A1 clock controller dt bindings to MAINTAINERS.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   | 58 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 .../dt-bindings/clock/amlogic,a1-pll-clkc.h   | 20 +++++++
 3 files changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
new file mode 100644
index 000000000000..5c6fa620a63c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a1-pll-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A1 PLL Clock Control Unit
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+  - Jerome Brunet <jbrunet@baylibre.com>
+  - Jian Hu <jian.hu@jian.hu.com>
+  - Dmitry Rokosov <ddrokosov@sberdevices.ru>
+
+properties:
+  compatible:
+    const: amlogic,a1-pll-clkc
+
+  '#clock-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: input fixpll_in
+      - description: input hifipll_in
+
+  clock-names:
+    items:
+      - const: fixpll_in
+      - const: hifipll_in
+
+required:
+  - compatible
+  - '#clock-cells'
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@7c80 {
+            compatible = "amlogic,a1-pll-clkc";
+            reg = <0 0x7c80 0 0x18c>;
+            #clock-cells = <1>;
+            clocks = <&clkc_periphs_fixpll_in>,
+                     <&clkc_periphs_hifipll_in>;
+            clock-names = "fixpll_in", "hifipll_in";
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 39ff1a717625..8438bc9bd636 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1895,6 +1895,7 @@ L:	linux-amlogic@lists.infradead.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/amlogic*
 F:	drivers/clk/meson/
+F:	include/dt-bindings/clock/a1*
 F:	include/dt-bindings/clock/gxbb*
 F:	include/dt-bindings/clock/meson*
 
diff --git a/include/dt-bindings/clock/amlogic,a1-pll-clkc.h b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
new file mode 100644
index 000000000000..01fb8164ac29
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PLL_CLKC_H
+#define __A1_PLL_CLKC_H
+
+#define CLKID_FIXED_PLL		1
+#define CLKID_FCLK_DIV2		6
+#define CLKID_FCLK_DIV3		7
+#define CLKID_FCLK_DIV5		8
+#define CLKID_FCLK_DIV7		9
+#define CLKID_HIFI_PLL		10
+
+#endif /* __A1_PLL_CLKC_H */
-- 
2.36.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 3/6] dt-bindings: clock: meson: add A1 PLL clock controller bindings
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov, Rob Herring

Add the documentation and dt bindings for Amlogic A1 PLL clock
controller.
Also include new A1 clock controller dt bindings to MAINTAINERS.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   | 58 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 .../dt-bindings/clock/amlogic,a1-pll-clkc.h   | 20 +++++++
 3 files changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
new file mode 100644
index 000000000000..5c6fa620a63c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a1-pll-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A1 PLL Clock Control Unit
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+  - Jerome Brunet <jbrunet@baylibre.com>
+  - Jian Hu <jian.hu@jian.hu.com>
+  - Dmitry Rokosov <ddrokosov@sberdevices.ru>
+
+properties:
+  compatible:
+    const: amlogic,a1-pll-clkc
+
+  '#clock-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: input fixpll_in
+      - description: input hifipll_in
+
+  clock-names:
+    items:
+      - const: fixpll_in
+      - const: hifipll_in
+
+required:
+  - compatible
+  - '#clock-cells'
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@7c80 {
+            compatible = "amlogic,a1-pll-clkc";
+            reg = <0 0x7c80 0 0x18c>;
+            #clock-cells = <1>;
+            clocks = <&clkc_periphs_fixpll_in>,
+                     <&clkc_periphs_hifipll_in>;
+            clock-names = "fixpll_in", "hifipll_in";
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 39ff1a717625..8438bc9bd636 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1895,6 +1895,7 @@ L:	linux-amlogic@lists.infradead.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/amlogic*
 F:	drivers/clk/meson/
+F:	include/dt-bindings/clock/a1*
 F:	include/dt-bindings/clock/gxbb*
 F:	include/dt-bindings/clock/meson*
 
diff --git a/include/dt-bindings/clock/amlogic,a1-pll-clkc.h b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
new file mode 100644
index 000000000000..01fb8164ac29
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PLL_CLKC_H
+#define __A1_PLL_CLKC_H
+
+#define CLKID_FIXED_PLL		1
+#define CLKID_FCLK_DIV2		6
+#define CLKID_FCLK_DIV3		7
+#define CLKID_FCLK_DIV5		8
+#define CLKID_FCLK_DIV7		9
+#define CLKID_HIFI_PLL		10
+
+#endif /* __A1_PLL_CLKC_H */
-- 
2.36.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 4/6] clk: meson: a1: add Amlogic A1 PLL clock controller driver
  2023-05-17 13:33 ` Dmitry Rokosov
  (?)
@ 2023-05-17 13:33   ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Introduce PLL clock controller for Amlogic A1 SoC family.
The clock unit is an APB slave module that is designed for generating all
of the internal and system clocks.
The SoC uses an external 24MHz crystal; there are 4 internal PLLs:
SYS_PLL/HIFI_PLL/USB_PLL/(FIXPLL), these PLLs generate 27 clock sources.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 drivers/clk/meson/Kconfig  |  10 ++
 drivers/clk/meson/Makefile |   1 +
 drivers/clk/meson/a1-pll.c | 356 +++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/a1-pll.h |  47 +++++
 4 files changed, 414 insertions(+)
 create mode 100644 drivers/clk/meson/a1-pll.c
 create mode 100644 drivers/clk/meson/a1-pll.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index fc002c155bc3..693c4cf60f27 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -99,6 +99,16 @@ config COMMON_CLK_AXG_AUDIO
 	  Support for the audio clock controller on AmLogic A113D devices,
 	  aka axg, Say Y if you want audio subsystem to work.
 
+config COMMON_CLK_A1_PLL
+	tristate "Amlogic A1 SoC PLL controller support"
+	depends on ARM64
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_PLL
+	help
+	  Support for the PLL clock controller on Amlogic A113L based
+	  device, A1 SoC Family. Say Y if you want A1 PLL clock controller
+	  to work.
+
 config COMMON_CLK_G12A
 	tristate "G12 and SM1 SoC clock controllers support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 6eca2a406ee3..2f17f475a48f 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
+obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.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
diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c
new file mode 100644
index 000000000000..bd2f1d1ec6e4
--- /dev/null
+++ b/drivers/clk/meson/a1-pll.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "a1-pll.h"
+#include "clk-regmap.h"
+
+static struct clk_regmap 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,
+		},
+		.frac = {
+			.reg_off = ANACTRL_FIXPLL_CTRL1,
+			.shift   = 0,
+			.width   = 19,
+		},
+		.l = {
+			.reg_off = ANACTRL_FIXPLL_STS,
+			.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 = "fixpll_in",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fixed_pll = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 20,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fixed_pll",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll_dco.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct pll_mult_range hifi_pll_mult_range = {
+	.min = 32,
+	.max = 64,
+};
+
+static const struct reg_sequence hifi_init_regs[] = {
+	{ .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x01800000 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00001100 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x100a1100 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x00302000 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x01f18000 },
+};
+
+static struct clk_regmap hifi_pll = {
+	.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,
+		},
+		.frac = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL1,
+			.shift   = 0,
+			.width   = 19,
+		},
+		.l = {
+			.reg_off = ANACTRL_HIFIPLL_STS,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.current_en = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL0,
+			.shift   = 26,
+			.width   = 1,
+		},
+		.l_detect = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL2,
+			.shift   = 6,
+			.width   = 1,
+		},
+		.range = &hifi_pll_mult_range,
+		.init_regs = hifi_init_regs,
+		.init_count = ARRAY_SIZE(hifi_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hifi_pll",
+		.ops = &meson_clk_pll_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "hifipll_in",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 21,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div2_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by DDR clock in BL2 firmware
+		 * and is required by the platform to operate correctly.
+		 * Until the following condition are met, we need this clock to
+		 * be marked as critical:
+		 * a) Mark the clock used by a firmware resource, if possible
+		 * b) CCF has a clock hand-off mechanism to make the sure the
+		 *    clock stays on until the proper driver comes along
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div3 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 22,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div3",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div3_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by APB bus which is set in boot ROM code
+		 * and is required by the platform to operate correctly.
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div5 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 23,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div5",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div5_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by AXI bus which setted in Romcode
+		 * and is required by the platform to operate correctly.
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div7 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div7",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div7_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+/* Array of all clocks registered by this provider */
+static struct clk_hw_onecell_data a1_pll_clks = {
+	.hws = {
+		[CLKID_FIXED_PLL_DCO]	= &fixed_pll_dco.hw,
+		[CLKID_FIXED_PLL]	= &fixed_pll.hw,
+		[CLKID_FCLK_DIV2_DIV]	= &fclk_div2_div.hw,
+		[CLKID_FCLK_DIV3_DIV]	= &fclk_div3_div.hw,
+		[CLKID_FCLK_DIV5_DIV]	= &fclk_div5_div.hw,
+		[CLKID_FCLK_DIV7_DIV]	= &fclk_div7_div.hw,
+		[CLKID_FCLK_DIV2]	= &fclk_div2.hw,
+		[CLKID_FCLK_DIV3]	= &fclk_div3.hw,
+		[CLKID_FCLK_DIV5]	= &fclk_div5.hw,
+		[CLKID_FCLK_DIV7]	= &fclk_div7.hw,
+		[CLKID_HIFI_PLL]	= &hifi_pll.hw,
+		[NR_PLL_CLKS]		= NULL,
+	},
+	.num = NR_PLL_CLKS,
+};
+
+static struct clk_regmap *const a1_pll_regmaps[] = {
+	&fixed_pll_dco,
+	&fixed_pll,
+	&fclk_div2,
+	&fclk_div3,
+	&fclk_div5,
+	&fclk_div7,
+	&hifi_pll,
+};
+
+static struct regmap_config a1_pll_regmap_cfg = {
+	.reg_bits   = 32,
+	.val_bits   = 32,
+	.reg_stride = 4,
+};
+
+static int meson_a1_pll_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *base;
+	struct regmap *map;
+	int clkid, i, err;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "can't ioremap resource\n");
+
+	map = devm_regmap_init_mmio(dev, base, &a1_pll_regmap_cfg);
+	if (IS_ERR(map))
+		return dev_err_probe(dev, PTR_ERR(map),
+				     "can't init regmap mmio region\n");
+
+	/* Populate regmap for the regmap backed clocks */
+	for (i = 0; i < ARRAY_SIZE(a1_pll_regmaps); i++)
+		a1_pll_regmaps[i]->map = map;
+
+	/* Register clocks */
+	for (clkid = 0; clkid < a1_pll_clks.num; clkid++) {
+		err = devm_clk_hw_register(dev, a1_pll_clks.hws[clkid]);
+		if (err)
+			return dev_err_probe(dev, err,
+					     "clock[%d] registration failed\n",
+					     clkid);
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &a1_pll_clks);
+}
+
+static const struct of_device_id a1_pll_clkc_match_table[] = {
+	{ .compatible = "amlogic,a1-pll-clkc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, a1_pll_clkc_match_table);
+
+static struct platform_driver a1_pll_clkc_driver = {
+	.probe = meson_a1_pll_probe,
+	.driver = {
+		.name = "a1-pll-clkc",
+		.of_match_table = a1_pll_clkc_match_table,
+	},
+};
+
+module_platform_driver(a1_pll_clkc_driver);
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/a1-pll.h b/drivers/clk/meson/a1-pll.h
new file mode 100644
index 000000000000..29726651b056
--- /dev/null
+++ b/drivers/clk/meson/a1-pll.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Amlogic A1 PLL Clock Controller internals
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PLL_H
+#define __A1_PLL_H
+
+#include "clk-pll.h"
+
+/* PLL register offset */
+#define ANACTRL_FIXPLL_CTRL0	0x0
+#define ANACTRL_FIXPLL_CTRL1	0x4
+#define ANACTRL_FIXPLL_STS	0x14
+#define ANACTRL_HIFIPLL_CTRL0	0xc0
+#define ANACTRL_HIFIPLL_CTRL1	0xc4
+#define ANACTRL_HIFIPLL_CTRL2	0xc8
+#define ANACTRL_HIFIPLL_CTRL3	0xcc
+#define ANACTRL_HIFIPLL_CTRL4	0xd0
+#define ANACTRL_HIFIPLL_STS	0xd4
+
+/* include the CLKIDs that have been made part of the DT binding */
+#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>
+
+/*
+ * CLKID index values for internal clocks
+ *
+ * These indices are entirely contrived and do not map onto the hardware.
+ * It has now been decided to expose everything by default in the DT header:
+ * include/dt-bindings/clock/a1-pll-clkc.h. Only the clocks ids we don't want
+ * to expose, such as the internal muxes and dividers of composite clocks,
+ * will remain defined here.
+ */
+#define CLKID_FIXED_PLL_DCO	0
+#define CLKID_FCLK_DIV2_DIV	2
+#define CLKID_FCLK_DIV3_DIV	3
+#define CLKID_FCLK_DIV5_DIV	4
+#define CLKID_FCLK_DIV7_DIV	5
+#define NR_PLL_CLKS		11
+
+#endif /* __A1_PLL_H */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 4/6] clk: meson: a1: add Amlogic A1 PLL clock controller driver
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Introduce PLL clock controller for Amlogic A1 SoC family.
The clock unit is an APB slave module that is designed for generating all
of the internal and system clocks.
The SoC uses an external 24MHz crystal; there are 4 internal PLLs:
SYS_PLL/HIFI_PLL/USB_PLL/(FIXPLL), these PLLs generate 27 clock sources.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 drivers/clk/meson/Kconfig  |  10 ++
 drivers/clk/meson/Makefile |   1 +
 drivers/clk/meson/a1-pll.c | 356 +++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/a1-pll.h |  47 +++++
 4 files changed, 414 insertions(+)
 create mode 100644 drivers/clk/meson/a1-pll.c
 create mode 100644 drivers/clk/meson/a1-pll.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index fc002c155bc3..693c4cf60f27 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -99,6 +99,16 @@ config COMMON_CLK_AXG_AUDIO
 	  Support for the audio clock controller on AmLogic A113D devices,
 	  aka axg, Say Y if you want audio subsystem to work.
 
+config COMMON_CLK_A1_PLL
+	tristate "Amlogic A1 SoC PLL controller support"
+	depends on ARM64
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_PLL
+	help
+	  Support for the PLL clock controller on Amlogic A113L based
+	  device, A1 SoC Family. Say Y if you want A1 PLL clock controller
+	  to work.
+
 config COMMON_CLK_G12A
 	tristate "G12 and SM1 SoC clock controllers support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 6eca2a406ee3..2f17f475a48f 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
+obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.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
diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c
new file mode 100644
index 000000000000..bd2f1d1ec6e4
--- /dev/null
+++ b/drivers/clk/meson/a1-pll.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "a1-pll.h"
+#include "clk-regmap.h"
+
+static struct clk_regmap 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,
+		},
+		.frac = {
+			.reg_off = ANACTRL_FIXPLL_CTRL1,
+			.shift   = 0,
+			.width   = 19,
+		},
+		.l = {
+			.reg_off = ANACTRL_FIXPLL_STS,
+			.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 = "fixpll_in",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fixed_pll = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 20,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fixed_pll",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll_dco.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct pll_mult_range hifi_pll_mult_range = {
+	.min = 32,
+	.max = 64,
+};
+
+static const struct reg_sequence hifi_init_regs[] = {
+	{ .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x01800000 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00001100 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x100a1100 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x00302000 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x01f18000 },
+};
+
+static struct clk_regmap hifi_pll = {
+	.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,
+		},
+		.frac = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL1,
+			.shift   = 0,
+			.width   = 19,
+		},
+		.l = {
+			.reg_off = ANACTRL_HIFIPLL_STS,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.current_en = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL0,
+			.shift   = 26,
+			.width   = 1,
+		},
+		.l_detect = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL2,
+			.shift   = 6,
+			.width   = 1,
+		},
+		.range = &hifi_pll_mult_range,
+		.init_regs = hifi_init_regs,
+		.init_count = ARRAY_SIZE(hifi_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hifi_pll",
+		.ops = &meson_clk_pll_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "hifipll_in",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 21,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div2_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by DDR clock in BL2 firmware
+		 * and is required by the platform to operate correctly.
+		 * Until the following condition are met, we need this clock to
+		 * be marked as critical:
+		 * a) Mark the clock used by a firmware resource, if possible
+		 * b) CCF has a clock hand-off mechanism to make the sure the
+		 *    clock stays on until the proper driver comes along
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div3 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 22,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div3",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div3_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by APB bus which is set in boot ROM code
+		 * and is required by the platform to operate correctly.
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div5 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 23,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div5",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div5_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by AXI bus which setted in Romcode
+		 * and is required by the platform to operate correctly.
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div7 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div7",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div7_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+/* Array of all clocks registered by this provider */
+static struct clk_hw_onecell_data a1_pll_clks = {
+	.hws = {
+		[CLKID_FIXED_PLL_DCO]	= &fixed_pll_dco.hw,
+		[CLKID_FIXED_PLL]	= &fixed_pll.hw,
+		[CLKID_FCLK_DIV2_DIV]	= &fclk_div2_div.hw,
+		[CLKID_FCLK_DIV3_DIV]	= &fclk_div3_div.hw,
+		[CLKID_FCLK_DIV5_DIV]	= &fclk_div5_div.hw,
+		[CLKID_FCLK_DIV7_DIV]	= &fclk_div7_div.hw,
+		[CLKID_FCLK_DIV2]	= &fclk_div2.hw,
+		[CLKID_FCLK_DIV3]	= &fclk_div3.hw,
+		[CLKID_FCLK_DIV5]	= &fclk_div5.hw,
+		[CLKID_FCLK_DIV7]	= &fclk_div7.hw,
+		[CLKID_HIFI_PLL]	= &hifi_pll.hw,
+		[NR_PLL_CLKS]		= NULL,
+	},
+	.num = NR_PLL_CLKS,
+};
+
+static struct clk_regmap *const a1_pll_regmaps[] = {
+	&fixed_pll_dco,
+	&fixed_pll,
+	&fclk_div2,
+	&fclk_div3,
+	&fclk_div5,
+	&fclk_div7,
+	&hifi_pll,
+};
+
+static struct regmap_config a1_pll_regmap_cfg = {
+	.reg_bits   = 32,
+	.val_bits   = 32,
+	.reg_stride = 4,
+};
+
+static int meson_a1_pll_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *base;
+	struct regmap *map;
+	int clkid, i, err;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "can't ioremap resource\n");
+
+	map = devm_regmap_init_mmio(dev, base, &a1_pll_regmap_cfg);
+	if (IS_ERR(map))
+		return dev_err_probe(dev, PTR_ERR(map),
+				     "can't init regmap mmio region\n");
+
+	/* Populate regmap for the regmap backed clocks */
+	for (i = 0; i < ARRAY_SIZE(a1_pll_regmaps); i++)
+		a1_pll_regmaps[i]->map = map;
+
+	/* Register clocks */
+	for (clkid = 0; clkid < a1_pll_clks.num; clkid++) {
+		err = devm_clk_hw_register(dev, a1_pll_clks.hws[clkid]);
+		if (err)
+			return dev_err_probe(dev, err,
+					     "clock[%d] registration failed\n",
+					     clkid);
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &a1_pll_clks);
+}
+
+static const struct of_device_id a1_pll_clkc_match_table[] = {
+	{ .compatible = "amlogic,a1-pll-clkc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, a1_pll_clkc_match_table);
+
+static struct platform_driver a1_pll_clkc_driver = {
+	.probe = meson_a1_pll_probe,
+	.driver = {
+		.name = "a1-pll-clkc",
+		.of_match_table = a1_pll_clkc_match_table,
+	},
+};
+
+module_platform_driver(a1_pll_clkc_driver);
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/a1-pll.h b/drivers/clk/meson/a1-pll.h
new file mode 100644
index 000000000000..29726651b056
--- /dev/null
+++ b/drivers/clk/meson/a1-pll.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Amlogic A1 PLL Clock Controller internals
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PLL_H
+#define __A1_PLL_H
+
+#include "clk-pll.h"
+
+/* PLL register offset */
+#define ANACTRL_FIXPLL_CTRL0	0x0
+#define ANACTRL_FIXPLL_CTRL1	0x4
+#define ANACTRL_FIXPLL_STS	0x14
+#define ANACTRL_HIFIPLL_CTRL0	0xc0
+#define ANACTRL_HIFIPLL_CTRL1	0xc4
+#define ANACTRL_HIFIPLL_CTRL2	0xc8
+#define ANACTRL_HIFIPLL_CTRL3	0xcc
+#define ANACTRL_HIFIPLL_CTRL4	0xd0
+#define ANACTRL_HIFIPLL_STS	0xd4
+
+/* include the CLKIDs that have been made part of the DT binding */
+#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>
+
+/*
+ * CLKID index values for internal clocks
+ *
+ * These indices are entirely contrived and do not map onto the hardware.
+ * It has now been decided to expose everything by default in the DT header:
+ * include/dt-bindings/clock/a1-pll-clkc.h. Only the clocks ids we don't want
+ * to expose, such as the internal muxes and dividers of composite clocks,
+ * will remain defined here.
+ */
+#define CLKID_FIXED_PLL_DCO	0
+#define CLKID_FCLK_DIV2_DIV	2
+#define CLKID_FCLK_DIV3_DIV	3
+#define CLKID_FCLK_DIV5_DIV	4
+#define CLKID_FCLK_DIV7_DIV	5
+#define NR_PLL_CLKS		11
+
+#endif /* __A1_PLL_H */
-- 
2.36.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 4/6] clk: meson: a1: add Amlogic A1 PLL clock controller driver
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Introduce PLL clock controller for Amlogic A1 SoC family.
The clock unit is an APB slave module that is designed for generating all
of the internal and system clocks.
The SoC uses an external 24MHz crystal; there are 4 internal PLLs:
SYS_PLL/HIFI_PLL/USB_PLL/(FIXPLL), these PLLs generate 27 clock sources.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 drivers/clk/meson/Kconfig  |  10 ++
 drivers/clk/meson/Makefile |   1 +
 drivers/clk/meson/a1-pll.c | 356 +++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/a1-pll.h |  47 +++++
 4 files changed, 414 insertions(+)
 create mode 100644 drivers/clk/meson/a1-pll.c
 create mode 100644 drivers/clk/meson/a1-pll.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index fc002c155bc3..693c4cf60f27 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -99,6 +99,16 @@ config COMMON_CLK_AXG_AUDIO
 	  Support for the audio clock controller on AmLogic A113D devices,
 	  aka axg, Say Y if you want audio subsystem to work.
 
+config COMMON_CLK_A1_PLL
+	tristate "Amlogic A1 SoC PLL controller support"
+	depends on ARM64
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_PLL
+	help
+	  Support for the PLL clock controller on Amlogic A113L based
+	  device, A1 SoC Family. Say Y if you want A1 PLL clock controller
+	  to work.
+
 config COMMON_CLK_G12A
 	tristate "G12 and SM1 SoC clock controllers support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 6eca2a406ee3..2f17f475a48f 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
+obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.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
diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c
new file mode 100644
index 000000000000..bd2f1d1ec6e4
--- /dev/null
+++ b/drivers/clk/meson/a1-pll.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "a1-pll.h"
+#include "clk-regmap.h"
+
+static struct clk_regmap 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,
+		},
+		.frac = {
+			.reg_off = ANACTRL_FIXPLL_CTRL1,
+			.shift   = 0,
+			.width   = 19,
+		},
+		.l = {
+			.reg_off = ANACTRL_FIXPLL_STS,
+			.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 = "fixpll_in",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fixed_pll = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 20,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fixed_pll",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll_dco.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct pll_mult_range hifi_pll_mult_range = {
+	.min = 32,
+	.max = 64,
+};
+
+static const struct reg_sequence hifi_init_regs[] = {
+	{ .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x01800000 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00001100 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x100a1100 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x00302000 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x01f18000 },
+};
+
+static struct clk_regmap hifi_pll = {
+	.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,
+		},
+		.frac = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL1,
+			.shift   = 0,
+			.width   = 19,
+		},
+		.l = {
+			.reg_off = ANACTRL_HIFIPLL_STS,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.current_en = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL0,
+			.shift   = 26,
+			.width   = 1,
+		},
+		.l_detect = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL2,
+			.shift   = 6,
+			.width   = 1,
+		},
+		.range = &hifi_pll_mult_range,
+		.init_regs = hifi_init_regs,
+		.init_count = ARRAY_SIZE(hifi_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hifi_pll",
+		.ops = &meson_clk_pll_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "hifipll_in",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 21,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div2_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by DDR clock in BL2 firmware
+		 * and is required by the platform to operate correctly.
+		 * Until the following condition are met, we need this clock to
+		 * be marked as critical:
+		 * a) Mark the clock used by a firmware resource, if possible
+		 * b) CCF has a clock hand-off mechanism to make the sure the
+		 *    clock stays on until the proper driver comes along
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div3 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 22,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div3",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div3_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by APB bus which is set in boot ROM code
+		 * and is required by the platform to operate correctly.
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div5 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 23,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div5",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div5_div.hw
+		},
+		.num_parents = 1,
+		/*
+		 * This clock is used by AXI bus which setted in Romcode
+		 * and is required by the platform to operate correctly.
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static struct clk_fixed_factor 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 *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div7 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div7",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div7_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+/* Array of all clocks registered by this provider */
+static struct clk_hw_onecell_data a1_pll_clks = {
+	.hws = {
+		[CLKID_FIXED_PLL_DCO]	= &fixed_pll_dco.hw,
+		[CLKID_FIXED_PLL]	= &fixed_pll.hw,
+		[CLKID_FCLK_DIV2_DIV]	= &fclk_div2_div.hw,
+		[CLKID_FCLK_DIV3_DIV]	= &fclk_div3_div.hw,
+		[CLKID_FCLK_DIV5_DIV]	= &fclk_div5_div.hw,
+		[CLKID_FCLK_DIV7_DIV]	= &fclk_div7_div.hw,
+		[CLKID_FCLK_DIV2]	= &fclk_div2.hw,
+		[CLKID_FCLK_DIV3]	= &fclk_div3.hw,
+		[CLKID_FCLK_DIV5]	= &fclk_div5.hw,
+		[CLKID_FCLK_DIV7]	= &fclk_div7.hw,
+		[CLKID_HIFI_PLL]	= &hifi_pll.hw,
+		[NR_PLL_CLKS]		= NULL,
+	},
+	.num = NR_PLL_CLKS,
+};
+
+static struct clk_regmap *const a1_pll_regmaps[] = {
+	&fixed_pll_dco,
+	&fixed_pll,
+	&fclk_div2,
+	&fclk_div3,
+	&fclk_div5,
+	&fclk_div7,
+	&hifi_pll,
+};
+
+static struct regmap_config a1_pll_regmap_cfg = {
+	.reg_bits   = 32,
+	.val_bits   = 32,
+	.reg_stride = 4,
+};
+
+static int meson_a1_pll_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *base;
+	struct regmap *map;
+	int clkid, i, err;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "can't ioremap resource\n");
+
+	map = devm_regmap_init_mmio(dev, base, &a1_pll_regmap_cfg);
+	if (IS_ERR(map))
+		return dev_err_probe(dev, PTR_ERR(map),
+				     "can't init regmap mmio region\n");
+
+	/* Populate regmap for the regmap backed clocks */
+	for (i = 0; i < ARRAY_SIZE(a1_pll_regmaps); i++)
+		a1_pll_regmaps[i]->map = map;
+
+	/* Register clocks */
+	for (clkid = 0; clkid < a1_pll_clks.num; clkid++) {
+		err = devm_clk_hw_register(dev, a1_pll_clks.hws[clkid]);
+		if (err)
+			return dev_err_probe(dev, err,
+					     "clock[%d] registration failed\n",
+					     clkid);
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &a1_pll_clks);
+}
+
+static const struct of_device_id a1_pll_clkc_match_table[] = {
+	{ .compatible = "amlogic,a1-pll-clkc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, a1_pll_clkc_match_table);
+
+static struct platform_driver a1_pll_clkc_driver = {
+	.probe = meson_a1_pll_probe,
+	.driver = {
+		.name = "a1-pll-clkc",
+		.of_match_table = a1_pll_clkc_match_table,
+	},
+};
+
+module_platform_driver(a1_pll_clkc_driver);
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/a1-pll.h b/drivers/clk/meson/a1-pll.h
new file mode 100644
index 000000000000..29726651b056
--- /dev/null
+++ b/drivers/clk/meson/a1-pll.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Amlogic A1 PLL Clock Controller internals
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PLL_H
+#define __A1_PLL_H
+
+#include "clk-pll.h"
+
+/* PLL register offset */
+#define ANACTRL_FIXPLL_CTRL0	0x0
+#define ANACTRL_FIXPLL_CTRL1	0x4
+#define ANACTRL_FIXPLL_STS	0x14
+#define ANACTRL_HIFIPLL_CTRL0	0xc0
+#define ANACTRL_HIFIPLL_CTRL1	0xc4
+#define ANACTRL_HIFIPLL_CTRL2	0xc8
+#define ANACTRL_HIFIPLL_CTRL3	0xcc
+#define ANACTRL_HIFIPLL_CTRL4	0xd0
+#define ANACTRL_HIFIPLL_STS	0xd4
+
+/* include the CLKIDs that have been made part of the DT binding */
+#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>
+
+/*
+ * CLKID index values for internal clocks
+ *
+ * These indices are entirely contrived and do not map onto the hardware.
+ * It has now been decided to expose everything by default in the DT header:
+ * include/dt-bindings/clock/a1-pll-clkc.h. Only the clocks ids we don't want
+ * to expose, such as the internal muxes and dividers of composite clocks,
+ * will remain defined here.
+ */
+#define CLKID_FIXED_PLL_DCO	0
+#define CLKID_FCLK_DIV2_DIV	2
+#define CLKID_FCLK_DIV3_DIV	3
+#define CLKID_FCLK_DIV5_DIV	4
+#define CLKID_FCLK_DIV7_DIV	5
+#define NR_PLL_CLKS		11
+
+#endif /* __A1_PLL_H */
-- 
2.36.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
  2023-05-17 13:33 ` Dmitry Rokosov
  (?)
@ 2023-05-17 13:33   ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Add documentation and dt bindings for the Amlogic A1 Peripherals clock
controller.
A1 PLL clock controller has references to A1 Peripherals clock
controller objects, so reflect them in the schema.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 .../clock/amlogic,a1-peripherals-clkc.yaml    |  73 +++++++++++
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   |   5 +-
 .../clock/amlogic,a1-peripherals-clkc.h       | 115 ++++++++++++++++++
 3 files changed, 191 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
new file mode 100644
index 000000000000..6d84cee1bd75
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a1-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A1 Peripherals Clock Control Unit
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+  - Jerome Brunet <jbrunet@baylibre.com>
+  - Jian Hu <jian.hu@jian.hu.com>
+  - Dmitry Rokosov <ddrokosov@sberdevices.ru>
+
+properties:
+  compatible:
+    const: amlogic,a1-peripherals-clkc
+
+  '#clock-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: input fixed pll div2
+      - description: input fixed pll div3
+      - description: input fixed pll div5
+      - description: input fixed pll div7
+      - description: input hifi pll
+      - description: input oscillator (usually at 24MHz)
+
+  clock-names:
+    items:
+      - const: fclk_div2
+      - const: fclk_div3
+      - const: fclk_div5
+      - const: fclk_div7
+      - const: hifi_pll
+      - const: xtal
+
+required:
+  - compatible
+  - '#clock-cells'
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,a1-pll-clkc.h>
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@800 {
+            compatible = "amlogic,a1-peripherals-clkc";
+            reg = <0 0x800 0 0x104>;
+            #clock-cells = <1>;
+            clocks = <&clkc_pll CLKID_FCLK_DIV2>,
+                     <&clkc_pll CLKID_FCLK_DIV3>,
+                     <&clkc_pll CLKID_FCLK_DIV5>,
+                     <&clkc_pll CLKID_FCLK_DIV7>,
+                     <&clkc_pll CLKID_HIFI_PLL>,
+                     <&xtal>;
+            clock-names = "fclk_div2", "fclk_div3",
+                          "fclk_div5", "fclk_div7",
+                          "hifi_pll", "xtal";
+        };
+    };
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
index 5c6fa620a63c..a59b188a8bf5 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
@@ -43,6 +43,7 @@ additionalProperties: false
 
 examples:
   - |
+    #include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
     apb {
         #address-cells = <2>;
         #size-cells = <2>;
@@ -51,8 +52,8 @@ examples:
             compatible = "amlogic,a1-pll-clkc";
             reg = <0 0x7c80 0 0x18c>;
             #clock-cells = <1>;
-            clocks = <&clkc_periphs_fixpll_in>,
-                     <&clkc_periphs_hifipll_in>;
+            clocks = <&clkc_periphs CLKID_FIXPLL_IN>,
+                     <&clkc_periphs CLKID_HIFIPLL_IN>;
             clock-names = "fixpll_in", "hifipll_in";
         };
     };
diff --git a/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
new file mode 100644
index 000000000000..ff2730f398a6
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PERIPHERALS_CLKC_H
+#define __A1_PERIPHERALS_CLKC_H
+
+#define CLKID_FIXPLL_IN		1
+#define CLKID_USB_PHY_IN	2
+#define CLKID_USB_CTRL_IN	3
+#define CLKID_HIFIPLL_IN	4
+#define CLKID_SYSPLL_IN		5
+#define CLKID_DDS_IN		6
+#define CLKID_SYS		7
+#define CLKID_CLKTREE		8
+#define CLKID_RESET_CTRL	9
+#define CLKID_ANALOG_CTRL	10
+#define CLKID_PWR_CTRL		11
+#define CLKID_PAD_CTRL		12
+#define CLKID_SYS_CTRL		13
+#define CLKID_TEMP_SENSOR	14
+#define CLKID_AM2AXI_DIV	15
+#define CLKID_SPICC_B		16
+#define CLKID_SPICC_A		17
+#define CLKID_MSR		18
+#define CLKID_AUDIO		19
+#define CLKID_JTAG_CTRL		20
+#define CLKID_SARADC_EN		21
+#define CLKID_PWM_EF		22
+#define CLKID_PWM_CD		23
+#define CLKID_PWM_AB		24
+#define CLKID_CEC		25
+#define CLKID_I2C_S		26
+#define CLKID_IR_CTRL		27
+#define CLKID_I2C_M_D		28
+#define CLKID_I2C_M_C		29
+#define CLKID_I2C_M_B		30
+#define CLKID_I2C_M_A		31
+#define CLKID_ACODEC		32
+#define CLKID_OTP		33
+#define CLKID_SD_EMMC_A		34
+#define CLKID_USB_PHY		35
+#define CLKID_USB_CTRL		36
+#define CLKID_SYS_DSPB		37
+#define CLKID_SYS_DSPA		38
+#define CLKID_DMA		39
+#define CLKID_IRQ_CTRL		40
+#define CLKID_NIC		41
+#define CLKID_GIC		42
+#define CLKID_UART_C		43
+#define CLKID_UART_B		44
+#define CLKID_UART_A		45
+#define CLKID_SYS_PSRAM		46
+#define CLKID_RSA		47
+#define CLKID_CORESIGHT		48
+#define CLKID_AM2AXI_VAD	49
+#define CLKID_AUDIO_VAD		50
+#define CLKID_AXI_DMC		51
+#define CLKID_AXI_PSRAM		52
+#define CLKID_RAMB		53
+#define CLKID_RAMA		54
+#define CLKID_AXI_SPIFC		55
+#define CLKID_AXI_NIC		56
+#define CLKID_AXI_DMA		57
+#define CLKID_CPU_CTRL		58
+#define CLKID_ROM		59
+#define CLKID_PROC_I2C		60
+#define CLKID_DSPA_EN		63
+#define CLKID_DSPA_EN_NIC	64
+#define CLKID_DSPB_EN		65
+#define CLKID_DSPB_EN_NIC	66
+#define CLKID_RTC		67
+#define CLKID_CECA_32K		68
+#define CLKID_CECB_32K		69
+#define CLKID_24M		70
+#define CLKID_12M		71
+#define CLKID_FCLK_DIV2_DIVN	72
+#define CLKID_GEN		73
+#define CLKID_SARADC		75
+#define CLKID_PWM_A		76
+#define CLKID_PWM_B		77
+#define CLKID_PWM_C		78
+#define CLKID_PWM_D		79
+#define CLKID_PWM_E		80
+#define CLKID_PWM_F		81
+#define CLKID_SPICC		82
+#define CLKID_TS		83
+#define CLKID_SPIFC		84
+#define CLKID_USB_BUS		85
+#define CLKID_SD_EMMC		86
+#define CLKID_PSRAM		87
+#define CLKID_DMC		88
+#define CLKID_DSPA_A_SEL	95
+#define CLKID_DSPA_B_SEL	98
+#define CLKID_DSPB_A_SEL	101
+#define CLKID_DSPB_B_SEL	104
+#define CLKID_CECB_32K_SEL_PRE	113
+#define CLKID_CECB_32K_SEL	114
+#define CLKID_CECA_32K_SEL_PRE	117
+#define CLKID_CECA_32K_SEL	118
+#define CLKID_GEN_SEL		121
+#define CLKID_PWM_A_SEL		124
+#define CLKID_PWM_B_SEL		126
+#define CLKID_PWM_C_SEL		128
+#define CLKID_PWM_D_SEL		130
+#define CLKID_PWM_E_SEL		132
+#define CLKID_PWM_F_SEL		134
+#define CLKID_SD_EMMC_SEL2	147
+
+#endif /* __A1_PERIPHERALS_CLKC_H */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Add documentation and dt bindings for the Amlogic A1 Peripherals clock
controller.
A1 PLL clock controller has references to A1 Peripherals clock
controller objects, so reflect them in the schema.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 .../clock/amlogic,a1-peripherals-clkc.yaml    |  73 +++++++++++
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   |   5 +-
 .../clock/amlogic,a1-peripherals-clkc.h       | 115 ++++++++++++++++++
 3 files changed, 191 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
new file mode 100644
index 000000000000..6d84cee1bd75
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a1-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A1 Peripherals Clock Control Unit
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+  - Jerome Brunet <jbrunet@baylibre.com>
+  - Jian Hu <jian.hu@jian.hu.com>
+  - Dmitry Rokosov <ddrokosov@sberdevices.ru>
+
+properties:
+  compatible:
+    const: amlogic,a1-peripherals-clkc
+
+  '#clock-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: input fixed pll div2
+      - description: input fixed pll div3
+      - description: input fixed pll div5
+      - description: input fixed pll div7
+      - description: input hifi pll
+      - description: input oscillator (usually at 24MHz)
+
+  clock-names:
+    items:
+      - const: fclk_div2
+      - const: fclk_div3
+      - const: fclk_div5
+      - const: fclk_div7
+      - const: hifi_pll
+      - const: xtal
+
+required:
+  - compatible
+  - '#clock-cells'
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,a1-pll-clkc.h>
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@800 {
+            compatible = "amlogic,a1-peripherals-clkc";
+            reg = <0 0x800 0 0x104>;
+            #clock-cells = <1>;
+            clocks = <&clkc_pll CLKID_FCLK_DIV2>,
+                     <&clkc_pll CLKID_FCLK_DIV3>,
+                     <&clkc_pll CLKID_FCLK_DIV5>,
+                     <&clkc_pll CLKID_FCLK_DIV7>,
+                     <&clkc_pll CLKID_HIFI_PLL>,
+                     <&xtal>;
+            clock-names = "fclk_div2", "fclk_div3",
+                          "fclk_div5", "fclk_div7",
+                          "hifi_pll", "xtal";
+        };
+    };
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
index 5c6fa620a63c..a59b188a8bf5 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
@@ -43,6 +43,7 @@ additionalProperties: false
 
 examples:
   - |
+    #include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
     apb {
         #address-cells = <2>;
         #size-cells = <2>;
@@ -51,8 +52,8 @@ examples:
             compatible = "amlogic,a1-pll-clkc";
             reg = <0 0x7c80 0 0x18c>;
             #clock-cells = <1>;
-            clocks = <&clkc_periphs_fixpll_in>,
-                     <&clkc_periphs_hifipll_in>;
+            clocks = <&clkc_periphs CLKID_FIXPLL_IN>,
+                     <&clkc_periphs CLKID_HIFIPLL_IN>;
             clock-names = "fixpll_in", "hifipll_in";
         };
     };
diff --git a/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
new file mode 100644
index 000000000000..ff2730f398a6
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PERIPHERALS_CLKC_H
+#define __A1_PERIPHERALS_CLKC_H
+
+#define CLKID_FIXPLL_IN		1
+#define CLKID_USB_PHY_IN	2
+#define CLKID_USB_CTRL_IN	3
+#define CLKID_HIFIPLL_IN	4
+#define CLKID_SYSPLL_IN		5
+#define CLKID_DDS_IN		6
+#define CLKID_SYS		7
+#define CLKID_CLKTREE		8
+#define CLKID_RESET_CTRL	9
+#define CLKID_ANALOG_CTRL	10
+#define CLKID_PWR_CTRL		11
+#define CLKID_PAD_CTRL		12
+#define CLKID_SYS_CTRL		13
+#define CLKID_TEMP_SENSOR	14
+#define CLKID_AM2AXI_DIV	15
+#define CLKID_SPICC_B		16
+#define CLKID_SPICC_A		17
+#define CLKID_MSR		18
+#define CLKID_AUDIO		19
+#define CLKID_JTAG_CTRL		20
+#define CLKID_SARADC_EN		21
+#define CLKID_PWM_EF		22
+#define CLKID_PWM_CD		23
+#define CLKID_PWM_AB		24
+#define CLKID_CEC		25
+#define CLKID_I2C_S		26
+#define CLKID_IR_CTRL		27
+#define CLKID_I2C_M_D		28
+#define CLKID_I2C_M_C		29
+#define CLKID_I2C_M_B		30
+#define CLKID_I2C_M_A		31
+#define CLKID_ACODEC		32
+#define CLKID_OTP		33
+#define CLKID_SD_EMMC_A		34
+#define CLKID_USB_PHY		35
+#define CLKID_USB_CTRL		36
+#define CLKID_SYS_DSPB		37
+#define CLKID_SYS_DSPA		38
+#define CLKID_DMA		39
+#define CLKID_IRQ_CTRL		40
+#define CLKID_NIC		41
+#define CLKID_GIC		42
+#define CLKID_UART_C		43
+#define CLKID_UART_B		44
+#define CLKID_UART_A		45
+#define CLKID_SYS_PSRAM		46
+#define CLKID_RSA		47
+#define CLKID_CORESIGHT		48
+#define CLKID_AM2AXI_VAD	49
+#define CLKID_AUDIO_VAD		50
+#define CLKID_AXI_DMC		51
+#define CLKID_AXI_PSRAM		52
+#define CLKID_RAMB		53
+#define CLKID_RAMA		54
+#define CLKID_AXI_SPIFC		55
+#define CLKID_AXI_NIC		56
+#define CLKID_AXI_DMA		57
+#define CLKID_CPU_CTRL		58
+#define CLKID_ROM		59
+#define CLKID_PROC_I2C		60
+#define CLKID_DSPA_EN		63
+#define CLKID_DSPA_EN_NIC	64
+#define CLKID_DSPB_EN		65
+#define CLKID_DSPB_EN_NIC	66
+#define CLKID_RTC		67
+#define CLKID_CECA_32K		68
+#define CLKID_CECB_32K		69
+#define CLKID_24M		70
+#define CLKID_12M		71
+#define CLKID_FCLK_DIV2_DIVN	72
+#define CLKID_GEN		73
+#define CLKID_SARADC		75
+#define CLKID_PWM_A		76
+#define CLKID_PWM_B		77
+#define CLKID_PWM_C		78
+#define CLKID_PWM_D		79
+#define CLKID_PWM_E		80
+#define CLKID_PWM_F		81
+#define CLKID_SPICC		82
+#define CLKID_TS		83
+#define CLKID_SPIFC		84
+#define CLKID_USB_BUS		85
+#define CLKID_SD_EMMC		86
+#define CLKID_PSRAM		87
+#define CLKID_DMC		88
+#define CLKID_DSPA_A_SEL	95
+#define CLKID_DSPA_B_SEL	98
+#define CLKID_DSPB_A_SEL	101
+#define CLKID_DSPB_B_SEL	104
+#define CLKID_CECB_32K_SEL_PRE	113
+#define CLKID_CECB_32K_SEL	114
+#define CLKID_CECA_32K_SEL_PRE	117
+#define CLKID_CECA_32K_SEL	118
+#define CLKID_GEN_SEL		121
+#define CLKID_PWM_A_SEL		124
+#define CLKID_PWM_B_SEL		126
+#define CLKID_PWM_C_SEL		128
+#define CLKID_PWM_D_SEL		130
+#define CLKID_PWM_E_SEL		132
+#define CLKID_PWM_F_SEL		134
+#define CLKID_SD_EMMC_SEL2	147
+
+#endif /* __A1_PERIPHERALS_CLKC_H */
-- 
2.36.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Add documentation and dt bindings for the Amlogic A1 Peripherals clock
controller.
A1 PLL clock controller has references to A1 Peripherals clock
controller objects, so reflect them in the schema.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 .../clock/amlogic,a1-peripherals-clkc.yaml    |  73 +++++++++++
 .../bindings/clock/amlogic,a1-pll-clkc.yaml   |   5 +-
 .../clock/amlogic,a1-peripherals-clkc.h       | 115 ++++++++++++++++++
 3 files changed, 191 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
new file mode 100644
index 000000000000..6d84cee1bd75
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-peripherals-clkc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a1-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A1 Peripherals Clock Control Unit
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+  - Jerome Brunet <jbrunet@baylibre.com>
+  - Jian Hu <jian.hu@jian.hu.com>
+  - Dmitry Rokosov <ddrokosov@sberdevices.ru>
+
+properties:
+  compatible:
+    const: amlogic,a1-peripherals-clkc
+
+  '#clock-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: input fixed pll div2
+      - description: input fixed pll div3
+      - description: input fixed pll div5
+      - description: input fixed pll div7
+      - description: input hifi pll
+      - description: input oscillator (usually at 24MHz)
+
+  clock-names:
+    items:
+      - const: fclk_div2
+      - const: fclk_div3
+      - const: fclk_div5
+      - const: fclk_div7
+      - const: hifi_pll
+      - const: xtal
+
+required:
+  - compatible
+  - '#clock-cells'
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,a1-pll-clkc.h>
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@800 {
+            compatible = "amlogic,a1-peripherals-clkc";
+            reg = <0 0x800 0 0x104>;
+            #clock-cells = <1>;
+            clocks = <&clkc_pll CLKID_FCLK_DIV2>,
+                     <&clkc_pll CLKID_FCLK_DIV3>,
+                     <&clkc_pll CLKID_FCLK_DIV5>,
+                     <&clkc_pll CLKID_FCLK_DIV7>,
+                     <&clkc_pll CLKID_HIFI_PLL>,
+                     <&xtal>;
+            clock-names = "fclk_div2", "fclk_div3",
+                          "fclk_div5", "fclk_div7",
+                          "hifi_pll", "xtal";
+        };
+    };
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
index 5c6fa620a63c..a59b188a8bf5 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
@@ -43,6 +43,7 @@ additionalProperties: false
 
 examples:
   - |
+    #include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
     apb {
         #address-cells = <2>;
         #size-cells = <2>;
@@ -51,8 +52,8 @@ examples:
             compatible = "amlogic,a1-pll-clkc";
             reg = <0 0x7c80 0 0x18c>;
             #clock-cells = <1>;
-            clocks = <&clkc_periphs_fixpll_in>,
-                     <&clkc_periphs_hifipll_in>;
+            clocks = <&clkc_periphs CLKID_FIXPLL_IN>,
+                     <&clkc_periphs CLKID_HIFIPLL_IN>;
             clock-names = "fixpll_in", "hifipll_in";
         };
     };
diff --git a/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
new file mode 100644
index 000000000000..ff2730f398a6
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PERIPHERALS_CLKC_H
+#define __A1_PERIPHERALS_CLKC_H
+
+#define CLKID_FIXPLL_IN		1
+#define CLKID_USB_PHY_IN	2
+#define CLKID_USB_CTRL_IN	3
+#define CLKID_HIFIPLL_IN	4
+#define CLKID_SYSPLL_IN		5
+#define CLKID_DDS_IN		6
+#define CLKID_SYS		7
+#define CLKID_CLKTREE		8
+#define CLKID_RESET_CTRL	9
+#define CLKID_ANALOG_CTRL	10
+#define CLKID_PWR_CTRL		11
+#define CLKID_PAD_CTRL		12
+#define CLKID_SYS_CTRL		13
+#define CLKID_TEMP_SENSOR	14
+#define CLKID_AM2AXI_DIV	15
+#define CLKID_SPICC_B		16
+#define CLKID_SPICC_A		17
+#define CLKID_MSR		18
+#define CLKID_AUDIO		19
+#define CLKID_JTAG_CTRL		20
+#define CLKID_SARADC_EN		21
+#define CLKID_PWM_EF		22
+#define CLKID_PWM_CD		23
+#define CLKID_PWM_AB		24
+#define CLKID_CEC		25
+#define CLKID_I2C_S		26
+#define CLKID_IR_CTRL		27
+#define CLKID_I2C_M_D		28
+#define CLKID_I2C_M_C		29
+#define CLKID_I2C_M_B		30
+#define CLKID_I2C_M_A		31
+#define CLKID_ACODEC		32
+#define CLKID_OTP		33
+#define CLKID_SD_EMMC_A		34
+#define CLKID_USB_PHY		35
+#define CLKID_USB_CTRL		36
+#define CLKID_SYS_DSPB		37
+#define CLKID_SYS_DSPA		38
+#define CLKID_DMA		39
+#define CLKID_IRQ_CTRL		40
+#define CLKID_NIC		41
+#define CLKID_GIC		42
+#define CLKID_UART_C		43
+#define CLKID_UART_B		44
+#define CLKID_UART_A		45
+#define CLKID_SYS_PSRAM		46
+#define CLKID_RSA		47
+#define CLKID_CORESIGHT		48
+#define CLKID_AM2AXI_VAD	49
+#define CLKID_AUDIO_VAD		50
+#define CLKID_AXI_DMC		51
+#define CLKID_AXI_PSRAM		52
+#define CLKID_RAMB		53
+#define CLKID_RAMA		54
+#define CLKID_AXI_SPIFC		55
+#define CLKID_AXI_NIC		56
+#define CLKID_AXI_DMA		57
+#define CLKID_CPU_CTRL		58
+#define CLKID_ROM		59
+#define CLKID_PROC_I2C		60
+#define CLKID_DSPA_EN		63
+#define CLKID_DSPA_EN_NIC	64
+#define CLKID_DSPB_EN		65
+#define CLKID_DSPB_EN_NIC	66
+#define CLKID_RTC		67
+#define CLKID_CECA_32K		68
+#define CLKID_CECB_32K		69
+#define CLKID_24M		70
+#define CLKID_12M		71
+#define CLKID_FCLK_DIV2_DIVN	72
+#define CLKID_GEN		73
+#define CLKID_SARADC		75
+#define CLKID_PWM_A		76
+#define CLKID_PWM_B		77
+#define CLKID_PWM_C		78
+#define CLKID_PWM_D		79
+#define CLKID_PWM_E		80
+#define CLKID_PWM_F		81
+#define CLKID_SPICC		82
+#define CLKID_TS		83
+#define CLKID_SPIFC		84
+#define CLKID_USB_BUS		85
+#define CLKID_SD_EMMC		86
+#define CLKID_PSRAM		87
+#define CLKID_DMC		88
+#define CLKID_DSPA_A_SEL	95
+#define CLKID_DSPA_B_SEL	98
+#define CLKID_DSPB_A_SEL	101
+#define CLKID_DSPB_B_SEL	104
+#define CLKID_CECB_32K_SEL_PRE	113
+#define CLKID_CECB_32K_SEL	114
+#define CLKID_CECA_32K_SEL_PRE	117
+#define CLKID_CECA_32K_SEL	118
+#define CLKID_GEN_SEL		121
+#define CLKID_PWM_A_SEL		124
+#define CLKID_PWM_B_SEL		126
+#define CLKID_PWM_C_SEL		128
+#define CLKID_PWM_D_SEL		130
+#define CLKID_PWM_E_SEL		132
+#define CLKID_PWM_F_SEL		134
+#define CLKID_SD_EMMC_SEL2	147
+
+#endif /* __A1_PERIPHERALS_CLKC_H */
-- 
2.36.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
  2023-05-17 13:33 ` Dmitry Rokosov
  (?)
@ 2023-05-17 13:33   ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Introduce Peripherals clock controller for Amlogic A1 SoC family.

A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
and Audio.
This patchset adds support for Amlogic A1 Peripherals clock driver and
allows to generate clocks for all A1 SoC peripheral IPs.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/Kconfig          |   10 +
 drivers/clk/meson/Makefile         |    1 +
 drivers/clk/meson/a1-peripherals.c | 2273 ++++++++++++++++++++++++++++
 drivers/clk/meson/a1-peripherals.h |  113 ++
 4 files changed, 2397 insertions(+)
 create mode 100644 drivers/clk/meson/a1-peripherals.c
 create mode 100644 drivers/clk/meson/a1-peripherals.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 693c4cf60f27..8ce846fdbe43 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -109,6 +109,16 @@ config COMMON_CLK_A1_PLL
 	  device, A1 SoC Family. Say Y if you want A1 PLL clock controller
 	  to work.
 
+config COMMON_CLK_A1_PERIPHERALS
+	tristate "Amlogic A1 SoC Peripherals clock controller support"
+	depends on ARM64
+	select COMMON_CLK_MESON_DUALDIV
+	select COMMON_CLK_MESON_REGMAP
+	help
+	  Support for the Peripherals clock controller on Amlogic A113L based
+	  device, A1 SoC Family. Say Y if you want A1 Peripherals clock
+	  controller to work.
+
 config COMMON_CLK_G12A
 	tristate "G12 and SM1 SoC clock controllers support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 2f17f475a48f..d5288662881d 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
 obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
+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
diff --git a/drivers/clk/meson/a1-peripherals.c b/drivers/clk/meson/a1-peripherals.c
new file mode 100644
index 000000000000..5e7a37cbbb88
--- /dev/null
+++ b/drivers/clk/meson/a1-peripherals.c
@@ -0,0 +1,2273 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "a1-peripherals.h"
+#include "clk-dualdiv.h"
+#include "clk-regmap.h"
+
+static struct clk_regmap xtal_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "xtal_in",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fixpll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fixpll_in",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap usb_phy_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_phy_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap usb_ctrl_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_ctrl_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap hifipll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifipll_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap syspll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 5,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "syspll_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap dds_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 6,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dds_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_32k_in",
+		.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 clk_32k_div_table[] = {
+	{
+		.dual		= 1,
+		.n1		= 733,
+		.m1		= 8,
+		.n2		= 732,
+		.m2		= 11,
+	},
+	{}
+};
+
+static struct clk_regmap rtc_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_xtal = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL1,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_32k_xtal",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = RTC_CTRL,
+		.mask = 0x3,
+		.shift = 0,
+		.flags = CLK_MUX_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc_32k_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_xtal.hw,
+			&rtc_32k_div.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * All clocks that can be inherited from a more accurate RTC clock are marked
+ * with the CLK_SET_RATE_NO_REPARENT flag. This is because in certain
+ * situations, we may need to freeze their parent. The parent setup of these
+ * clocks should be located on the device tree side.
+ */
+struct clk_regmap rtc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 mux_table_sys[] = { 0, 1, 2, 3, 7 };
+static const struct clk_parent_data sys_parents[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div5" },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap sys_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_sys,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_b_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = sys_parents,
+		.num_parents = ARRAY_SIZE(sys_parents),
+	},
+};
+
+static struct clk_regmap sys_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SYS_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_sys,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_a_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = sys_parents,
+		.num_parents = ARRAY_SIZE(sys_parents),
+	},
+};
+
+static struct clk_regmap sys_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SYS_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a.hw,
+			&sys_b.hw,
+		},
+		.num_parents = 2,
+		/*
+		 * This clock is used by APB bus which is set in boot ROM code
+		 * and is required by the platform to operate correctly.
+		 * Until the following condition are met, we need this clock to
+		 * be marked as critical:
+		 * a) Mark the clock used by a firmware resource, if possible
+		 * b) CCF has a clock hand-off mechanism to make the sure the
+		 *    clock stays on until the proper driver comes along
+		 */
+		.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+	},
+};
+
+static u32 mux_table_dsp_ab[] = { 0, 1, 2, 3, 4, 7 };
+static const struct clk_parent_data dsp_ab_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "hifi_pll", },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap dspa_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspa_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPA_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspa_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPA_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a.hw,
+			&dspa_b.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_EN,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_en_nic = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_EN,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_en_nic",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspb_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPB_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspb_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPB_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a.hw,
+			&dspb_b.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_EN,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_en_nic = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_EN,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_en_nic",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap clk_24m = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "24m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor clk_24m_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "24m_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&clk_24m.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap clk_12m = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 10,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "12m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&clk_24m_div2.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2_divn_pre = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = CLK12_24_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2_divn_pre",
+		.ops = &clk_regmap_divider_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "fclk_div2",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2_divn = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 12,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2_divn",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div2_divn_pre.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
+ * the index 4 is the clock measurement source, it's not supported yet
+ */
+static u32 gen_table[] = { 0, 1, 3, 5, 6, 7, 8 };
+static const struct clk_parent_data gen_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &rtc.hw },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", },
+};
+
+static struct clk_regmap gen_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = GEN_CLK_CTRL,
+		.mask = 0xf,
+		.shift = 12,
+		.table = gen_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gen_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = gen_parent_data,
+		.num_parents = ARRAY_SIZE(gen_parent_data),
+		/*
+		 * The GEN clock can be connected to an external pad, so it
+		 * may be set up directly from the device tree. Additionally,
+		 * the GEN clock can be inherited from a more accurate RTC
+		 * clock, so in certain situations, it may be necessary
+		 * to freeze its parent.
+		 */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap gen_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = GEN_CLK_CTRL,
+		.shift = 0,
+		.width = 11,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gen_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gen_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap gen = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = GEN_CLK_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gen",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gen_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap saradc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SAR_ADC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "saradc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .fw_name = "xtal", },
+			{ .hw = &sys.hw, },
+		},
+		.num_parents = 2,
+	},
+};
+
+static struct clk_regmap saradc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SAR_ADC_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 *[]) {
+			&saradc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap saradc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SAR_ADC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "saradc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&saradc_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data pwm_abcd_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap pwm_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.mask = 0x1,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_c_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_c_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_c_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_c_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_c = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_c",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_c_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_d_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.mask = 0x1,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_d_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_d_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_d_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_d = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_d",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_d_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data pwm_ef_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .fw_name = "fclk_div5", },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap pwm_e_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_e_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_ef_parents,
+		.num_parents = ARRAY_SIZE(pwm_ef_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_e_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_e_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_e = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_e",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_e_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_f_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_f_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_ef_parents,
+		.num_parents = ARRAY_SIZE(pwm_ef_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_f_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_f_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_f = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_f",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_f_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * spicc clk
+ *   fdiv2   |\         |\       _____
+ *  ---------| |---DIV--| |     |     |    spicc out
+ *  ---------| |        | |-----|GATE |---------
+ *     ..... |/         | /     |_____|
+ *  --------------------|/
+ *                 24M
+ */
+static const struct clk_parent_data spicc_spifc_parents[] = {
+	{ .fw_name = "fclk_div2"},
+	{ .fw_name = "fclk_div3"},
+	{ .fw_name = "fclk_div5"},
+	{ .fw_name = "hifi_pll" },
+};
+
+static struct clk_regmap spicc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPICC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spicc_spifc_parents,
+		.num_parents = ARRAY_SIZE(spicc_spifc_parents),
+	},
+};
+
+static struct clk_regmap spicc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPICC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPICC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &spicc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPICC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spicc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ts_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = TS_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ts_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ts = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = TS_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ts",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ts_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPIFC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spicc_spifc_parents,
+		.num_parents = ARRAY_SIZE(spicc_spifc_parents),
+	},
+};
+
+static struct clk_regmap spifc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPIFC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spifc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPIFC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &spifc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPIFC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spifc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spifc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data usb_bus_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+};
+
+static struct clk_regmap usb_bus_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = USB_BUSCLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "usb_bus_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = usb_bus_parents,
+		.num_parents = ARRAY_SIZE(usb_bus_parents),
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap usb_bus_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = USB_BUSCLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "usb_bus_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&usb_bus_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap usb_bus = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = USB_BUSCLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_bus",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&usb_bus_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data sd_emmc_psram_dmc_parents[] = {
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "hifi_pll", },
+};
+
+static struct clk_regmap sd_emmc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap sd_emmc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &sd_emmc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sd_emmc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PSRAM_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap psram_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PSRAM_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&psram_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PSRAM_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &psram_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PSRAM_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "psram",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&psram_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DMC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap dmc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DMC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dmc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DMC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &dmc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DMC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dmc",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dmc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECA_CLK_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ceca_32k_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ceca_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = CECA_CLK_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = CECA_CLK_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ceca_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ceca_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ceca_32k_sel_pre = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECA_CLK_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 *[]) {
+			&ceca_32k_div.hw,
+			&ceca_32k_in.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECA_CLK_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 *[]) {
+			&ceca_32k_sel_pre.hw,
+			&rtc.hw,
+		},
+		.num_parents = 2,
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_out = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECA_CLK_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ceca_32k_out",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ceca_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECB_CLK_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cecb_32k_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap cecb_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = CECB_CLK_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = CECB_CLK_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cecb_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&cecb_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap cecb_32k_sel_pre = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECB_CLK_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 *[]) {
+			&cecb_32k_div.hw,
+			&cecb_32k_in.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECB_CLK_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 *[]) {
+			&cecb_32k_sel_pre.hw,
+			&rtc.hw,
+		},
+		.num_parents = 2,
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_out = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECB_CLK_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cecb_32k_out",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&cecb_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+#define MESON_GATE(_name, _reg, _bit) \
+	MESON_PCLK(_name, _reg, _bit, &sys.hw)
+
+static MESON_GATE(clktree,	SYS_CLK_EN0,	0);
+static MESON_GATE(reset_ctrl,	SYS_CLK_EN0,	1);
+static MESON_GATE(analog_ctrl,	SYS_CLK_EN0,	2);
+static MESON_GATE(pwr_ctrl,	SYS_CLK_EN0,	3);
+static MESON_GATE(pad_ctrl,	SYS_CLK_EN0,	4);
+static MESON_GATE(sys_ctrl,	SYS_CLK_EN0,	5);
+static MESON_GATE(temp_sensor,	SYS_CLK_EN0,	6);
+static MESON_GATE(am2axi_dev,	SYS_CLK_EN0,	7);
+static MESON_GATE(spicc_b,	SYS_CLK_EN0,	8);
+static MESON_GATE(spicc_a,	SYS_CLK_EN0,	9);
+static MESON_GATE(msr,		SYS_CLK_EN0,	10);
+static MESON_GATE(audio,	SYS_CLK_EN0,	11);
+static MESON_GATE(jtag_ctrl,	SYS_CLK_EN0,	12);
+static MESON_GATE(saradc_en,	SYS_CLK_EN0,	13);
+static MESON_GATE(pwm_ef,	SYS_CLK_EN0,	14);
+static MESON_GATE(pwm_cd,	SYS_CLK_EN0,	15);
+static MESON_GATE(pwm_ab,	SYS_CLK_EN0,	16);
+static MESON_GATE(cec,		SYS_CLK_EN0,	17);
+static MESON_GATE(i2c_s,	SYS_CLK_EN0,	18);
+static MESON_GATE(ir_ctrl,	SYS_CLK_EN0,	19);
+static MESON_GATE(i2c_m_d,	SYS_CLK_EN0,	20);
+static MESON_GATE(i2c_m_c,	SYS_CLK_EN0,	21);
+static MESON_GATE(i2c_m_b,	SYS_CLK_EN0,	22);
+static MESON_GATE(i2c_m_a,	SYS_CLK_EN0,	23);
+static MESON_GATE(acodec,	SYS_CLK_EN0,	24);
+static MESON_GATE(otp,		SYS_CLK_EN0,	25);
+static MESON_GATE(sd_emmc_a,	SYS_CLK_EN0,	26);
+static MESON_GATE(usb_phy,	SYS_CLK_EN0,	27);
+static MESON_GATE(usb_ctrl,	SYS_CLK_EN0,	28);
+static MESON_GATE(sys_dspb,	SYS_CLK_EN0,	29);
+static MESON_GATE(sys_dspa,	SYS_CLK_EN0,	30);
+static MESON_GATE(dma,		SYS_CLK_EN0,	31);
+static MESON_GATE(irq_ctrl,	SYS_CLK_EN1,	0);
+static MESON_GATE(nic,		SYS_CLK_EN1,	1);
+static MESON_GATE(gic,		SYS_CLK_EN1,	2);
+static MESON_GATE(uart_c,	SYS_CLK_EN1,	3);
+static MESON_GATE(uart_b,	SYS_CLK_EN1,	4);
+static MESON_GATE(uart_a,	SYS_CLK_EN1,	5);
+static MESON_GATE(sys_psram,	SYS_CLK_EN1,	6);
+static MESON_GATE(rsa,		SYS_CLK_EN1,	8);
+static MESON_GATE(coresight,	SYS_CLK_EN1,	9);
+static MESON_GATE(am2axi_vad,	AXI_CLK_EN,	0);
+static MESON_GATE(audio_vad,	AXI_CLK_EN,	1);
+static MESON_GATE(axi_dmc,	AXI_CLK_EN,	3);
+static MESON_GATE(axi_psram,	AXI_CLK_EN,	4);
+static MESON_GATE(ramb,		AXI_CLK_EN,	5);
+static MESON_GATE(rama,		AXI_CLK_EN,	6);
+static MESON_GATE(axi_spifc,	AXI_CLK_EN,	7);
+static MESON_GATE(axi_nic,	AXI_CLK_EN,	8);
+static MESON_GATE(axi_dma,	AXI_CLK_EN,	9);
+static MESON_GATE(cpu_ctrl,	AXI_CLK_EN,	10);
+static MESON_GATE(rom,		AXI_CLK_EN,	11);
+static MESON_GATE(prod_i2c,	AXI_CLK_EN,	12);
+
+/* Array of all clocks registered by this provider */
+static struct clk_hw_onecell_data a1_periphs_clks = {
+	.hws = {
+		[CLKID_XTAL_IN]			= &xtal_in.hw,
+		[CLKID_FIXPLL_IN]		= &fixpll_in.hw,
+		[CLKID_USB_PHY_IN]		= &usb_phy_in.hw,
+		[CLKID_USB_CTRL_IN]		= &usb_ctrl_in.hw,
+		[CLKID_HIFIPLL_IN]		= &hifipll_in.hw,
+		[CLKID_SYSPLL_IN]		= &syspll_in.hw,
+		[CLKID_DDS_IN]			= &dds_in.hw,
+		[CLKID_SYS]			= &sys.hw,
+		[CLKID_CLKTREE]			= &clktree.hw,
+		[CLKID_RESET_CTRL]		= &reset_ctrl.hw,
+		[CLKID_ANALOG_CTRL]		= &analog_ctrl.hw,
+		[CLKID_PWR_CTRL]		= &pwr_ctrl.hw,
+		[CLKID_PAD_CTRL]		= &pad_ctrl.hw,
+		[CLKID_SYS_CTRL]		= &sys_ctrl.hw,
+		[CLKID_TEMP_SENSOR]		= &temp_sensor.hw,
+		[CLKID_AM2AXI_DIV]		= &am2axi_dev.hw,
+		[CLKID_SPICC_B]			= &spicc_b.hw,
+		[CLKID_SPICC_A]			= &spicc_a.hw,
+		[CLKID_MSR]			= &msr.hw,
+		[CLKID_AUDIO]			= &audio.hw,
+		[CLKID_JTAG_CTRL]		= &jtag_ctrl.hw,
+		[CLKID_SARADC_EN]		= &saradc_en.hw,
+		[CLKID_PWM_EF]			= &pwm_ef.hw,
+		[CLKID_PWM_CD]			= &pwm_cd.hw,
+		[CLKID_PWM_AB]			= &pwm_ab.hw,
+		[CLKID_CEC]			= &cec.hw,
+		[CLKID_I2C_S]			= &i2c_s.hw,
+		[CLKID_IR_CTRL]			= &ir_ctrl.hw,
+		[CLKID_I2C_M_D]			= &i2c_m_d.hw,
+		[CLKID_I2C_M_C]			= &i2c_m_c.hw,
+		[CLKID_I2C_M_B]			= &i2c_m_b.hw,
+		[CLKID_I2C_M_A]			= &i2c_m_a.hw,
+		[CLKID_ACODEC]			= &acodec.hw,
+		[CLKID_OTP]			= &otp.hw,
+		[CLKID_SD_EMMC_A]		= &sd_emmc_a.hw,
+		[CLKID_USB_PHY]			= &usb_phy.hw,
+		[CLKID_USB_CTRL]		= &usb_ctrl.hw,
+		[CLKID_SYS_DSPB]		= &sys_dspb.hw,
+		[CLKID_SYS_DSPA]		= &sys_dspa.hw,
+		[CLKID_DMA]			= &dma.hw,
+		[CLKID_IRQ_CTRL]		= &irq_ctrl.hw,
+		[CLKID_NIC]			= &nic.hw,
+		[CLKID_GIC]			= &gic.hw,
+		[CLKID_UART_C]			= &uart_c.hw,
+		[CLKID_UART_B]			= &uart_b.hw,
+		[CLKID_UART_A]			= &uart_a.hw,
+		[CLKID_SYS_PSRAM]		= &sys_psram.hw,
+		[CLKID_RSA]			= &rsa.hw,
+		[CLKID_CORESIGHT]		= &coresight.hw,
+		[CLKID_AM2AXI_VAD]		= &am2axi_vad.hw,
+		[CLKID_AUDIO_VAD]		= &audio_vad.hw,
+		[CLKID_AXI_DMC]			= &axi_dmc.hw,
+		[CLKID_AXI_PSRAM]		= &axi_psram.hw,
+		[CLKID_RAMB]			= &ramb.hw,
+		[CLKID_RAMA]			= &rama.hw,
+		[CLKID_AXI_SPIFC]		= &axi_spifc.hw,
+		[CLKID_AXI_NIC]			= &axi_nic.hw,
+		[CLKID_AXI_DMA]			= &axi_dma.hw,
+		[CLKID_CPU_CTRL]		= &cpu_ctrl.hw,
+		[CLKID_ROM]			= &rom.hw,
+		[CLKID_PROC_I2C]		= &prod_i2c.hw,
+		[CLKID_DSPA_SEL]		= &dspa_sel.hw,
+		[CLKID_DSPB_SEL]		= &dspb_sel.hw,
+		[CLKID_DSPA_EN]			= &dspa_en.hw,
+		[CLKID_DSPA_EN_NIC]		= &dspa_en_nic.hw,
+		[CLKID_DSPB_EN]			= &dspb_en.hw,
+		[CLKID_DSPB_EN_NIC]		= &dspb_en_nic.hw,
+		[CLKID_RTC]			= &rtc.hw,
+		[CLKID_CECA_32K]		= &ceca_32k_out.hw,
+		[CLKID_CECB_32K]		= &cecb_32k_out.hw,
+		[CLKID_24M]			= &clk_24m.hw,
+		[CLKID_12M]			= &clk_12m.hw,
+		[CLKID_FCLK_DIV2_DIVN]		= &fclk_div2_divn.hw,
+		[CLKID_GEN]			= &gen.hw,
+		[CLKID_SARADC_SEL]		= &saradc_sel.hw,
+		[CLKID_SARADC]			= &saradc.hw,
+		[CLKID_PWM_A]			= &pwm_a.hw,
+		[CLKID_PWM_B]			= &pwm_b.hw,
+		[CLKID_PWM_C]			= &pwm_c.hw,
+		[CLKID_PWM_D]			= &pwm_d.hw,
+		[CLKID_PWM_E]			= &pwm_e.hw,
+		[CLKID_PWM_F]			= &pwm_f.hw,
+		[CLKID_SPICC]			= &spicc.hw,
+		[CLKID_TS]			= &ts.hw,
+		[CLKID_SPIFC]			= &spifc.hw,
+		[CLKID_USB_BUS]			= &usb_bus.hw,
+		[CLKID_SD_EMMC]			= &sd_emmc.hw,
+		[CLKID_PSRAM]			= &psram.hw,
+		[CLKID_DMC]			= &dmc.hw,
+		[CLKID_SYS_A_SEL]		= &sys_a_sel.hw,
+		[CLKID_SYS_A_DIV]		= &sys_a_div.hw,
+		[CLKID_SYS_A]			= &sys_a.hw,
+		[CLKID_SYS_B_SEL]		= &sys_b_sel.hw,
+		[CLKID_SYS_B_DIV]		= &sys_b_div.hw,
+		[CLKID_SYS_B]			= &sys_b.hw,
+		[CLKID_DSPA_A_SEL]		= &dspa_a_sel.hw,
+		[CLKID_DSPA_A_DIV]		= &dspa_a_div.hw,
+		[CLKID_DSPA_A]			= &dspa_a.hw,
+		[CLKID_DSPA_B_SEL]		= &dspa_b_sel.hw,
+		[CLKID_DSPA_B_DIV]		= &dspa_b_div.hw,
+		[CLKID_DSPA_B]			= &dspa_b.hw,
+		[CLKID_DSPB_A_SEL]		= &dspb_a_sel.hw,
+		[CLKID_DSPB_A_DIV]		= &dspb_a_div.hw,
+		[CLKID_DSPB_A]			= &dspb_a.hw,
+		[CLKID_DSPB_B_SEL]		= &dspb_b_sel.hw,
+		[CLKID_DSPB_B_DIV]		= &dspb_b_div.hw,
+		[CLKID_DSPB_B]			= &dspb_b.hw,
+		[CLKID_RTC_32K_IN]		= &rtc_32k_in.hw,
+		[CLKID_RTC_32K_DIV]		= &rtc_32k_div.hw,
+		[CLKID_RTC_32K_XTAL]		= &rtc_32k_xtal.hw,
+		[CLKID_RTC_32K_SEL]		= &rtc_32k_sel.hw,
+		[CLKID_CECB_32K_IN]		= &cecb_32k_in.hw,
+		[CLKID_CECB_32K_DIV]		= &cecb_32k_div.hw,
+		[CLKID_CECB_32K_SEL_PRE]	= &cecb_32k_sel_pre.hw,
+		[CLKID_CECB_32K_SEL]		= &cecb_32k_sel.hw,
+		[CLKID_CECA_32K_IN]		= &ceca_32k_in.hw,
+		[CLKID_CECA_32K_DIV]		= &ceca_32k_div.hw,
+		[CLKID_CECA_32K_SEL_PRE]	= &ceca_32k_sel_pre.hw,
+		[CLKID_CECA_32K_SEL]		= &ceca_32k_sel.hw,
+		[CLKID_DIV2_PRE]		= &fclk_div2_divn_pre.hw,
+		[CLKID_24M_DIV2]		= &clk_24m_div2.hw,
+		[CLKID_GEN_SEL]			= &gen_sel.hw,
+		[CLKID_GEN_DIV]			= &gen_div.hw,
+		[CLKID_SARADC_DIV]		= &saradc_div.hw,
+		[CLKID_PWM_A_SEL]		= &pwm_a_sel.hw,
+		[CLKID_PWM_A_DIV]		= &pwm_a_div.hw,
+		[CLKID_PWM_B_SEL]		= &pwm_b_sel.hw,
+		[CLKID_PWM_B_DIV]		= &pwm_b_div.hw,
+		[CLKID_PWM_C_SEL]		= &pwm_c_sel.hw,
+		[CLKID_PWM_C_DIV]		= &pwm_c_div.hw,
+		[CLKID_PWM_D_SEL]		= &pwm_d_sel.hw,
+		[CLKID_PWM_D_DIV]		= &pwm_d_div.hw,
+		[CLKID_PWM_E_SEL]		= &pwm_e_sel.hw,
+		[CLKID_PWM_E_DIV]		= &pwm_e_div.hw,
+		[CLKID_PWM_F_SEL]		= &pwm_f_sel.hw,
+		[CLKID_PWM_F_DIV]		= &pwm_f_div.hw,
+		[CLKID_SPICC_SEL]		= &spicc_sel.hw,
+		[CLKID_SPICC_DIV]		= &spicc_div.hw,
+		[CLKID_SPICC_SEL2]		= &spicc_sel2.hw,
+		[CLKID_TS_DIV]			= &ts_div.hw,
+		[CLKID_SPIFC_SEL]		= &spifc_sel.hw,
+		[CLKID_SPIFC_DIV]		= &spifc_div.hw,
+		[CLKID_SPIFC_SEL2]		= &spifc_sel2.hw,
+		[CLKID_USB_BUS_SEL]		= &usb_bus_sel.hw,
+		[CLKID_USB_BUS_DIV]		= &usb_bus_div.hw,
+		[CLKID_SD_EMMC_SEL]		= &sd_emmc_sel.hw,
+		[CLKID_SD_EMMC_DIV]		= &sd_emmc_div.hw,
+		[CLKID_SD_EMMC_SEL2]		= &sd_emmc_sel2.hw,
+		[CLKID_PSRAM_SEL]		= &psram_sel.hw,
+		[CLKID_PSRAM_DIV]		= &psram_div.hw,
+		[CLKID_PSRAM_SEL2]		= &psram_sel2.hw,
+		[CLKID_DMC_SEL]			= &dmc_sel.hw,
+		[CLKID_DMC_DIV]			= &dmc_div.hw,
+		[CLKID_DMC_SEL2]		= &dmc_sel2.hw,
+		[NR_CLKS]			= NULL,
+	},
+	.num = NR_CLKS,
+};
+
+/* Convenience table to populate regmap in .probe */
+static struct clk_regmap *const a1_periphs_regmaps[] = {
+	&xtal_in,
+	&fixpll_in,
+	&usb_phy_in,
+	&usb_ctrl_in,
+	&hifipll_in,
+	&syspll_in,
+	&dds_in,
+	&sys,
+	&clktree,
+	&reset_ctrl,
+	&analog_ctrl,
+	&pwr_ctrl,
+	&pad_ctrl,
+	&sys_ctrl,
+	&temp_sensor,
+	&am2axi_dev,
+	&spicc_b,
+	&spicc_a,
+	&msr,
+	&audio,
+	&jtag_ctrl,
+	&saradc_en,
+	&pwm_ef,
+	&pwm_cd,
+	&pwm_ab,
+	&cec,
+	&i2c_s,
+	&ir_ctrl,
+	&i2c_m_d,
+	&i2c_m_c,
+	&i2c_m_b,
+	&i2c_m_a,
+	&acodec,
+	&otp,
+	&sd_emmc_a,
+	&usb_phy,
+	&usb_ctrl,
+	&sys_dspb,
+	&sys_dspa,
+	&dma,
+	&irq_ctrl,
+	&nic,
+	&gic,
+	&uart_c,
+	&uart_b,
+	&uart_a,
+	&sys_psram,
+	&rsa,
+	&coresight,
+	&am2axi_vad,
+	&audio_vad,
+	&axi_dmc,
+	&axi_psram,
+	&ramb,
+	&rama,
+	&axi_spifc,
+	&axi_nic,
+	&axi_dma,
+	&cpu_ctrl,
+	&rom,
+	&prod_i2c,
+	&dspa_sel,
+	&dspb_sel,
+	&dspa_en,
+	&dspa_en_nic,
+	&dspb_en,
+	&dspb_en_nic,
+	&rtc,
+	&ceca_32k_out,
+	&cecb_32k_out,
+	&clk_24m,
+	&clk_12m,
+	&fclk_div2_divn,
+	&gen,
+	&saradc_sel,
+	&saradc,
+	&pwm_a,
+	&pwm_b,
+	&pwm_c,
+	&pwm_d,
+	&pwm_e,
+	&pwm_f,
+	&spicc,
+	&ts,
+	&spifc,
+	&usb_bus,
+	&sd_emmc,
+	&psram,
+	&dmc,
+	&sys_a_sel,
+	&sys_a_div,
+	&sys_a,
+	&sys_b_sel,
+	&sys_b_div,
+	&sys_b,
+	&dspa_a_sel,
+	&dspa_a_div,
+	&dspa_a,
+	&dspa_b_sel,
+	&dspa_b_div,
+	&dspa_b,
+	&dspb_a_sel,
+	&dspb_a_div,
+	&dspb_a,
+	&dspb_b_sel,
+	&dspb_b_div,
+	&dspb_b,
+	&rtc_32k_in,
+	&rtc_32k_div,
+	&rtc_32k_xtal,
+	&rtc_32k_sel,
+	&cecb_32k_in,
+	&cecb_32k_div,
+	&cecb_32k_sel_pre,
+	&cecb_32k_sel,
+	&ceca_32k_in,
+	&ceca_32k_div,
+	&ceca_32k_sel_pre,
+	&ceca_32k_sel,
+	&fclk_div2_divn_pre,
+	&gen_sel,
+	&gen_div,
+	&saradc_div,
+	&pwm_a_sel,
+	&pwm_a_div,
+	&pwm_b_sel,
+	&pwm_b_div,
+	&pwm_c_sel,
+	&pwm_c_div,
+	&pwm_d_sel,
+	&pwm_d_div,
+	&pwm_e_sel,
+	&pwm_e_div,
+	&pwm_f_sel,
+	&pwm_f_div,
+	&spicc_sel,
+	&spicc_div,
+	&spicc_sel2,
+	&ts_div,
+	&spifc_sel,
+	&spifc_div,
+	&spifc_sel2,
+	&usb_bus_sel,
+	&usb_bus_div,
+	&sd_emmc_sel,
+	&sd_emmc_div,
+	&sd_emmc_sel2,
+	&psram_sel,
+	&psram_div,
+	&psram_sel2,
+	&dmc_sel,
+	&dmc_div,
+	&dmc_sel2,
+};
+
+static struct regmap_config a1_periphs_regmap_cfg = {
+	.reg_bits   = 32,
+	.val_bits   = 32,
+	.reg_stride = 4,
+};
+
+static int meson_a1_periphs_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *base;
+	struct regmap *map;
+	int clkid, i, err;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "can't ioremap resource\n");
+
+	map = devm_regmap_init_mmio(dev, base, &a1_periphs_regmap_cfg);
+	if (IS_ERR(map))
+		return dev_err_probe(dev, PTR_ERR(map),
+				     "can't init regmap mmio region\n");
+
+	/* Populate regmap for the regmap backed clocks */
+	for (i = 0; i < ARRAY_SIZE(a1_periphs_regmaps); i++)
+		a1_periphs_regmaps[i]->map = map;
+
+	for (clkid = 0; clkid < a1_periphs_clks.num; clkid++) {
+		err = devm_clk_hw_register(dev, a1_periphs_clks.hws[clkid]);
+		if (err)
+			return dev_err_probe(dev, err,
+					     "clock[%d] registration failed\n",
+					     clkid);
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &a1_periphs_clks);
+}
+
+static const struct of_device_id a1_periphs_clkc_match_table[] = {
+	{ .compatible = "amlogic,a1-peripherals-clkc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, a1_periphs_clkc_match_table);
+
+static struct platform_driver a1_periphs_clkc_driver = {
+	.probe = meson_a1_periphs_probe,
+	.driver = {
+		.name = "a1-peripherals-clkc",
+		.of_match_table = a1_periphs_clkc_match_table,
+	},
+};
+
+module_platform_driver(a1_periphs_clkc_driver);
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/a1-peripherals.h b/drivers/clk/meson/a1-peripherals.h
new file mode 100644
index 000000000000..526fc9ba5c9f
--- /dev/null
+++ b/drivers/clk/meson/a1-peripherals.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Amlogic A1 Peripherals Clock Controller internals
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PERIPHERALS_H
+#define __A1_PERIPHERALS_H
+
+/* peripherals clock controller register offset */
+#define SYS_OSCIN_CTRL		0x0
+#define RTC_BY_OSCIN_CTRL0	0x4
+#define RTC_BY_OSCIN_CTRL1	0x8
+#define RTC_CTRL		0xc
+#define SYS_CLK_CTRL0		0x10
+#define SYS_CLK_EN0		0x1c
+#define SYS_CLK_EN1		0x20
+#define AXI_CLK_EN		0x24
+#define DSPA_CLK_EN		0x28
+#define DSPB_CLK_EN		0x2c
+#define DSPA_CLK_CTRL0		0x30
+#define DSPB_CLK_CTRL0		0x34
+#define CLK12_24_CTRL		0x38
+#define GEN_CLK_CTRL		0x3c
+#define SAR_ADC_CLK_CTRL	0xc0
+#define PWM_CLK_AB_CTRL		0xc4
+#define PWM_CLK_CD_CTRL		0xc8
+#define PWM_CLK_EF_CTRL		0xcc
+#define SPICC_CLK_CTRL		0xd0
+#define TS_CLK_CTRL		0xd4
+#define SPIFC_CLK_CTRL		0xd8
+#define USB_BUSCLK_CTRL		0xdc
+#define SD_EMMC_CLK_CTRL	0xe0
+#define CECA_CLK_CTRL0		0xe4
+#define CECA_CLK_CTRL1		0xe8
+#define CECB_CLK_CTRL0		0xec
+#define CECB_CLK_CTRL1		0xf0
+#define PSRAM_CLK_CTRL		0xf4
+#define DMC_CLK_CTRL		0xf8
+
+/* include the CLKIDs that have been made part of the DT binding */
+#include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
+
+/*
+ * CLKID index values for internal clocks
+ *
+ * These indices are entirely contrived and do not map onto the hardware.
+ * It has now been decided to expose everything by default in the DT header:
+ * include/dt-bindings/clock/a1-peripherals-clkc.h.
+ * Only the clocks ids we don't want to expose, such as the internal muxes and
+ * dividers of composite clocks, will remain defined here.
+ */
+#define CLKID_XTAL_IN		0
+#define CLKID_DSPA_SEL		61
+#define CLKID_DSPB_SEL		62
+#define CLKID_SARADC_SEL	74
+#define CLKID_SYS_A_SEL		89
+#define CLKID_SYS_A_DIV		90
+#define CLKID_SYS_A		91
+#define CLKID_SYS_B_SEL		92
+#define CLKID_SYS_B_DIV		93
+#define CLKID_SYS_B		94
+#define CLKID_DSPA_A_DIV	96
+#define CLKID_DSPA_A		97
+#define CLKID_DSPA_B_DIV	99
+#define CLKID_DSPA_B		100
+#define CLKID_DSPB_A_DIV	102
+#define CLKID_DSPB_A		103
+#define CLKID_DSPB_B_DIV	105
+#define CLKID_DSPB_B		106
+#define CLKID_RTC_32K_IN	107
+#define CLKID_RTC_32K_DIV	108
+#define CLKID_RTC_32K_XTAL	109
+#define CLKID_RTC_32K_SEL	110
+#define CLKID_CECB_32K_IN	111
+#define CLKID_CECB_32K_DIV	112
+#define CLKID_CECA_32K_IN	115
+#define CLKID_CECA_32K_DIV	116
+#define CLKID_DIV2_PRE		119
+#define CLKID_24M_DIV2		120
+#define CLKID_GEN_DIV		122
+#define CLKID_SARADC_DIV	123
+#define CLKID_PWM_A_DIV		125
+#define CLKID_PWM_B_DIV		127
+#define CLKID_PWM_C_DIV		129
+#define CLKID_PWM_D_DIV		131
+#define CLKID_PWM_E_DIV		133
+#define CLKID_PWM_F_DIV		135
+#define CLKID_SPICC_SEL		136
+#define CLKID_SPICC_DIV		137
+#define CLKID_SPICC_SEL2	138
+#define CLKID_TS_DIV		139
+#define CLKID_SPIFC_SEL		140
+#define CLKID_SPIFC_DIV		141
+#define CLKID_SPIFC_SEL2	142
+#define CLKID_USB_BUS_SEL	143
+#define CLKID_USB_BUS_DIV	144
+#define CLKID_SD_EMMC_SEL	145
+#define CLKID_SD_EMMC_DIV	146
+#define CLKID_PSRAM_SEL		148
+#define CLKID_PSRAM_DIV		149
+#define CLKID_PSRAM_SEL2	150
+#define CLKID_DMC_SEL		151
+#define CLKID_DMC_DIV		152
+#define CLKID_DMC_SEL2		153
+#define NR_CLKS			154
+
+#endif /* __A1_PERIPHERALS_H */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Introduce Peripherals clock controller for Amlogic A1 SoC family.

A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
and Audio.
This patchset adds support for Amlogic A1 Peripherals clock driver and
allows to generate clocks for all A1 SoC peripheral IPs.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/Kconfig          |   10 +
 drivers/clk/meson/Makefile         |    1 +
 drivers/clk/meson/a1-peripherals.c | 2273 ++++++++++++++++++++++++++++
 drivers/clk/meson/a1-peripherals.h |  113 ++
 4 files changed, 2397 insertions(+)
 create mode 100644 drivers/clk/meson/a1-peripherals.c
 create mode 100644 drivers/clk/meson/a1-peripherals.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 693c4cf60f27..8ce846fdbe43 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -109,6 +109,16 @@ config COMMON_CLK_A1_PLL
 	  device, A1 SoC Family. Say Y if you want A1 PLL clock controller
 	  to work.
 
+config COMMON_CLK_A1_PERIPHERALS
+	tristate "Amlogic A1 SoC Peripherals clock controller support"
+	depends on ARM64
+	select COMMON_CLK_MESON_DUALDIV
+	select COMMON_CLK_MESON_REGMAP
+	help
+	  Support for the Peripherals clock controller on Amlogic A113L based
+	  device, A1 SoC Family. Say Y if you want A1 Peripherals clock
+	  controller to work.
+
 config COMMON_CLK_G12A
 	tristate "G12 and SM1 SoC clock controllers support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 2f17f475a48f..d5288662881d 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
 obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
+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
diff --git a/drivers/clk/meson/a1-peripherals.c b/drivers/clk/meson/a1-peripherals.c
new file mode 100644
index 000000000000..5e7a37cbbb88
--- /dev/null
+++ b/drivers/clk/meson/a1-peripherals.c
@@ -0,0 +1,2273 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "a1-peripherals.h"
+#include "clk-dualdiv.h"
+#include "clk-regmap.h"
+
+static struct clk_regmap xtal_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "xtal_in",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fixpll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fixpll_in",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap usb_phy_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_phy_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap usb_ctrl_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_ctrl_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap hifipll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifipll_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap syspll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 5,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "syspll_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap dds_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 6,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dds_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_32k_in",
+		.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 clk_32k_div_table[] = {
+	{
+		.dual		= 1,
+		.n1		= 733,
+		.m1		= 8,
+		.n2		= 732,
+		.m2		= 11,
+	},
+	{}
+};
+
+static struct clk_regmap rtc_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_xtal = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL1,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_32k_xtal",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = RTC_CTRL,
+		.mask = 0x3,
+		.shift = 0,
+		.flags = CLK_MUX_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc_32k_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_xtal.hw,
+			&rtc_32k_div.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * All clocks that can be inherited from a more accurate RTC clock are marked
+ * with the CLK_SET_RATE_NO_REPARENT flag. This is because in certain
+ * situations, we may need to freeze their parent. The parent setup of these
+ * clocks should be located on the device tree side.
+ */
+struct clk_regmap rtc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 mux_table_sys[] = { 0, 1, 2, 3, 7 };
+static const struct clk_parent_data sys_parents[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div5" },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap sys_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_sys,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_b_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = sys_parents,
+		.num_parents = ARRAY_SIZE(sys_parents),
+	},
+};
+
+static struct clk_regmap sys_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SYS_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_sys,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_a_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = sys_parents,
+		.num_parents = ARRAY_SIZE(sys_parents),
+	},
+};
+
+static struct clk_regmap sys_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SYS_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a.hw,
+			&sys_b.hw,
+		},
+		.num_parents = 2,
+		/*
+		 * This clock is used by APB bus which is set in boot ROM code
+		 * and is required by the platform to operate correctly.
+		 * Until the following condition are met, we need this clock to
+		 * be marked as critical:
+		 * a) Mark the clock used by a firmware resource, if possible
+		 * b) CCF has a clock hand-off mechanism to make the sure the
+		 *    clock stays on until the proper driver comes along
+		 */
+		.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+	},
+};
+
+static u32 mux_table_dsp_ab[] = { 0, 1, 2, 3, 4, 7 };
+static const struct clk_parent_data dsp_ab_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "hifi_pll", },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap dspa_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspa_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPA_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspa_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPA_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a.hw,
+			&dspa_b.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_EN,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_en_nic = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_EN,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_en_nic",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspb_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPB_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspb_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPB_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a.hw,
+			&dspb_b.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_EN,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_en_nic = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_EN,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_en_nic",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap clk_24m = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "24m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor clk_24m_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "24m_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&clk_24m.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap clk_12m = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 10,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "12m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&clk_24m_div2.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2_divn_pre = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = CLK12_24_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2_divn_pre",
+		.ops = &clk_regmap_divider_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "fclk_div2",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2_divn = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 12,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2_divn",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div2_divn_pre.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
+ * the index 4 is the clock measurement source, it's not supported yet
+ */
+static u32 gen_table[] = { 0, 1, 3, 5, 6, 7, 8 };
+static const struct clk_parent_data gen_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &rtc.hw },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", },
+};
+
+static struct clk_regmap gen_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = GEN_CLK_CTRL,
+		.mask = 0xf,
+		.shift = 12,
+		.table = gen_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gen_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = gen_parent_data,
+		.num_parents = ARRAY_SIZE(gen_parent_data),
+		/*
+		 * The GEN clock can be connected to an external pad, so it
+		 * may be set up directly from the device tree. Additionally,
+		 * the GEN clock can be inherited from a more accurate RTC
+		 * clock, so in certain situations, it may be necessary
+		 * to freeze its parent.
+		 */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap gen_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = GEN_CLK_CTRL,
+		.shift = 0,
+		.width = 11,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gen_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gen_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap gen = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = GEN_CLK_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gen",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gen_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap saradc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SAR_ADC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "saradc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .fw_name = "xtal", },
+			{ .hw = &sys.hw, },
+		},
+		.num_parents = 2,
+	},
+};
+
+static struct clk_regmap saradc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SAR_ADC_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 *[]) {
+			&saradc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap saradc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SAR_ADC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "saradc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&saradc_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data pwm_abcd_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap pwm_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.mask = 0x1,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_c_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_c_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_c_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_c_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_c = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_c",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_c_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_d_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.mask = 0x1,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_d_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_d_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_d_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_d = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_d",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_d_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data pwm_ef_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .fw_name = "fclk_div5", },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap pwm_e_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_e_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_ef_parents,
+		.num_parents = ARRAY_SIZE(pwm_ef_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_e_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_e_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_e = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_e",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_e_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_f_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_f_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_ef_parents,
+		.num_parents = ARRAY_SIZE(pwm_ef_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_f_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_f_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_f = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_f",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_f_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * spicc clk
+ *   fdiv2   |\         |\       _____
+ *  ---------| |---DIV--| |     |     |    spicc out
+ *  ---------| |        | |-----|GATE |---------
+ *     ..... |/         | /     |_____|
+ *  --------------------|/
+ *                 24M
+ */
+static const struct clk_parent_data spicc_spifc_parents[] = {
+	{ .fw_name = "fclk_div2"},
+	{ .fw_name = "fclk_div3"},
+	{ .fw_name = "fclk_div5"},
+	{ .fw_name = "hifi_pll" },
+};
+
+static struct clk_regmap spicc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPICC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spicc_spifc_parents,
+		.num_parents = ARRAY_SIZE(spicc_spifc_parents),
+	},
+};
+
+static struct clk_regmap spicc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPICC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPICC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &spicc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPICC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spicc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ts_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = TS_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ts_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ts = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = TS_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ts",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ts_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPIFC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spicc_spifc_parents,
+		.num_parents = ARRAY_SIZE(spicc_spifc_parents),
+	},
+};
+
+static struct clk_regmap spifc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPIFC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spifc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPIFC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &spifc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPIFC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spifc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spifc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data usb_bus_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+};
+
+static struct clk_regmap usb_bus_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = USB_BUSCLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "usb_bus_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = usb_bus_parents,
+		.num_parents = ARRAY_SIZE(usb_bus_parents),
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap usb_bus_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = USB_BUSCLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "usb_bus_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&usb_bus_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap usb_bus = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = USB_BUSCLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_bus",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&usb_bus_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data sd_emmc_psram_dmc_parents[] = {
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "hifi_pll", },
+};
+
+static struct clk_regmap sd_emmc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap sd_emmc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &sd_emmc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sd_emmc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PSRAM_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap psram_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PSRAM_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&psram_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PSRAM_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &psram_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PSRAM_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "psram",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&psram_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DMC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap dmc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DMC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dmc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DMC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &dmc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DMC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dmc",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dmc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECA_CLK_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ceca_32k_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ceca_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = CECA_CLK_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = CECA_CLK_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ceca_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ceca_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ceca_32k_sel_pre = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECA_CLK_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 *[]) {
+			&ceca_32k_div.hw,
+			&ceca_32k_in.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECA_CLK_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 *[]) {
+			&ceca_32k_sel_pre.hw,
+			&rtc.hw,
+		},
+		.num_parents = 2,
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_out = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECA_CLK_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ceca_32k_out",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ceca_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECB_CLK_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cecb_32k_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap cecb_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = CECB_CLK_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = CECB_CLK_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cecb_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&cecb_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap cecb_32k_sel_pre = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECB_CLK_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 *[]) {
+			&cecb_32k_div.hw,
+			&cecb_32k_in.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECB_CLK_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 *[]) {
+			&cecb_32k_sel_pre.hw,
+			&rtc.hw,
+		},
+		.num_parents = 2,
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_out = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECB_CLK_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cecb_32k_out",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&cecb_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+#define MESON_GATE(_name, _reg, _bit) \
+	MESON_PCLK(_name, _reg, _bit, &sys.hw)
+
+static MESON_GATE(clktree,	SYS_CLK_EN0,	0);
+static MESON_GATE(reset_ctrl,	SYS_CLK_EN0,	1);
+static MESON_GATE(analog_ctrl,	SYS_CLK_EN0,	2);
+static MESON_GATE(pwr_ctrl,	SYS_CLK_EN0,	3);
+static MESON_GATE(pad_ctrl,	SYS_CLK_EN0,	4);
+static MESON_GATE(sys_ctrl,	SYS_CLK_EN0,	5);
+static MESON_GATE(temp_sensor,	SYS_CLK_EN0,	6);
+static MESON_GATE(am2axi_dev,	SYS_CLK_EN0,	7);
+static MESON_GATE(spicc_b,	SYS_CLK_EN0,	8);
+static MESON_GATE(spicc_a,	SYS_CLK_EN0,	9);
+static MESON_GATE(msr,		SYS_CLK_EN0,	10);
+static MESON_GATE(audio,	SYS_CLK_EN0,	11);
+static MESON_GATE(jtag_ctrl,	SYS_CLK_EN0,	12);
+static MESON_GATE(saradc_en,	SYS_CLK_EN0,	13);
+static MESON_GATE(pwm_ef,	SYS_CLK_EN0,	14);
+static MESON_GATE(pwm_cd,	SYS_CLK_EN0,	15);
+static MESON_GATE(pwm_ab,	SYS_CLK_EN0,	16);
+static MESON_GATE(cec,		SYS_CLK_EN0,	17);
+static MESON_GATE(i2c_s,	SYS_CLK_EN0,	18);
+static MESON_GATE(ir_ctrl,	SYS_CLK_EN0,	19);
+static MESON_GATE(i2c_m_d,	SYS_CLK_EN0,	20);
+static MESON_GATE(i2c_m_c,	SYS_CLK_EN0,	21);
+static MESON_GATE(i2c_m_b,	SYS_CLK_EN0,	22);
+static MESON_GATE(i2c_m_a,	SYS_CLK_EN0,	23);
+static MESON_GATE(acodec,	SYS_CLK_EN0,	24);
+static MESON_GATE(otp,		SYS_CLK_EN0,	25);
+static MESON_GATE(sd_emmc_a,	SYS_CLK_EN0,	26);
+static MESON_GATE(usb_phy,	SYS_CLK_EN0,	27);
+static MESON_GATE(usb_ctrl,	SYS_CLK_EN0,	28);
+static MESON_GATE(sys_dspb,	SYS_CLK_EN0,	29);
+static MESON_GATE(sys_dspa,	SYS_CLK_EN0,	30);
+static MESON_GATE(dma,		SYS_CLK_EN0,	31);
+static MESON_GATE(irq_ctrl,	SYS_CLK_EN1,	0);
+static MESON_GATE(nic,		SYS_CLK_EN1,	1);
+static MESON_GATE(gic,		SYS_CLK_EN1,	2);
+static MESON_GATE(uart_c,	SYS_CLK_EN1,	3);
+static MESON_GATE(uart_b,	SYS_CLK_EN1,	4);
+static MESON_GATE(uart_a,	SYS_CLK_EN1,	5);
+static MESON_GATE(sys_psram,	SYS_CLK_EN1,	6);
+static MESON_GATE(rsa,		SYS_CLK_EN1,	8);
+static MESON_GATE(coresight,	SYS_CLK_EN1,	9);
+static MESON_GATE(am2axi_vad,	AXI_CLK_EN,	0);
+static MESON_GATE(audio_vad,	AXI_CLK_EN,	1);
+static MESON_GATE(axi_dmc,	AXI_CLK_EN,	3);
+static MESON_GATE(axi_psram,	AXI_CLK_EN,	4);
+static MESON_GATE(ramb,		AXI_CLK_EN,	5);
+static MESON_GATE(rama,		AXI_CLK_EN,	6);
+static MESON_GATE(axi_spifc,	AXI_CLK_EN,	7);
+static MESON_GATE(axi_nic,	AXI_CLK_EN,	8);
+static MESON_GATE(axi_dma,	AXI_CLK_EN,	9);
+static MESON_GATE(cpu_ctrl,	AXI_CLK_EN,	10);
+static MESON_GATE(rom,		AXI_CLK_EN,	11);
+static MESON_GATE(prod_i2c,	AXI_CLK_EN,	12);
+
+/* Array of all clocks registered by this provider */
+static struct clk_hw_onecell_data a1_periphs_clks = {
+	.hws = {
+		[CLKID_XTAL_IN]			= &xtal_in.hw,
+		[CLKID_FIXPLL_IN]		= &fixpll_in.hw,
+		[CLKID_USB_PHY_IN]		= &usb_phy_in.hw,
+		[CLKID_USB_CTRL_IN]		= &usb_ctrl_in.hw,
+		[CLKID_HIFIPLL_IN]		= &hifipll_in.hw,
+		[CLKID_SYSPLL_IN]		= &syspll_in.hw,
+		[CLKID_DDS_IN]			= &dds_in.hw,
+		[CLKID_SYS]			= &sys.hw,
+		[CLKID_CLKTREE]			= &clktree.hw,
+		[CLKID_RESET_CTRL]		= &reset_ctrl.hw,
+		[CLKID_ANALOG_CTRL]		= &analog_ctrl.hw,
+		[CLKID_PWR_CTRL]		= &pwr_ctrl.hw,
+		[CLKID_PAD_CTRL]		= &pad_ctrl.hw,
+		[CLKID_SYS_CTRL]		= &sys_ctrl.hw,
+		[CLKID_TEMP_SENSOR]		= &temp_sensor.hw,
+		[CLKID_AM2AXI_DIV]		= &am2axi_dev.hw,
+		[CLKID_SPICC_B]			= &spicc_b.hw,
+		[CLKID_SPICC_A]			= &spicc_a.hw,
+		[CLKID_MSR]			= &msr.hw,
+		[CLKID_AUDIO]			= &audio.hw,
+		[CLKID_JTAG_CTRL]		= &jtag_ctrl.hw,
+		[CLKID_SARADC_EN]		= &saradc_en.hw,
+		[CLKID_PWM_EF]			= &pwm_ef.hw,
+		[CLKID_PWM_CD]			= &pwm_cd.hw,
+		[CLKID_PWM_AB]			= &pwm_ab.hw,
+		[CLKID_CEC]			= &cec.hw,
+		[CLKID_I2C_S]			= &i2c_s.hw,
+		[CLKID_IR_CTRL]			= &ir_ctrl.hw,
+		[CLKID_I2C_M_D]			= &i2c_m_d.hw,
+		[CLKID_I2C_M_C]			= &i2c_m_c.hw,
+		[CLKID_I2C_M_B]			= &i2c_m_b.hw,
+		[CLKID_I2C_M_A]			= &i2c_m_a.hw,
+		[CLKID_ACODEC]			= &acodec.hw,
+		[CLKID_OTP]			= &otp.hw,
+		[CLKID_SD_EMMC_A]		= &sd_emmc_a.hw,
+		[CLKID_USB_PHY]			= &usb_phy.hw,
+		[CLKID_USB_CTRL]		= &usb_ctrl.hw,
+		[CLKID_SYS_DSPB]		= &sys_dspb.hw,
+		[CLKID_SYS_DSPA]		= &sys_dspa.hw,
+		[CLKID_DMA]			= &dma.hw,
+		[CLKID_IRQ_CTRL]		= &irq_ctrl.hw,
+		[CLKID_NIC]			= &nic.hw,
+		[CLKID_GIC]			= &gic.hw,
+		[CLKID_UART_C]			= &uart_c.hw,
+		[CLKID_UART_B]			= &uart_b.hw,
+		[CLKID_UART_A]			= &uart_a.hw,
+		[CLKID_SYS_PSRAM]		= &sys_psram.hw,
+		[CLKID_RSA]			= &rsa.hw,
+		[CLKID_CORESIGHT]		= &coresight.hw,
+		[CLKID_AM2AXI_VAD]		= &am2axi_vad.hw,
+		[CLKID_AUDIO_VAD]		= &audio_vad.hw,
+		[CLKID_AXI_DMC]			= &axi_dmc.hw,
+		[CLKID_AXI_PSRAM]		= &axi_psram.hw,
+		[CLKID_RAMB]			= &ramb.hw,
+		[CLKID_RAMA]			= &rama.hw,
+		[CLKID_AXI_SPIFC]		= &axi_spifc.hw,
+		[CLKID_AXI_NIC]			= &axi_nic.hw,
+		[CLKID_AXI_DMA]			= &axi_dma.hw,
+		[CLKID_CPU_CTRL]		= &cpu_ctrl.hw,
+		[CLKID_ROM]			= &rom.hw,
+		[CLKID_PROC_I2C]		= &prod_i2c.hw,
+		[CLKID_DSPA_SEL]		= &dspa_sel.hw,
+		[CLKID_DSPB_SEL]		= &dspb_sel.hw,
+		[CLKID_DSPA_EN]			= &dspa_en.hw,
+		[CLKID_DSPA_EN_NIC]		= &dspa_en_nic.hw,
+		[CLKID_DSPB_EN]			= &dspb_en.hw,
+		[CLKID_DSPB_EN_NIC]		= &dspb_en_nic.hw,
+		[CLKID_RTC]			= &rtc.hw,
+		[CLKID_CECA_32K]		= &ceca_32k_out.hw,
+		[CLKID_CECB_32K]		= &cecb_32k_out.hw,
+		[CLKID_24M]			= &clk_24m.hw,
+		[CLKID_12M]			= &clk_12m.hw,
+		[CLKID_FCLK_DIV2_DIVN]		= &fclk_div2_divn.hw,
+		[CLKID_GEN]			= &gen.hw,
+		[CLKID_SARADC_SEL]		= &saradc_sel.hw,
+		[CLKID_SARADC]			= &saradc.hw,
+		[CLKID_PWM_A]			= &pwm_a.hw,
+		[CLKID_PWM_B]			= &pwm_b.hw,
+		[CLKID_PWM_C]			= &pwm_c.hw,
+		[CLKID_PWM_D]			= &pwm_d.hw,
+		[CLKID_PWM_E]			= &pwm_e.hw,
+		[CLKID_PWM_F]			= &pwm_f.hw,
+		[CLKID_SPICC]			= &spicc.hw,
+		[CLKID_TS]			= &ts.hw,
+		[CLKID_SPIFC]			= &spifc.hw,
+		[CLKID_USB_BUS]			= &usb_bus.hw,
+		[CLKID_SD_EMMC]			= &sd_emmc.hw,
+		[CLKID_PSRAM]			= &psram.hw,
+		[CLKID_DMC]			= &dmc.hw,
+		[CLKID_SYS_A_SEL]		= &sys_a_sel.hw,
+		[CLKID_SYS_A_DIV]		= &sys_a_div.hw,
+		[CLKID_SYS_A]			= &sys_a.hw,
+		[CLKID_SYS_B_SEL]		= &sys_b_sel.hw,
+		[CLKID_SYS_B_DIV]		= &sys_b_div.hw,
+		[CLKID_SYS_B]			= &sys_b.hw,
+		[CLKID_DSPA_A_SEL]		= &dspa_a_sel.hw,
+		[CLKID_DSPA_A_DIV]		= &dspa_a_div.hw,
+		[CLKID_DSPA_A]			= &dspa_a.hw,
+		[CLKID_DSPA_B_SEL]		= &dspa_b_sel.hw,
+		[CLKID_DSPA_B_DIV]		= &dspa_b_div.hw,
+		[CLKID_DSPA_B]			= &dspa_b.hw,
+		[CLKID_DSPB_A_SEL]		= &dspb_a_sel.hw,
+		[CLKID_DSPB_A_DIV]		= &dspb_a_div.hw,
+		[CLKID_DSPB_A]			= &dspb_a.hw,
+		[CLKID_DSPB_B_SEL]		= &dspb_b_sel.hw,
+		[CLKID_DSPB_B_DIV]		= &dspb_b_div.hw,
+		[CLKID_DSPB_B]			= &dspb_b.hw,
+		[CLKID_RTC_32K_IN]		= &rtc_32k_in.hw,
+		[CLKID_RTC_32K_DIV]		= &rtc_32k_div.hw,
+		[CLKID_RTC_32K_XTAL]		= &rtc_32k_xtal.hw,
+		[CLKID_RTC_32K_SEL]		= &rtc_32k_sel.hw,
+		[CLKID_CECB_32K_IN]		= &cecb_32k_in.hw,
+		[CLKID_CECB_32K_DIV]		= &cecb_32k_div.hw,
+		[CLKID_CECB_32K_SEL_PRE]	= &cecb_32k_sel_pre.hw,
+		[CLKID_CECB_32K_SEL]		= &cecb_32k_sel.hw,
+		[CLKID_CECA_32K_IN]		= &ceca_32k_in.hw,
+		[CLKID_CECA_32K_DIV]		= &ceca_32k_div.hw,
+		[CLKID_CECA_32K_SEL_PRE]	= &ceca_32k_sel_pre.hw,
+		[CLKID_CECA_32K_SEL]		= &ceca_32k_sel.hw,
+		[CLKID_DIV2_PRE]		= &fclk_div2_divn_pre.hw,
+		[CLKID_24M_DIV2]		= &clk_24m_div2.hw,
+		[CLKID_GEN_SEL]			= &gen_sel.hw,
+		[CLKID_GEN_DIV]			= &gen_div.hw,
+		[CLKID_SARADC_DIV]		= &saradc_div.hw,
+		[CLKID_PWM_A_SEL]		= &pwm_a_sel.hw,
+		[CLKID_PWM_A_DIV]		= &pwm_a_div.hw,
+		[CLKID_PWM_B_SEL]		= &pwm_b_sel.hw,
+		[CLKID_PWM_B_DIV]		= &pwm_b_div.hw,
+		[CLKID_PWM_C_SEL]		= &pwm_c_sel.hw,
+		[CLKID_PWM_C_DIV]		= &pwm_c_div.hw,
+		[CLKID_PWM_D_SEL]		= &pwm_d_sel.hw,
+		[CLKID_PWM_D_DIV]		= &pwm_d_div.hw,
+		[CLKID_PWM_E_SEL]		= &pwm_e_sel.hw,
+		[CLKID_PWM_E_DIV]		= &pwm_e_div.hw,
+		[CLKID_PWM_F_SEL]		= &pwm_f_sel.hw,
+		[CLKID_PWM_F_DIV]		= &pwm_f_div.hw,
+		[CLKID_SPICC_SEL]		= &spicc_sel.hw,
+		[CLKID_SPICC_DIV]		= &spicc_div.hw,
+		[CLKID_SPICC_SEL2]		= &spicc_sel2.hw,
+		[CLKID_TS_DIV]			= &ts_div.hw,
+		[CLKID_SPIFC_SEL]		= &spifc_sel.hw,
+		[CLKID_SPIFC_DIV]		= &spifc_div.hw,
+		[CLKID_SPIFC_SEL2]		= &spifc_sel2.hw,
+		[CLKID_USB_BUS_SEL]		= &usb_bus_sel.hw,
+		[CLKID_USB_BUS_DIV]		= &usb_bus_div.hw,
+		[CLKID_SD_EMMC_SEL]		= &sd_emmc_sel.hw,
+		[CLKID_SD_EMMC_DIV]		= &sd_emmc_div.hw,
+		[CLKID_SD_EMMC_SEL2]		= &sd_emmc_sel2.hw,
+		[CLKID_PSRAM_SEL]		= &psram_sel.hw,
+		[CLKID_PSRAM_DIV]		= &psram_div.hw,
+		[CLKID_PSRAM_SEL2]		= &psram_sel2.hw,
+		[CLKID_DMC_SEL]			= &dmc_sel.hw,
+		[CLKID_DMC_DIV]			= &dmc_div.hw,
+		[CLKID_DMC_SEL2]		= &dmc_sel2.hw,
+		[NR_CLKS]			= NULL,
+	},
+	.num = NR_CLKS,
+};
+
+/* Convenience table to populate regmap in .probe */
+static struct clk_regmap *const a1_periphs_regmaps[] = {
+	&xtal_in,
+	&fixpll_in,
+	&usb_phy_in,
+	&usb_ctrl_in,
+	&hifipll_in,
+	&syspll_in,
+	&dds_in,
+	&sys,
+	&clktree,
+	&reset_ctrl,
+	&analog_ctrl,
+	&pwr_ctrl,
+	&pad_ctrl,
+	&sys_ctrl,
+	&temp_sensor,
+	&am2axi_dev,
+	&spicc_b,
+	&spicc_a,
+	&msr,
+	&audio,
+	&jtag_ctrl,
+	&saradc_en,
+	&pwm_ef,
+	&pwm_cd,
+	&pwm_ab,
+	&cec,
+	&i2c_s,
+	&ir_ctrl,
+	&i2c_m_d,
+	&i2c_m_c,
+	&i2c_m_b,
+	&i2c_m_a,
+	&acodec,
+	&otp,
+	&sd_emmc_a,
+	&usb_phy,
+	&usb_ctrl,
+	&sys_dspb,
+	&sys_dspa,
+	&dma,
+	&irq_ctrl,
+	&nic,
+	&gic,
+	&uart_c,
+	&uart_b,
+	&uart_a,
+	&sys_psram,
+	&rsa,
+	&coresight,
+	&am2axi_vad,
+	&audio_vad,
+	&axi_dmc,
+	&axi_psram,
+	&ramb,
+	&rama,
+	&axi_spifc,
+	&axi_nic,
+	&axi_dma,
+	&cpu_ctrl,
+	&rom,
+	&prod_i2c,
+	&dspa_sel,
+	&dspb_sel,
+	&dspa_en,
+	&dspa_en_nic,
+	&dspb_en,
+	&dspb_en_nic,
+	&rtc,
+	&ceca_32k_out,
+	&cecb_32k_out,
+	&clk_24m,
+	&clk_12m,
+	&fclk_div2_divn,
+	&gen,
+	&saradc_sel,
+	&saradc,
+	&pwm_a,
+	&pwm_b,
+	&pwm_c,
+	&pwm_d,
+	&pwm_e,
+	&pwm_f,
+	&spicc,
+	&ts,
+	&spifc,
+	&usb_bus,
+	&sd_emmc,
+	&psram,
+	&dmc,
+	&sys_a_sel,
+	&sys_a_div,
+	&sys_a,
+	&sys_b_sel,
+	&sys_b_div,
+	&sys_b,
+	&dspa_a_sel,
+	&dspa_a_div,
+	&dspa_a,
+	&dspa_b_sel,
+	&dspa_b_div,
+	&dspa_b,
+	&dspb_a_sel,
+	&dspb_a_div,
+	&dspb_a,
+	&dspb_b_sel,
+	&dspb_b_div,
+	&dspb_b,
+	&rtc_32k_in,
+	&rtc_32k_div,
+	&rtc_32k_xtal,
+	&rtc_32k_sel,
+	&cecb_32k_in,
+	&cecb_32k_div,
+	&cecb_32k_sel_pre,
+	&cecb_32k_sel,
+	&ceca_32k_in,
+	&ceca_32k_div,
+	&ceca_32k_sel_pre,
+	&ceca_32k_sel,
+	&fclk_div2_divn_pre,
+	&gen_sel,
+	&gen_div,
+	&saradc_div,
+	&pwm_a_sel,
+	&pwm_a_div,
+	&pwm_b_sel,
+	&pwm_b_div,
+	&pwm_c_sel,
+	&pwm_c_div,
+	&pwm_d_sel,
+	&pwm_d_div,
+	&pwm_e_sel,
+	&pwm_e_div,
+	&pwm_f_sel,
+	&pwm_f_div,
+	&spicc_sel,
+	&spicc_div,
+	&spicc_sel2,
+	&ts_div,
+	&spifc_sel,
+	&spifc_div,
+	&spifc_sel2,
+	&usb_bus_sel,
+	&usb_bus_div,
+	&sd_emmc_sel,
+	&sd_emmc_div,
+	&sd_emmc_sel2,
+	&psram_sel,
+	&psram_div,
+	&psram_sel2,
+	&dmc_sel,
+	&dmc_div,
+	&dmc_sel2,
+};
+
+static struct regmap_config a1_periphs_regmap_cfg = {
+	.reg_bits   = 32,
+	.val_bits   = 32,
+	.reg_stride = 4,
+};
+
+static int meson_a1_periphs_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *base;
+	struct regmap *map;
+	int clkid, i, err;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "can't ioremap resource\n");
+
+	map = devm_regmap_init_mmio(dev, base, &a1_periphs_regmap_cfg);
+	if (IS_ERR(map))
+		return dev_err_probe(dev, PTR_ERR(map),
+				     "can't init regmap mmio region\n");
+
+	/* Populate regmap for the regmap backed clocks */
+	for (i = 0; i < ARRAY_SIZE(a1_periphs_regmaps); i++)
+		a1_periphs_regmaps[i]->map = map;
+
+	for (clkid = 0; clkid < a1_periphs_clks.num; clkid++) {
+		err = devm_clk_hw_register(dev, a1_periphs_clks.hws[clkid]);
+		if (err)
+			return dev_err_probe(dev, err,
+					     "clock[%d] registration failed\n",
+					     clkid);
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &a1_periphs_clks);
+}
+
+static const struct of_device_id a1_periphs_clkc_match_table[] = {
+	{ .compatible = "amlogic,a1-peripherals-clkc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, a1_periphs_clkc_match_table);
+
+static struct platform_driver a1_periphs_clkc_driver = {
+	.probe = meson_a1_periphs_probe,
+	.driver = {
+		.name = "a1-peripherals-clkc",
+		.of_match_table = a1_periphs_clkc_match_table,
+	},
+};
+
+module_platform_driver(a1_periphs_clkc_driver);
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/a1-peripherals.h b/drivers/clk/meson/a1-peripherals.h
new file mode 100644
index 000000000000..526fc9ba5c9f
--- /dev/null
+++ b/drivers/clk/meson/a1-peripherals.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Amlogic A1 Peripherals Clock Controller internals
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PERIPHERALS_H
+#define __A1_PERIPHERALS_H
+
+/* peripherals clock controller register offset */
+#define SYS_OSCIN_CTRL		0x0
+#define RTC_BY_OSCIN_CTRL0	0x4
+#define RTC_BY_OSCIN_CTRL1	0x8
+#define RTC_CTRL		0xc
+#define SYS_CLK_CTRL0		0x10
+#define SYS_CLK_EN0		0x1c
+#define SYS_CLK_EN1		0x20
+#define AXI_CLK_EN		0x24
+#define DSPA_CLK_EN		0x28
+#define DSPB_CLK_EN		0x2c
+#define DSPA_CLK_CTRL0		0x30
+#define DSPB_CLK_CTRL0		0x34
+#define CLK12_24_CTRL		0x38
+#define GEN_CLK_CTRL		0x3c
+#define SAR_ADC_CLK_CTRL	0xc0
+#define PWM_CLK_AB_CTRL		0xc4
+#define PWM_CLK_CD_CTRL		0xc8
+#define PWM_CLK_EF_CTRL		0xcc
+#define SPICC_CLK_CTRL		0xd0
+#define TS_CLK_CTRL		0xd4
+#define SPIFC_CLK_CTRL		0xd8
+#define USB_BUSCLK_CTRL		0xdc
+#define SD_EMMC_CLK_CTRL	0xe0
+#define CECA_CLK_CTRL0		0xe4
+#define CECA_CLK_CTRL1		0xe8
+#define CECB_CLK_CTRL0		0xec
+#define CECB_CLK_CTRL1		0xf0
+#define PSRAM_CLK_CTRL		0xf4
+#define DMC_CLK_CTRL		0xf8
+
+/* include the CLKIDs that have been made part of the DT binding */
+#include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
+
+/*
+ * CLKID index values for internal clocks
+ *
+ * These indices are entirely contrived and do not map onto the hardware.
+ * It has now been decided to expose everything by default in the DT header:
+ * include/dt-bindings/clock/a1-peripherals-clkc.h.
+ * Only the clocks ids we don't want to expose, such as the internal muxes and
+ * dividers of composite clocks, will remain defined here.
+ */
+#define CLKID_XTAL_IN		0
+#define CLKID_DSPA_SEL		61
+#define CLKID_DSPB_SEL		62
+#define CLKID_SARADC_SEL	74
+#define CLKID_SYS_A_SEL		89
+#define CLKID_SYS_A_DIV		90
+#define CLKID_SYS_A		91
+#define CLKID_SYS_B_SEL		92
+#define CLKID_SYS_B_DIV		93
+#define CLKID_SYS_B		94
+#define CLKID_DSPA_A_DIV	96
+#define CLKID_DSPA_A		97
+#define CLKID_DSPA_B_DIV	99
+#define CLKID_DSPA_B		100
+#define CLKID_DSPB_A_DIV	102
+#define CLKID_DSPB_A		103
+#define CLKID_DSPB_B_DIV	105
+#define CLKID_DSPB_B		106
+#define CLKID_RTC_32K_IN	107
+#define CLKID_RTC_32K_DIV	108
+#define CLKID_RTC_32K_XTAL	109
+#define CLKID_RTC_32K_SEL	110
+#define CLKID_CECB_32K_IN	111
+#define CLKID_CECB_32K_DIV	112
+#define CLKID_CECA_32K_IN	115
+#define CLKID_CECA_32K_DIV	116
+#define CLKID_DIV2_PRE		119
+#define CLKID_24M_DIV2		120
+#define CLKID_GEN_DIV		122
+#define CLKID_SARADC_DIV	123
+#define CLKID_PWM_A_DIV		125
+#define CLKID_PWM_B_DIV		127
+#define CLKID_PWM_C_DIV		129
+#define CLKID_PWM_D_DIV		131
+#define CLKID_PWM_E_DIV		133
+#define CLKID_PWM_F_DIV		135
+#define CLKID_SPICC_SEL		136
+#define CLKID_SPICC_DIV		137
+#define CLKID_SPICC_SEL2	138
+#define CLKID_TS_DIV		139
+#define CLKID_SPIFC_SEL		140
+#define CLKID_SPIFC_DIV		141
+#define CLKID_SPIFC_SEL2	142
+#define CLKID_USB_BUS_SEL	143
+#define CLKID_USB_BUS_DIV	144
+#define CLKID_SD_EMMC_SEL	145
+#define CLKID_SD_EMMC_DIV	146
+#define CLKID_PSRAM_SEL		148
+#define CLKID_PSRAM_DIV		149
+#define CLKID_PSRAM_SEL2	150
+#define CLKID_DMC_SEL		151
+#define CLKID_DMC_DIV		152
+#define CLKID_DMC_SEL2		153
+#define NR_CLKS			154
+
+#endif /* __A1_PERIPHERALS_H */
-- 
2.36.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-17 13:33   ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-17 13:33 UTC (permalink / raw)
  To: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel, Dmitry Rokosov

Introduce Peripherals clock controller for Amlogic A1 SoC family.

A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
and Audio.
This patchset adds support for Amlogic A1 Peripherals clock driver and
allows to generate clocks for all A1 SoC peripheral IPs.

Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
---
 drivers/clk/meson/Kconfig          |   10 +
 drivers/clk/meson/Makefile         |    1 +
 drivers/clk/meson/a1-peripherals.c | 2273 ++++++++++++++++++++++++++++
 drivers/clk/meson/a1-peripherals.h |  113 ++
 4 files changed, 2397 insertions(+)
 create mode 100644 drivers/clk/meson/a1-peripherals.c
 create mode 100644 drivers/clk/meson/a1-peripherals.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 693c4cf60f27..8ce846fdbe43 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -109,6 +109,16 @@ config COMMON_CLK_A1_PLL
 	  device, A1 SoC Family. Say Y if you want A1 PLL clock controller
 	  to work.
 
+config COMMON_CLK_A1_PERIPHERALS
+	tristate "Amlogic A1 SoC Peripherals clock controller support"
+	depends on ARM64
+	select COMMON_CLK_MESON_DUALDIV
+	select COMMON_CLK_MESON_REGMAP
+	help
+	  Support for the Peripherals clock controller on Amlogic A113L based
+	  device, A1 SoC Family. Say Y if you want A1 Peripherals clock
+	  controller to work.
+
 config COMMON_CLK_G12A
 	tristate "G12 and SM1 SoC clock controllers support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 2f17f475a48f..d5288662881d 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
 obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
+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
diff --git a/drivers/clk/meson/a1-peripherals.c b/drivers/clk/meson/a1-peripherals.c
new file mode 100644
index 000000000000..5e7a37cbbb88
--- /dev/null
+++ b/drivers/clk/meson/a1-peripherals.c
@@ -0,0 +1,2273 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "a1-peripherals.h"
+#include "clk-dualdiv.h"
+#include "clk-regmap.h"
+
+static struct clk_regmap xtal_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "xtal_in",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fixpll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fixpll_in",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap usb_phy_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_phy_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap usb_ctrl_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_ctrl_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap hifipll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifipll_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap syspll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 5,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "syspll_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap dds_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_OSCIN_CTRL,
+		.bit_idx = 6,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dds_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_32k_in",
+		.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 clk_32k_div_table[] = {
+	{
+		.dual		= 1,
+		.n1		= 733,
+		.m1		= 8,
+		.n2		= 732,
+		.m2		= 11,
+	},
+	{}
+};
+
+static struct clk_regmap rtc_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_xtal = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL1,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_32k_xtal",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap rtc_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = RTC_CTRL,
+		.mask = 0x3,
+		.shift = 0,
+		.flags = CLK_MUX_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc_32k_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_xtal.hw,
+			&rtc_32k_div.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * All clocks that can be inherited from a more accurate RTC clock are marked
+ * with the CLK_SET_RATE_NO_REPARENT flag. This is because in certain
+ * situations, we may need to freeze their parent. The parent setup of these
+ * clocks should be located on the device tree side.
+ */
+struct clk_regmap rtc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 mux_table_sys[] = { 0, 1, 2, 3, 7 };
+static const struct clk_parent_data sys_parents[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div5" },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap sys_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_sys,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_b_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = sys_parents,
+		.num_parents = ARRAY_SIZE(sys_parents),
+	},
+};
+
+static struct clk_regmap sys_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SYS_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_sys,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_a_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = sys_parents,
+		.num_parents = ARRAY_SIZE(sys_parents),
+	},
+};
+
+static struct clk_regmap sys_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SYS_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sys = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a.hw,
+			&sys_b.hw,
+		},
+		.num_parents = 2,
+		/*
+		 * This clock is used by APB bus which is set in boot ROM code
+		 * and is required by the platform to operate correctly.
+		 * Until the following condition are met, we need this clock to
+		 * be marked as critical:
+		 * a) Mark the clock used by a firmware resource, if possible
+		 * b) CCF has a clock hand-off mechanism to make the sure the
+		 *    clock stays on until the proper driver comes along
+		 */
+		.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+	},
+};
+
+static u32 mux_table_dsp_ab[] = { 0, 1, 2, 3, 4, 7 };
+static const struct clk_parent_data dsp_ab_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "hifi_pll", },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap dspa_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspa_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPA_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspa_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPA_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspa_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_a.hw,
+			&dspa_b.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_EN,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspa_en_nic = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPA_CLK_EN,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_en_nic",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspa_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspb_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPB_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = mux_table_dsp_ab,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsp_ab_parent_data,
+		.num_parents = ARRAY_SIZE(dsp_ab_parent_data),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap dspb_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DSPB_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPB_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dspb_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_a.hw,
+			&dspb_b.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_EN,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dspb_en_nic = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DSPB_CLK_EN,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspb_en_nic",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dspb_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap clk_24m = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "24m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor clk_24m_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "24m_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&clk_24m.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap clk_12m = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 10,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "12m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&clk_24m_div2.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2_divn_pre = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = CLK12_24_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2_divn_pre",
+		.ops = &clk_regmap_divider_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "fclk_div2",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2_divn = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 12,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2_divn",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div2_divn_pre.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
+ * the index 4 is the clock measurement source, it's not supported yet
+ */
+static u32 gen_table[] = { 0, 1, 3, 5, 6, 7, 8 };
+static const struct clk_parent_data gen_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &rtc.hw },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", },
+};
+
+static struct clk_regmap gen_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = GEN_CLK_CTRL,
+		.mask = 0xf,
+		.shift = 12,
+		.table = gen_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gen_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = gen_parent_data,
+		.num_parents = ARRAY_SIZE(gen_parent_data),
+		/*
+		 * The GEN clock can be connected to an external pad, so it
+		 * may be set up directly from the device tree. Additionally,
+		 * the GEN clock can be inherited from a more accurate RTC
+		 * clock, so in certain situations, it may be necessary
+		 * to freeze its parent.
+		 */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap gen_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = GEN_CLK_CTRL,
+		.shift = 0,
+		.width = 11,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gen_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gen_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap gen = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = GEN_CLK_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gen",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gen_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap saradc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SAR_ADC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "saradc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .fw_name = "xtal", },
+			{ .hw = &sys.hw, },
+		},
+		.num_parents = 2,
+	},
+};
+
+static struct clk_regmap saradc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SAR_ADC_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 *[]) {
+			&saradc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap saradc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SAR_ADC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "saradc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&saradc_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data pwm_abcd_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap pwm_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.mask = 0x1,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_c_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_c_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_c_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_c_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_c = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_c",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_c_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_d_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.mask = 0x1,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_d_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_abcd_parents,
+		.num_parents = ARRAY_SIZE(pwm_abcd_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_d_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_d_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_d = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_d",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_d_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data pwm_ef_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .fw_name = "fclk_div5", },
+	{ .hw = &rtc.hw },
+};
+
+static struct clk_regmap pwm_e_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_e_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_ef_parents,
+		.num_parents = ARRAY_SIZE(pwm_ef_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_e_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_e_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_e = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_e",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_e_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_f_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_f_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_ef_parents,
+		.num_parents = ARRAY_SIZE(pwm_ef_parents),
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap pwm_f_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = 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 *[]) {
+			&pwm_f_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_f = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_f",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_f_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * spicc clk
+ *   fdiv2   |\         |\       _____
+ *  ---------| |---DIV--| |     |     |    spicc out
+ *  ---------| |        | |-----|GATE |---------
+ *     ..... |/         | /     |_____|
+ *  --------------------|/
+ *                 24M
+ */
+static const struct clk_parent_data spicc_spifc_parents[] = {
+	{ .fw_name = "fclk_div2"},
+	{ .fw_name = "fclk_div3"},
+	{ .fw_name = "fclk_div5"},
+	{ .fw_name = "hifi_pll" },
+};
+
+static struct clk_regmap spicc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPICC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spicc_spifc_parents,
+		.num_parents = ARRAY_SIZE(spicc_spifc_parents),
+	},
+};
+
+static struct clk_regmap spicc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPICC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPICC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &spicc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPICC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spicc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ts_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = TS_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ts_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ts = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = TS_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ts",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ts_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPIFC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spicc_spifc_parents,
+		.num_parents = ARRAY_SIZE(spicc_spifc_parents),
+	},
+};
+
+static struct clk_regmap spifc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPIFC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spifc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPIFC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &spifc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPIFC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spifc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spifc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data usb_bus_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &sys.hw },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+};
+
+static struct clk_regmap usb_bus_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = USB_BUSCLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "usb_bus_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = usb_bus_parents,
+		.num_parents = ARRAY_SIZE(usb_bus_parents),
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap usb_bus_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = USB_BUSCLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "usb_bus_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&usb_bus_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap usb_bus = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = USB_BUSCLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "usb_bus",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&usb_bus_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data sd_emmc_psram_dmc_parents[] = {
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "hifi_pll", },
+};
+
+static struct clk_regmap sd_emmc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap sd_emmc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &sd_emmc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sd_emmc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PSRAM_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap psram_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PSRAM_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&psram_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PSRAM_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "psram_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &psram_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap psram = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PSRAM_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "psram",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&psram_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DMC_CLK_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sd_emmc_psram_dmc_parents,
+		.num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents),
+	},
+};
+
+static struct clk_regmap dmc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DMC_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dmc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc_sel2 = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DMC_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dmc_sel2",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &dmc_div.hw },
+			{ .fw_name = "xtal", },
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dmc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DMC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dmc",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dmc_sel2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECA_CLK_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ceca_32k_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ceca_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = CECA_CLK_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = CECA_CLK_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = CECA_CLK_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ceca_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ceca_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap ceca_32k_sel_pre = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECA_CLK_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 *[]) {
+			&ceca_32k_div.hw,
+			&ceca_32k_in.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECA_CLK_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 *[]) {
+			&ceca_32k_sel_pre.hw,
+			&rtc.hw,
+		},
+		.num_parents = 2,
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap ceca_32k_out = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECA_CLK_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ceca_32k_out",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ceca_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECB_CLK_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cecb_32k_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap cecb_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = CECB_CLK_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = CECB_CLK_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = CECB_CLK_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = clk_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cecb_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&cecb_32k_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap cecb_32k_sel_pre = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECB_CLK_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 *[]) {
+			&cecb_32k_div.hw,
+			&cecb_32k_in.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECB_CLK_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 *[]) {
+			&cecb_32k_sel_pre.hw,
+			&rtc.hw,
+		},
+		.num_parents = 2,
+		/* For more information, please refer to rtc clock */
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap cecb_32k_out = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = CECB_CLK_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cecb_32k_out",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&cecb_32k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+#define MESON_GATE(_name, _reg, _bit) \
+	MESON_PCLK(_name, _reg, _bit, &sys.hw)
+
+static MESON_GATE(clktree,	SYS_CLK_EN0,	0);
+static MESON_GATE(reset_ctrl,	SYS_CLK_EN0,	1);
+static MESON_GATE(analog_ctrl,	SYS_CLK_EN0,	2);
+static MESON_GATE(pwr_ctrl,	SYS_CLK_EN0,	3);
+static MESON_GATE(pad_ctrl,	SYS_CLK_EN0,	4);
+static MESON_GATE(sys_ctrl,	SYS_CLK_EN0,	5);
+static MESON_GATE(temp_sensor,	SYS_CLK_EN0,	6);
+static MESON_GATE(am2axi_dev,	SYS_CLK_EN0,	7);
+static MESON_GATE(spicc_b,	SYS_CLK_EN0,	8);
+static MESON_GATE(spicc_a,	SYS_CLK_EN0,	9);
+static MESON_GATE(msr,		SYS_CLK_EN0,	10);
+static MESON_GATE(audio,	SYS_CLK_EN0,	11);
+static MESON_GATE(jtag_ctrl,	SYS_CLK_EN0,	12);
+static MESON_GATE(saradc_en,	SYS_CLK_EN0,	13);
+static MESON_GATE(pwm_ef,	SYS_CLK_EN0,	14);
+static MESON_GATE(pwm_cd,	SYS_CLK_EN0,	15);
+static MESON_GATE(pwm_ab,	SYS_CLK_EN0,	16);
+static MESON_GATE(cec,		SYS_CLK_EN0,	17);
+static MESON_GATE(i2c_s,	SYS_CLK_EN0,	18);
+static MESON_GATE(ir_ctrl,	SYS_CLK_EN0,	19);
+static MESON_GATE(i2c_m_d,	SYS_CLK_EN0,	20);
+static MESON_GATE(i2c_m_c,	SYS_CLK_EN0,	21);
+static MESON_GATE(i2c_m_b,	SYS_CLK_EN0,	22);
+static MESON_GATE(i2c_m_a,	SYS_CLK_EN0,	23);
+static MESON_GATE(acodec,	SYS_CLK_EN0,	24);
+static MESON_GATE(otp,		SYS_CLK_EN0,	25);
+static MESON_GATE(sd_emmc_a,	SYS_CLK_EN0,	26);
+static MESON_GATE(usb_phy,	SYS_CLK_EN0,	27);
+static MESON_GATE(usb_ctrl,	SYS_CLK_EN0,	28);
+static MESON_GATE(sys_dspb,	SYS_CLK_EN0,	29);
+static MESON_GATE(sys_dspa,	SYS_CLK_EN0,	30);
+static MESON_GATE(dma,		SYS_CLK_EN0,	31);
+static MESON_GATE(irq_ctrl,	SYS_CLK_EN1,	0);
+static MESON_GATE(nic,		SYS_CLK_EN1,	1);
+static MESON_GATE(gic,		SYS_CLK_EN1,	2);
+static MESON_GATE(uart_c,	SYS_CLK_EN1,	3);
+static MESON_GATE(uart_b,	SYS_CLK_EN1,	4);
+static MESON_GATE(uart_a,	SYS_CLK_EN1,	5);
+static MESON_GATE(sys_psram,	SYS_CLK_EN1,	6);
+static MESON_GATE(rsa,		SYS_CLK_EN1,	8);
+static MESON_GATE(coresight,	SYS_CLK_EN1,	9);
+static MESON_GATE(am2axi_vad,	AXI_CLK_EN,	0);
+static MESON_GATE(audio_vad,	AXI_CLK_EN,	1);
+static MESON_GATE(axi_dmc,	AXI_CLK_EN,	3);
+static MESON_GATE(axi_psram,	AXI_CLK_EN,	4);
+static MESON_GATE(ramb,		AXI_CLK_EN,	5);
+static MESON_GATE(rama,		AXI_CLK_EN,	6);
+static MESON_GATE(axi_spifc,	AXI_CLK_EN,	7);
+static MESON_GATE(axi_nic,	AXI_CLK_EN,	8);
+static MESON_GATE(axi_dma,	AXI_CLK_EN,	9);
+static MESON_GATE(cpu_ctrl,	AXI_CLK_EN,	10);
+static MESON_GATE(rom,		AXI_CLK_EN,	11);
+static MESON_GATE(prod_i2c,	AXI_CLK_EN,	12);
+
+/* Array of all clocks registered by this provider */
+static struct clk_hw_onecell_data a1_periphs_clks = {
+	.hws = {
+		[CLKID_XTAL_IN]			= &xtal_in.hw,
+		[CLKID_FIXPLL_IN]		= &fixpll_in.hw,
+		[CLKID_USB_PHY_IN]		= &usb_phy_in.hw,
+		[CLKID_USB_CTRL_IN]		= &usb_ctrl_in.hw,
+		[CLKID_HIFIPLL_IN]		= &hifipll_in.hw,
+		[CLKID_SYSPLL_IN]		= &syspll_in.hw,
+		[CLKID_DDS_IN]			= &dds_in.hw,
+		[CLKID_SYS]			= &sys.hw,
+		[CLKID_CLKTREE]			= &clktree.hw,
+		[CLKID_RESET_CTRL]		= &reset_ctrl.hw,
+		[CLKID_ANALOG_CTRL]		= &analog_ctrl.hw,
+		[CLKID_PWR_CTRL]		= &pwr_ctrl.hw,
+		[CLKID_PAD_CTRL]		= &pad_ctrl.hw,
+		[CLKID_SYS_CTRL]		= &sys_ctrl.hw,
+		[CLKID_TEMP_SENSOR]		= &temp_sensor.hw,
+		[CLKID_AM2AXI_DIV]		= &am2axi_dev.hw,
+		[CLKID_SPICC_B]			= &spicc_b.hw,
+		[CLKID_SPICC_A]			= &spicc_a.hw,
+		[CLKID_MSR]			= &msr.hw,
+		[CLKID_AUDIO]			= &audio.hw,
+		[CLKID_JTAG_CTRL]		= &jtag_ctrl.hw,
+		[CLKID_SARADC_EN]		= &saradc_en.hw,
+		[CLKID_PWM_EF]			= &pwm_ef.hw,
+		[CLKID_PWM_CD]			= &pwm_cd.hw,
+		[CLKID_PWM_AB]			= &pwm_ab.hw,
+		[CLKID_CEC]			= &cec.hw,
+		[CLKID_I2C_S]			= &i2c_s.hw,
+		[CLKID_IR_CTRL]			= &ir_ctrl.hw,
+		[CLKID_I2C_M_D]			= &i2c_m_d.hw,
+		[CLKID_I2C_M_C]			= &i2c_m_c.hw,
+		[CLKID_I2C_M_B]			= &i2c_m_b.hw,
+		[CLKID_I2C_M_A]			= &i2c_m_a.hw,
+		[CLKID_ACODEC]			= &acodec.hw,
+		[CLKID_OTP]			= &otp.hw,
+		[CLKID_SD_EMMC_A]		= &sd_emmc_a.hw,
+		[CLKID_USB_PHY]			= &usb_phy.hw,
+		[CLKID_USB_CTRL]		= &usb_ctrl.hw,
+		[CLKID_SYS_DSPB]		= &sys_dspb.hw,
+		[CLKID_SYS_DSPA]		= &sys_dspa.hw,
+		[CLKID_DMA]			= &dma.hw,
+		[CLKID_IRQ_CTRL]		= &irq_ctrl.hw,
+		[CLKID_NIC]			= &nic.hw,
+		[CLKID_GIC]			= &gic.hw,
+		[CLKID_UART_C]			= &uart_c.hw,
+		[CLKID_UART_B]			= &uart_b.hw,
+		[CLKID_UART_A]			= &uart_a.hw,
+		[CLKID_SYS_PSRAM]		= &sys_psram.hw,
+		[CLKID_RSA]			= &rsa.hw,
+		[CLKID_CORESIGHT]		= &coresight.hw,
+		[CLKID_AM2AXI_VAD]		= &am2axi_vad.hw,
+		[CLKID_AUDIO_VAD]		= &audio_vad.hw,
+		[CLKID_AXI_DMC]			= &axi_dmc.hw,
+		[CLKID_AXI_PSRAM]		= &axi_psram.hw,
+		[CLKID_RAMB]			= &ramb.hw,
+		[CLKID_RAMA]			= &rama.hw,
+		[CLKID_AXI_SPIFC]		= &axi_spifc.hw,
+		[CLKID_AXI_NIC]			= &axi_nic.hw,
+		[CLKID_AXI_DMA]			= &axi_dma.hw,
+		[CLKID_CPU_CTRL]		= &cpu_ctrl.hw,
+		[CLKID_ROM]			= &rom.hw,
+		[CLKID_PROC_I2C]		= &prod_i2c.hw,
+		[CLKID_DSPA_SEL]		= &dspa_sel.hw,
+		[CLKID_DSPB_SEL]		= &dspb_sel.hw,
+		[CLKID_DSPA_EN]			= &dspa_en.hw,
+		[CLKID_DSPA_EN_NIC]		= &dspa_en_nic.hw,
+		[CLKID_DSPB_EN]			= &dspb_en.hw,
+		[CLKID_DSPB_EN_NIC]		= &dspb_en_nic.hw,
+		[CLKID_RTC]			= &rtc.hw,
+		[CLKID_CECA_32K]		= &ceca_32k_out.hw,
+		[CLKID_CECB_32K]		= &cecb_32k_out.hw,
+		[CLKID_24M]			= &clk_24m.hw,
+		[CLKID_12M]			= &clk_12m.hw,
+		[CLKID_FCLK_DIV2_DIVN]		= &fclk_div2_divn.hw,
+		[CLKID_GEN]			= &gen.hw,
+		[CLKID_SARADC_SEL]		= &saradc_sel.hw,
+		[CLKID_SARADC]			= &saradc.hw,
+		[CLKID_PWM_A]			= &pwm_a.hw,
+		[CLKID_PWM_B]			= &pwm_b.hw,
+		[CLKID_PWM_C]			= &pwm_c.hw,
+		[CLKID_PWM_D]			= &pwm_d.hw,
+		[CLKID_PWM_E]			= &pwm_e.hw,
+		[CLKID_PWM_F]			= &pwm_f.hw,
+		[CLKID_SPICC]			= &spicc.hw,
+		[CLKID_TS]			= &ts.hw,
+		[CLKID_SPIFC]			= &spifc.hw,
+		[CLKID_USB_BUS]			= &usb_bus.hw,
+		[CLKID_SD_EMMC]			= &sd_emmc.hw,
+		[CLKID_PSRAM]			= &psram.hw,
+		[CLKID_DMC]			= &dmc.hw,
+		[CLKID_SYS_A_SEL]		= &sys_a_sel.hw,
+		[CLKID_SYS_A_DIV]		= &sys_a_div.hw,
+		[CLKID_SYS_A]			= &sys_a.hw,
+		[CLKID_SYS_B_SEL]		= &sys_b_sel.hw,
+		[CLKID_SYS_B_DIV]		= &sys_b_div.hw,
+		[CLKID_SYS_B]			= &sys_b.hw,
+		[CLKID_DSPA_A_SEL]		= &dspa_a_sel.hw,
+		[CLKID_DSPA_A_DIV]		= &dspa_a_div.hw,
+		[CLKID_DSPA_A]			= &dspa_a.hw,
+		[CLKID_DSPA_B_SEL]		= &dspa_b_sel.hw,
+		[CLKID_DSPA_B_DIV]		= &dspa_b_div.hw,
+		[CLKID_DSPA_B]			= &dspa_b.hw,
+		[CLKID_DSPB_A_SEL]		= &dspb_a_sel.hw,
+		[CLKID_DSPB_A_DIV]		= &dspb_a_div.hw,
+		[CLKID_DSPB_A]			= &dspb_a.hw,
+		[CLKID_DSPB_B_SEL]		= &dspb_b_sel.hw,
+		[CLKID_DSPB_B_DIV]		= &dspb_b_div.hw,
+		[CLKID_DSPB_B]			= &dspb_b.hw,
+		[CLKID_RTC_32K_IN]		= &rtc_32k_in.hw,
+		[CLKID_RTC_32K_DIV]		= &rtc_32k_div.hw,
+		[CLKID_RTC_32K_XTAL]		= &rtc_32k_xtal.hw,
+		[CLKID_RTC_32K_SEL]		= &rtc_32k_sel.hw,
+		[CLKID_CECB_32K_IN]		= &cecb_32k_in.hw,
+		[CLKID_CECB_32K_DIV]		= &cecb_32k_div.hw,
+		[CLKID_CECB_32K_SEL_PRE]	= &cecb_32k_sel_pre.hw,
+		[CLKID_CECB_32K_SEL]		= &cecb_32k_sel.hw,
+		[CLKID_CECA_32K_IN]		= &ceca_32k_in.hw,
+		[CLKID_CECA_32K_DIV]		= &ceca_32k_div.hw,
+		[CLKID_CECA_32K_SEL_PRE]	= &ceca_32k_sel_pre.hw,
+		[CLKID_CECA_32K_SEL]		= &ceca_32k_sel.hw,
+		[CLKID_DIV2_PRE]		= &fclk_div2_divn_pre.hw,
+		[CLKID_24M_DIV2]		= &clk_24m_div2.hw,
+		[CLKID_GEN_SEL]			= &gen_sel.hw,
+		[CLKID_GEN_DIV]			= &gen_div.hw,
+		[CLKID_SARADC_DIV]		= &saradc_div.hw,
+		[CLKID_PWM_A_SEL]		= &pwm_a_sel.hw,
+		[CLKID_PWM_A_DIV]		= &pwm_a_div.hw,
+		[CLKID_PWM_B_SEL]		= &pwm_b_sel.hw,
+		[CLKID_PWM_B_DIV]		= &pwm_b_div.hw,
+		[CLKID_PWM_C_SEL]		= &pwm_c_sel.hw,
+		[CLKID_PWM_C_DIV]		= &pwm_c_div.hw,
+		[CLKID_PWM_D_SEL]		= &pwm_d_sel.hw,
+		[CLKID_PWM_D_DIV]		= &pwm_d_div.hw,
+		[CLKID_PWM_E_SEL]		= &pwm_e_sel.hw,
+		[CLKID_PWM_E_DIV]		= &pwm_e_div.hw,
+		[CLKID_PWM_F_SEL]		= &pwm_f_sel.hw,
+		[CLKID_PWM_F_DIV]		= &pwm_f_div.hw,
+		[CLKID_SPICC_SEL]		= &spicc_sel.hw,
+		[CLKID_SPICC_DIV]		= &spicc_div.hw,
+		[CLKID_SPICC_SEL2]		= &spicc_sel2.hw,
+		[CLKID_TS_DIV]			= &ts_div.hw,
+		[CLKID_SPIFC_SEL]		= &spifc_sel.hw,
+		[CLKID_SPIFC_DIV]		= &spifc_div.hw,
+		[CLKID_SPIFC_SEL2]		= &spifc_sel2.hw,
+		[CLKID_USB_BUS_SEL]		= &usb_bus_sel.hw,
+		[CLKID_USB_BUS_DIV]		= &usb_bus_div.hw,
+		[CLKID_SD_EMMC_SEL]		= &sd_emmc_sel.hw,
+		[CLKID_SD_EMMC_DIV]		= &sd_emmc_div.hw,
+		[CLKID_SD_EMMC_SEL2]		= &sd_emmc_sel2.hw,
+		[CLKID_PSRAM_SEL]		= &psram_sel.hw,
+		[CLKID_PSRAM_DIV]		= &psram_div.hw,
+		[CLKID_PSRAM_SEL2]		= &psram_sel2.hw,
+		[CLKID_DMC_SEL]			= &dmc_sel.hw,
+		[CLKID_DMC_DIV]			= &dmc_div.hw,
+		[CLKID_DMC_SEL2]		= &dmc_sel2.hw,
+		[NR_CLKS]			= NULL,
+	},
+	.num = NR_CLKS,
+};
+
+/* Convenience table to populate regmap in .probe */
+static struct clk_regmap *const a1_periphs_regmaps[] = {
+	&xtal_in,
+	&fixpll_in,
+	&usb_phy_in,
+	&usb_ctrl_in,
+	&hifipll_in,
+	&syspll_in,
+	&dds_in,
+	&sys,
+	&clktree,
+	&reset_ctrl,
+	&analog_ctrl,
+	&pwr_ctrl,
+	&pad_ctrl,
+	&sys_ctrl,
+	&temp_sensor,
+	&am2axi_dev,
+	&spicc_b,
+	&spicc_a,
+	&msr,
+	&audio,
+	&jtag_ctrl,
+	&saradc_en,
+	&pwm_ef,
+	&pwm_cd,
+	&pwm_ab,
+	&cec,
+	&i2c_s,
+	&ir_ctrl,
+	&i2c_m_d,
+	&i2c_m_c,
+	&i2c_m_b,
+	&i2c_m_a,
+	&acodec,
+	&otp,
+	&sd_emmc_a,
+	&usb_phy,
+	&usb_ctrl,
+	&sys_dspb,
+	&sys_dspa,
+	&dma,
+	&irq_ctrl,
+	&nic,
+	&gic,
+	&uart_c,
+	&uart_b,
+	&uart_a,
+	&sys_psram,
+	&rsa,
+	&coresight,
+	&am2axi_vad,
+	&audio_vad,
+	&axi_dmc,
+	&axi_psram,
+	&ramb,
+	&rama,
+	&axi_spifc,
+	&axi_nic,
+	&axi_dma,
+	&cpu_ctrl,
+	&rom,
+	&prod_i2c,
+	&dspa_sel,
+	&dspb_sel,
+	&dspa_en,
+	&dspa_en_nic,
+	&dspb_en,
+	&dspb_en_nic,
+	&rtc,
+	&ceca_32k_out,
+	&cecb_32k_out,
+	&clk_24m,
+	&clk_12m,
+	&fclk_div2_divn,
+	&gen,
+	&saradc_sel,
+	&saradc,
+	&pwm_a,
+	&pwm_b,
+	&pwm_c,
+	&pwm_d,
+	&pwm_e,
+	&pwm_f,
+	&spicc,
+	&ts,
+	&spifc,
+	&usb_bus,
+	&sd_emmc,
+	&psram,
+	&dmc,
+	&sys_a_sel,
+	&sys_a_div,
+	&sys_a,
+	&sys_b_sel,
+	&sys_b_div,
+	&sys_b,
+	&dspa_a_sel,
+	&dspa_a_div,
+	&dspa_a,
+	&dspa_b_sel,
+	&dspa_b_div,
+	&dspa_b,
+	&dspb_a_sel,
+	&dspb_a_div,
+	&dspb_a,
+	&dspb_b_sel,
+	&dspb_b_div,
+	&dspb_b,
+	&rtc_32k_in,
+	&rtc_32k_div,
+	&rtc_32k_xtal,
+	&rtc_32k_sel,
+	&cecb_32k_in,
+	&cecb_32k_div,
+	&cecb_32k_sel_pre,
+	&cecb_32k_sel,
+	&ceca_32k_in,
+	&ceca_32k_div,
+	&ceca_32k_sel_pre,
+	&ceca_32k_sel,
+	&fclk_div2_divn_pre,
+	&gen_sel,
+	&gen_div,
+	&saradc_div,
+	&pwm_a_sel,
+	&pwm_a_div,
+	&pwm_b_sel,
+	&pwm_b_div,
+	&pwm_c_sel,
+	&pwm_c_div,
+	&pwm_d_sel,
+	&pwm_d_div,
+	&pwm_e_sel,
+	&pwm_e_div,
+	&pwm_f_sel,
+	&pwm_f_div,
+	&spicc_sel,
+	&spicc_div,
+	&spicc_sel2,
+	&ts_div,
+	&spifc_sel,
+	&spifc_div,
+	&spifc_sel2,
+	&usb_bus_sel,
+	&usb_bus_div,
+	&sd_emmc_sel,
+	&sd_emmc_div,
+	&sd_emmc_sel2,
+	&psram_sel,
+	&psram_div,
+	&psram_sel2,
+	&dmc_sel,
+	&dmc_div,
+	&dmc_sel2,
+};
+
+static struct regmap_config a1_periphs_regmap_cfg = {
+	.reg_bits   = 32,
+	.val_bits   = 32,
+	.reg_stride = 4,
+};
+
+static int meson_a1_periphs_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *base;
+	struct regmap *map;
+	int clkid, i, err;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base),
+				     "can't ioremap resource\n");
+
+	map = devm_regmap_init_mmio(dev, base, &a1_periphs_regmap_cfg);
+	if (IS_ERR(map))
+		return dev_err_probe(dev, PTR_ERR(map),
+				     "can't init regmap mmio region\n");
+
+	/* Populate regmap for the regmap backed clocks */
+	for (i = 0; i < ARRAY_SIZE(a1_periphs_regmaps); i++)
+		a1_periphs_regmaps[i]->map = map;
+
+	for (clkid = 0; clkid < a1_periphs_clks.num; clkid++) {
+		err = devm_clk_hw_register(dev, a1_periphs_clks.hws[clkid]);
+		if (err)
+			return dev_err_probe(dev, err,
+					     "clock[%d] registration failed\n",
+					     clkid);
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &a1_periphs_clks);
+}
+
+static const struct of_device_id a1_periphs_clkc_match_table[] = {
+	{ .compatible = "amlogic,a1-peripherals-clkc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, a1_periphs_clkc_match_table);
+
+static struct platform_driver a1_periphs_clkc_driver = {
+	.probe = meson_a1_periphs_probe,
+	.driver = {
+		.name = "a1-peripherals-clkc",
+		.of_match_table = a1_periphs_clkc_match_table,
+	},
+};
+
+module_platform_driver(a1_periphs_clkc_driver);
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/a1-peripherals.h b/drivers/clk/meson/a1-peripherals.h
new file mode 100644
index 000000000000..526fc9ba5c9f
--- /dev/null
+++ b/drivers/clk/meson/a1-peripherals.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Amlogic A1 Peripherals Clock Controller internals
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <jian.hu@amlogic.com>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru>
+ */
+
+#ifndef __A1_PERIPHERALS_H
+#define __A1_PERIPHERALS_H
+
+/* peripherals clock controller register offset */
+#define SYS_OSCIN_CTRL		0x0
+#define RTC_BY_OSCIN_CTRL0	0x4
+#define RTC_BY_OSCIN_CTRL1	0x8
+#define RTC_CTRL		0xc
+#define SYS_CLK_CTRL0		0x10
+#define SYS_CLK_EN0		0x1c
+#define SYS_CLK_EN1		0x20
+#define AXI_CLK_EN		0x24
+#define DSPA_CLK_EN		0x28
+#define DSPB_CLK_EN		0x2c
+#define DSPA_CLK_CTRL0		0x30
+#define DSPB_CLK_CTRL0		0x34
+#define CLK12_24_CTRL		0x38
+#define GEN_CLK_CTRL		0x3c
+#define SAR_ADC_CLK_CTRL	0xc0
+#define PWM_CLK_AB_CTRL		0xc4
+#define PWM_CLK_CD_CTRL		0xc8
+#define PWM_CLK_EF_CTRL		0xcc
+#define SPICC_CLK_CTRL		0xd0
+#define TS_CLK_CTRL		0xd4
+#define SPIFC_CLK_CTRL		0xd8
+#define USB_BUSCLK_CTRL		0xdc
+#define SD_EMMC_CLK_CTRL	0xe0
+#define CECA_CLK_CTRL0		0xe4
+#define CECA_CLK_CTRL1		0xe8
+#define CECB_CLK_CTRL0		0xec
+#define CECB_CLK_CTRL1		0xf0
+#define PSRAM_CLK_CTRL		0xf4
+#define DMC_CLK_CTRL		0xf8
+
+/* include the CLKIDs that have been made part of the DT binding */
+#include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
+
+/*
+ * CLKID index values for internal clocks
+ *
+ * These indices are entirely contrived and do not map onto the hardware.
+ * It has now been decided to expose everything by default in the DT header:
+ * include/dt-bindings/clock/a1-peripherals-clkc.h.
+ * Only the clocks ids we don't want to expose, such as the internal muxes and
+ * dividers of composite clocks, will remain defined here.
+ */
+#define CLKID_XTAL_IN		0
+#define CLKID_DSPA_SEL		61
+#define CLKID_DSPB_SEL		62
+#define CLKID_SARADC_SEL	74
+#define CLKID_SYS_A_SEL		89
+#define CLKID_SYS_A_DIV		90
+#define CLKID_SYS_A		91
+#define CLKID_SYS_B_SEL		92
+#define CLKID_SYS_B_DIV		93
+#define CLKID_SYS_B		94
+#define CLKID_DSPA_A_DIV	96
+#define CLKID_DSPA_A		97
+#define CLKID_DSPA_B_DIV	99
+#define CLKID_DSPA_B		100
+#define CLKID_DSPB_A_DIV	102
+#define CLKID_DSPB_A		103
+#define CLKID_DSPB_B_DIV	105
+#define CLKID_DSPB_B		106
+#define CLKID_RTC_32K_IN	107
+#define CLKID_RTC_32K_DIV	108
+#define CLKID_RTC_32K_XTAL	109
+#define CLKID_RTC_32K_SEL	110
+#define CLKID_CECB_32K_IN	111
+#define CLKID_CECB_32K_DIV	112
+#define CLKID_CECA_32K_IN	115
+#define CLKID_CECA_32K_DIV	116
+#define CLKID_DIV2_PRE		119
+#define CLKID_24M_DIV2		120
+#define CLKID_GEN_DIV		122
+#define CLKID_SARADC_DIV	123
+#define CLKID_PWM_A_DIV		125
+#define CLKID_PWM_B_DIV		127
+#define CLKID_PWM_C_DIV		129
+#define CLKID_PWM_D_DIV		131
+#define CLKID_PWM_E_DIV		133
+#define CLKID_PWM_F_DIV		135
+#define CLKID_SPICC_SEL		136
+#define CLKID_SPICC_DIV		137
+#define CLKID_SPICC_SEL2	138
+#define CLKID_TS_DIV		139
+#define CLKID_SPIFC_SEL		140
+#define CLKID_SPIFC_DIV		141
+#define CLKID_SPIFC_SEL2	142
+#define CLKID_USB_BUS_SEL	143
+#define CLKID_USB_BUS_DIV	144
+#define CLKID_SD_EMMC_SEL	145
+#define CLKID_SD_EMMC_DIV	146
+#define CLKID_PSRAM_SEL		148
+#define CLKID_PSRAM_DIV		149
+#define CLKID_PSRAM_SEL2	150
+#define CLKID_DMC_SEL		151
+#define CLKID_DMC_DIV		152
+#define CLKID_DMC_SEL2		153
+#define NR_CLKS			154
+
+#endif /* __A1_PERIPHERALS_H */
-- 
2.36.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
  2023-05-17 13:33   ` Dmitry Rokosov
  (?)
@ 2023-05-19 21:03     ` Martin Blumenstingl
  -1 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-19 21:03 UTC (permalink / raw)
  To: Dmitry Rokosov
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hi Dmitry,

On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> +static struct clk_regmap sys_b_sel = {
> +       .data = &(struct clk_regmap_mux_data){
> +               .offset = SYS_CLK_CTRL0,
> +               .mask = 0x7,
> +               .shift = 26,
> +               .table = mux_table_sys,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "sys_b_sel",
> +               .ops = &clk_regmap_mux_ro_ops,
the sys_*_sel muxes and sys_*_gate are _ro...

> +               .parent_data = sys_parents,
> +               .num_parents = ARRAY_SIZE(sys_parents),
> +       },
> +};
> +
> +static struct clk_regmap sys_b_div = {
> +       .data = &(struct clk_regmap_div_data){
> +               .offset = SYS_CLK_CTRL0,
> +               .shift = 16,
> +               .width = 10,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "sys_b_div",
> +               .ops = &clk_regmap_divider_ops,
...but the sys_*_div aren't
Is this on purpose? If it is: why can the divider be changed at
runtime but the mux can't?

[...]
> +/*
> + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
We need to add the "sys_pll_div16" input to the dt-bindings since they
should always describe the hardware (regardless of what the driver
implements currently).
I'm not sure how to manage this while we don't have the CPU clock
driver ready yet but I'm sure Rob or Krzysztof will be able to help us
here.

> + * the index 4 is the clock measurement source, it's not supported yet
I suspect that this comes from the clock measurer IP block and if so
the dt-bindings should probably describe this input. But again, we'd
need to keep it optional for now since our clock measurer driver
doesn't even implement a clock controller.

[...]
> +static struct clk_regmap pwm_a_sel = {
> +       .data = &(struct clk_regmap_mux_data){
> +               .offset = PWM_CLK_AB_CTRL,
> +               .mask = 0x1,
> +               .shift = 9,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "pwm_a_sel",
> +               .ops = &clk_regmap_mux_ops,
> +               .parent_data = pwm_abcd_parents,
> +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> +               /* For more information, please refer to rtc clock */
> +               .flags = CLK_SET_RATE_NO_REPARENT,
As mentioned in [0] we'll work with Heiner to see if we can improve
the decision making process of the PWM controller driver so that we
can just have .flags = 0 here.
This applies to all other occurrences of the same comment about the rtc clock.


Best regards,
Martin

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-19 21:03     ` Martin Blumenstingl
  0 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-19 21:03 UTC (permalink / raw)
  To: Dmitry Rokosov
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hi Dmitry,

On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> +static struct clk_regmap sys_b_sel = {
> +       .data = &(struct clk_regmap_mux_data){
> +               .offset = SYS_CLK_CTRL0,
> +               .mask = 0x7,
> +               .shift = 26,
> +               .table = mux_table_sys,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "sys_b_sel",
> +               .ops = &clk_regmap_mux_ro_ops,
the sys_*_sel muxes and sys_*_gate are _ro...

> +               .parent_data = sys_parents,
> +               .num_parents = ARRAY_SIZE(sys_parents),
> +       },
> +};
> +
> +static struct clk_regmap sys_b_div = {
> +       .data = &(struct clk_regmap_div_data){
> +               .offset = SYS_CLK_CTRL0,
> +               .shift = 16,
> +               .width = 10,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "sys_b_div",
> +               .ops = &clk_regmap_divider_ops,
...but the sys_*_div aren't
Is this on purpose? If it is: why can the divider be changed at
runtime but the mux can't?

[...]
> +/*
> + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
We need to add the "sys_pll_div16" input to the dt-bindings since they
should always describe the hardware (regardless of what the driver
implements currently).
I'm not sure how to manage this while we don't have the CPU clock
driver ready yet but I'm sure Rob or Krzysztof will be able to help us
here.

> + * the index 4 is the clock measurement source, it's not supported yet
I suspect that this comes from the clock measurer IP block and if so
the dt-bindings should probably describe this input. But again, we'd
need to keep it optional for now since our clock measurer driver
doesn't even implement a clock controller.

[...]
> +static struct clk_regmap pwm_a_sel = {
> +       .data = &(struct clk_regmap_mux_data){
> +               .offset = PWM_CLK_AB_CTRL,
> +               .mask = 0x1,
> +               .shift = 9,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "pwm_a_sel",
> +               .ops = &clk_regmap_mux_ops,
> +               .parent_data = pwm_abcd_parents,
> +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> +               /* For more information, please refer to rtc clock */
> +               .flags = CLK_SET_RATE_NO_REPARENT,
As mentioned in [0] we'll work with Heiner to see if we can improve
the decision making process of the PWM controller driver so that we
can just have .flags = 0 here.
This applies to all other occurrences of the same comment about the rtc clock.


Best regards,
Martin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-19 21:03     ` Martin Blumenstingl
  0 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-19 21:03 UTC (permalink / raw)
  To: Dmitry Rokosov
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hi Dmitry,

On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> +static struct clk_regmap sys_b_sel = {
> +       .data = &(struct clk_regmap_mux_data){
> +               .offset = SYS_CLK_CTRL0,
> +               .mask = 0x7,
> +               .shift = 26,
> +               .table = mux_table_sys,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "sys_b_sel",
> +               .ops = &clk_regmap_mux_ro_ops,
the sys_*_sel muxes and sys_*_gate are _ro...

> +               .parent_data = sys_parents,
> +               .num_parents = ARRAY_SIZE(sys_parents),
> +       },
> +};
> +
> +static struct clk_regmap sys_b_div = {
> +       .data = &(struct clk_regmap_div_data){
> +               .offset = SYS_CLK_CTRL0,
> +               .shift = 16,
> +               .width = 10,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "sys_b_div",
> +               .ops = &clk_regmap_divider_ops,
...but the sys_*_div aren't
Is this on purpose? If it is: why can the divider be changed at
runtime but the mux can't?

[...]
> +/*
> + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
We need to add the "sys_pll_div16" input to the dt-bindings since they
should always describe the hardware (regardless of what the driver
implements currently).
I'm not sure how to manage this while we don't have the CPU clock
driver ready yet but I'm sure Rob or Krzysztof will be able to help us
here.

> + * the index 4 is the clock measurement source, it's not supported yet
I suspect that this comes from the clock measurer IP block and if so
the dt-bindings should probably describe this input. But again, we'd
need to keep it optional for now since our clock measurer driver
doesn't even implement a clock controller.

[...]
> +static struct clk_regmap pwm_a_sel = {
> +       .data = &(struct clk_regmap_mux_data){
> +               .offset = PWM_CLK_AB_CTRL,
> +               .mask = 0x1,
> +               .shift = 9,
> +       },
> +       .hw.init = &(struct clk_init_data){
> +               .name = "pwm_a_sel",
> +               .ops = &clk_regmap_mux_ops,
> +               .parent_data = pwm_abcd_parents,
> +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> +               /* For more information, please refer to rtc clock */
> +               .flags = CLK_SET_RATE_NO_REPARENT,
As mentioned in [0] we'll work with Heiner to see if we can improve
the decision making process of the PWM controller driver so that we
can just have .flags = 0 here.
This applies to all other occurrences of the same comment about the rtc clock.


Best regards,
Martin

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
  2023-05-17 13:33   ` Dmitry Rokosov
  (?)
@ 2023-05-19 21:09     ` Martin Blumenstingl
  -1 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-19 21:09 UTC (permalink / raw)
  To: Dmitry Rokosov, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Hi Krzysztof and Dmitry,

On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> +  clocks:
> +    items:
> +      - description: input fixed pll div2
> +      - description: input fixed pll div3
> +      - description: input fixed pll div5
> +      - description: input fixed pll div7
> +      - description: input hifi pll
> +      - description: input oscillator (usually at 24MHz)
> +
> +  clock-names:
> +    items:
> +      - const: fclk_div2
> +      - const: fclk_div3
> +      - const: fclk_div5
> +      - const: fclk_div7
> +      - const: hifi_pll
> +      - const: xtal
This IP block has at least one additional input called "sys_pll_div16".
My understanding is that the "sys_pll_div16" clock is generated by the
CPU clock controller. Support for the CPU clock controller
(dt-bindings and a driver) will be added at a later time by Dmitry.
How can we manage incrementally implementing the clock controllers?
From a hardware perspective the "sys_pll_div16" input is mandatory.
How to manage this in the .dts patches then (for example: does this
mean that Dmitry can only add the clock controller to the .dts when
all clock controller bindings have been implemented - or is there
another way)?


Best regards,
Martin

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-19 21:09     ` Martin Blumenstingl
  0 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-19 21:09 UTC (permalink / raw)
  To: Dmitry Rokosov, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Hi Krzysztof and Dmitry,

On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> +  clocks:
> +    items:
> +      - description: input fixed pll div2
> +      - description: input fixed pll div3
> +      - description: input fixed pll div5
> +      - description: input fixed pll div7
> +      - description: input hifi pll
> +      - description: input oscillator (usually at 24MHz)
> +
> +  clock-names:
> +    items:
> +      - const: fclk_div2
> +      - const: fclk_div3
> +      - const: fclk_div5
> +      - const: fclk_div7
> +      - const: hifi_pll
> +      - const: xtal
This IP block has at least one additional input called "sys_pll_div16".
My understanding is that the "sys_pll_div16" clock is generated by the
CPU clock controller. Support for the CPU clock controller
(dt-bindings and a driver) will be added at a later time by Dmitry.
How can we manage incrementally implementing the clock controllers?
From a hardware perspective the "sys_pll_div16" input is mandatory.
How to manage this in the .dts patches then (for example: does this
mean that Dmitry can only add the clock controller to the .dts when
all clock controller bindings have been implemented - or is there
another way)?


Best regards,
Martin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-19 21:09     ` Martin Blumenstingl
  0 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-19 21:09 UTC (permalink / raw)
  To: Dmitry Rokosov, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Hi Krzysztof and Dmitry,

On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> +  clocks:
> +    items:
> +      - description: input fixed pll div2
> +      - description: input fixed pll div3
> +      - description: input fixed pll div5
> +      - description: input fixed pll div7
> +      - description: input hifi pll
> +      - description: input oscillator (usually at 24MHz)
> +
> +  clock-names:
> +    items:
> +      - const: fclk_div2
> +      - const: fclk_div3
> +      - const: fclk_div5
> +      - const: fclk_div7
> +      - const: hifi_pll
> +      - const: xtal
This IP block has at least one additional input called "sys_pll_div16".
My understanding is that the "sys_pll_div16" clock is generated by the
CPU clock controller. Support for the CPU clock controller
(dt-bindings and a driver) will be added at a later time by Dmitry.
How can we manage incrementally implementing the clock controllers?
From a hardware perspective the "sys_pll_div16" input is mandatory.
How to manage this in the .dts patches then (for example: does this
mean that Dmitry can only add the clock controller to the .dts when
all clock controller bindings have been implemented - or is there
another way)?


Best regards,
Martin

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
  2023-05-19 21:09     ` Martin Blumenstingl
  (?)
@ 2023-05-22 13:00       ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-22 13:00 UTC (permalink / raw)
  To: Martin Blumenstingl, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Martin,

On Fri, May 19, 2023 at 11:09:29PM +0200, Martin Blumenstingl wrote:
> Hi Krzysztof and Dmitry,
> 
> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > +  clocks:
> > +    items:
> > +      - description: input fixed pll div2
> > +      - description: input fixed pll div3
> > +      - description: input fixed pll div5
> > +      - description: input fixed pll div7
> > +      - description: input hifi pll
> > +      - description: input oscillator (usually at 24MHz)
> > +
> > +  clock-names:
> > +    items:
> > +      - const: fclk_div2
> > +      - const: fclk_div3
> > +      - const: fclk_div5
> > +      - const: fclk_div7
> > +      - const: hifi_pll
> > +      - const: xtal
> This IP block has at least one additional input called "sys_pll_div16".
> My understanding is that the "sys_pll_div16" clock is generated by the
> CPU clock controller. Support for the CPU clock controller
> (dt-bindings and a driver) will be added at a later time by Dmitry.
> How can we manage incrementally implementing the clock controllers?
> From a hardware perspective the "sys_pll_div16" input is mandatory.
> How to manage this in the .dts patches then (for example: does this
> mean that Dmitry can only add the clock controller to the .dts when
> all clock controller bindings have been implemented - or is there
> another way)?

You're absolutely right: currently, not all inputs are supported because
the CPU clock controller isn't ready yet – I'm working on it at the
moment.

I understand your concerns about bindings and schema description, but
there is an issue to be considered. I'm developing the entire clock
controller A1 subsystem incrementally in three stages: peripherals and
PLL, CPU, and Audio. This is because the CPU can operate at a static
frequency and voltage, and the board boots normally without the CPU
clock controller, thermal sensor, and OPP table. Audio is also
important, but it's optional. On the other hand, without setting up the
peripherals and PLL controllers, the board won't function because
they're fundamental.

Right now, we're in the first stage of the plan. Unfortunately, I can't
disclose the exact names and number of clock bindings for the CPU and
Audio, as they're still in development and only exist in my head or
draft versions.

If possible, I'd prefer to provide the new bindings and connections once
all the appropriate drivers are finalized.

-- 
Thank you,
Dmitry

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-22 13:00       ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-22 13:00 UTC (permalink / raw)
  To: Martin Blumenstingl, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Martin,

On Fri, May 19, 2023 at 11:09:29PM +0200, Martin Blumenstingl wrote:
> Hi Krzysztof and Dmitry,
> 
> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > +  clocks:
> > +    items:
> > +      - description: input fixed pll div2
> > +      - description: input fixed pll div3
> > +      - description: input fixed pll div5
> > +      - description: input fixed pll div7
> > +      - description: input hifi pll
> > +      - description: input oscillator (usually at 24MHz)
> > +
> > +  clock-names:
> > +    items:
> > +      - const: fclk_div2
> > +      - const: fclk_div3
> > +      - const: fclk_div5
> > +      - const: fclk_div7
> > +      - const: hifi_pll
> > +      - const: xtal
> This IP block has at least one additional input called "sys_pll_div16".
> My understanding is that the "sys_pll_div16" clock is generated by the
> CPU clock controller. Support for the CPU clock controller
> (dt-bindings and a driver) will be added at a later time by Dmitry.
> How can we manage incrementally implementing the clock controllers?
> From a hardware perspective the "sys_pll_div16" input is mandatory.
> How to manage this in the .dts patches then (for example: does this
> mean that Dmitry can only add the clock controller to the .dts when
> all clock controller bindings have been implemented - or is there
> another way)?

You're absolutely right: currently, not all inputs are supported because
the CPU clock controller isn't ready yet – I'm working on it at the
moment.

I understand your concerns about bindings and schema description, but
there is an issue to be considered. I'm developing the entire clock
controller A1 subsystem incrementally in three stages: peripherals and
PLL, CPU, and Audio. This is because the CPU can operate at a static
frequency and voltage, and the board boots normally without the CPU
clock controller, thermal sensor, and OPP table. Audio is also
important, but it's optional. On the other hand, without setting up the
peripherals and PLL controllers, the board won't function because
they're fundamental.

Right now, we're in the first stage of the plan. Unfortunately, I can't
disclose the exact names and number of clock bindings for the CPU and
Audio, as they're still in development and only exist in my head or
draft versions.

If possible, I'd prefer to provide the new bindings and connections once
all the appropriate drivers are finalized.

-- 
Thank you,
Dmitry

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-22 13:00       ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-22 13:00 UTC (permalink / raw)
  To: Martin Blumenstingl, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Martin,

On Fri, May 19, 2023 at 11:09:29PM +0200, Martin Blumenstingl wrote:
> Hi Krzysztof and Dmitry,
> 
> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > +  clocks:
> > +    items:
> > +      - description: input fixed pll div2
> > +      - description: input fixed pll div3
> > +      - description: input fixed pll div5
> > +      - description: input fixed pll div7
> > +      - description: input hifi pll
> > +      - description: input oscillator (usually at 24MHz)
> > +
> > +  clock-names:
> > +    items:
> > +      - const: fclk_div2
> > +      - const: fclk_div3
> > +      - const: fclk_div5
> > +      - const: fclk_div7
> > +      - const: hifi_pll
> > +      - const: xtal
> This IP block has at least one additional input called "sys_pll_div16".
> My understanding is that the "sys_pll_div16" clock is generated by the
> CPU clock controller. Support for the CPU clock controller
> (dt-bindings and a driver) will be added at a later time by Dmitry.
> How can we manage incrementally implementing the clock controllers?
> From a hardware perspective the "sys_pll_div16" input is mandatory.
> How to manage this in the .dts patches then (for example: does this
> mean that Dmitry can only add the clock controller to the .dts when
> all clock controller bindings have been implemented - or is there
> another way)?

You're absolutely right: currently, not all inputs are supported because
the CPU clock controller isn't ready yet – I'm working on it at the
moment.

I understand your concerns about bindings and schema description, but
there is an issue to be considered. I'm developing the entire clock
controller A1 subsystem incrementally in three stages: peripherals and
PLL, CPU, and Audio. This is because the CPU can operate at a static
frequency and voltage, and the board boots normally without the CPU
clock controller, thermal sensor, and OPP table. Audio is also
important, but it's optional. On the other hand, without setting up the
peripherals and PLL controllers, the board won't function because
they're fundamental.

Right now, we're in the first stage of the plan. Unfortunately, I can't
disclose the exact names and number of clock bindings for the CPU and
Audio, as they're still in development and only exist in my head or
draft versions.

If possible, I'd prefer to provide the new bindings and connections once
all the appropriate drivers are finalized.

-- 
Thank you,
Dmitry

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
  2023-05-19 21:03     ` Martin Blumenstingl
  (?)
@ 2023-05-22 13:32       ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-22 13:32 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hello Martin,

Thank you so much for the review, I really appreciate it!
Please find my comments below.

On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
> Hi Dmitry,
> 
> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > +static struct clk_regmap sys_b_sel = {
> > +       .data = &(struct clk_regmap_mux_data){
> > +               .offset = SYS_CLK_CTRL0,
> > +               .mask = 0x7,
> > +               .shift = 26,
> > +               .table = mux_table_sys,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "sys_b_sel",
> > +               .ops = &clk_regmap_mux_ro_ops,
> the sys_*_sel muxes and sys_*_gate are _ro...
> 
> > +               .parent_data = sys_parents,
> > +               .num_parents = ARRAY_SIZE(sys_parents),
> > +       },
> > +};
> > +
> > +static struct clk_regmap sys_b_div = {
> > +       .data = &(struct clk_regmap_div_data){
> > +               .offset = SYS_CLK_CTRL0,
> > +               .shift = 16,
> > +               .width = 10,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "sys_b_div",
> > +               .ops = &clk_regmap_divider_ops,
> ...but the sys_*_div aren't
> Is this on purpose? If it is: why can the divider be changed at
> runtime but the mux can't?
> 

Ah, that's a good catch. Since the system clock is set up by the BootROM
code, all sys_* dividers and gates should be read-only. I'll make sure
to change that in the next version.

> [...]
> > +/*
> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
> We need to add the "sys_pll_div16" input to the dt-bindings since they
> should always describe the hardware (regardless of what the driver
> implements currently).
> I'm not sure how to manage this while we don't have the CPU clock
> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
> here.
> 

I've shared my thoughts about it in the bindings thread. Please take a
look.

> > + * the index 4 is the clock measurement source, it's not supported yet
> I suspect that this comes from the clock measurer IP block and if so
> the dt-bindings should probably describe this input. But again, we'd
> need to keep it optional for now since our clock measurer driver
> doesn't even implement a clock controller.
> 

Indeed, this is a similar situation to what we have with the inputs and
clocks of the CPU and Audio clock controllers. It seems like there is
only one option here: we should mark it with a TODO tag...

> [...]
> > +static struct clk_regmap pwm_a_sel = {
> > +       .data = &(struct clk_regmap_mux_data){
> > +               .offset = PWM_CLK_AB_CTRL,
> > +               .mask = 0x1,
> > +               .shift = 9,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "pwm_a_sel",
> > +               .ops = &clk_regmap_mux_ops,
> > +               .parent_data = pwm_abcd_parents,
> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> > +               /* For more information, please refer to rtc clock */
> > +               .flags = CLK_SET_RATE_NO_REPARENT,
> As mentioned in [0] we'll work with Heiner to see if we can improve
> the decision making process of the PWM controller driver so that we
> can just have .flags = 0 here.
> This applies to all other occurrences of the same comment about the rtc clock.

Sure, I'll make the change in v16. In my opinion, we should remove the
CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
including PWM, regardless of the outcome of the Heiner discussion. Based
on our IRC talk, the decision has more pros than cons -
https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18

-- 
Thank you,
Dmitry

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-22 13:32       ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-22 13:32 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hello Martin,

Thank you so much for the review, I really appreciate it!
Please find my comments below.

On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
> Hi Dmitry,
> 
> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > +static struct clk_regmap sys_b_sel = {
> > +       .data = &(struct clk_regmap_mux_data){
> > +               .offset = SYS_CLK_CTRL0,
> > +               .mask = 0x7,
> > +               .shift = 26,
> > +               .table = mux_table_sys,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "sys_b_sel",
> > +               .ops = &clk_regmap_mux_ro_ops,
> the sys_*_sel muxes and sys_*_gate are _ro...
> 
> > +               .parent_data = sys_parents,
> > +               .num_parents = ARRAY_SIZE(sys_parents),
> > +       },
> > +};
> > +
> > +static struct clk_regmap sys_b_div = {
> > +       .data = &(struct clk_regmap_div_data){
> > +               .offset = SYS_CLK_CTRL0,
> > +               .shift = 16,
> > +               .width = 10,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "sys_b_div",
> > +               .ops = &clk_regmap_divider_ops,
> ...but the sys_*_div aren't
> Is this on purpose? If it is: why can the divider be changed at
> runtime but the mux can't?
> 

Ah, that's a good catch. Since the system clock is set up by the BootROM
code, all sys_* dividers and gates should be read-only. I'll make sure
to change that in the next version.

> [...]
> > +/*
> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
> We need to add the "sys_pll_div16" input to the dt-bindings since they
> should always describe the hardware (regardless of what the driver
> implements currently).
> I'm not sure how to manage this while we don't have the CPU clock
> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
> here.
> 

I've shared my thoughts about it in the bindings thread. Please take a
look.

> > + * the index 4 is the clock measurement source, it's not supported yet
> I suspect that this comes from the clock measurer IP block and if so
> the dt-bindings should probably describe this input. But again, we'd
> need to keep it optional for now since our clock measurer driver
> doesn't even implement a clock controller.
> 

Indeed, this is a similar situation to what we have with the inputs and
clocks of the CPU and Audio clock controllers. It seems like there is
only one option here: we should mark it with a TODO tag...

> [...]
> > +static struct clk_regmap pwm_a_sel = {
> > +       .data = &(struct clk_regmap_mux_data){
> > +               .offset = PWM_CLK_AB_CTRL,
> > +               .mask = 0x1,
> > +               .shift = 9,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "pwm_a_sel",
> > +               .ops = &clk_regmap_mux_ops,
> > +               .parent_data = pwm_abcd_parents,
> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> > +               /* For more information, please refer to rtc clock */
> > +               .flags = CLK_SET_RATE_NO_REPARENT,
> As mentioned in [0] we'll work with Heiner to see if we can improve
> the decision making process of the PWM controller driver so that we
> can just have .flags = 0 here.
> This applies to all other occurrences of the same comment about the rtc clock.

Sure, I'll make the change in v16. In my opinion, we should remove the
CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
including PWM, regardless of the outcome of the Heiner discussion. Based
on our IRC talk, the decision has more pros than cons -
https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18

-- 
Thank you,
Dmitry

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-22 13:32       ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-22 13:32 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hello Martin,

Thank you so much for the review, I really appreciate it!
Please find my comments below.

On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
> Hi Dmitry,
> 
> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > +static struct clk_regmap sys_b_sel = {
> > +       .data = &(struct clk_regmap_mux_data){
> > +               .offset = SYS_CLK_CTRL0,
> > +               .mask = 0x7,
> > +               .shift = 26,
> > +               .table = mux_table_sys,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "sys_b_sel",
> > +               .ops = &clk_regmap_mux_ro_ops,
> the sys_*_sel muxes and sys_*_gate are _ro...
> 
> > +               .parent_data = sys_parents,
> > +               .num_parents = ARRAY_SIZE(sys_parents),
> > +       },
> > +};
> > +
> > +static struct clk_regmap sys_b_div = {
> > +       .data = &(struct clk_regmap_div_data){
> > +               .offset = SYS_CLK_CTRL0,
> > +               .shift = 16,
> > +               .width = 10,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "sys_b_div",
> > +               .ops = &clk_regmap_divider_ops,
> ...but the sys_*_div aren't
> Is this on purpose? If it is: why can the divider be changed at
> runtime but the mux can't?
> 

Ah, that's a good catch. Since the system clock is set up by the BootROM
code, all sys_* dividers and gates should be read-only. I'll make sure
to change that in the next version.

> [...]
> > +/*
> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
> We need to add the "sys_pll_div16" input to the dt-bindings since they
> should always describe the hardware (regardless of what the driver
> implements currently).
> I'm not sure how to manage this while we don't have the CPU clock
> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
> here.
> 

I've shared my thoughts about it in the bindings thread. Please take a
look.

> > + * the index 4 is the clock measurement source, it's not supported yet
> I suspect that this comes from the clock measurer IP block and if so
> the dt-bindings should probably describe this input. But again, we'd
> need to keep it optional for now since our clock measurer driver
> doesn't even implement a clock controller.
> 

Indeed, this is a similar situation to what we have with the inputs and
clocks of the CPU and Audio clock controllers. It seems like there is
only one option here: we should mark it with a TODO tag...

> [...]
> > +static struct clk_regmap pwm_a_sel = {
> > +       .data = &(struct clk_regmap_mux_data){
> > +               .offset = PWM_CLK_AB_CTRL,
> > +               .mask = 0x1,
> > +               .shift = 9,
> > +       },
> > +       .hw.init = &(struct clk_init_data){
> > +               .name = "pwm_a_sel",
> > +               .ops = &clk_regmap_mux_ops,
> > +               .parent_data = pwm_abcd_parents,
> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> > +               /* For more information, please refer to rtc clock */
> > +               .flags = CLK_SET_RATE_NO_REPARENT,
> As mentioned in [0] we'll work with Heiner to see if we can improve
> the decision making process of the PWM controller driver so that we
> can just have .flags = 0 here.
> This applies to all other occurrences of the same comment about the rtc clock.

Sure, I'll make the change in v16. In my opinion, we should remove the
CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
including PWM, regardless of the outcome of the Heiner discussion. Based
on our IRC talk, the decision has more pros than cons -
https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18

-- 
Thank you,
Dmitry

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
  2023-05-22 13:00       ` Dmitry Rokosov
  (?)
@ 2023-05-29 20:38         ` Martin Blumenstingl
  -1 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-29 20:38 UTC (permalink / raw)
  To: Dmitry Rokosov, Conor Dooley, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Hi Dmitry,

On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> > This IP block has at least one additional input called "sys_pll_div16".
> > My understanding is that the "sys_pll_div16" clock is generated by the
> > CPU clock controller. Support for the CPU clock controller
> > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > How can we manage incrementally implementing the clock controllers?
> > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > How to manage this in the .dts patches then (for example: does this
> > mean that Dmitry can only add the clock controller to the .dts when
> > all clock controller bindings have been implemented - or is there
> > another way)?
>
> You're absolutely right: currently, not all inputs are supported because
> the CPU clock controller isn't ready yet – I'm working on it at the
> moment.
>
> I understand your concerns about bindings and schema description, but
> there is an issue to be considered. I'm developing the entire clock
> controller A1 subsystem incrementally in three stages: peripherals and
> PLL, CPU, and Audio. This is because the CPU can operate at a static
> frequency and voltage, and the board boots normally without the CPU
> clock controller, thermal sensor, and OPP table. Audio is also
> important, but it's optional. On the other hand, without setting up the
> peripherals and PLL controllers, the board won't function because
> they're fundamental.
I understand your approach and I like it (without that incremental
approach you would probably be looking at a series with 15-20
patches).

Maybe the dt-binding maintainers have a suggestion for us here?
Let me try to summarize the issue in a few bullet points:
- There's (at least) four clock controllers on the Amlogic A1 SoC
- Some of these clock controllers take the outputs of another clock
controller as inputs
- In this series patch the peripheral clock controller has an input
called "sys_pll_div16"
- The clock controller which provides the "sys_pll_div16" clock is not
implemented yet (my understanding is that implementing it and adding
it to this series is not easy: it would add even more patches that
need to be reviewed and in general it's a tricky clock controller to
implement as it manages the CPU clocks)

> Right now, we're in the first stage of the plan. Unfortunately, I can't
> disclose the exact names and number of clock bindings for the CPU and
> Audio, as they're still in development and only exist in my head or
> draft versions.
>
> If possible, I'd prefer to provide the new bindings and connections once
> all the appropriate drivers are finalized.
Question to Conor and Krzysztof (assuming you read my summary above):
Is it fine that Dmitry adds additional inputs to the peripheral clock
controller binding in later patches?
If not: how can we proceed in case we need to add them now (the
dt-binding example is the easy part for me as we can just make up a
phandle like &sys_pll_div16_clk and use that - but this can't work
when Dmitry tries to add the clock controller to meson-a1.dtsi)

PS: Dmitry is trying to get this series into Linux 6.5. As far as I
remember the common clock maintainers don't take pull requests with
new features after -rc6 (which is in less than two weeks).
So time is getting a bit short and for me this is the very last
outstanding question. If you say that it's fine to add clocks later on
this will immediately get my Reviewed-by.


Best regards,
Martin

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-29 20:38         ` Martin Blumenstingl
  0 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-29 20:38 UTC (permalink / raw)
  To: Dmitry Rokosov, Conor Dooley, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Hi Dmitry,

On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> > This IP block has at least one additional input called "sys_pll_div16".
> > My understanding is that the "sys_pll_div16" clock is generated by the
> > CPU clock controller. Support for the CPU clock controller
> > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > How can we manage incrementally implementing the clock controllers?
> > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > How to manage this in the .dts patches then (for example: does this
> > mean that Dmitry can only add the clock controller to the .dts when
> > all clock controller bindings have been implemented - or is there
> > another way)?
>
> You're absolutely right: currently, not all inputs are supported because
> the CPU clock controller isn't ready yet – I'm working on it at the
> moment.
>
> I understand your concerns about bindings and schema description, but
> there is an issue to be considered. I'm developing the entire clock
> controller A1 subsystem incrementally in three stages: peripherals and
> PLL, CPU, and Audio. This is because the CPU can operate at a static
> frequency and voltage, and the board boots normally without the CPU
> clock controller, thermal sensor, and OPP table. Audio is also
> important, but it's optional. On the other hand, without setting up the
> peripherals and PLL controllers, the board won't function because
> they're fundamental.
I understand your approach and I like it (without that incremental
approach you would probably be looking at a series with 15-20
patches).

Maybe the dt-binding maintainers have a suggestion for us here?
Let me try to summarize the issue in a few bullet points:
- There's (at least) four clock controllers on the Amlogic A1 SoC
- Some of these clock controllers take the outputs of another clock
controller as inputs
- In this series patch the peripheral clock controller has an input
called "sys_pll_div16"
- The clock controller which provides the "sys_pll_div16" clock is not
implemented yet (my understanding is that implementing it and adding
it to this series is not easy: it would add even more patches that
need to be reviewed and in general it's a tricky clock controller to
implement as it manages the CPU clocks)

> Right now, we're in the first stage of the plan. Unfortunately, I can't
> disclose the exact names and number of clock bindings for the CPU and
> Audio, as they're still in development and only exist in my head or
> draft versions.
>
> If possible, I'd prefer to provide the new bindings and connections once
> all the appropriate drivers are finalized.
Question to Conor and Krzysztof (assuming you read my summary above):
Is it fine that Dmitry adds additional inputs to the peripheral clock
controller binding in later patches?
If not: how can we proceed in case we need to add them now (the
dt-binding example is the easy part for me as we can just make up a
phandle like &sys_pll_div16_clk and use that - but this can't work
when Dmitry tries to add the clock controller to meson-a1.dtsi)

PS: Dmitry is trying to get this series into Linux 6.5. As far as I
remember the common clock maintainers don't take pull requests with
new features after -rc6 (which is in less than two weeks).
So time is getting a bit short and for me this is the very last
outstanding question. If you say that it's fine to add clocks later on
this will immediately get my Reviewed-by.


Best regards,
Martin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-29 20:38         ` Martin Blumenstingl
  0 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-29 20:38 UTC (permalink / raw)
  To: Dmitry Rokosov, Conor Dooley, krzysztof.kozlowski+dt
  Cc: neil.armstrong, jbrunet, mturquette, sboyd, robh+dt, khilman,
	jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Hi Dmitry,

On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> > This IP block has at least one additional input called "sys_pll_div16".
> > My understanding is that the "sys_pll_div16" clock is generated by the
> > CPU clock controller. Support for the CPU clock controller
> > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > How can we manage incrementally implementing the clock controllers?
> > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > How to manage this in the .dts patches then (for example: does this
> > mean that Dmitry can only add the clock controller to the .dts when
> > all clock controller bindings have been implemented - or is there
> > another way)?
>
> You're absolutely right: currently, not all inputs are supported because
> the CPU clock controller isn't ready yet – I'm working on it at the
> moment.
>
> I understand your concerns about bindings and schema description, but
> there is an issue to be considered. I'm developing the entire clock
> controller A1 subsystem incrementally in three stages: peripherals and
> PLL, CPU, and Audio. This is because the CPU can operate at a static
> frequency and voltage, and the board boots normally without the CPU
> clock controller, thermal sensor, and OPP table. Audio is also
> important, but it's optional. On the other hand, without setting up the
> peripherals and PLL controllers, the board won't function because
> they're fundamental.
I understand your approach and I like it (without that incremental
approach you would probably be looking at a series with 15-20
patches).

Maybe the dt-binding maintainers have a suggestion for us here?
Let me try to summarize the issue in a few bullet points:
- There's (at least) four clock controllers on the Amlogic A1 SoC
- Some of these clock controllers take the outputs of another clock
controller as inputs
- In this series patch the peripheral clock controller has an input
called "sys_pll_div16"
- The clock controller which provides the "sys_pll_div16" clock is not
implemented yet (my understanding is that implementing it and adding
it to this series is not easy: it would add even more patches that
need to be reviewed and in general it's a tricky clock controller to
implement as it manages the CPU clocks)

> Right now, we're in the first stage of the plan. Unfortunately, I can't
> disclose the exact names and number of clock bindings for the CPU and
> Audio, as they're still in development and only exist in my head or
> draft versions.
>
> If possible, I'd prefer to provide the new bindings and connections once
> all the appropriate drivers are finalized.
Question to Conor and Krzysztof (assuming you read my summary above):
Is it fine that Dmitry adds additional inputs to the peripheral clock
controller binding in later patches?
If not: how can we proceed in case we need to add them now (the
dt-binding example is the easy part for me as we can just make up a
phandle like &sys_pll_div16_clk and use that - but this can't work
when Dmitry tries to add the clock controller to meson-a1.dtsi)

PS: Dmitry is trying to get this series into Linux 6.5. As far as I
remember the common clock maintainers don't take pull requests with
new features after -rc6 (which is in less than two weeks).
So time is getting a bit short and for me this is the very last
outstanding question. If you say that it's fine to add clocks later on
this will immediately get my Reviewed-by.


Best regards,
Martin

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
  2023-05-22 13:32       ` Dmitry Rokosov
  (?)
@ 2023-05-30  8:32         ` Jerome Brunet
  -1 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30  8:32 UTC (permalink / raw)
  To: Dmitry Rokosov, Martin Blumenstingl
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel


On Mon 22 May 2023 at 16:32, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:

> Hello Martin,
>
> Thank you so much for the review, I really appreciate it!
> Please find my comments below.
>
> On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
>> Hi Dmitry,
>> 
>> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
>> [...]
>> > +static struct clk_regmap sys_b_sel = {
>> > +       .data = &(struct clk_regmap_mux_data){
>> > +               .offset = SYS_CLK_CTRL0,
>> > +               .mask = 0x7,
>> > +               .shift = 26,
>> > +               .table = mux_table_sys,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "sys_b_sel",
>> > +               .ops = &clk_regmap_mux_ro_ops,
>> the sys_*_sel muxes and sys_*_gate are _ro...
>> 
>> > +               .parent_data = sys_parents,
>> > +               .num_parents = ARRAY_SIZE(sys_parents),
>> > +       },
>> > +};
>> > +
>> > +static struct clk_regmap sys_b_div = {
>> > +       .data = &(struct clk_regmap_div_data){
>> > +               .offset = SYS_CLK_CTRL0,
>> > +               .shift = 16,
>> > +               .width = 10,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "sys_b_div",
>> > +               .ops = &clk_regmap_divider_ops,
>> ...but the sys_*_div aren't
>> Is this on purpose? If it is: why can the divider be changed at
>> runtime but the mux can't?
>> 
>
> Ah, that's a good catch. Since the system clock is set up by the BootROM
> code, all sys_* dividers and gates should be read-only. I'll make sure
> to change that in the next version.
>
>> [...]
>> > +/*
>> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
>> We need to add the "sys_pll_div16" input to the dt-bindings since they
>> should always describe the hardware (regardless of what the driver
>> implements currently).
>> I'm not sure how to manage this while we don't have the CPU clock
>> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
>> here.
>> 
>
> I've shared my thoughts about it in the bindings thread. Please take a
> look.
>
>> > + * the index 4 is the clock measurement source, it's not supported yet
>> I suspect that this comes from the clock measurer IP block and if so
>> the dt-bindings should probably describe this input. But again, we'd
>> need to keep it optional for now since our clock measurer driver
>> doesn't even implement a clock controller.
>> 
>
> Indeed, this is a similar situation to what we have with the inputs and
> clocks of the CPU and Audio clock controllers. It seems like there is
> only one option here: we should mark it with a TODO tag...
>
>> [...]
>> > +static struct clk_regmap pwm_a_sel = {
>> > +       .data = &(struct clk_regmap_mux_data){
>> > +               .offset = PWM_CLK_AB_CTRL,
>> > +               .mask = 0x1,
>> > +               .shift = 9,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "pwm_a_sel",
>> > +               .ops = &clk_regmap_mux_ops,
>> > +               .parent_data = pwm_abcd_parents,
>> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
>> > +               /* For more information, please refer to rtc clock */
>> > +               .flags = CLK_SET_RATE_NO_REPARENT,
>> As mentioned in [0] we'll work with Heiner to see if we can improve
>> the decision making process of the PWM controller driver so that we
>> can just have .flags = 0 here.
>> This applies to all other occurrences of the same comment about the rtc clock.
>
> Sure, I'll make the change in v16. In my opinion, we should remove the
> CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
> including PWM, regardless of the outcome of the Heiner discussion. Based
> on our IRC talk, the decision has more pros than cons -
> https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18

The clock scheme of PWM could indeed be handled like audio is but it
not strictly required.

In audio we have a limited number of PLLs (root sources). There is a lot
more consummers than there is root sources. If the root sources rate is
not carefully chosen to statisfy all needs, we could end in a situation
where we can't satisfy all consummers or we must glitch the source to do
so.

For the PWM, I think (but I'm not 100% sure) that the main clock controller
provides a source for each PWM. No risk of race there. That is why AML
decided to completly ignore the clock element in the PWM IP, because
they can do almost everything with what is in the main controller ... Still
ignoring those part is wrong

For the RTC, If you want/need to handle external RTCs, I don't think you
have much of a choice. If both the internal and external *report* the
same rate, CCF can't really know if one is best. It will just pick one,
no necessarily the one you want. I don't really see a way around manual
selection for this.


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-30  8:32         ` Jerome Brunet
  0 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30  8:32 UTC (permalink / raw)
  To: Dmitry Rokosov, Martin Blumenstingl
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel


On Mon 22 May 2023 at 16:32, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:

> Hello Martin,
>
> Thank you so much for the review, I really appreciate it!
> Please find my comments below.
>
> On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
>> Hi Dmitry,
>> 
>> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
>> [...]
>> > +static struct clk_regmap sys_b_sel = {
>> > +       .data = &(struct clk_regmap_mux_data){
>> > +               .offset = SYS_CLK_CTRL0,
>> > +               .mask = 0x7,
>> > +               .shift = 26,
>> > +               .table = mux_table_sys,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "sys_b_sel",
>> > +               .ops = &clk_regmap_mux_ro_ops,
>> the sys_*_sel muxes and sys_*_gate are _ro...
>> 
>> > +               .parent_data = sys_parents,
>> > +               .num_parents = ARRAY_SIZE(sys_parents),
>> > +       },
>> > +};
>> > +
>> > +static struct clk_regmap sys_b_div = {
>> > +       .data = &(struct clk_regmap_div_data){
>> > +               .offset = SYS_CLK_CTRL0,
>> > +               .shift = 16,
>> > +               .width = 10,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "sys_b_div",
>> > +               .ops = &clk_regmap_divider_ops,
>> ...but the sys_*_div aren't
>> Is this on purpose? If it is: why can the divider be changed at
>> runtime but the mux can't?
>> 
>
> Ah, that's a good catch. Since the system clock is set up by the BootROM
> code, all sys_* dividers and gates should be read-only. I'll make sure
> to change that in the next version.
>
>> [...]
>> > +/*
>> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
>> We need to add the "sys_pll_div16" input to the dt-bindings since they
>> should always describe the hardware (regardless of what the driver
>> implements currently).
>> I'm not sure how to manage this while we don't have the CPU clock
>> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
>> here.
>> 
>
> I've shared my thoughts about it in the bindings thread. Please take a
> look.
>
>> > + * the index 4 is the clock measurement source, it's not supported yet
>> I suspect that this comes from the clock measurer IP block and if so
>> the dt-bindings should probably describe this input. But again, we'd
>> need to keep it optional for now since our clock measurer driver
>> doesn't even implement a clock controller.
>> 
>
> Indeed, this is a similar situation to what we have with the inputs and
> clocks of the CPU and Audio clock controllers. It seems like there is
> only one option here: we should mark it with a TODO tag...
>
>> [...]
>> > +static struct clk_regmap pwm_a_sel = {
>> > +       .data = &(struct clk_regmap_mux_data){
>> > +               .offset = PWM_CLK_AB_CTRL,
>> > +               .mask = 0x1,
>> > +               .shift = 9,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "pwm_a_sel",
>> > +               .ops = &clk_regmap_mux_ops,
>> > +               .parent_data = pwm_abcd_parents,
>> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
>> > +               /* For more information, please refer to rtc clock */
>> > +               .flags = CLK_SET_RATE_NO_REPARENT,
>> As mentioned in [0] we'll work with Heiner to see if we can improve
>> the decision making process of the PWM controller driver so that we
>> can just have .flags = 0 here.
>> This applies to all other occurrences of the same comment about the rtc clock.
>
> Sure, I'll make the change in v16. In my opinion, we should remove the
> CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
> including PWM, regardless of the outcome of the Heiner discussion. Based
> on our IRC talk, the decision has more pros than cons -
> https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18

The clock scheme of PWM could indeed be handled like audio is but it
not strictly required.

In audio we have a limited number of PLLs (root sources). There is a lot
more consummers than there is root sources. If the root sources rate is
not carefully chosen to statisfy all needs, we could end in a situation
where we can't satisfy all consummers or we must glitch the source to do
so.

For the PWM, I think (but I'm not 100% sure) that the main clock controller
provides a source for each PWM. No risk of race there. That is why AML
decided to completly ignore the clock element in the PWM IP, because
they can do almost everything with what is in the main controller ... Still
ignoring those part is wrong

For the RTC, If you want/need to handle external RTCs, I don't think you
have much of a choice. If both the internal and external *report* the
same rate, CCF can't really know if one is best. It will just pick one,
no necessarily the one you want. I don't really see a way around manual
selection for this.


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-30  8:32         ` Jerome Brunet
  0 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30  8:32 UTC (permalink / raw)
  To: Dmitry Rokosov, Martin Blumenstingl
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel


On Mon 22 May 2023 at 16:32, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:

> Hello Martin,
>
> Thank you so much for the review, I really appreciate it!
> Please find my comments below.
>
> On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
>> Hi Dmitry,
>> 
>> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
>> [...]
>> > +static struct clk_regmap sys_b_sel = {
>> > +       .data = &(struct clk_regmap_mux_data){
>> > +               .offset = SYS_CLK_CTRL0,
>> > +               .mask = 0x7,
>> > +               .shift = 26,
>> > +               .table = mux_table_sys,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "sys_b_sel",
>> > +               .ops = &clk_regmap_mux_ro_ops,
>> the sys_*_sel muxes and sys_*_gate are _ro...
>> 
>> > +               .parent_data = sys_parents,
>> > +               .num_parents = ARRAY_SIZE(sys_parents),
>> > +       },
>> > +};
>> > +
>> > +static struct clk_regmap sys_b_div = {
>> > +       .data = &(struct clk_regmap_div_data){
>> > +               .offset = SYS_CLK_CTRL0,
>> > +               .shift = 16,
>> > +               .width = 10,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "sys_b_div",
>> > +               .ops = &clk_regmap_divider_ops,
>> ...but the sys_*_div aren't
>> Is this on purpose? If it is: why can the divider be changed at
>> runtime but the mux can't?
>> 
>
> Ah, that's a good catch. Since the system clock is set up by the BootROM
> code, all sys_* dividers and gates should be read-only. I'll make sure
> to change that in the next version.
>
>> [...]
>> > +/*
>> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
>> We need to add the "sys_pll_div16" input to the dt-bindings since they
>> should always describe the hardware (regardless of what the driver
>> implements currently).
>> I'm not sure how to manage this while we don't have the CPU clock
>> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
>> here.
>> 
>
> I've shared my thoughts about it in the bindings thread. Please take a
> look.
>
>> > + * the index 4 is the clock measurement source, it's not supported yet
>> I suspect that this comes from the clock measurer IP block and if so
>> the dt-bindings should probably describe this input. But again, we'd
>> need to keep it optional for now since our clock measurer driver
>> doesn't even implement a clock controller.
>> 
>
> Indeed, this is a similar situation to what we have with the inputs and
> clocks of the CPU and Audio clock controllers. It seems like there is
> only one option here: we should mark it with a TODO tag...
>
>> [...]
>> > +static struct clk_regmap pwm_a_sel = {
>> > +       .data = &(struct clk_regmap_mux_data){
>> > +               .offset = PWM_CLK_AB_CTRL,
>> > +               .mask = 0x1,
>> > +               .shift = 9,
>> > +       },
>> > +       .hw.init = &(struct clk_init_data){
>> > +               .name = "pwm_a_sel",
>> > +               .ops = &clk_regmap_mux_ops,
>> > +               .parent_data = pwm_abcd_parents,
>> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
>> > +               /* For more information, please refer to rtc clock */
>> > +               .flags = CLK_SET_RATE_NO_REPARENT,
>> As mentioned in [0] we'll work with Heiner to see if we can improve
>> the decision making process of the PWM controller driver so that we
>> can just have .flags = 0 here.
>> This applies to all other occurrences of the same comment about the rtc clock.
>
> Sure, I'll make the change in v16. In my opinion, we should remove the
> CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
> including PWM, regardless of the outcome of the Heiner discussion. Based
> on our IRC talk, the decision has more pros than cons -
> https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18

The clock scheme of PWM could indeed be handled like audio is but it
not strictly required.

In audio we have a limited number of PLLs (root sources). There is a lot
more consummers than there is root sources. If the root sources rate is
not carefully chosen to statisfy all needs, we could end in a situation
where we can't satisfy all consummers or we must glitch the source to do
so.

For the PWM, I think (but I'm not 100% sure) that the main clock controller
provides a source for each PWM. No risk of race there. That is why AML
decided to completly ignore the clock element in the PWM IP, because
they can do almost everything with what is in the main controller ... Still
ignoring those part is wrong

For the RTC, If you want/need to handle external RTCs, I don't think you
have much of a choice. If both the internal and external *report* the
same rate, CCF can't really know if one is best. It will just pick one,
no necessarily the one you want. I don't really see a way around manual
selection for this.


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
  2023-05-29 20:38         ` Martin Blumenstingl
  (?)
@ 2023-05-30  8:56           ` Jerome Brunet
  -1 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30  8:56 UTC (permalink / raw)
  To: Martin Blumenstingl, Dmitry Rokosov, Conor Dooley,
	krzysztof.kozlowski+dt
  Cc: neil.armstrong, mturquette, sboyd, robh+dt, khilman, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel


On Mon 29 May 2023 at 22:38, Martin Blumenstingl <martin.blumenstingl@googlemail.com> wrote:

> Hi Dmitry,
>
> On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
>> > This IP block has at least one additional input called "sys_pll_div16".
>> > My understanding is that the "sys_pll_div16" clock is generated by the
>> > CPU clock controller. Support for the CPU clock controller
>> > (dt-bindings and a driver) will be added at a later time by Dmitry.
>> > How can we manage incrementally implementing the clock controllers?
>> > From a hardware perspective the "sys_pll_div16" input is mandatory.
>> > How to manage this in the .dts patches then (for example: does this
>> > mean that Dmitry can only add the clock controller to the .dts when
>> > all clock controller bindings have been implemented - or is there
>> > another way)?
>>
>> You're absolutely right: currently, not all inputs are supported because
>> the CPU clock controller isn't ready yet – I'm working on it at the
>> moment.
>>
>> I understand your concerns about bindings and schema description, but
>> there is an issue to be considered. I'm developing the entire clock
>> controller A1 subsystem incrementally in three stages: peripherals and
>> PLL, CPU, and Audio. This is because the CPU can operate at a static
>> frequency and voltage, and the board boots normally without the CPU
>> clock controller, thermal sensor, and OPP table. Audio is also
>> important, but it's optional. On the other hand, without setting up the
>> peripherals and PLL controllers, the board won't function because
>> they're fundamental.
> I understand your approach and I like it (without that incremental
> approach you would probably be looking at a series with 15-20
> patches).
>
> Maybe the dt-binding maintainers have a suggestion for us here?
> Let me try to summarize the issue in a few bullet points:
> - There's (at least) four clock controllers on the Amlogic A1 SoC
> - Some of these clock controllers take the outputs of another clock
> controller as inputs
> - In this series patch the peripheral clock controller has an input
> called "sys_pll_div16"
> - The clock controller which provides the "sys_pll_div16" clock is not
> implemented yet (my understanding is that implementing it and adding
> it to this series is not easy: it would add even more patches that
> need to be reviewed and in general it's a tricky clock controller to
> implement as it manages the CPU clocks)

IMO, if you just add another const later on, it is fine. I would not make
any existing DT invalid as a result. The problem would be if you removed
an entry

That's my understanding at least

>
>> Right now, we're in the first stage of the plan. Unfortunately, I can't
>> disclose the exact names and number of clock bindings for the CPU and
>> Audio, as they're still in development and only exist in my head or
>> draft versions.
>>
>> If possible, I'd prefer to provide the new bindings and connections once
>> all the appropriate drivers are finalized.
> Question to Conor and Krzysztof (assuming you read my summary above):
> Is it fine that Dmitry adds additional inputs to the peripheral clock
> controller binding in later patches?
> If not: how can we proceed in case we need to add them now (the
> dt-binding example is the easy part for me as we can just make up a
> phandle like &sys_pll_div16_clk and use that - but this can't work
> when Dmitry tries to add the clock controller to meson-a1.dtsi)
>
> PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> remember the common clock maintainers don't take pull requests with
> new features after -rc6 (which is in less than two weeks).
> So time is getting a bit short and for me this is the very last
> outstanding question. If you say that it's fine to add clocks later on
> this will immediately get my Reviewed-by.
>
>
> Best regards,
> Martin


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-30  8:56           ` Jerome Brunet
  0 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30  8:56 UTC (permalink / raw)
  To: Martin Blumenstingl, Dmitry Rokosov, Conor Dooley,
	krzysztof.kozlowski+dt
  Cc: neil.armstrong, mturquette, sboyd, robh+dt, khilman, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel


On Mon 29 May 2023 at 22:38, Martin Blumenstingl <martin.blumenstingl@googlemail.com> wrote:

> Hi Dmitry,
>
> On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
>> > This IP block has at least one additional input called "sys_pll_div16".
>> > My understanding is that the "sys_pll_div16" clock is generated by the
>> > CPU clock controller. Support for the CPU clock controller
>> > (dt-bindings and a driver) will be added at a later time by Dmitry.
>> > How can we manage incrementally implementing the clock controllers?
>> > From a hardware perspective the "sys_pll_div16" input is mandatory.
>> > How to manage this in the .dts patches then (for example: does this
>> > mean that Dmitry can only add the clock controller to the .dts when
>> > all clock controller bindings have been implemented - or is there
>> > another way)?
>>
>> You're absolutely right: currently, not all inputs are supported because
>> the CPU clock controller isn't ready yet – I'm working on it at the
>> moment.
>>
>> I understand your concerns about bindings and schema description, but
>> there is an issue to be considered. I'm developing the entire clock
>> controller A1 subsystem incrementally in three stages: peripherals and
>> PLL, CPU, and Audio. This is because the CPU can operate at a static
>> frequency and voltage, and the board boots normally without the CPU
>> clock controller, thermal sensor, and OPP table. Audio is also
>> important, but it's optional. On the other hand, without setting up the
>> peripherals and PLL controllers, the board won't function because
>> they're fundamental.
> I understand your approach and I like it (without that incremental
> approach you would probably be looking at a series with 15-20
> patches).
>
> Maybe the dt-binding maintainers have a suggestion for us here?
> Let me try to summarize the issue in a few bullet points:
> - There's (at least) four clock controllers on the Amlogic A1 SoC
> - Some of these clock controllers take the outputs of another clock
> controller as inputs
> - In this series patch the peripheral clock controller has an input
> called "sys_pll_div16"
> - The clock controller which provides the "sys_pll_div16" clock is not
> implemented yet (my understanding is that implementing it and adding
> it to this series is not easy: it would add even more patches that
> need to be reviewed and in general it's a tricky clock controller to
> implement as it manages the CPU clocks)

IMO, if you just add another const later on, it is fine. I would not make
any existing DT invalid as a result. The problem would be if you removed
an entry

That's my understanding at least

>
>> Right now, we're in the first stage of the plan. Unfortunately, I can't
>> disclose the exact names and number of clock bindings for the CPU and
>> Audio, as they're still in development and only exist in my head or
>> draft versions.
>>
>> If possible, I'd prefer to provide the new bindings and connections once
>> all the appropriate drivers are finalized.
> Question to Conor and Krzysztof (assuming you read my summary above):
> Is it fine that Dmitry adds additional inputs to the peripheral clock
> controller binding in later patches?
> If not: how can we proceed in case we need to add them now (the
> dt-binding example is the easy part for me as we can just make up a
> phandle like &sys_pll_div16_clk and use that - but this can't work
> when Dmitry tries to add the clock controller to meson-a1.dtsi)
>
> PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> remember the common clock maintainers don't take pull requests with
> new features after -rc6 (which is in less than two weeks).
> So time is getting a bit short and for me this is the very last
> outstanding question. If you say that it's fine to add clocks later on
> this will immediately get my Reviewed-by.
>
>
> Best regards,
> Martin


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-30  8:56           ` Jerome Brunet
  0 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30  8:56 UTC (permalink / raw)
  To: Martin Blumenstingl, Dmitry Rokosov, Conor Dooley,
	krzysztof.kozlowski+dt
  Cc: neil.armstrong, mturquette, sboyd, robh+dt, khilman, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel


On Mon 29 May 2023 at 22:38, Martin Blumenstingl <martin.blumenstingl@googlemail.com> wrote:

> Hi Dmitry,
>
> On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
>> > This IP block has at least one additional input called "sys_pll_div16".
>> > My understanding is that the "sys_pll_div16" clock is generated by the
>> > CPU clock controller. Support for the CPU clock controller
>> > (dt-bindings and a driver) will be added at a later time by Dmitry.
>> > How can we manage incrementally implementing the clock controllers?
>> > From a hardware perspective the "sys_pll_div16" input is mandatory.
>> > How to manage this in the .dts patches then (for example: does this
>> > mean that Dmitry can only add the clock controller to the .dts when
>> > all clock controller bindings have been implemented - or is there
>> > another way)?
>>
>> You're absolutely right: currently, not all inputs are supported because
>> the CPU clock controller isn't ready yet – I'm working on it at the
>> moment.
>>
>> I understand your concerns about bindings and schema description, but
>> there is an issue to be considered. I'm developing the entire clock
>> controller A1 subsystem incrementally in three stages: peripherals and
>> PLL, CPU, and Audio. This is because the CPU can operate at a static
>> frequency and voltage, and the board boots normally without the CPU
>> clock controller, thermal sensor, and OPP table. Audio is also
>> important, but it's optional. On the other hand, without setting up the
>> peripherals and PLL controllers, the board won't function because
>> they're fundamental.
> I understand your approach and I like it (without that incremental
> approach you would probably be looking at a series with 15-20
> patches).
>
> Maybe the dt-binding maintainers have a suggestion for us here?
> Let me try to summarize the issue in a few bullet points:
> - There's (at least) four clock controllers on the Amlogic A1 SoC
> - Some of these clock controllers take the outputs of another clock
> controller as inputs
> - In this series patch the peripheral clock controller has an input
> called "sys_pll_div16"
> - The clock controller which provides the "sys_pll_div16" clock is not
> implemented yet (my understanding is that implementing it and adding
> it to this series is not easy: it would add even more patches that
> need to be reviewed and in general it's a tricky clock controller to
> implement as it manages the CPU clocks)

IMO, if you just add another const later on, it is fine. I would not make
any existing DT invalid as a result. The problem would be if you removed
an entry

That's my understanding at least

>
>> Right now, we're in the first stage of the plan. Unfortunately, I can't
>> disclose the exact names and number of clock bindings for the CPU and
>> Audio, as they're still in development and only exist in my head or
>> draft versions.
>>
>> If possible, I'd prefer to provide the new bindings and connections once
>> all the appropriate drivers are finalized.
> Question to Conor and Krzysztof (assuming you read my summary above):
> Is it fine that Dmitry adds additional inputs to the peripheral clock
> controller binding in later patches?
> If not: how can we proceed in case we need to add them now (the
> dt-binding example is the easy part for me as we can just make up a
> phandle like &sys_pll_div16_clk and use that - but this can't work
> when Dmitry tries to add the clock controller to meson-a1.dtsi)
>
> PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> remember the common clock maintainers don't take pull requests with
> new features after -rc6 (which is in less than two weeks).
> So time is getting a bit short and for me this is the very last
> outstanding question. If you say that it's fine to add clocks later on
> this will immediately get my Reviewed-by.
>
>
> Best regards,
> Martin


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
  2023-05-29 20:38         ` Martin Blumenstingl
  (?)
@ 2023-05-30  9:34           ` Conor Dooley
  -1 siblings, 0 replies; 63+ messages in thread
From: Conor Dooley @ 2023-05-30  9:34 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: Dmitry Rokosov, krzysztof.kozlowski+dt, neil.armstrong, jbrunet,
	mturquette, sboyd, robh+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 5223 bytes --]

Yo,

On Mon, May 29, 2023 at 10:38:33PM +0200, Martin Blumenstingl wrote:
> On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > > This IP block has at least one additional input called "sys_pll_div16".
> > > My understanding is that the "sys_pll_div16" clock is generated by the
> > > CPU clock controller. Support for the CPU clock controller
> > > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > > How can we manage incrementally implementing the clock controllers?
> > > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > > How to manage this in the .dts patches then (for example: does this
> > > mean that Dmitry can only add the clock controller to the .dts when
> > > all clock controller bindings have been implemented - or is there
> > > another way)?
> >
> > You're absolutely right: currently, not all inputs are supported because
> > the CPU clock controller isn't ready yet – I'm working on it at the
> > moment.
> >
> > I understand your concerns about bindings and schema description, but
> > there is an issue to be considered. I'm developing the entire clock
> > controller A1 subsystem incrementally in three stages: peripherals and
> > PLL, CPU, and Audio. This is because the CPU can operate at a static
> > frequency and voltage, and the board boots normally without the CPU
> > clock controller, thermal sensor, and OPP table. Audio is also
> > important, but it's optional. On the other hand, without setting up the
> > peripherals and PLL controllers, the board won't function because
> > they're fundamental.
> I understand your approach and I like it (without that incremental
> approach you would probably be looking at a series with 15-20
> patches).
> 
> Maybe the dt-binding maintainers have a suggestion for us here?
> Let me try to summarize the issue in a few bullet points:
> - There's (at least) four clock controllers on the Amlogic A1 SoC
> - Some of these clock controllers take the outputs of another clock
> controller as inputs
> - In this series patch the peripheral clock controller has an input
> called "sys_pll_div16"
> - The clock controller which provides the "sys_pll_div16" clock is not
> implemented yet (my understanding is that implementing it and adding
> it to this series is not easy: it would add even more patches that
> need to be reviewed and in general it's a tricky clock controller to
> implement as it manages the CPU clocks)

If I am understanding correctly, this series implements the child
controller and a parent, which is unimplemented, provides the child with
sys_pll_div16.
The thing I am missing is whether the child controller has some outputs
that depend on this sys_pll_div16 input & whether those are documented
in this series. Regardless, you should be able to add more output clocks
without compatibility issues.

> > Right now, we're in the first stage of the plan. Unfortunately, I can't
> > disclose the exact names and number of clock bindings for the CPU and
> > Audio, as they're still in development and only exist in my head or
> > draft versions.
> >
> > If possible, I'd prefer to provide the new bindings and connections once
> > all the appropriate drivers are finalized.
> Question to Conor and Krzysztof (assuming you read my summary above):
> Is it fine that Dmitry adds additional inputs to the peripheral clock
> controller binding in later patches?

Perhaps Krzysztof will disagree with me, but my take on it would be that
the binding should describe the individual clock controller in its
totality, but the driver can choose to only implement a subset of it.

If you define the binding as only needing N inputs, but then later
expand it to having N+M inputs, the driver will have to support N & N+M
input clocks to preserve compatibility.
If you define it as needing N+M inputs from the beginning, but only use
N, there is no issue with backwards compatibility when you later use
them all.

> If not: how can we proceed in case we need to add them now (the
> dt-binding example is the easy part for me as we can just make up a
> phandle like &sys_pll_div16_clk and use that - but this can't work
> when Dmitry tries to add the clock controller to meson-a1.dtsi)

I would be inclined to do the same thing in the dts as the example,
and make up a fixed-frequency clock and use it to plug the hole.
When you have bindings etc written for the clock controller providing
that clock, the fixed-frequency clock could be swapped out for the real
one.

> PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> remember the common clock maintainers don't take pull requests with
> new features after -rc6 (which is in less than two weeks).
> So time is getting a bit short and for me this is the very last
> outstanding question. If you say that it's fine to add clocks later on
> this will immediately get my Reviewed-by.

I *think* that what I've just said should not get in the way of such a
timeline, as it would only involve a "small" change to the dt-binding,
but not require additional bindings or driver.

Cheers,
Conor.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-30  9:34           ` Conor Dooley
  0 siblings, 0 replies; 63+ messages in thread
From: Conor Dooley @ 2023-05-30  9:34 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: Dmitry Rokosov, krzysztof.kozlowski+dt, neil.armstrong, jbrunet,
	mturquette, sboyd, robh+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 5223 bytes --]

Yo,

On Mon, May 29, 2023 at 10:38:33PM +0200, Martin Blumenstingl wrote:
> On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > > This IP block has at least one additional input called "sys_pll_div16".
> > > My understanding is that the "sys_pll_div16" clock is generated by the
> > > CPU clock controller. Support for the CPU clock controller
> > > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > > How can we manage incrementally implementing the clock controllers?
> > > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > > How to manage this in the .dts patches then (for example: does this
> > > mean that Dmitry can only add the clock controller to the .dts when
> > > all clock controller bindings have been implemented - or is there
> > > another way)?
> >
> > You're absolutely right: currently, not all inputs are supported because
> > the CPU clock controller isn't ready yet – I'm working on it at the
> > moment.
> >
> > I understand your concerns about bindings and schema description, but
> > there is an issue to be considered. I'm developing the entire clock
> > controller A1 subsystem incrementally in three stages: peripherals and
> > PLL, CPU, and Audio. This is because the CPU can operate at a static
> > frequency and voltage, and the board boots normally without the CPU
> > clock controller, thermal sensor, and OPP table. Audio is also
> > important, but it's optional. On the other hand, without setting up the
> > peripherals and PLL controllers, the board won't function because
> > they're fundamental.
> I understand your approach and I like it (without that incremental
> approach you would probably be looking at a series with 15-20
> patches).
> 
> Maybe the dt-binding maintainers have a suggestion for us here?
> Let me try to summarize the issue in a few bullet points:
> - There's (at least) four clock controllers on the Amlogic A1 SoC
> - Some of these clock controllers take the outputs of another clock
> controller as inputs
> - In this series patch the peripheral clock controller has an input
> called "sys_pll_div16"
> - The clock controller which provides the "sys_pll_div16" clock is not
> implemented yet (my understanding is that implementing it and adding
> it to this series is not easy: it would add even more patches that
> need to be reviewed and in general it's a tricky clock controller to
> implement as it manages the CPU clocks)

If I am understanding correctly, this series implements the child
controller and a parent, which is unimplemented, provides the child with
sys_pll_div16.
The thing I am missing is whether the child controller has some outputs
that depend on this sys_pll_div16 input & whether those are documented
in this series. Regardless, you should be able to add more output clocks
without compatibility issues.

> > Right now, we're in the first stage of the plan. Unfortunately, I can't
> > disclose the exact names and number of clock bindings for the CPU and
> > Audio, as they're still in development and only exist in my head or
> > draft versions.
> >
> > If possible, I'd prefer to provide the new bindings and connections once
> > all the appropriate drivers are finalized.
> Question to Conor and Krzysztof (assuming you read my summary above):
> Is it fine that Dmitry adds additional inputs to the peripheral clock
> controller binding in later patches?

Perhaps Krzysztof will disagree with me, but my take on it would be that
the binding should describe the individual clock controller in its
totality, but the driver can choose to only implement a subset of it.

If you define the binding as only needing N inputs, but then later
expand it to having N+M inputs, the driver will have to support N & N+M
input clocks to preserve compatibility.
If you define it as needing N+M inputs from the beginning, but only use
N, there is no issue with backwards compatibility when you later use
them all.

> If not: how can we proceed in case we need to add them now (the
> dt-binding example is the easy part for me as we can just make up a
> phandle like &sys_pll_div16_clk and use that - but this can't work
> when Dmitry tries to add the clock controller to meson-a1.dtsi)

I would be inclined to do the same thing in the dts as the example,
and make up a fixed-frequency clock and use it to plug the hole.
When you have bindings etc written for the clock controller providing
that clock, the fixed-frequency clock could be swapped out for the real
one.

> PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> remember the common clock maintainers don't take pull requests with
> new features after -rc6 (which is in less than two weeks).
> So time is getting a bit short and for me this is the very last
> outstanding question. If you say that it's fine to add clocks later on
> this will immediately get my Reviewed-by.

I *think* that what I've just said should not get in the way of such a
timeline, as it would only involve a "small" change to the dt-binding,
but not require additional bindings or driver.

Cheers,
Conor.


[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-30  9:34           ` Conor Dooley
  0 siblings, 0 replies; 63+ messages in thread
From: Conor Dooley @ 2023-05-30  9:34 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: Dmitry Rokosov, krzysztof.kozlowski+dt, neil.armstrong, jbrunet,
	mturquette, sboyd, robh+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 5223 bytes --]

Yo,

On Mon, May 29, 2023 at 10:38:33PM +0200, Martin Blumenstingl wrote:
> On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> [...]
> > > This IP block has at least one additional input called "sys_pll_div16".
> > > My understanding is that the "sys_pll_div16" clock is generated by the
> > > CPU clock controller. Support for the CPU clock controller
> > > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > > How can we manage incrementally implementing the clock controllers?
> > > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > > How to manage this in the .dts patches then (for example: does this
> > > mean that Dmitry can only add the clock controller to the .dts when
> > > all clock controller bindings have been implemented - or is there
> > > another way)?
> >
> > You're absolutely right: currently, not all inputs are supported because
> > the CPU clock controller isn't ready yet – I'm working on it at the
> > moment.
> >
> > I understand your concerns about bindings and schema description, but
> > there is an issue to be considered. I'm developing the entire clock
> > controller A1 subsystem incrementally in three stages: peripherals and
> > PLL, CPU, and Audio. This is because the CPU can operate at a static
> > frequency and voltage, and the board boots normally without the CPU
> > clock controller, thermal sensor, and OPP table. Audio is also
> > important, but it's optional. On the other hand, without setting up the
> > peripherals and PLL controllers, the board won't function because
> > they're fundamental.
> I understand your approach and I like it (without that incremental
> approach you would probably be looking at a series with 15-20
> patches).
> 
> Maybe the dt-binding maintainers have a suggestion for us here?
> Let me try to summarize the issue in a few bullet points:
> - There's (at least) four clock controllers on the Amlogic A1 SoC
> - Some of these clock controllers take the outputs of another clock
> controller as inputs
> - In this series patch the peripheral clock controller has an input
> called "sys_pll_div16"
> - The clock controller which provides the "sys_pll_div16" clock is not
> implemented yet (my understanding is that implementing it and adding
> it to this series is not easy: it would add even more patches that
> need to be reviewed and in general it's a tricky clock controller to
> implement as it manages the CPU clocks)

If I am understanding correctly, this series implements the child
controller and a parent, which is unimplemented, provides the child with
sys_pll_div16.
The thing I am missing is whether the child controller has some outputs
that depend on this sys_pll_div16 input & whether those are documented
in this series. Regardless, you should be able to add more output clocks
without compatibility issues.

> > Right now, we're in the first stage of the plan. Unfortunately, I can't
> > disclose the exact names and number of clock bindings for the CPU and
> > Audio, as they're still in development and only exist in my head or
> > draft versions.
> >
> > If possible, I'd prefer to provide the new bindings and connections once
> > all the appropriate drivers are finalized.
> Question to Conor and Krzysztof (assuming you read my summary above):
> Is it fine that Dmitry adds additional inputs to the peripheral clock
> controller binding in later patches?

Perhaps Krzysztof will disagree with me, but my take on it would be that
the binding should describe the individual clock controller in its
totality, but the driver can choose to only implement a subset of it.

If you define the binding as only needing N inputs, but then later
expand it to having N+M inputs, the driver will have to support N & N+M
input clocks to preserve compatibility.
If you define it as needing N+M inputs from the beginning, but only use
N, there is no issue with backwards compatibility when you later use
them all.

> If not: how can we proceed in case we need to add them now (the
> dt-binding example is the easy part for me as we can just make up a
> phandle like &sys_pll_div16_clk and use that - but this can't work
> when Dmitry tries to add the clock controller to meson-a1.dtsi)

I would be inclined to do the same thing in the dts as the example,
and make up a fixed-frequency clock and use it to plug the hole.
When you have bindings etc written for the clock controller providing
that clock, the fixed-frequency clock could be swapped out for the real
one.

> PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> remember the common clock maintainers don't take pull requests with
> new features after -rc6 (which is in less than two weeks).
> So time is getting a bit short and for me this is the very last
> outstanding question. If you say that it's fine to add clocks later on
> this will immediately get my Reviewed-by.

I *think* that what I've just said should not get in the way of such a
timeline, as it would only involve a "small" change to the dt-binding,
but not require additional bindings or driver.

Cheers,
Conor.


[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 167 bytes --]

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
  2023-05-30  8:32         ` Jerome Brunet
  (?)
@ 2023-05-30 12:06           ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 12:06 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: Martin Blumenstingl, neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hello Jerome,

Thank you for the review!

On Tue, May 30, 2023 at 10:32:57AM +0200, Jerome Brunet wrote:
> 
> On Mon 22 May 2023 at 16:32, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> 
> > Hello Martin,
> >
> > Thank you so much for the review, I really appreciate it!
> > Please find my comments below.
> >
> > On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
> >> Hi Dmitry,
> >> 
> >> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> >> [...]
> >> > +static struct clk_regmap sys_b_sel = {
> >> > +       .data = &(struct clk_regmap_mux_data){
> >> > +               .offset = SYS_CLK_CTRL0,
> >> > +               .mask = 0x7,
> >> > +               .shift = 26,
> >> > +               .table = mux_table_sys,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "sys_b_sel",
> >> > +               .ops = &clk_regmap_mux_ro_ops,
> >> the sys_*_sel muxes and sys_*_gate are _ro...
> >> 
> >> > +               .parent_data = sys_parents,
> >> > +               .num_parents = ARRAY_SIZE(sys_parents),
> >> > +       },
> >> > +};
> >> > +
> >> > +static struct clk_regmap sys_b_div = {
> >> > +       .data = &(struct clk_regmap_div_data){
> >> > +               .offset = SYS_CLK_CTRL0,
> >> > +               .shift = 16,
> >> > +               .width = 10,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "sys_b_div",
> >> > +               .ops = &clk_regmap_divider_ops,
> >> ...but the sys_*_div aren't
> >> Is this on purpose? If it is: why can the divider be changed at
> >> runtime but the mux can't?
> >> 
> >
> > Ah, that's a good catch. Since the system clock is set up by the BootROM
> > code, all sys_* dividers and gates should be read-only. I'll make sure
> > to change that in the next version.
> >
> >> [...]
> >> > +/*
> >> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
> >> We need to add the "sys_pll_div16" input to the dt-bindings since they
> >> should always describe the hardware (regardless of what the driver
> >> implements currently).
> >> I'm not sure how to manage this while we don't have the CPU clock
> >> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
> >> here.
> >> 
> >
> > I've shared my thoughts about it in the bindings thread. Please take a
> > look.
> >
> >> > + * the index 4 is the clock measurement source, it's not supported yet
> >> I suspect that this comes from the clock measurer IP block and if so
> >> the dt-bindings should probably describe this input. But again, we'd
> >> need to keep it optional for now since our clock measurer driver
> >> doesn't even implement a clock controller.
> >> 
> >
> > Indeed, this is a similar situation to what we have with the inputs and
> > clocks of the CPU and Audio clock controllers. It seems like there is
> > only one option here: we should mark it with a TODO tag...
> >
> >> [...]
> >> > +static struct clk_regmap pwm_a_sel = {
> >> > +       .data = &(struct clk_regmap_mux_data){
> >> > +               .offset = PWM_CLK_AB_CTRL,
> >> > +               .mask = 0x1,
> >> > +               .shift = 9,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "pwm_a_sel",
> >> > +               .ops = &clk_regmap_mux_ops,
> >> > +               .parent_data = pwm_abcd_parents,
> >> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> >> > +               /* For more information, please refer to rtc clock */
> >> > +               .flags = CLK_SET_RATE_NO_REPARENT,
> >> As mentioned in [0] we'll work with Heiner to see if we can improve
> >> the decision making process of the PWM controller driver so that we
> >> can just have .flags = 0 here.
> >> This applies to all other occurrences of the same comment about the rtc clock.
> >
> > Sure, I'll make the change in v16. In my opinion, we should remove the
> > CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
> > including PWM, regardless of the outcome of the Heiner discussion. Based
> > on our IRC talk, the decision has more pros than cons -
> > https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18
> 
> The clock scheme of PWM could indeed be handled like audio is but it
> not strictly required.
> 
> In audio we have a limited number of PLLs (root sources). There is a lot
> more consummers than there is root sources. If the root sources rate is
> not carefully chosen to statisfy all needs, we could end in a situation
> where we can't satisfy all consummers or we must glitch the source to do
> so.
> 
> For the PWM, I think (but I'm not 100% sure) that the main clock controller
> provides a source for each PWM. No risk of race there. That is why AML
> decided to completly ignore the clock element in the PWM IP, because
> they can do almost everything with what is in the main controller ... Still
> ignoring those part is wrong
> 
> For the RTC, If you want/need to handle external RTCs, I don't think you
> have much of a choice. If both the internal and external *report* the
> same rate, CCF can't really know if one is best. It will just pick one,
> no necessarily the one you want. I don't really see a way around manual
> selection for this.
> 

Per my understading, the rtc32k Amlogic clock is an internal clock and
cannot be an external one. Amlogic has provided it as an internal 32k
stable clock with low jitter.

You're absolutely right that there is no data available to confirm the
choice of an external RTC clock in the CCF. However, as per the approach
we discussed with Martin and Heiner, we can still use the RTC clock as a
parent for PWM in the current implementation. If the parent clock
already has 32k, we do not change the rate from the PWM driver. The
benefit of this approach is that reparenting is still available, but the
PWM child cannot change the RTC frequency; it simply uses the
appropriate parent clock. Additionally, if the parent is already set to
rtc32k, we shouldn't change it.

-- 
Thank you,
Dmitry

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-30 12:06           ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 12:06 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: Martin Blumenstingl, neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hello Jerome,

Thank you for the review!

On Tue, May 30, 2023 at 10:32:57AM +0200, Jerome Brunet wrote:
> 
> On Mon 22 May 2023 at 16:32, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> 
> > Hello Martin,
> >
> > Thank you so much for the review, I really appreciate it!
> > Please find my comments below.
> >
> > On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
> >> Hi Dmitry,
> >> 
> >> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> >> [...]
> >> > +static struct clk_regmap sys_b_sel = {
> >> > +       .data = &(struct clk_regmap_mux_data){
> >> > +               .offset = SYS_CLK_CTRL0,
> >> > +               .mask = 0x7,
> >> > +               .shift = 26,
> >> > +               .table = mux_table_sys,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "sys_b_sel",
> >> > +               .ops = &clk_regmap_mux_ro_ops,
> >> the sys_*_sel muxes and sys_*_gate are _ro...
> >> 
> >> > +               .parent_data = sys_parents,
> >> > +               .num_parents = ARRAY_SIZE(sys_parents),
> >> > +       },
> >> > +};
> >> > +
> >> > +static struct clk_regmap sys_b_div = {
> >> > +       .data = &(struct clk_regmap_div_data){
> >> > +               .offset = SYS_CLK_CTRL0,
> >> > +               .shift = 16,
> >> > +               .width = 10,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "sys_b_div",
> >> > +               .ops = &clk_regmap_divider_ops,
> >> ...but the sys_*_div aren't
> >> Is this on purpose? If it is: why can the divider be changed at
> >> runtime but the mux can't?
> >> 
> >
> > Ah, that's a good catch. Since the system clock is set up by the BootROM
> > code, all sys_* dividers and gates should be read-only. I'll make sure
> > to change that in the next version.
> >
> >> [...]
> >> > +/*
> >> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
> >> We need to add the "sys_pll_div16" input to the dt-bindings since they
> >> should always describe the hardware (regardless of what the driver
> >> implements currently).
> >> I'm not sure how to manage this while we don't have the CPU clock
> >> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
> >> here.
> >> 
> >
> > I've shared my thoughts about it in the bindings thread. Please take a
> > look.
> >
> >> > + * the index 4 is the clock measurement source, it's not supported yet
> >> I suspect that this comes from the clock measurer IP block and if so
> >> the dt-bindings should probably describe this input. But again, we'd
> >> need to keep it optional for now since our clock measurer driver
> >> doesn't even implement a clock controller.
> >> 
> >
> > Indeed, this is a similar situation to what we have with the inputs and
> > clocks of the CPU and Audio clock controllers. It seems like there is
> > only one option here: we should mark it with a TODO tag...
> >
> >> [...]
> >> > +static struct clk_regmap pwm_a_sel = {
> >> > +       .data = &(struct clk_regmap_mux_data){
> >> > +               .offset = PWM_CLK_AB_CTRL,
> >> > +               .mask = 0x1,
> >> > +               .shift = 9,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "pwm_a_sel",
> >> > +               .ops = &clk_regmap_mux_ops,
> >> > +               .parent_data = pwm_abcd_parents,
> >> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> >> > +               /* For more information, please refer to rtc clock */
> >> > +               .flags = CLK_SET_RATE_NO_REPARENT,
> >> As mentioned in [0] we'll work with Heiner to see if we can improve
> >> the decision making process of the PWM controller driver so that we
> >> can just have .flags = 0 here.
> >> This applies to all other occurrences of the same comment about the rtc clock.
> >
> > Sure, I'll make the change in v16. In my opinion, we should remove the
> > CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
> > including PWM, regardless of the outcome of the Heiner discussion. Based
> > on our IRC talk, the decision has more pros than cons -
> > https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18
> 
> The clock scheme of PWM could indeed be handled like audio is but it
> not strictly required.
> 
> In audio we have a limited number of PLLs (root sources). There is a lot
> more consummers than there is root sources. If the root sources rate is
> not carefully chosen to statisfy all needs, we could end in a situation
> where we can't satisfy all consummers or we must glitch the source to do
> so.
> 
> For the PWM, I think (but I'm not 100% sure) that the main clock controller
> provides a source for each PWM. No risk of race there. That is why AML
> decided to completly ignore the clock element in the PWM IP, because
> they can do almost everything with what is in the main controller ... Still
> ignoring those part is wrong
> 
> For the RTC, If you want/need to handle external RTCs, I don't think you
> have much of a choice. If both the internal and external *report* the
> same rate, CCF can't really know if one is best. It will just pick one,
> no necessarily the one you want. I don't really see a way around manual
> selection for this.
> 

Per my understading, the rtc32k Amlogic clock is an internal clock and
cannot be an external one. Amlogic has provided it as an internal 32k
stable clock with low jitter.

You're absolutely right that there is no data available to confirm the
choice of an external RTC clock in the CCF. However, as per the approach
we discussed with Martin and Heiner, we can still use the RTC clock as a
parent for PWM in the current implementation. If the parent clock
already has 32k, we do not change the rate from the PWM driver. The
benefit of this approach is that reparenting is still available, but the
PWM child cannot change the RTC frequency; it simply uses the
appropriate parent clock. Additionally, if the parent is already set to
rtc32k, we shouldn't change it.

-- 
Thank you,
Dmitry

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver
@ 2023-05-30 12:06           ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 12:06 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: Martin Blumenstingl, neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hello Jerome,

Thank you for the review!

On Tue, May 30, 2023 at 10:32:57AM +0200, Jerome Brunet wrote:
> 
> On Mon 22 May 2023 at 16:32, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> 
> > Hello Martin,
> >
> > Thank you so much for the review, I really appreciate it!
> > Please find my comments below.
> >
> > On Fri, May 19, 2023 at 11:03:54PM +0200, Martin Blumenstingl wrote:
> >> Hi Dmitry,
> >> 
> >> On Wed, May 17, 2023 at 3:33 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> >> [...]
> >> > +static struct clk_regmap sys_b_sel = {
> >> > +       .data = &(struct clk_regmap_mux_data){
> >> > +               .offset = SYS_CLK_CTRL0,
> >> > +               .mask = 0x7,
> >> > +               .shift = 26,
> >> > +               .table = mux_table_sys,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "sys_b_sel",
> >> > +               .ops = &clk_regmap_mux_ro_ops,
> >> the sys_*_sel muxes and sys_*_gate are _ro...
> >> 
> >> > +               .parent_data = sys_parents,
> >> > +               .num_parents = ARRAY_SIZE(sys_parents),
> >> > +       },
> >> > +};
> >> > +
> >> > +static struct clk_regmap sys_b_div = {
> >> > +       .data = &(struct clk_regmap_div_data){
> >> > +               .offset = SYS_CLK_CTRL0,
> >> > +               .shift = 16,
> >> > +               .width = 10,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "sys_b_div",
> >> > +               .ops = &clk_regmap_divider_ops,
> >> ...but the sys_*_div aren't
> >> Is this on purpose? If it is: why can the divider be changed at
> >> runtime but the mux can't?
> >> 
> >
> > Ah, that's a good catch. Since the system clock is set up by the BootROM
> > code, all sys_* dividers and gates should be read-only. I'll make sure
> > to change that in the next version.
> >
> >> [...]
> >> > +/*
> >> > + * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver,
> >> We need to add the "sys_pll_div16" input to the dt-bindings since they
> >> should always describe the hardware (regardless of what the driver
> >> implements currently).
> >> I'm not sure how to manage this while we don't have the CPU clock
> >> driver ready yet but I'm sure Rob or Krzysztof will be able to help us
> >> here.
> >> 
> >
> > I've shared my thoughts about it in the bindings thread. Please take a
> > look.
> >
> >> > + * the index 4 is the clock measurement source, it's not supported yet
> >> I suspect that this comes from the clock measurer IP block and if so
> >> the dt-bindings should probably describe this input. But again, we'd
> >> need to keep it optional for now since our clock measurer driver
> >> doesn't even implement a clock controller.
> >> 
> >
> > Indeed, this is a similar situation to what we have with the inputs and
> > clocks of the CPU and Audio clock controllers. It seems like there is
> > only one option here: we should mark it with a TODO tag...
> >
> >> [...]
> >> > +static struct clk_regmap pwm_a_sel = {
> >> > +       .data = &(struct clk_regmap_mux_data){
> >> > +               .offset = PWM_CLK_AB_CTRL,
> >> > +               .mask = 0x1,
> >> > +               .shift = 9,
> >> > +       },
> >> > +       .hw.init = &(struct clk_init_data){
> >> > +               .name = "pwm_a_sel",
> >> > +               .ops = &clk_regmap_mux_ops,
> >> > +               .parent_data = pwm_abcd_parents,
> >> > +               .num_parents = ARRAY_SIZE(pwm_abcd_parents),
> >> > +               /* For more information, please refer to rtc clock */
> >> > +               .flags = CLK_SET_RATE_NO_REPARENT,
> >> As mentioned in [0] we'll work with Heiner to see if we can improve
> >> the decision making process of the PWM controller driver so that we
> >> can just have .flags = 0 here.
> >> This applies to all other occurrences of the same comment about the rtc clock.
> >
> > Sure, I'll make the change in v16. In my opinion, we should remove the
> > CLK_SET_RATE_NO_REPARENT flag from all RTC related clock objects,
> > including PWM, regardless of the outcome of the Heiner discussion. Based
> > on our IRC talk, the decision has more pros than cons -
> > https://libera.irclog.whitequark.org/linux-amlogic/2023-05-18
> 
> The clock scheme of PWM could indeed be handled like audio is but it
> not strictly required.
> 
> In audio we have a limited number of PLLs (root sources). There is a lot
> more consummers than there is root sources. If the root sources rate is
> not carefully chosen to statisfy all needs, we could end in a situation
> where we can't satisfy all consummers or we must glitch the source to do
> so.
> 
> For the PWM, I think (but I'm not 100% sure) that the main clock controller
> provides a source for each PWM. No risk of race there. That is why AML
> decided to completly ignore the clock element in the PWM IP, because
> they can do almost everything with what is in the main controller ... Still
> ignoring those part is wrong
> 
> For the RTC, If you want/need to handle external RTCs, I don't think you
> have much of a choice. If both the internal and external *report* the
> same rate, CCF can't really know if one is best. It will just pick one,
> no necessarily the one you want. I don't really see a way around manual
> selection for this.
> 

Per my understading, the rtc32k Amlogic clock is an internal clock and
cannot be an external one. Amlogic has provided it as an internal 32k
stable clock with low jitter.

You're absolutely right that there is no data available to confirm the
choice of an external RTC clock in the CCF. However, as per the approach
we discussed with Martin and Heiner, we can still use the RTC clock as a
parent for PWM in the current implementation. If the parent clock
already has 32k, we do not change the rate from the PWM driver. The
benefit of this approach is that reparenting is still available, but the
PWM child cannot change the RTC frequency; it simply uses the
appropriate parent clock. Additionally, if the parent is already set to
rtc32k, we shouldn't change it.

-- 
Thank you,
Dmitry

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
  2023-05-30  9:34           ` Conor Dooley
  (?)
@ 2023-05-30 16:03             ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 16:03 UTC (permalink / raw)
  To: Conor Dooley, Martin Blumenstingl, jbrunet
  Cc: krzysztof.kozlowski+dt, neil.armstrong, mturquette, sboyd,
	robh+dt, khilman, jian.hu, kernel, rockosov, linux-amlogic,
	linux-clk, devicetree, linux-kernel, linux-arm-kernel

Hello Conor, Martin and Jerome,

Thank you so much for the detailed information and thoughts you shared
about the important process of changing DT bindings. Please find my
comments below.

On Tue, May 30, 2023 at 10:34:07AM +0100, Conor Dooley wrote:
> Yo,
> 
> On Mon, May 29, 2023 at 10:38:33PM +0200, Martin Blumenstingl wrote:
> > On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> > [...]
> > > > This IP block has at least one additional input called "sys_pll_div16".
> > > > My understanding is that the "sys_pll_div16" clock is generated by the
> > > > CPU clock controller. Support for the CPU clock controller
> > > > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > > > How can we manage incrementally implementing the clock controllers?
> > > > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > > > How to manage this in the .dts patches then (for example: does this
> > > > mean that Dmitry can only add the clock controller to the .dts when
> > > > all clock controller bindings have been implemented - or is there
> > > > another way)?
> > >
> > > You're absolutely right: currently, not all inputs are supported because
> > > the CPU clock controller isn't ready yet – I'm working on it at the
> > > moment.
> > >
> > > I understand your concerns about bindings and schema description, but
> > > there is an issue to be considered. I'm developing the entire clock
> > > controller A1 subsystem incrementally in three stages: peripherals and
> > > PLL, CPU, and Audio. This is because the CPU can operate at a static
> > > frequency and voltage, and the board boots normally without the CPU
> > > clock controller, thermal sensor, and OPP table. Audio is also
> > > important, but it's optional. On the other hand, without setting up the
> > > peripherals and PLL controllers, the board won't function because
> > > they're fundamental.
> > I understand your approach and I like it (without that incremental
> > approach you would probably be looking at a series with 15-20
> > patches).
> > 
> > Maybe the dt-binding maintainers have a suggestion for us here?
> > Let me try to summarize the issue in a few bullet points:
> > - There's (at least) four clock controllers on the Amlogic A1 SoC
> > - Some of these clock controllers take the outputs of another clock
> > controller as inputs
> > - In this series patch the peripheral clock controller has an input
> > called "sys_pll_div16"
> > - The clock controller which provides the "sys_pll_div16" clock is not
> > implemented yet (my understanding is that implementing it and adding
> > it to this series is not easy: it would add even more patches that
> > need to be reviewed and in general it's a tricky clock controller to
> > implement as it manages the CPU clocks)
> 
> If I am understanding correctly, this series implements the child
> controller and a parent, which is unimplemented, provides the child with
> sys_pll_div16.
> The thing I am missing is whether the child controller has some outputs
> that depend on this sys_pll_div16 input & whether those are documented
> in this series. Regardless, you should be able to add more output clocks
> without compatibility issues.
> 
> > > Right now, we're in the first stage of the plan. Unfortunately, I can't
> > > disclose the exact names and number of clock bindings for the CPU and
> > > Audio, as they're still in development and only exist in my head or
> > > draft versions.
> > >
> > > If possible, I'd prefer to provide the new bindings and connections once
> > > all the appropriate drivers are finalized.
> > Question to Conor and Krzysztof (assuming you read my summary above):
> > Is it fine that Dmitry adds additional inputs to the peripheral clock
> > controller binding in later patches?
> 
> Perhaps Krzysztof will disagree with me, but my take on it would be that
> the binding should describe the individual clock controller in its
> totality, but the driver can choose to only implement a subset of it.
> 
> If you define the binding as only needing N inputs, but then later
> expand it to having N+M inputs, the driver will have to support N & N+M
> input clocks to preserve compatibility.
> If you define it as needing N+M inputs from the beginning, but only use
> N, there is no issue with backwards compatibility when you later use
> them all.
> 

In short, I agree with Jerome's position, which he shared in the
parallel email:
https://lore.kernel.org/all/1jmt1m42m1.fsf@starbuckisacylon.baylibre.com/

Below I will try to explain my position.

Please correct me if I am mistaken, but it appears we are currently
discussing a scenario where a new kernel X+1 image version is flashed
onto a device with a device tree from kernel X-1 image version, and
whether a new driver with clock object connections can function on the
previous Device Tree version.

If I'm grasping the issue correctly, it seems that we have four
potential scenarios at play here:
1) we may have altered the relationships between internal clock objects;
2) we may have introduced new output clock connections;
3) we may have introduced new input clock connections;
4) we may have removed existing connections from the driver.

It seems that options 1 and 4 are straightforward and easy to
understand.
The 4 case is fully prohibited. We cannot remove
any object or connection from the clock driver if another consumer uses
it in the previous Device Tree versions. It is also important to note
that any internal changes within the driver do not affect the device
tree connections, as this is already clear.

The second and third cases are more complex.

For instance, let's say we are preparing a new patchset for an existing
clock driver, such as Peripherals, where we are adding an Audio clock
that is handled by an MMIO register inside Peripherals clock driver. X-1
dts does not recognize this new clock and doesn't have any connection to
any node or to any other clock driver, thereby eliminating any backwards
compatibility issues.

As for new input clock connections, such as the cpu_clock
(sys_pll_div16), these are handled by clock muxing abstraction, allowing
CCF to find the clock object by fw.name and returning -ENOENT if the
connection is missing without breaking any CCF flow. It happens in the
kernel function clk_core_fill_parent_index()
https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L424
Despite not having the connection for the new input in the old Device
Tree version, this will not break kernel boot flow and workflow, and the
new clock object just would not be utilized.

Based on the presented arguments, I fully agree with Jerome's position.
We can add new connections and objects in new driver versions, but their
removal is prohibited.

If it's alright with you, I would prefer to keep the Peripherals and PLL
clock driver and their bindings as they are, and continue with the CPU
and Audio clock controllers in a separate patch series. Would that be
feasible for you?

> > If not: how can we proceed in case we need to add them now (the
> > dt-binding example is the easy part for me as we can just make up a
> > phandle like &sys_pll_div16_clk and use that - but this can't work
> > when Dmitry tries to add the clock controller to meson-a1.dtsi)
> 
> I would be inclined to do the same thing in the dts as the example,
> and make up a fixed-frequency clock and use it to plug the hole.
> When you have bindings etc written for the clock controller providing
> that clock, the fixed-frequency clock could be swapped out for the real
> one.
> 
> > PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> > remember the common clock maintainers don't take pull requests with
> > new features after -rc6 (which is in less than two weeks).
> > So time is getting a bit short and for me this is the very last
> > outstanding question. If you say that it's fine to add clocks later on
> > this will immediately get my Reviewed-by.
> 
> I *think* that what I've just said should not get in the way of such a
> timeline, as it would only involve a "small" change to the dt-binding,
> but not require additional bindings or driver.
> 
> Cheers,
> Conor.
> 

-- 
Thank you,
Dmitry

УВЕДОМЛЕНИЕ О КОНФИДЕНЦИАЛЬНОСТИ: Это электронное сообщение и любые документы, приложенные к нему, содержат конфиденциальную информацию. Настоящим уведомляем Вас о том, что если это сообщение не предназначено Вам, использование, копирование, распространение информации, содержащейся в настоящем сообщении, а также осуществление любых действий на основе этой информации, строго запрещено. Если Вы получили это сообщение по ошибке, пожалуйста, сообщите об этом отправителю по электронной почте и удалите это сообщение.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-30 16:03             ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 16:03 UTC (permalink / raw)
  To: Conor Dooley, Martin Blumenstingl, jbrunet
  Cc: krzysztof.kozlowski+dt, neil.armstrong, mturquette, sboyd,
	robh+dt, khilman, jian.hu, kernel, rockosov, linux-amlogic,
	linux-clk, devicetree, linux-kernel, linux-arm-kernel

Hello Conor, Martin and Jerome,

Thank you so much for the detailed information and thoughts you shared
about the important process of changing DT bindings. Please find my
comments below.

On Tue, May 30, 2023 at 10:34:07AM +0100, Conor Dooley wrote:
> Yo,
> 
> On Mon, May 29, 2023 at 10:38:33PM +0200, Martin Blumenstingl wrote:
> > On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> > [...]
> > > > This IP block has at least one additional input called "sys_pll_div16".
> > > > My understanding is that the "sys_pll_div16" clock is generated by the
> > > > CPU clock controller. Support for the CPU clock controller
> > > > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > > > How can we manage incrementally implementing the clock controllers?
> > > > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > > > How to manage this in the .dts patches then (for example: does this
> > > > mean that Dmitry can only add the clock controller to the .dts when
> > > > all clock controller bindings have been implemented - or is there
> > > > another way)?
> > >
> > > You're absolutely right: currently, not all inputs are supported because
> > > the CPU clock controller isn't ready yet – I'm working on it at the
> > > moment.
> > >
> > > I understand your concerns about bindings and schema description, but
> > > there is an issue to be considered. I'm developing the entire clock
> > > controller A1 subsystem incrementally in three stages: peripherals and
> > > PLL, CPU, and Audio. This is because the CPU can operate at a static
> > > frequency and voltage, and the board boots normally without the CPU
> > > clock controller, thermal sensor, and OPP table. Audio is also
> > > important, but it's optional. On the other hand, without setting up the
> > > peripherals and PLL controllers, the board won't function because
> > > they're fundamental.
> > I understand your approach and I like it (without that incremental
> > approach you would probably be looking at a series with 15-20
> > patches).
> > 
> > Maybe the dt-binding maintainers have a suggestion for us here?
> > Let me try to summarize the issue in a few bullet points:
> > - There's (at least) four clock controllers on the Amlogic A1 SoC
> > - Some of these clock controllers take the outputs of another clock
> > controller as inputs
> > - In this series patch the peripheral clock controller has an input
> > called "sys_pll_div16"
> > - The clock controller which provides the "sys_pll_div16" clock is not
> > implemented yet (my understanding is that implementing it and adding
> > it to this series is not easy: it would add even more patches that
> > need to be reviewed and in general it's a tricky clock controller to
> > implement as it manages the CPU clocks)
> 
> If I am understanding correctly, this series implements the child
> controller and a parent, which is unimplemented, provides the child with
> sys_pll_div16.
> The thing I am missing is whether the child controller has some outputs
> that depend on this sys_pll_div16 input & whether those are documented
> in this series. Regardless, you should be able to add more output clocks
> without compatibility issues.
> 
> > > Right now, we're in the first stage of the plan. Unfortunately, I can't
> > > disclose the exact names and number of clock bindings for the CPU and
> > > Audio, as they're still in development and only exist in my head or
> > > draft versions.
> > >
> > > If possible, I'd prefer to provide the new bindings and connections once
> > > all the appropriate drivers are finalized.
> > Question to Conor and Krzysztof (assuming you read my summary above):
> > Is it fine that Dmitry adds additional inputs to the peripheral clock
> > controller binding in later patches?
> 
> Perhaps Krzysztof will disagree with me, but my take on it would be that
> the binding should describe the individual clock controller in its
> totality, but the driver can choose to only implement a subset of it.
> 
> If you define the binding as only needing N inputs, but then later
> expand it to having N+M inputs, the driver will have to support N & N+M
> input clocks to preserve compatibility.
> If you define it as needing N+M inputs from the beginning, but only use
> N, there is no issue with backwards compatibility when you later use
> them all.
> 

In short, I agree with Jerome's position, which he shared in the
parallel email:
https://lore.kernel.org/all/1jmt1m42m1.fsf@starbuckisacylon.baylibre.com/

Below I will try to explain my position.

Please correct me if I am mistaken, but it appears we are currently
discussing a scenario where a new kernel X+1 image version is flashed
onto a device with a device tree from kernel X-1 image version, and
whether a new driver with clock object connections can function on the
previous Device Tree version.

If I'm grasping the issue correctly, it seems that we have four
potential scenarios at play here:
1) we may have altered the relationships between internal clock objects;
2) we may have introduced new output clock connections;
3) we may have introduced new input clock connections;
4) we may have removed existing connections from the driver.

It seems that options 1 and 4 are straightforward and easy to
understand.
The 4 case is fully prohibited. We cannot remove
any object or connection from the clock driver if another consumer uses
it in the previous Device Tree versions. It is also important to note
that any internal changes within the driver do not affect the device
tree connections, as this is already clear.

The second and third cases are more complex.

For instance, let's say we are preparing a new patchset for an existing
clock driver, such as Peripherals, where we are adding an Audio clock
that is handled by an MMIO register inside Peripherals clock driver. X-1
dts does not recognize this new clock and doesn't have any connection to
any node or to any other clock driver, thereby eliminating any backwards
compatibility issues.

As for new input clock connections, such as the cpu_clock
(sys_pll_div16), these are handled by clock muxing abstraction, allowing
CCF to find the clock object by fw.name and returning -ENOENT if the
connection is missing without breaking any CCF flow. It happens in the
kernel function clk_core_fill_parent_index()
https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L424
Despite not having the connection for the new input in the old Device
Tree version, this will not break kernel boot flow and workflow, and the
new clock object just would not be utilized.

Based on the presented arguments, I fully agree with Jerome's position.
We can add new connections and objects in new driver versions, but their
removal is prohibited.

If it's alright with you, I would prefer to keep the Peripherals and PLL
clock driver and their bindings as they are, and continue with the CPU
and Audio clock controllers in a separate patch series. Would that be
feasible for you?

> > If not: how can we proceed in case we need to add them now (the
> > dt-binding example is the easy part for me as we can just make up a
> > phandle like &sys_pll_div16_clk and use that - but this can't work
> > when Dmitry tries to add the clock controller to meson-a1.dtsi)
> 
> I would be inclined to do the same thing in the dts as the example,
> and make up a fixed-frequency clock and use it to plug the hole.
> When you have bindings etc written for the clock controller providing
> that clock, the fixed-frequency clock could be swapped out for the real
> one.
> 
> > PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> > remember the common clock maintainers don't take pull requests with
> > new features after -rc6 (which is in less than two weeks).
> > So time is getting a bit short and for me this is the very last
> > outstanding question. If you say that it's fine to add clocks later on
> > this will immediately get my Reviewed-by.
> 
> I *think* that what I've just said should not get in the way of such a
> timeline, as it would only involve a "small" change to the dt-binding,
> but not require additional bindings or driver.
> 
> Cheers,
> Conor.
> 

-- 
Thank you,
Dmitry

УВЕДОМЛЕНИЕ О КОНФИДЕНЦИАЛЬНОСТИ: Это электронное сообщение и любые документы, приложенные к нему, содержат конфиденциальную информацию. Настоящим уведомляем Вас о том, что если это сообщение не предназначено Вам, использование, копирование, распространение информации, содержащейся в настоящем сообщении, а также осуществление любых действий на основе этой информации, строго запрещено. Если Вы получили это сообщение по ошибке, пожалуйста, сообщите об этом отправителю по электронной почте и удалите это сообщение.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-30 16:03             ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 16:03 UTC (permalink / raw)
  To: Conor Dooley, Martin Blumenstingl, jbrunet
  Cc: krzysztof.kozlowski+dt, neil.armstrong, mturquette, sboyd,
	robh+dt, khilman, jian.hu, kernel, rockosov, linux-amlogic,
	linux-clk, devicetree, linux-kernel, linux-arm-kernel

Hello Conor, Martin and Jerome,

Thank you so much for the detailed information and thoughts you shared
about the important process of changing DT bindings. Please find my
comments below.

On Tue, May 30, 2023 at 10:34:07AM +0100, Conor Dooley wrote:
> Yo,
> 
> On Mon, May 29, 2023 at 10:38:33PM +0200, Martin Blumenstingl wrote:
> > On Mon, May 22, 2023 at 3:00 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> > [...]
> > > > This IP block has at least one additional input called "sys_pll_div16".
> > > > My understanding is that the "sys_pll_div16" clock is generated by the
> > > > CPU clock controller. Support for the CPU clock controller
> > > > (dt-bindings and a driver) will be added at a later time by Dmitry.
> > > > How can we manage incrementally implementing the clock controllers?
> > > > From a hardware perspective the "sys_pll_div16" input is mandatory.
> > > > How to manage this in the .dts patches then (for example: does this
> > > > mean that Dmitry can only add the clock controller to the .dts when
> > > > all clock controller bindings have been implemented - or is there
> > > > another way)?
> > >
> > > You're absolutely right: currently, not all inputs are supported because
> > > the CPU clock controller isn't ready yet – I'm working on it at the
> > > moment.
> > >
> > > I understand your concerns about bindings and schema description, but
> > > there is an issue to be considered. I'm developing the entire clock
> > > controller A1 subsystem incrementally in three stages: peripherals and
> > > PLL, CPU, and Audio. This is because the CPU can operate at a static
> > > frequency and voltage, and the board boots normally without the CPU
> > > clock controller, thermal sensor, and OPP table. Audio is also
> > > important, but it's optional. On the other hand, without setting up the
> > > peripherals and PLL controllers, the board won't function because
> > > they're fundamental.
> > I understand your approach and I like it (without that incremental
> > approach you would probably be looking at a series with 15-20
> > patches).
> > 
> > Maybe the dt-binding maintainers have a suggestion for us here?
> > Let me try to summarize the issue in a few bullet points:
> > - There's (at least) four clock controllers on the Amlogic A1 SoC
> > - Some of these clock controllers take the outputs of another clock
> > controller as inputs
> > - In this series patch the peripheral clock controller has an input
> > called "sys_pll_div16"
> > - The clock controller which provides the "sys_pll_div16" clock is not
> > implemented yet (my understanding is that implementing it and adding
> > it to this series is not easy: it would add even more patches that
> > need to be reviewed and in general it's a tricky clock controller to
> > implement as it manages the CPU clocks)
> 
> If I am understanding correctly, this series implements the child
> controller and a parent, which is unimplemented, provides the child with
> sys_pll_div16.
> The thing I am missing is whether the child controller has some outputs
> that depend on this sys_pll_div16 input & whether those are documented
> in this series. Regardless, you should be able to add more output clocks
> without compatibility issues.
> 
> > > Right now, we're in the first stage of the plan. Unfortunately, I can't
> > > disclose the exact names and number of clock bindings for the CPU and
> > > Audio, as they're still in development and only exist in my head or
> > > draft versions.
> > >
> > > If possible, I'd prefer to provide the new bindings and connections once
> > > all the appropriate drivers are finalized.
> > Question to Conor and Krzysztof (assuming you read my summary above):
> > Is it fine that Dmitry adds additional inputs to the peripheral clock
> > controller binding in later patches?
> 
> Perhaps Krzysztof will disagree with me, but my take on it would be that
> the binding should describe the individual clock controller in its
> totality, but the driver can choose to only implement a subset of it.
> 
> If you define the binding as only needing N inputs, but then later
> expand it to having N+M inputs, the driver will have to support N & N+M
> input clocks to preserve compatibility.
> If you define it as needing N+M inputs from the beginning, but only use
> N, there is no issue with backwards compatibility when you later use
> them all.
> 

In short, I agree with Jerome's position, which he shared in the
parallel email:
https://lore.kernel.org/all/1jmt1m42m1.fsf@starbuckisacylon.baylibre.com/

Below I will try to explain my position.

Please correct me if I am mistaken, but it appears we are currently
discussing a scenario where a new kernel X+1 image version is flashed
onto a device with a device tree from kernel X-1 image version, and
whether a new driver with clock object connections can function on the
previous Device Tree version.

If I'm grasping the issue correctly, it seems that we have four
potential scenarios at play here:
1) we may have altered the relationships between internal clock objects;
2) we may have introduced new output clock connections;
3) we may have introduced new input clock connections;
4) we may have removed existing connections from the driver.

It seems that options 1 and 4 are straightforward and easy to
understand.
The 4 case is fully prohibited. We cannot remove
any object or connection from the clock driver if another consumer uses
it in the previous Device Tree versions. It is also important to note
that any internal changes within the driver do not affect the device
tree connections, as this is already clear.

The second and third cases are more complex.

For instance, let's say we are preparing a new patchset for an existing
clock driver, such as Peripherals, where we are adding an Audio clock
that is handled by an MMIO register inside Peripherals clock driver. X-1
dts does not recognize this new clock and doesn't have any connection to
any node or to any other clock driver, thereby eliminating any backwards
compatibility issues.

As for new input clock connections, such as the cpu_clock
(sys_pll_div16), these are handled by clock muxing abstraction, allowing
CCF to find the clock object by fw.name and returning -ENOENT if the
connection is missing without breaking any CCF flow. It happens in the
kernel function clk_core_fill_parent_index()
https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L424
Despite not having the connection for the new input in the old Device
Tree version, this will not break kernel boot flow and workflow, and the
new clock object just would not be utilized.

Based on the presented arguments, I fully agree with Jerome's position.
We can add new connections and objects in new driver versions, but their
removal is prohibited.

If it's alright with you, I would prefer to keep the Peripherals and PLL
clock driver and their bindings as they are, and continue with the CPU
and Audio clock controllers in a separate patch series. Would that be
feasible for you?

> > If not: how can we proceed in case we need to add them now (the
> > dt-binding example is the easy part for me as we can just make up a
> > phandle like &sys_pll_div16_clk and use that - but this can't work
> > when Dmitry tries to add the clock controller to meson-a1.dtsi)
> 
> I would be inclined to do the same thing in the dts as the example,
> and make up a fixed-frequency clock and use it to plug the hole.
> When you have bindings etc written for the clock controller providing
> that clock, the fixed-frequency clock could be swapped out for the real
> one.
> 
> > PS: Dmitry is trying to get this series into Linux 6.5. As far as I
> > remember the common clock maintainers don't take pull requests with
> > new features after -rc6 (which is in less than two weeks).
> > So time is getting a bit short and for me this is the very last
> > outstanding question. If you say that it's fine to add clocks later on
> > this will immediately get my Reviewed-by.
> 
> I *think* that what I've just said should not get in the way of such a
> timeline, as it would only involve a "small" change to the dt-binding,
> but not require additional bindings or driver.
> 
> Cheers,
> Conor.
> 

-- 
Thank you,
Dmitry

УВЕДОМЛЕНИЕ О КОНФИДЕНЦИАЛЬНОСТИ: Это электронное сообщение и любые документы, приложенные к нему, содержат конфиденциальную информацию. Настоящим уведомляем Вас о том, что если это сообщение не предназначено Вам, использование, копирование, распространение информации, содержащейся в настоящем сообщении, а также осуществление любых действий на основе этой информации, строго запрещено. Если Вы получили это сообщение по ошибке, пожалуйста, сообщите об этом отправителю по электронной почте и удалите это сообщение.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
  2023-05-17 13:33 ` Dmitry Rokosov
  (?)
@ 2023-05-30 16:14   ` Jerome Brunet
  -1 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30 16:14 UTC (permalink / raw)
  To: Dmitry Rokosov, neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel


On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:

> A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> and Audio. The audio clock controller is different from others, but the
> rest are very similar from a functional and regmap point of view.
> This patch series add support for Amlogic A1 PLL and Peripherals clock
> drivers.
> It blocks all A1 peripherals mainline support and a couple of patch series,
> which were already reviewed and acked, but weren't merged due to pending
> clock controller drivers series, e.g.
> https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
>
> TODO: CPU and Audio clock controllers are not included in this patch
> series, it will be sent later. The following clks from these controllers
> are not supported for now:
> * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
>    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
>    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
>    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
>    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
>    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
>    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
>
> * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
>             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
>
> Validation:
> * to double check all clk flags run below helper script:
>     pushd /sys/kernel/debug/clk
>     for f in *; do
>         if [[ -f "$f/clk_flags" ]]; then
>             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
>             echo -e "$f: $flags"
>         fi
>     done
>     popd
>
> * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
>   with jq post-processing:
>     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
>
> * to debug clk rate propagation, compile kernel with the following
>   definition:
>     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
>   after that, clk_rate debug node for each clock will be available for
>   write operation
>

Applied, Thx

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-30 16:14   ` Jerome Brunet
  0 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30 16:14 UTC (permalink / raw)
  To: Dmitry Rokosov, neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel


On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:

> A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> and Audio. The audio clock controller is different from others, but the
> rest are very similar from a functional and regmap point of view.
> This patch series add support for Amlogic A1 PLL and Peripherals clock
> drivers.
> It blocks all A1 peripherals mainline support and a couple of patch series,
> which were already reviewed and acked, but weren't merged due to pending
> clock controller drivers series, e.g.
> https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
>
> TODO: CPU and Audio clock controllers are not included in this patch
> series, it will be sent later. The following clks from these controllers
> are not supported for now:
> * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
>    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
>    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
>    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
>    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
>    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
>    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
>
> * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
>             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
>
> Validation:
> * to double check all clk flags run below helper script:
>     pushd /sys/kernel/debug/clk
>     for f in *; do
>         if [[ -f "$f/clk_flags" ]]; then
>             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
>             echo -e "$f: $flags"
>         fi
>     done
>     popd
>
> * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
>   with jq post-processing:
>     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
>
> * to debug clk rate propagation, compile kernel with the following
>   definition:
>     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
>   after that, clk_rate debug node for each clock will be available for
>   write operation
>

Applied, Thx

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-30 16:14   ` Jerome Brunet
  0 siblings, 0 replies; 63+ messages in thread
From: Jerome Brunet @ 2023-05-30 16:14 UTC (permalink / raw)
  To: Dmitry Rokosov, neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl
  Cc: jian.hu, kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel


On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:

> A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> and Audio. The audio clock controller is different from others, but the
> rest are very similar from a functional and regmap point of view.
> This patch series add support for Amlogic A1 PLL and Peripherals clock
> drivers.
> It blocks all A1 peripherals mainline support and a couple of patch series,
> which were already reviewed and acked, but weren't merged due to pending
> clock controller drivers series, e.g.
> https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
>
> TODO: CPU and Audio clock controllers are not included in this patch
> series, it will be sent later. The following clks from these controllers
> are not supported for now:
> * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
>    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
>    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
>    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
>    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
>    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
>    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
>
> * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
>             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
>
> Validation:
> * to double check all clk flags run below helper script:
>     pushd /sys/kernel/debug/clk
>     for f in *; do
>         if [[ -f "$f/clk_flags" ]]; then
>             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
>             echo -e "$f: $flags"
>         fi
>     done
>     popd
>
> * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
>   with jq post-processing:
>     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
>
> * to debug clk rate propagation, compile kernel with the following
>   definition:
>     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
>   after that, clk_rate debug node for each clock will be available for
>   write operation
>

Applied, Thx

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
  2023-05-30 16:14   ` Jerome Brunet
  (?)
@ 2023-05-30 16:49     ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 16:49 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Jerome,

On Tue, May 30, 2023 at 06:14:01PM +0200, Jerome Brunet wrote:
> On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> 
> > A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> > and Audio. The audio clock controller is different from others, but the
> > rest are very similar from a functional and regmap point of view.
> > This patch series add support for Amlogic A1 PLL and Peripherals clock
> > drivers.
> > It blocks all A1 peripherals mainline support and a couple of patch series,
> > which were already reviewed and acked, but weren't merged due to pending
> > clock controller drivers series, e.g.
> > https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
> >
> > TODO: CPU and Audio clock controllers are not included in this patch
> > series, it will be sent later. The following clks from these controllers
> > are not supported for now:
> > * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
> >    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
> >    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
> >    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
> >    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
> >    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
> >    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
> >
> > * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
> >             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
> >
> > Validation:
> > * to double check all clk flags run below helper script:
> >     pushd /sys/kernel/debug/clk
> >     for f in *; do
> >         if [[ -f "$f/clk_flags" ]]; then
> >             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
> >             echo -e "$f: $flags"
> >         fi
> >     done
> >     popd
> >
> > * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
> >   with jq post-processing:
> >     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
> >
> > * to debug clk rate propagation, compile kernel with the following
> >   definition:
> >     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
> >   after that, clk_rate debug node for each clock will be available for
> >   write operation
> >
> 
> Applied, Thx

Thank you very much!

I noticed that you have applied version 15 of the patch. If I understand
correctly, this is because CLK_SET_RATE_NO_REPARENT for all RTC children
is preferred from your perspective. I agree with this decision. However,
version 16 includes a small refactoring patch that corrects a
misstyping by changing all sys_* related dividers and gates to
read-only operations, since they are set up from BootROM. Should I
submit this patch separately at a later time?

Also could you please clarify the official process for handling these
patches? Currently, I don't see them in the linux-amlogic for-next
branches. Is there a separate repository for clock changes? I believe
the next repository is a fork of the clock framework, but unfortunately,
I cannot seem to locate it on git.kernel.org... Apologies for the
potentially simple questions...

-- 
Thank you,
Dmitry

\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a: \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a \x1a\x1a\x1a, \x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-30 16:49     ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 16:49 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Jerome,

On Tue, May 30, 2023 at 06:14:01PM +0200, Jerome Brunet wrote:
> On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> 
> > A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> > and Audio. The audio clock controller is different from others, but the
> > rest are very similar from a functional and regmap point of view.
> > This patch series add support for Amlogic A1 PLL and Peripherals clock
> > drivers.
> > It blocks all A1 peripherals mainline support and a couple of patch series,
> > which were already reviewed and acked, but weren't merged due to pending
> > clock controller drivers series, e.g.
> > https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
> >
> > TODO: CPU and Audio clock controllers are not included in this patch
> > series, it will be sent later. The following clks from these controllers
> > are not supported for now:
> > * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
> >    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
> >    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
> >    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
> >    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
> >    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
> >    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
> >
> > * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
> >             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
> >
> > Validation:
> > * to double check all clk flags run below helper script:
> >     pushd /sys/kernel/debug/clk
> >     for f in *; do
> >         if [[ -f "$f/clk_flags" ]]; then
> >             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
> >             echo -e "$f: $flags"
> >         fi
> >     done
> >     popd
> >
> > * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
> >   with jq post-processing:
> >     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
> >
> > * to debug clk rate propagation, compile kernel with the following
> >   definition:
> >     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
> >   after that, clk_rate debug node for each clock will be available for
> >   write operation
> >
> 
> Applied, Thx

Thank you very much!

I noticed that you have applied version 15 of the patch. If I understand
correctly, this is because CLK_SET_RATE_NO_REPARENT for all RTC children
is preferred from your perspective. I agree with this decision. However,
version 16 includes a small refactoring patch that corrects a
misstyping by changing all sys_* related dividers and gates to
read-only operations, since they are set up from BootROM. Should I
submit this patch separately at a later time?

Also could you please clarify the official process for handling these
patches? Currently, I don't see them in the linux-amlogic for-next
branches. Is there a separate repository for clock changes? I believe
the next repository is a fork of the clock framework, but unfortunately,
I cannot seem to locate it on git.kernel.org... Apologies for the
potentially simple questions...

-- 
Thank you,
Dmitry

\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a: \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a \x1a\x1a\x1a, \x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-30 16:49     ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 16:49 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Jerome,

On Tue, May 30, 2023 at 06:14:01PM +0200, Jerome Brunet wrote:
> On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> 
> > A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> > and Audio. The audio clock controller is different from others, but the
> > rest are very similar from a functional and regmap point of view.
> > This patch series add support for Amlogic A1 PLL and Peripherals clock
> > drivers.
> > It blocks all A1 peripherals mainline support and a couple of patch series,
> > which were already reviewed and acked, but weren't merged due to pending
> > clock controller drivers series, e.g.
> > https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
> >
> > TODO: CPU and Audio clock controllers are not included in this patch
> > series, it will be sent later. The following clks from these controllers
> > are not supported for now:
> > * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
> >    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
> >    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
> >    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
> >    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
> >    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
> >    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
> >
> > * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
> >             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
> >
> > Validation:
> > * to double check all clk flags run below helper script:
> >     pushd /sys/kernel/debug/clk
> >     for f in *; do
> >         if [[ -f "$f/clk_flags" ]]; then
> >             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
> >             echo -e "$f: $flags"
> >         fi
> >     done
> >     popd
> >
> > * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
> >   with jq post-processing:
> >     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
> >
> > * to debug clk rate propagation, compile kernel with the following
> >   definition:
> >     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
> >   after that, clk_rate debug node for each clock will be available for
> >   write operation
> >
> 
> Applied, Thx

Thank you very much!

I noticed that you have applied version 15 of the patch. If I understand
correctly, this is because CLK_SET_RATE_NO_REPARENT for all RTC children
is preferred from your perspective. I agree with this decision. However,
version 16 includes a small refactoring patch that corrects a
misstyping by changing all sys_* related dividers and gates to
read-only operations, since they are set up from BootROM. Should I
submit this patch separately at a later time?

Also could you please clarify the official process for handling these
patches? Currently, I don't see them in the linux-amlogic for-next
branches. Is there a separate repository for clock changes? I believe
the next repository is a fork of the clock framework, but unfortunately,
I cannot seem to locate it on git.kernel.org... Apologies for the
potentially simple questions...

-- 
Thank you,
Dmitry

\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a: \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a \x1a\x1a\x1a, \x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
  2023-05-30 16:49     ` Dmitry Rokosov
  (?)
@ 2023-05-30 17:24       ` Dmitry Rokosov
  -1 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 17:24 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Jerome,

On Tue, May 30, 2023 at 07:49:33PM +0300, Dmitry Rokosov wrote:
> Jerome,
> 
> On Tue, May 30, 2023 at 06:14:01PM +0200, Jerome Brunet wrote:
> > On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> > 
> > > A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> > > and Audio. The audio clock controller is different from others, but the
> > > rest are very similar from a functional and regmap point of view.
> > > This patch series add support for Amlogic A1 PLL and Peripherals clock
> > > drivers.
> > > It blocks all A1 peripherals mainline support and a couple of patch series,
> > > which were already reviewed and acked, but weren't merged due to pending
> > > clock controller drivers series, e.g.
> > > https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
> > >
> > > TODO: CPU and Audio clock controllers are not included in this patch
> > > series, it will be sent later. The following clks from these controllers
> > > are not supported for now:
> > > * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
> > >    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
> > >    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
> > >    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
> > >    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
> > >    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
> > >    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
> > >
> > > * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
> > >             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
> > >
> > > Validation:
> > > * to double check all clk flags run below helper script:
> > >     pushd /sys/kernel/debug/clk
> > >     for f in *; do
> > >         if [[ -f "$f/clk_flags" ]]; then
> > >             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
> > >             echo -e "$f: $flags"
> > >         fi
> > >     done
> > >     popd
> > >
> > > * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
> > >   with jq post-processing:
> > >     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
> > >
> > > * to debug clk rate propagation, compile kernel with the following
> > >   definition:
> > >     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
> > >   after that, clk_rate debug node for each clock will be available for
> > >   write operation
> > >
> > 
> > Applied, Thx
> 
> Thank you very much!
> 
> I noticed that you have applied version 15 of the patch. If I understand
> correctly, this is because CLK_SET_RATE_NO_REPARENT for all RTC children
> is preferred from your perspective. I agree with this decision. However,
> version 16 includes a small refactoring patch that corrects a
> misstyping by changing all sys_* related dividers and gates to
> read-only operations, since they are set up from BootROM. Should I
> submit this patch separately at a later time?
> 
> Also could you please clarify the official process for handling these
> patches? Currently, I don't see them in the linux-amlogic for-next
> branches. Is there a separate repository for clock changes? I believe
> the next repository is a fork of the clock framework, but unfortunately,
> I cannot seem to locate it on git.kernel.org... Apologies for the
> potentially simple questions...

I came across your development tree on GitHub, and I noticed that you've
applied the latest v16 version. Apologies for the noise!

https://github.com/BayLibre/clk-meson/commit/84af914404dbc01f388c440cac72428784b8a161#diff-9e8258bc44803391f868de351058eef033cf3828d52801e1711f786501bc5911

-- 
Thank you,
Dmitry

\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a: \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a \x1a\x1a\x1a, \x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-30 17:24       ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 17:24 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Jerome,

On Tue, May 30, 2023 at 07:49:33PM +0300, Dmitry Rokosov wrote:
> Jerome,
> 
> On Tue, May 30, 2023 at 06:14:01PM +0200, Jerome Brunet wrote:
> > On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> > 
> > > A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> > > and Audio. The audio clock controller is different from others, but the
> > > rest are very similar from a functional and regmap point of view.
> > > This patch series add support for Amlogic A1 PLL and Peripherals clock
> > > drivers.
> > > It blocks all A1 peripherals mainline support and a couple of patch series,
> > > which were already reviewed and acked, but weren't merged due to pending
> > > clock controller drivers series, e.g.
> > > https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
> > >
> > > TODO: CPU and Audio clock controllers are not included in this patch
> > > series, it will be sent later. The following clks from these controllers
> > > are not supported for now:
> > > * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
> > >    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
> > >    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
> > >    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
> > >    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
> > >    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
> > >    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
> > >
> > > * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
> > >             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
> > >
> > > Validation:
> > > * to double check all clk flags run below helper script:
> > >     pushd /sys/kernel/debug/clk
> > >     for f in *; do
> > >         if [[ -f "$f/clk_flags" ]]; then
> > >             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
> > >             echo -e "$f: $flags"
> > >         fi
> > >     done
> > >     popd
> > >
> > > * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
> > >   with jq post-processing:
> > >     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
> > >
> > > * to debug clk rate propagation, compile kernel with the following
> > >   definition:
> > >     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
> > >   after that, clk_rate debug node for each clock will be available for
> > >   write operation
> > >
> > 
> > Applied, Thx
> 
> Thank you very much!
> 
> I noticed that you have applied version 15 of the patch. If I understand
> correctly, this is because CLK_SET_RATE_NO_REPARENT for all RTC children
> is preferred from your perspective. I agree with this decision. However,
> version 16 includes a small refactoring patch that corrects a
> misstyping by changing all sys_* related dividers and gates to
> read-only operations, since they are set up from BootROM. Should I
> submit this patch separately at a later time?
> 
> Also could you please clarify the official process for handling these
> patches? Currently, I don't see them in the linux-amlogic for-next
> branches. Is there a separate repository for clock changes? I believe
> the next repository is a fork of the clock framework, but unfortunately,
> I cannot seem to locate it on git.kernel.org... Apologies for the
> potentially simple questions...

I came across your development tree on GitHub, and I noticed that you've
applied the latest v16 version. Apologies for the noise!

https://github.com/BayLibre/clk-meson/commit/84af914404dbc01f388c440cac72428784b8a161#diff-9e8258bc44803391f868de351058eef033cf3828d52801e1711f786501bc5911

-- 
Thank you,
Dmitry

\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a: \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a \x1a\x1a\x1a, \x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 0/6] add Amlogic A1 clock controller drivers
@ 2023-05-30 17:24       ` Dmitry Rokosov
  0 siblings, 0 replies; 63+ messages in thread
From: Dmitry Rokosov @ 2023-05-30 17:24 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: neil.armstrong, mturquette, sboyd, robh+dt,
	krzysztof.kozlowski+dt, khilman, martin.blumenstingl, jian.hu,
	kernel, rockosov, linux-amlogic, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel

Jerome,

On Tue, May 30, 2023 at 07:49:33PM +0300, Dmitry Rokosov wrote:
> Jerome,
> 
> On Tue, May 30, 2023 at 06:14:01PM +0200, Jerome Brunet wrote:
> > On Wed 17 May 2023 at 16:33, Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
> > 
> > > A1 SoC has four clock controllers on the board: PLL, Peripherals, CPU,
> > > and Audio. The audio clock controller is different from others, but the
> > > rest are very similar from a functional and regmap point of view.
> > > This patch series add support for Amlogic A1 PLL and Peripherals clock
> > > drivers.
> > > It blocks all A1 peripherals mainline support and a couple of patch series,
> > > which were already reviewed and acked, but weren't merged due to pending
> > > clock controller drivers series, e.g.
> > > https://lore.kernel.org/all/20230418111612.19479-1-ddrokosov@sberdevices.ru/
> > >
> > > TODO: CPU and Audio clock controllers are not included in this patch
> > > series, it will be sent later. The following clks from these controllers
> > > are not supported for now:
> > > * Audio clks - vad, mclk_vad, mclk_d, resample_a, locker_in, mclk_b,
> > >    pdmdclk, pdmsysclk, eqdrc, spdifin, mclk_a, audio2_toaudiotop,
> > >    audio2_tovad, audio2_toddr_vad, audio2_tdmin_vad, audio2_pdm,
> > >    audio2_ddr_arb, audio_audiolocker, audio_eqdrc, audio_resamplea,
> > >    audio_spdifin, audio_toddrb, audio_toddra, audio_frddrb, audio_frddra,
> > >    audio_tdmoutb, audio_tdmouta, audio_loopbacka, audio_tdminlb,
> > >    audio_tdminb, audio_tdmina, audio_ddr_arb, mclk_c
> > >
> > > * CPU clks: cpu_fixed_source_sel0, cpu_fixed_source_div0,
> > >             cpu_fixed_source_sel1, cpu_fixed_source_div1, cpu_clk
> > >
> > > Validation:
> > > * to double check all clk flags run below helper script:
> > >     pushd /sys/kernel/debug/clk
> > >     for f in *; do
> > >         if [[ -f "$f/clk_flags" ]]; then
> > >             flags="$(cat $f/clk_flags | awk '{$1=$1};1' | sed ':a;N;$!ba;s/\n/ | /g')"
> > >             echo -e "$f: $flags"
> > >         fi
> > >     done
> > >     popd
> > >
> > > * to trace current clks state use '/sys/kernel/debug/clk/clk_dump' node
> > >   with jq post-processing:
> > >     $ cat /sys/kernel/debug/clk/clk_dump | jq '.' > clk_dump.json
> > >
> > > * to debug clk rate propagation, compile kernel with the following
> > >   definition:
> > >     $ sed -i "s/undef CLOCK_ALLOW_WRITE_DEBUGFS/define CLOCK_ALLOW_WRITE_DEBUGFS/g" drivers/clk/clk.c
> > >   after that, clk_rate debug node for each clock will be available for
> > >   write operation
> > >
> > 
> > Applied, Thx
> 
> Thank you very much!
> 
> I noticed that you have applied version 15 of the patch. If I understand
> correctly, this is because CLK_SET_RATE_NO_REPARENT for all RTC children
> is preferred from your perspective. I agree with this decision. However,
> version 16 includes a small refactoring patch that corrects a
> misstyping by changing all sys_* related dividers and gates to
> read-only operations, since they are set up from BootROM. Should I
> submit this patch separately at a later time?
> 
> Also could you please clarify the official process for handling these
> patches? Currently, I don't see them in the linux-amlogic for-next
> branches. Is there a separate repository for clock changes? I believe
> the next repository is a fork of the clock framework, but unfortunately,
> I cannot seem to locate it on git.kernel.org... Apologies for the
> potentially simple questions...

I came across your development tree on GitHub, and I noticed that you've
applied the latest v16 version. Apologies for the noise!

https://github.com/BayLibre/clk-meson/commit/84af914404dbc01f388c440cac72428784b8a161#diff-9e8258bc44803391f868de351058eef033cf3828d52801e1711f786501bc5911

-- 
Thank you,
Dmitry

\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a: \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a \x1a\x1a\x1a, \x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a. \x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a, \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a \x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a \x1a\x1a\x1a \x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a.
CONFIDENTIALITY NOTICE: This email and any files attached to it are confidential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
  2023-05-30 16:03             ` Dmitry Rokosov
  (?)
@ 2023-05-30 19:55               ` Martin Blumenstingl
  -1 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-30 19:55 UTC (permalink / raw)
  To: Dmitry Rokosov
  Cc: Conor Dooley, jbrunet, krzysztof.kozlowski+dt, neil.armstrong,
	mturquette, sboyd, robh+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hi,

On Tue, May 30, 2023 at 6:03 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> > If I am understanding correctly, this series implements the child
> > controller and a parent, which is unimplemented, provides the child with
> > sys_pll_div16.
> > The thing I am missing is whether the child controller has some outputs
> > that depend on this sys_pll_div16 input & whether those are documented
> > in this series. Regardless, you should be able to add more output clocks
> > without compatibility issues.
Conor, the short answer is yes, the "gen_sel" mux (see patch 6/6 from
this series, which is then part of a clock tree that's an output of
the peripheral clock controller) uses sys_pll_div16 as input.
Dmitry goes into more details below.

[...]
> As for new input clock connections, such as the cpu_clock
> (sys_pll_div16), these are handled by clock muxing abstraction, allowing
> CCF to find the clock object by fw.name and returning -ENOENT if the
> connection is missing without breaking any CCF flow. It happens in the
> kernel function clk_core_fill_parent_index()
> https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L424
> Despite not having the connection for the new input in the old Device
> Tree version, this will not break kernel boot flow and workflow, and the
> new clock object just would not be utilized.
>
> Based on the presented arguments, I fully agree with Jerome's position.
> We can add new connections and objects in new driver versions, but their
> removal is prohibited.
>
> If it's alright with you, I would prefer to keep the Peripherals and PLL
> clock driver and their bindings as they are, and continue with the CPU
> and Audio clock controllers in a separate patch series. Would that be
> feasible for you?
To me this sounds good!


Best regards,
Martin

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-30 19:55               ` Martin Blumenstingl
  0 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-30 19:55 UTC (permalink / raw)
  To: Dmitry Rokosov
  Cc: Conor Dooley, jbrunet, krzysztof.kozlowski+dt, neil.armstrong,
	mturquette, sboyd, robh+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hi,

On Tue, May 30, 2023 at 6:03 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> > If I am understanding correctly, this series implements the child
> > controller and a parent, which is unimplemented, provides the child with
> > sys_pll_div16.
> > The thing I am missing is whether the child controller has some outputs
> > that depend on this sys_pll_div16 input & whether those are documented
> > in this series. Regardless, you should be able to add more output clocks
> > without compatibility issues.
Conor, the short answer is yes, the "gen_sel" mux (see patch 6/6 from
this series, which is then part of a clock tree that's an output of
the peripheral clock controller) uses sys_pll_div16 as input.
Dmitry goes into more details below.

[...]
> As for new input clock connections, such as the cpu_clock
> (sys_pll_div16), these are handled by clock muxing abstraction, allowing
> CCF to find the clock object by fw.name and returning -ENOENT if the
> connection is missing without breaking any CCF flow. It happens in the
> kernel function clk_core_fill_parent_index()
> https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L424
> Despite not having the connection for the new input in the old Device
> Tree version, this will not break kernel boot flow and workflow, and the
> new clock object just would not be utilized.
>
> Based on the presented arguments, I fully agree with Jerome's position.
> We can add new connections and objects in new driver versions, but their
> removal is prohibited.
>
> If it's alright with you, I would prefer to keep the Peripherals and PLL
> clock driver and their bindings as they are, and continue with the CPU
> and Audio clock controllers in a separate patch series. Would that be
> feasible for you?
To me this sounds good!


Best regards,
Martin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings
@ 2023-05-30 19:55               ` Martin Blumenstingl
  0 siblings, 0 replies; 63+ messages in thread
From: Martin Blumenstingl @ 2023-05-30 19:55 UTC (permalink / raw)
  To: Dmitry Rokosov
  Cc: Conor Dooley, jbrunet, krzysztof.kozlowski+dt, neil.armstrong,
	mturquette, sboyd, robh+dt, khilman, jian.hu, kernel, rockosov,
	linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel

Hi,

On Tue, May 30, 2023 at 6:03 PM Dmitry Rokosov <ddrokosov@sberdevices.ru> wrote:
[...]
> > If I am understanding correctly, this series implements the child
> > controller and a parent, which is unimplemented, provides the child with
> > sys_pll_div16.
> > The thing I am missing is whether the child controller has some outputs
> > that depend on this sys_pll_div16 input & whether those are documented
> > in this series. Regardless, you should be able to add more output clocks
> > without compatibility issues.
Conor, the short answer is yes, the "gen_sel" mux (see patch 6/6 from
this series, which is then part of a clock tree that's an output of
the peripheral clock controller) uses sys_pll_div16 as input.
Dmitry goes into more details below.

[...]
> As for new input clock connections, such as the cpu_clock
> (sys_pll_div16), these are handled by clock muxing abstraction, allowing
> CCF to find the clock object by fw.name and returning -ENOENT if the
> connection is missing without breaking any CCF flow. It happens in the
> kernel function clk_core_fill_parent_index()
> https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L424
> Despite not having the connection for the new input in the old Device
> Tree version, this will not break kernel boot flow and workflow, and the
> new clock object just would not be utilized.
>
> Based on the presented arguments, I fully agree with Jerome's position.
> We can add new connections and objects in new driver versions, but their
> removal is prohibited.
>
> If it's alright with you, I would prefer to keep the Peripherals and PLL
> clock driver and their bindings as they are, and continue with the CPU
> and Audio clock controllers in a separate patch series. Would that be
> feasible for you?
To me this sounds good!


Best regards,
Martin

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 63+ messages in thread

end of thread, other threads:[~2023-05-30 19:55 UTC | newest]

Thread overview: 63+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-17 13:33 [PATCH v15 0/6] add Amlogic A1 clock controller drivers Dmitry Rokosov
2023-05-17 13:33 ` Dmitry Rokosov
2023-05-17 13:33 ` Dmitry Rokosov
2023-05-17 13:33 ` [PATCH v15 1/6] clk: meson: make pll rst bit as optional Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33 ` [PATCH v15 2/6] clk: meson: introduce new pll power-on sequence for A1 SoC family Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33 ` [PATCH v15 3/6] dt-bindings: clock: meson: add A1 PLL clock controller bindings Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33 ` [PATCH v15 4/6] clk: meson: a1: add Amlogic A1 PLL clock controller driver Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33 ` [PATCH v15 5/6] dt-bindings: clock: meson: add A1 Peripherals clock controller bindings Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-19 21:09   ` Martin Blumenstingl
2023-05-19 21:09     ` Martin Blumenstingl
2023-05-19 21:09     ` Martin Blumenstingl
2023-05-22 13:00     ` Dmitry Rokosov
2023-05-22 13:00       ` Dmitry Rokosov
2023-05-22 13:00       ` Dmitry Rokosov
2023-05-29 20:38       ` Martin Blumenstingl
2023-05-29 20:38         ` Martin Blumenstingl
2023-05-29 20:38         ` Martin Blumenstingl
2023-05-30  8:56         ` Jerome Brunet
2023-05-30  8:56           ` Jerome Brunet
2023-05-30  8:56           ` Jerome Brunet
2023-05-30  9:34         ` Conor Dooley
2023-05-30  9:34           ` Conor Dooley
2023-05-30  9:34           ` Conor Dooley
2023-05-30 16:03           ` Dmitry Rokosov
2023-05-30 16:03             ` Dmitry Rokosov
2023-05-30 16:03             ` Dmitry Rokosov
2023-05-30 19:55             ` Martin Blumenstingl
2023-05-30 19:55               ` Martin Blumenstingl
2023-05-30 19:55               ` Martin Blumenstingl
2023-05-17 13:33 ` [PATCH v15 6/6] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-17 13:33   ` Dmitry Rokosov
2023-05-19 21:03   ` Martin Blumenstingl
2023-05-19 21:03     ` Martin Blumenstingl
2023-05-19 21:03     ` Martin Blumenstingl
2023-05-22 13:32     ` Dmitry Rokosov
2023-05-22 13:32       ` Dmitry Rokosov
2023-05-22 13:32       ` Dmitry Rokosov
2023-05-30  8:32       ` Jerome Brunet
2023-05-30  8:32         ` Jerome Brunet
2023-05-30  8:32         ` Jerome Brunet
2023-05-30 12:06         ` Dmitry Rokosov
2023-05-30 12:06           ` Dmitry Rokosov
2023-05-30 12:06           ` Dmitry Rokosov
2023-05-30 16:14 ` [PATCH v15 0/6] add Amlogic A1 clock controller drivers Jerome Brunet
2023-05-30 16:14   ` Jerome Brunet
2023-05-30 16:14   ` Jerome Brunet
2023-05-30 16:49   ` Dmitry Rokosov
2023-05-30 16:49     ` Dmitry Rokosov
2023-05-30 16:49     ` Dmitry Rokosov
2023-05-30 17:24     ` Dmitry Rokosov
2023-05-30 17:24       ` Dmitry Rokosov
2023-05-30 17:24       ` Dmitry Rokosov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.