2023-03-21 19:31:04

by Dmitry Rokosov

[permalink] [raw]
Subject: [PATCH v11 0/5] add Amlogic A1 clock controller drivers

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/linux-amlogic/[email protected]/

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 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/[email protected]
[2] https://lkml.kernel.org/r/[email protected]
[3] https://lkml.kernel.org/r/[email protected]
[4] https://lkml.kernel.org/r/[email protected]
[5] https://lkml.kernel.org/r/[email protected]
[6] https://lkml.kernel.org/r/[email protected]
[7] https://lkml.kernel.org/r/[email protected]
[8] https://lore.kernel.org/linux-amlogic/[email protected]/
[9] https://lore.kernel.org/linux-amlogic/[email protected]/
[10] https://lore.kernel.org/all/[email protected]/
[11] https://lore.kernel.org/all/[email protected]/

Dmitry Rokosov (5):
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 and Peripherals clkcs bindings
clk: meson: a1: add Amlogic A1 PLL clock controller driver
clk: meson: a1: add Amlogic A1 Peripherals clock controller driver

.../bindings/clock/amlogic,a1-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-pll.c | 385 +++
drivers/clk/meson/a1-pll.h | 31 +
drivers/clk/meson/a1.c | 2344 +++++++++++++++++
drivers/clk/meson/a1.h | 49 +
drivers/clk/meson/clk-pll.c | 47 +-
drivers/clk/meson/clk-pll.h | 2 +
include/dt-bindings/clock/amlogic,a1-clkc.h | 113 +
.../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 +
13 files changed, 3140 insertions(+), 7 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
create mode 100644 drivers/clk/meson/a1-pll.c
create mode 100644 drivers/clk/meson/a1-pll.h
create mode 100644 drivers/clk/meson/a1.c
create mode 100644 drivers/clk/meson/a1.h
create mode 100644 include/dt-bindings/clock/amlogic,a1-clkc.h
create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h

--
2.36.0



2023-03-21 19:31:04

by Dmitry Rokosov

[permalink] [raw]
Subject: [PATCH v11 2/5] clk: meson: introduce new pll power-on sequence for A1 SoC family

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 <[email protected]>
Acked-by: Martin Blumenstingl <[email protected]>
Signed-off-by: Dmitry Rokosov <[email protected]>
---
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


2023-03-21 19:31:04

by Dmitry Rokosov

[permalink] [raw]
Subject: [PATCH v11 1/5] clk: meson: make pll rst bit as optional

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 <[email protected]>
Acked-by: Martin Blumenstingl <[email protected]>
Signed-off-by: Dmitry Rokosov <[email protected]>
---
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


2023-03-21 19:31:04

by Dmitry Rokosov

[permalink] [raw]
Subject: [PATCH v11 4/5] clk: meson: a1: add Amlogic A1 PLL clock controller driver

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 <[email protected]>
Signed-off-by: Dmitry Rokosov <[email protected]>
---
drivers/clk/meson/Kconfig | 10 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a1-pll.c | 385 +++++++++++++++++++++++++++++++++++++
drivers/clk/meson/a1-pll.h | 31 +++
4 files changed, 427 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..f56da2a4b000 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 "Meson 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..3420fecb8fc3
--- /dev/null
+++ b/drivers/clk/meson/a1-pll.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <[email protected]>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <[email protected]>
+ */
+
+#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 provided by this provider */
+static struct clk_hw_onecell_data a1_pll_public_clks = {
+ .hws = {
+ [CLKID_FIXED_PLL] = &fixed_pll.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,
+};
+
+/*
+ * These clocks are entirely contrived and do not map onto the hardware.
+ * It has now been decided to expose public clocks in the DT bindings.
+ * Only below clocks we don't want to expose, such as the internal muxes
+ * and dividers of composite clocks, will remain defined here.
+ */
+static struct clk_hw_onecell_data a1_pll_private_clks = {
+ .hws = {
+ &fixed_pll_dco.hw,
+ &fclk_div2_div.hw,
+ &fclk_div3_div.hw,
+ &fclk_div5_div.hw,
+ &fclk_div7_div.hw,
+ },
+ .num = 5,
+};
+
+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_clks_register(struct device *dev,
+ struct clk_hw_onecell_data *clks)
+{
+ int i, err = 0;
+
+ for (i = 0; i < clks->num; i++) {
+ err = devm_clk_hw_register(dev, clks->hws[i]);
+ if (err)
+ return err;
+ }
+
+ return err;
+}
+
+static int meson_a1_pll_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ void __iomem *base;
+ struct regmap *map;
+ int 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;
+
+ /* DT clocks registration */
+ err = meson_a1_pll_clks_register(dev, &a1_pll_public_clks);
+ if (err)
+ return dev_err_probe(dev, err,
+ "public clks registration failed\n");
+
+ /* Internal clocks registration */
+ err = meson_a1_pll_clks_register(dev, &a1_pll_private_clks);
+ if (err)
+ return dev_err_probe(dev, err,
+ "private clks registration failed\n");
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+ &a1_pll_public_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 = of_match_ptr(a1_pll_clkc_match_table),
+ },
+};
+
+module_platform_driver(a1_pll_clkc_driver);
+MODULE_AUTHOR("Jian Hu <[email protected]>");
+MODULE_AUTHOR("Dmitry Rokosov <[email protected]>");
+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..97d0cc2c1f7c
--- /dev/null
+++ b/drivers/clk/meson/a1-pll.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Amlogic Meson-A1 PLL Clock Controller internals
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <[email protected]>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <[email protected]>
+ */
+
+#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>
+
+#endif /* __A1_PLL_H */
--
2.36.0


2023-03-21 19:31:04

by Dmitry Rokosov

[permalink] [raw]
Subject: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
clock drivers.
Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
bindings and include them to MAINTAINERS.

Signed-off-by: Jian Hu <[email protected]>
Signed-off-by: Dmitry Rokosov <[email protected]>
---
.../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
.../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
MAINTAINERS | 1 +
include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
.../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
5 files changed, 267 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
create mode 100644 include/dt-bindings/clock/amlogic,a1-clkc.h
create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
new file mode 100644
index 000000000000..cb6d8f4eb959
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-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-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic Meson A/C serials Peripheral Clock Control Unit
+
+maintainers:
+ - Neil Armstrong <[email protected]>
+ - Jerome Brunet <[email protected]>
+ - Jian Hu <[email protected]>
+ - Dmitry Rokosov <[email protected]>
+
+properties:
+ compatible:
+ const: amlogic,a1-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-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
new file mode 100644
index 000000000000..77a13b1f9d5a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
@@ -0,0 +1,59 @@
+# 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 Meson A/C serials PLL Clock Control Unit
+
+maintainers:
+ - Neil Armstrong <[email protected]>
+ - Jerome Brunet <[email protected]>
+ - Jian Hu <[email protected]>
+ - Dmitry Rokosov <[email protected]>
+
+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:
+ - |
+ #include <dt-bindings/clock/amlogic,a1-clkc.h>
+ 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 CLKID_FIXPLL_IN>,
+ <&clkc_periphs CLKID_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: [email protected]
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-clkc.h b/include/dt-bindings/clock/amlogic,a1-clkc.h
new file mode 100644
index 000000000000..95131779982c
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-clkc.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <[email protected]>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <[email protected]>
+ */
+
+#ifndef __A1_CLKC_H
+#define __A1_CLKC_H
+
+#define CLKID_FIXPLL_IN 0
+#define CLKID_USB_PHY_IN 1
+#define CLKID_USB_CTRL_IN 2
+#define CLKID_HIFIPLL_IN 3
+#define CLKID_SYSPLL_IN 4
+#define CLKID_DDS_IN 5
+#define CLKID_SYS 6
+#define CLKID_CLKTREE 7
+#define CLKID_RESET_CTRL 8
+#define CLKID_ANALOG_CTRL 9
+#define CLKID_PWR_CTRL 10
+#define CLKID_PAD_CTRL 11
+#define CLKID_SYS_CTRL 12
+#define CLKID_TEMP_SENSOR 13
+#define CLKID_AM2AXI_DIV 14
+#define CLKID_SPICC_B 15
+#define CLKID_SPICC_A 16
+#define CLKID_MSR 17
+#define CLKID_AUDIO 18
+#define CLKID_JTAG_CTRL 19
+#define CLKID_SARADC_EN 20
+#define CLKID_PWM_EF 21
+#define CLKID_PWM_CD 22
+#define CLKID_PWM_AB 23
+#define CLKID_CEC 24
+#define CLKID_I2C_S 25
+#define CLKID_IR_CTRL 26
+#define CLKID_I2C_M_D 27
+#define CLKID_I2C_M_C 28
+#define CLKID_I2C_M_B 29
+#define CLKID_I2C_M_A 30
+#define CLKID_ACODEC 31
+#define CLKID_OTP 32
+#define CLKID_SD_EMMC_A 33
+#define CLKID_USB_PHY 34
+#define CLKID_USB_CTRL 35
+#define CLKID_SYS_DSPB 36
+#define CLKID_SYS_DSPA 37
+#define CLKID_DMA 38
+#define CLKID_IRQ_CTRL 39
+#define CLKID_NIC 40
+#define CLKID_GIC 41
+#define CLKID_UART_C 42
+#define CLKID_UART_B 43
+#define CLKID_UART_A 44
+#define CLKID_SYS_PSRAM 45
+#define CLKID_RSA 46
+#define CLKID_CORESIGHT 47
+#define CLKID_AM2AXI_VAD 48
+#define CLKID_AUDIO_VAD 49
+#define CLKID_AXI_DMC 50
+#define CLKID_AXI_PSRAM 51
+#define CLKID_RAMB 52
+#define CLKID_RAMA 53
+#define CLKID_AXI_SPIFC 54
+#define CLKID_AXI_NIC 55
+#define CLKID_AXI_DMA 56
+#define CLKID_CPU_CTRL 57
+#define CLKID_ROM 58
+#define CLKID_PROC_I2C 59
+#define CLKID_DSPA_EN 60
+#define CLKID_DSPA_EN_NIC 61
+#define CLKID_DSPB_EN 62
+#define CLKID_DSPB_EN_NIC 63
+#define CLKID_RTC 64
+#define CLKID_CECA_32K 65
+#define CLKID_CECB_32K 66
+#define CLKID_24M 67
+#define CLKID_12M 68
+#define CLKID_FCLK_DIV2_DIVN 69
+#define CLKID_GEN 70
+#define CLKID_SARADC 71
+#define CLKID_PWM_A 72
+#define CLKID_PWM_B 73
+#define CLKID_PWM_C 74
+#define CLKID_PWM_D 75
+#define CLKID_PWM_E 76
+#define CLKID_PWM_F 77
+#define CLKID_SPICC 78
+#define CLKID_TS 79
+#define CLKID_SPIFC 80
+#define CLKID_USB_BUS 81
+#define CLKID_SD_EMMC 82
+#define CLKID_PSRAM 83
+#define CLKID_DMC 84
+#define CLKID_GEN_SEL 85
+#define CLKID_PWM_A_SEL 86
+#define CLKID_PWM_B_SEL 87
+#define CLKID_PWM_C_SEL 88
+#define CLKID_PWM_D_SEL 89
+#define CLKID_PWM_E_SEL 90
+#define CLKID_PWM_F_SEL 91
+#define CLKID_DSPA_A_SEL 92
+#define CLKID_DSPA_B_SEL 93
+#define CLKID_DSPB_A_SEL 94
+#define CLKID_DSPB_B_SEL 95
+#define CLKID_CECA_32K_SEL 96
+#define CLKID_CECB_32K_SEL 97
+#define NR_CLKS 98
+
+#endif /* __A1_CLKC_H */
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..740fe8c4db5d
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <[email protected]>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <[email protected]>
+ */
+
+#ifndef __A1_PLL_CLKC_H
+#define __A1_PLL_CLKC_H
+
+#define CLKID_FIXED_PLL 0
+#define CLKID_FCLK_DIV2 1
+#define CLKID_FCLK_DIV3 2
+#define CLKID_FCLK_DIV5 3
+#define CLKID_FCLK_DIV7 4
+#define CLKID_HIFI_PLL 5
+#define NR_PLL_CLKS 6
+
+#endif /* __A1_PLL_CLKC_H */
--
2.36.0


2023-03-21 19:31:12

by Dmitry Rokosov

[permalink] [raw]
Subject: [PATCH v11 5/5] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver

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 <[email protected]>
Signed-off-by: Dmitry Rokosov <[email protected]>
---
drivers/clk/meson/Kconfig | 10 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a1.c | 2344 ++++++++++++++++++++++++++++++++++++
drivers/clk/meson/a1.h | 49 +
4 files changed, 2404 insertions(+)
create mode 100644 drivers/clk/meson/a1.c
create mode 100644 drivers/clk/meson/a1.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index f56da2a4b000..970892b07043 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
+ tristate "Meson A1 SoC 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..0e6f293c05d4 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) += a1.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.c b/drivers/clk/meson/a1.c
new file mode 100644
index 000000000000..3f4263ac404c
--- /dev/null
+++ b/drivers/clk/meson/a1.c
@@ -0,0 +1,2344 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <[email protected]>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "a1.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,
+ },
+};
+
+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),
+ /*
+ * DSPA_A clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force dsp parent setup on device tree side
+ */
+ .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),
+ /*
+ * DSPA_B clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force dsp parent setup on device tree side
+ */
+ .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),
+ /*
+ * DSPB_A clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force dsp parent setup on device tree side
+ */
+ .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),
+ /*
+ * DSPB_B clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force dsp parent setup on device tree side
+ */
+ .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),
+ /*
+ * GEN clk can be connected to external PAD, so we may want to
+ * setup it from device tree directly.
+ * Also GEN clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want 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),
+ /*
+ * PWM_A clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force pwm parent setup on device tree side
+ */
+ .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),
+ /*
+ * PWM_B clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force pwm parent setup on device tree side
+ */
+ .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),
+ /*
+ * PWM_C clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force pwm parent setup on device tree side
+ */
+ .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),
+ /*
+ * PWM_D clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force pwm parent setup on device tree side
+ */
+ .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),
+ /*
+ * PWM_E clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force pwm parent setup on device tree side
+ */
+ .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),
+ /*
+ * PWM_F clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force pwm parent setup on device tree side
+ */
+ .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,
+ /*
+ * CECA_32K clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force ceca_32k parent setup on device tree side
+ */
+ .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,
+ /*
+ * CECB_32K clk can be inherited from more accurate RTC clock,
+ * so in some situations we may want to freeze its parent.
+ * Therefore force cecb_32k parent setup on device tree side
+ */
+ .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 provided by this provider */
+static struct clk_hw_onecell_data a1_periphs_public_clks = {
+ .hws = {
+ [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_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] = &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_GEN_SEL] = &gen_sel.hw,
+ [CLKID_PWM_A_SEL] = &pwm_a_sel.hw,
+ [CLKID_PWM_B_SEL] = &pwm_b_sel.hw,
+ [CLKID_PWM_C_SEL] = &pwm_c_sel.hw,
+ [CLKID_PWM_D_SEL] = &pwm_d_sel.hw,
+ [CLKID_PWM_E_SEL] = &pwm_e_sel.hw,
+ [CLKID_PWM_F_SEL] = &pwm_f_sel.hw,
+ [CLKID_DSPA_A_SEL] = &dspa_a_sel.hw,
+ [CLKID_DSPA_B_SEL] = &dspa_b_sel.hw,
+ [CLKID_DSPB_A_SEL] = &dspb_a_sel.hw,
+ [CLKID_DSPB_B_SEL] = &dspb_b_sel.hw,
+ [CLKID_CECA_32K_SEL] = &ceca_32k_sel.hw,
+ [CLKID_CECB_32K_SEL] = &cecb_32k_sel.hw,
+ [NR_CLKS] = NULL,
+ },
+ .num = NR_CLKS,
+};
+
+/*
+ * These clocks are entirely contrived and do not map onto the hardware.
+ * It has now been decided to expose public clocks in the DT bindings.
+ * Only below clocks we don't want to expose, such as the internal muxes
+ * and dividers of composite clocks, will remain defined here.
+ */
+static struct clk_hw_onecell_data a1_periphs_private_clks = {
+ .hws = {
+ &xtal_in.hw,
+ &dspa_sel.hw,
+ &dspb_sel.hw,
+ &saradc_sel.hw,
+ &sys_a_sel.hw,
+ &sys_a_div.hw,
+ &sys_a.hw,
+ &sys_b_sel.hw,
+ &sys_b_div.hw,
+ &sys_b.hw,
+ &dspa_a_div.hw,
+ &dspa_a.hw,
+ &dspa_b_div.hw,
+ &dspa_b.hw,
+ &dspb_a_div.hw,
+ &dspb_a.hw,
+ &dspb_b_div.hw,
+ &dspb_b.hw,
+ &rtc_32k_in.hw,
+ &rtc_32k_div.hw,
+ &rtc_32k_xtal.hw,
+ &rtc_32k_sel.hw,
+ &cecb_32k_in.hw,
+ &cecb_32k_div.hw,
+ &cecb_32k_sel_pre.hw,
+ &ceca_32k_in.hw,
+ &ceca_32k_div.hw,
+ &ceca_32k_sel_pre.hw,
+ &fclk_div2_divn_pre.hw,
+ &clk_24m_div2.hw,
+ &gen_div.hw,
+ &saradc_div.hw,
+ &pwm_a_div.hw,
+ &pwm_b_div.hw,
+ &pwm_c_div.hw,
+ &pwm_d_div.hw,
+ &pwm_e_div.hw,
+ &pwm_f_div.hw,
+ &spicc_sel.hw,
+ &spicc_div.hw,
+ &spicc_sel2.hw,
+ &ts_div.hw,
+ &spifc_sel.hw,
+ &spifc_div.hw,
+ &spifc_sel2.hw,
+ &usb_bus_sel.hw,
+ &usb_bus_div.hw,
+ &sd_emmc_sel.hw,
+ &sd_emmc_div.hw,
+ &sd_emmc_sel2.hw,
+ &psram_sel.hw,
+ &psram_div.hw,
+ &psram_sel2.hw,
+ &dmc_sel.hw,
+ &dmc_div.hw,
+ &dmc_sel2.hw,
+ },
+ .num = 56,
+};
+
+/* 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_clks_register(struct device *dev,
+ struct clk_hw_onecell_data *clks)
+{
+ int i, err = 0;
+
+ for (i = 0; i < clks->num; i++) {
+ err = devm_clk_hw_register(dev, clks->hws[i]);
+ if (err)
+ return err;
+ }
+
+ return err;
+}
+
+static int meson_a1_periphs_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ void __iomem *base;
+ struct regmap *map;
+ int 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;
+
+ /* DT clocks registration */
+ err = meson_a1_periphs_clks_register(dev, &a1_periphs_public_clks);
+ if (err)
+ return dev_err_probe(dev, err,
+ "public clks registration failed\n");
+
+ /* Internal clocks registration */
+ err = meson_a1_periphs_clks_register(dev, &a1_periphs_private_clks);
+ if (err)
+ return dev_err_probe(dev, err,
+ "private clks registration failed\n");
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+ &a1_periphs_public_clks);
+}
+
+static const struct of_device_id a1_periphs_clkc_match_table[] = {
+ { .compatible = "amlogic,a1-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-clkc",
+ .of_match_table = of_match_ptr(a1_periphs_clkc_match_table),
+ },
+};
+
+module_platform_driver(a1_periphs_clkc_driver);
+MODULE_AUTHOR("Jian Hu <[email protected]>");
+MODULE_AUTHOR("Dmitry Rokosov <[email protected]>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/a1.h b/drivers/clk/meson/a1.h
new file mode 100644
index 000000000000..164d52f5b17b
--- /dev/null
+++ b/drivers/clk/meson/a1.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Amlogic Meson-A1 Peripheral Clock Controller internals
+ *
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ * Author: Jian Hu <[email protected]>
+ *
+ * Copyright (c) 2023, SberDevices. All Rights Reserved.
+ * Author: Dmitry Rokosov <[email protected]>
+ */
+
+#ifndef __A1_H
+#define __A1_H
+
+/* peripheral 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-clkc.h>
+
+#endif /* __A1_H */
--
2.36.0


2023-03-27 10:24:39

by Jerome Brunet

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings


On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:

> Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
> clock drivers.
> Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
> bindings and include them to MAINTAINERS.
>
> Signed-off-by: Jian Hu <[email protected]>
> Signed-off-by: Dmitry Rokosov <[email protected]>
> ---
> .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
> .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
> MAINTAINERS | 1 +
> include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
> .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
> 5 files changed, 267 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml

There is two drivers (and 2 independent patches). There should be 2
bindings patches as well.

> create mode 100644 include/dt-bindings/clock/amlogic,a1-clkc.h
> create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h
>
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> new file mode 100644
> index 000000000000..cb6d8f4eb959
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-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-clkc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic Meson A/C serials Peripheral Clock Control Unit
> +
> +maintainers:
> + - Neil Armstrong <[email protected]>
> + - Jerome Brunet <[email protected]>
> + - Jian Hu <[email protected]>
> + - Dmitry Rokosov <[email protected]>
> +
> +properties:
> + compatible:
> + const: amlogic,a1-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-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
> new file mode 100644
> index 000000000000..77a13b1f9d5a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
> @@ -0,0 +1,59 @@
> +# 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 Meson A/C serials PLL Clock Control Unit
> +
> +maintainers:
> + - Neil Armstrong <[email protected]>
> + - Jerome Brunet <[email protected]>
> + - Jian Hu <[email protected]>
> + - Dmitry Rokosov <[email protected]>
> +
> +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:
> + - |
> + #include <dt-bindings/clock/amlogic,a1-clkc.h>
> + 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 CLKID_FIXPLL_IN>,
> + <&clkc_periphs CLKID_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: [email protected]
> 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-clkc.h b/include/dt-bindings/clock/amlogic,a1-clkc.h
> new file mode 100644
> index 000000000000..95131779982c
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,a1-clkc.h
> @@ -0,0 +1,113 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
> + * Author: Jian Hu <[email protected]>
> + *
> + * Copyright (c) 2023, SberDevices. All Rights Reserved.
> + * Author: Dmitry Rokosov <[email protected]>
> + */
> +
> +#ifndef __A1_CLKC_H
> +#define __A1_CLKC_H
> +
> +#define CLKID_FIXPLL_IN 0
> +#define CLKID_USB_PHY_IN 1
> +#define CLKID_USB_CTRL_IN 2
> +#define CLKID_HIFIPLL_IN 3
> +#define CLKID_SYSPLL_IN 4
> +#define CLKID_DDS_IN 5
> +#define CLKID_SYS 6
> +#define CLKID_CLKTREE 7
> +#define CLKID_RESET_CTRL 8
> +#define CLKID_ANALOG_CTRL 9
> +#define CLKID_PWR_CTRL 10
> +#define CLKID_PAD_CTRL 11
> +#define CLKID_SYS_CTRL 12
> +#define CLKID_TEMP_SENSOR 13
> +#define CLKID_AM2AXI_DIV 14
> +#define CLKID_SPICC_B 15
> +#define CLKID_SPICC_A 16
> +#define CLKID_MSR 17
> +#define CLKID_AUDIO 18
> +#define CLKID_JTAG_CTRL 19
> +#define CLKID_SARADC_EN 20
> +#define CLKID_PWM_EF 21
> +#define CLKID_PWM_CD 22
> +#define CLKID_PWM_AB 23
> +#define CLKID_CEC 24
> +#define CLKID_I2C_S 25
> +#define CLKID_IR_CTRL 26
> +#define CLKID_I2C_M_D 27
> +#define CLKID_I2C_M_C 28
> +#define CLKID_I2C_M_B 29
> +#define CLKID_I2C_M_A 30
> +#define CLKID_ACODEC 31
> +#define CLKID_OTP 32
> +#define CLKID_SD_EMMC_A 33
> +#define CLKID_USB_PHY 34
> +#define CLKID_USB_CTRL 35
> +#define CLKID_SYS_DSPB 36
> +#define CLKID_SYS_DSPA 37
> +#define CLKID_DMA 38
> +#define CLKID_IRQ_CTRL 39
> +#define CLKID_NIC 40
> +#define CLKID_GIC 41
> +#define CLKID_UART_C 42
> +#define CLKID_UART_B 43
> +#define CLKID_UART_A 44
> +#define CLKID_SYS_PSRAM 45
> +#define CLKID_RSA 46
> +#define CLKID_CORESIGHT 47
> +#define CLKID_AM2AXI_VAD 48
> +#define CLKID_AUDIO_VAD 49
> +#define CLKID_AXI_DMC 50
> +#define CLKID_AXI_PSRAM 51
> +#define CLKID_RAMB 52
> +#define CLKID_RAMA 53
> +#define CLKID_AXI_SPIFC 54
> +#define CLKID_AXI_NIC 55
> +#define CLKID_AXI_DMA 56
> +#define CLKID_CPU_CTRL 57
> +#define CLKID_ROM 58
> +#define CLKID_PROC_I2C 59
> +#define CLKID_DSPA_EN 60
> +#define CLKID_DSPA_EN_NIC 61
> +#define CLKID_DSPB_EN 62
> +#define CLKID_DSPB_EN_NIC 63
> +#define CLKID_RTC 64
> +#define CLKID_CECA_32K 65
> +#define CLKID_CECB_32K 66
> +#define CLKID_24M 67
> +#define CLKID_12M 68
> +#define CLKID_FCLK_DIV2_DIVN 69
> +#define CLKID_GEN 70
> +#define CLKID_SARADC 71
> +#define CLKID_PWM_A 72
> +#define CLKID_PWM_B 73
> +#define CLKID_PWM_C 74
> +#define CLKID_PWM_D 75
> +#define CLKID_PWM_E 76
> +#define CLKID_PWM_F 77
> +#define CLKID_SPICC 78
> +#define CLKID_TS 79
> +#define CLKID_SPIFC 80
> +#define CLKID_USB_BUS 81
> +#define CLKID_SD_EMMC 82
> +#define CLKID_PSRAM 83
> +#define CLKID_DMC 84
> +#define CLKID_GEN_SEL 85
> +#define CLKID_PWM_A_SEL 86
> +#define CLKID_PWM_B_SEL 87
> +#define CLKID_PWM_C_SEL 88
> +#define CLKID_PWM_D_SEL 89
> +#define CLKID_PWM_E_SEL 90
> +#define CLKID_PWM_F_SEL 91
> +#define CLKID_DSPA_A_SEL 92
> +#define CLKID_DSPA_B_SEL 93
> +#define CLKID_DSPB_A_SEL 94
> +#define CLKID_DSPB_B_SEL 95
> +#define CLKID_CECA_32K_SEL 96
> +#define CLKID_CECB_32K_SEL 97
> +#define NR_CLKS 98
> +
> +#endif /* __A1_CLKC_H */
> 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..740fe8c4db5d
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
> + * Author: Jian Hu <[email protected]>
> + *
> + * Copyright (c) 2023, SberDevices. All Rights Reserved.
> + * Author: Dmitry Rokosov <[email protected]>
> + */
> +
> +#ifndef __A1_PLL_CLKC_H
> +#define __A1_PLL_CLKC_H
> +
> +#define CLKID_FIXED_PLL 0
> +#define CLKID_FCLK_DIV2 1
> +#define CLKID_FCLK_DIV3 2
> +#define CLKID_FCLK_DIV5 3
> +#define CLKID_FCLK_DIV7 4
> +#define CLKID_HIFI_PLL 5
> +#define NR_PLL_CLKS 6
> +
> +#endif /* __A1_PLL_CLKC_H */

2023-03-27 10:25:25

by Jerome Brunet

[permalink] [raw]
Subject: Re: [PATCH v11 5/5] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver


On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:

> 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 <[email protected]>
> Signed-off-by: Dmitry Rokosov <[email protected]>
> ---
> drivers/clk/meson/Kconfig | 10 +
> drivers/clk/meson/Makefile | 1 +
> drivers/clk/meson/a1.c | 2344 ++++++++++++++++++++++++++++++++++++
> drivers/clk/meson/a1.h | 49 +
> 4 files changed, 2404 insertions(+)
> create mode 100644 drivers/clk/meson/a1.c
> create mode 100644 drivers/clk/meson/a1.h
>

[...]

> +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),
> + /*
> + * DSPA_B clk can be inherited from more accurate RTC clock,
> + * so in some situations we may want to freeze its parent.
> + * Therefore force dsp parent setup on device tree side
> + */

This gets copy-pasted A LOT.
Please comment this once and for all ... then reference the comment if
you need to.

> + .flags = CLK_SET_RATE_NO_REPARENT,
> + },
> +};

[...]

> +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,
> + /*
> + * CECB_32K clk can be inherited from more accurate RTC clock,
> + * so in some situations we may want to freeze its parent.
> + * Therefore force cecb_32k parent setup on device tree side
> + */

How do you plan on doing that ?

You've made the parent "private" and it is not even available to be
referenced in DT.

This whole concept of public and private to seems broken to me.
I would much prefer you keep the existing model, with one big table and
possibly some IDs not exposed in the bindings.

This gives an hint about the clocks we think consummers should use while
allowing us to change things if we got it wrong, and keep the IDs stable
for DT. This has been working so far. I don't see the benefit of
changing that right now.

> + .flags = CLK_SET_RATE_NO_REPARENT,
> + },
> +};
> +

[...]

> +
> +static int meson_a1_periphs_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + void __iomem *base;
> + struct regmap *map;
> + int 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;
> +
> + /* DT clocks registration */
> + err = meson_a1_periphs_clks_register(dev, &a1_periphs_public_clks);
> + if (err)
> + return dev_err_probe(dev, err,
> + "public clks registration failed\n");
> +
> + /* Internal clocks registration */
> + err = meson_a1_periphs_clks_register(dev, &a1_periphs_private_clks);
> + if (err)
> + return dev_err_probe(dev, err,
> + "private clks registration failed\n");

I defenitely don't like this public/private concept.
Please remove it

> +
> + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
> + &a1_periphs_public_clks);
> +}
> +

2023-03-27 11:07:59

by Dmitry Rokosov

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
>
> On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
>
> > Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
> > clock drivers.
> > Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
> > bindings and include them to MAINTAINERS.
> >
> > Signed-off-by: Jian Hu <[email protected]>
> > Signed-off-by: Dmitry Rokosov <[email protected]>
> > ---
> > .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
> > .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
> > MAINTAINERS | 1 +
> > include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
> > .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
> > 5 files changed, 267 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
>
> There is two drivers (and 2 independent patches). There should be 2
> bindings patches as well.
>

Before, in previous versions I had two versions, but it wasn't bisectable
approach.
a1-clkc schema depends on a1-pll-clkc headers and vice versa.
It means dt schemas checkers will show us failure if we split them into two
patchsets.
I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
look like production schema and it requires one more patchset above the
series with proper CLKID definitons usage and proper header including.

BTW, there is an example of Rob's test bot failure found in the previous
v10 patch series due to chicken or the egg problem.
https://lore.kernel.org/all/[email protected]/

Please advise what's the best practice to resolve that..

> > create mode 100644 include/dt-bindings/clock/amlogic,a1-clkc.h
> > create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h
> >
> > diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> > new file mode 100644
> > index 000000000000..cb6d8f4eb959
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-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-clkc.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Amlogic Meson A/C serials Peripheral Clock Control Unit
> > +
> > +maintainers:
> > + - Neil Armstrong <[email protected]>
> > + - Jerome Brunet <[email protected]>
> > + - Jian Hu <[email protected]>
> > + - Dmitry Rokosov <[email protected]>
> > +
> > +properties:
> > + compatible:
> > + const: amlogic,a1-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-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
> > new file mode 100644
> > index 000000000000..77a13b1f9d5a
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
> > @@ -0,0 +1,59 @@
> > +# 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 Meson A/C serials PLL Clock Control Unit
> > +
> > +maintainers:
> > + - Neil Armstrong <[email protected]>
> > + - Jerome Brunet <[email protected]>
> > + - Jian Hu <[email protected]>
> > + - Dmitry Rokosov <[email protected]>
> > +
> > +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:
> > + - |
> > + #include <dt-bindings/clock/amlogic,a1-clkc.h>
> > + 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 CLKID_FIXPLL_IN>,
> > + <&clkc_periphs CLKID_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: [email protected]
> > 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-clkc.h b/include/dt-bindings/clock/amlogic,a1-clkc.h
> > new file mode 100644
> > index 000000000000..95131779982c
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/amlogic,a1-clkc.h
> > @@ -0,0 +1,113 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> > +/*
> > + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
> > + * Author: Jian Hu <[email protected]>
> > + *
> > + * Copyright (c) 2023, SberDevices. All Rights Reserved.
> > + * Author: Dmitry Rokosov <[email protected]>
> > + */
> > +
> > +#ifndef __A1_CLKC_H
> > +#define __A1_CLKC_H
> > +
> > +#define CLKID_FIXPLL_IN 0
> > +#define CLKID_USB_PHY_IN 1
> > +#define CLKID_USB_CTRL_IN 2
> > +#define CLKID_HIFIPLL_IN 3
> > +#define CLKID_SYSPLL_IN 4
> > +#define CLKID_DDS_IN 5
> > +#define CLKID_SYS 6
> > +#define CLKID_CLKTREE 7
> > +#define CLKID_RESET_CTRL 8
> > +#define CLKID_ANALOG_CTRL 9
> > +#define CLKID_PWR_CTRL 10
> > +#define CLKID_PAD_CTRL 11
> > +#define CLKID_SYS_CTRL 12
> > +#define CLKID_TEMP_SENSOR 13
> > +#define CLKID_AM2AXI_DIV 14
> > +#define CLKID_SPICC_B 15
> > +#define CLKID_SPICC_A 16
> > +#define CLKID_MSR 17
> > +#define CLKID_AUDIO 18
> > +#define CLKID_JTAG_CTRL 19
> > +#define CLKID_SARADC_EN 20
> > +#define CLKID_PWM_EF 21
> > +#define CLKID_PWM_CD 22
> > +#define CLKID_PWM_AB 23
> > +#define CLKID_CEC 24
> > +#define CLKID_I2C_S 25
> > +#define CLKID_IR_CTRL 26
> > +#define CLKID_I2C_M_D 27
> > +#define CLKID_I2C_M_C 28
> > +#define CLKID_I2C_M_B 29
> > +#define CLKID_I2C_M_A 30
> > +#define CLKID_ACODEC 31
> > +#define CLKID_OTP 32
> > +#define CLKID_SD_EMMC_A 33
> > +#define CLKID_USB_PHY 34
> > +#define CLKID_USB_CTRL 35
> > +#define CLKID_SYS_DSPB 36
> > +#define CLKID_SYS_DSPA 37
> > +#define CLKID_DMA 38
> > +#define CLKID_IRQ_CTRL 39
> > +#define CLKID_NIC 40
> > +#define CLKID_GIC 41
> > +#define CLKID_UART_C 42
> > +#define CLKID_UART_B 43
> > +#define CLKID_UART_A 44
> > +#define CLKID_SYS_PSRAM 45
> > +#define CLKID_RSA 46
> > +#define CLKID_CORESIGHT 47
> > +#define CLKID_AM2AXI_VAD 48
> > +#define CLKID_AUDIO_VAD 49
> > +#define CLKID_AXI_DMC 50
> > +#define CLKID_AXI_PSRAM 51
> > +#define CLKID_RAMB 52
> > +#define CLKID_RAMA 53
> > +#define CLKID_AXI_SPIFC 54
> > +#define CLKID_AXI_NIC 55
> > +#define CLKID_AXI_DMA 56
> > +#define CLKID_CPU_CTRL 57
> > +#define CLKID_ROM 58
> > +#define CLKID_PROC_I2C 59
> > +#define CLKID_DSPA_EN 60
> > +#define CLKID_DSPA_EN_NIC 61
> > +#define CLKID_DSPB_EN 62
> > +#define CLKID_DSPB_EN_NIC 63
> > +#define CLKID_RTC 64
> > +#define CLKID_CECA_32K 65
> > +#define CLKID_CECB_32K 66
> > +#define CLKID_24M 67
> > +#define CLKID_12M 68
> > +#define CLKID_FCLK_DIV2_DIVN 69
> > +#define CLKID_GEN 70
> > +#define CLKID_SARADC 71
> > +#define CLKID_PWM_A 72
> > +#define CLKID_PWM_B 73
> > +#define CLKID_PWM_C 74
> > +#define CLKID_PWM_D 75
> > +#define CLKID_PWM_E 76
> > +#define CLKID_PWM_F 77
> > +#define CLKID_SPICC 78
> > +#define CLKID_TS 79
> > +#define CLKID_SPIFC 80
> > +#define CLKID_USB_BUS 81
> > +#define CLKID_SD_EMMC 82
> > +#define CLKID_PSRAM 83
> > +#define CLKID_DMC 84
> > +#define CLKID_GEN_SEL 85
> > +#define CLKID_PWM_A_SEL 86
> > +#define CLKID_PWM_B_SEL 87
> > +#define CLKID_PWM_C_SEL 88
> > +#define CLKID_PWM_D_SEL 89
> > +#define CLKID_PWM_E_SEL 90
> > +#define CLKID_PWM_F_SEL 91
> > +#define CLKID_DSPA_A_SEL 92
> > +#define CLKID_DSPA_B_SEL 93
> > +#define CLKID_DSPB_A_SEL 94
> > +#define CLKID_DSPB_B_SEL 95
> > +#define CLKID_CECA_32K_SEL 96
> > +#define CLKID_CECB_32K_SEL 97
> > +#define NR_CLKS 98
> > +
> > +#endif /* __A1_CLKC_H */
> > 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..740fe8c4db5d
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
> > @@ -0,0 +1,21 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> > +/*
> > + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
> > + * Author: Jian Hu <[email protected]>
> > + *
> > + * Copyright (c) 2023, SberDevices. All Rights Reserved.
> > + * Author: Dmitry Rokosov <[email protected]>
> > + */
> > +
> > +#ifndef __A1_PLL_CLKC_H
> > +#define __A1_PLL_CLKC_H
> > +
> > +#define CLKID_FIXED_PLL 0
> > +#define CLKID_FCLK_DIV2 1
> > +#define CLKID_FCLK_DIV3 2
> > +#define CLKID_FCLK_DIV5 3
> > +#define CLKID_FCLK_DIV7 4
> > +#define CLKID_HIFI_PLL 5
> > +#define NR_PLL_CLKS 6
> > +
> > +#endif /* __A1_PLL_CLKC_H */
>

--
Thank you,
Dmitry

2023-03-27 11:55:17

by Jerome Brunet

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings


On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:

> On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
>>
>> On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
>>
>> > Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
>> > clock drivers.
>> > Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
>> > bindings and include them to MAINTAINERS.
>> >
>> > Signed-off-by: Jian Hu <[email protected]>
>> > Signed-off-by: Dmitry Rokosov <[email protected]>
>> > ---
>> > .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
>> > .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
>> > MAINTAINERS | 1 +
>> > include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
>> > .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
>> > 5 files changed, 267 insertions(+)
>> > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
>> > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
>>
>> There is two drivers (and 2 independent patches). There should be 2
>> bindings patches as well.
>>
>
> Before, in previous versions I had two versions, but it wasn't bisectable
> approach.

You are confusing bisectable and Rob's robot. Splitting patches is more
that likely to help bisect (and patches backport) - not the other way around.

> a1-clkc schema depends on a1-pll-clkc headers and vice versa.
> It means dt schemas checkers will show us failure if we split them into two
> patchsets.

Only because you are patches are not upstream yet ...

> I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
> look like production schema and it requires one more patchset above the
> series with proper CLKID definitons usage and proper header including.
>
> BTW, there is an example of Rob's test bot failure found in the previous
> v10 patch series due to chicken or the egg problem.
> https://lore.kernel.org/all/[email protected]/
>
> Please advise what's the best practice to resolve that..

Don't use the header in your example would solve the problem and
still be correct DT wise.

The examples are just examples, they are not required to actually
matches a real HW, as far as I know.

>
>> > create mode 100644 include/dt-bindings/clock/amlogic,a1-clkc.h
>> > create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h
>> >
>> > diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
>> > new file mode 100644
>> > index 000000000000..cb6d8f4eb959
>> > --- /dev/null
>> > +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-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-clkc.yaml#
>> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> > +
>> > +title: Amlogic Meson A/C serials Peripheral Clock Control Unit
>> > +
>> > +maintainers:
>> > + - Neil Armstrong <[email protected]>
>> > + - Jerome Brunet <[email protected]>
>> > + - Jian Hu <[email protected]>
>> > + - Dmitry Rokosov <[email protected]>
>> > +
>> > +properties:
>> > + compatible:
>> > + const: amlogic,a1-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-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
>> > new file mode 100644
>> > index 000000000000..77a13b1f9d5a
>> > --- /dev/null
>> > +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
>> > @@ -0,0 +1,59 @@
>> > +# 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 Meson A/C serials PLL Clock Control Unit
>> > +
>> > +maintainers:
>> > + - Neil Armstrong <[email protected]>
>> > + - Jerome Brunet <[email protected]>
>> > + - Jian Hu <[email protected]>
>> > + - Dmitry Rokosov <[email protected]>
>> > +
>> > +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:
>> > + - |
>> > + #include <dt-bindings/clock/amlogic,a1-clkc.h>
>> > + 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 CLKID_FIXPLL_IN>,
>> > + <&clkc_periphs CLKID_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: [email protected]
>> > 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-clkc.h b/include/dt-bindings/clock/amlogic,a1-clkc.h
>> > new file mode 100644
>> > index 000000000000..95131779982c
>> > --- /dev/null
>> > +++ b/include/dt-bindings/clock/amlogic,a1-clkc.h
>> > @@ -0,0 +1,113 @@
>> > +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
>> > +/*
>> > + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
>> > + * Author: Jian Hu <[email protected]>
>> > + *
>> > + * Copyright (c) 2023, SberDevices. All Rights Reserved.
>> > + * Author: Dmitry Rokosov <[email protected]>
>> > + */
>> > +
>> > +#ifndef __A1_CLKC_H
>> > +#define __A1_CLKC_H
>> > +
>> > +#define CLKID_FIXPLL_IN 0
>> > +#define CLKID_USB_PHY_IN 1
>> > +#define CLKID_USB_CTRL_IN 2
>> > +#define CLKID_HIFIPLL_IN 3
>> > +#define CLKID_SYSPLL_IN 4
>> > +#define CLKID_DDS_IN 5
>> > +#define CLKID_SYS 6
>> > +#define CLKID_CLKTREE 7
>> > +#define CLKID_RESET_CTRL 8
>> > +#define CLKID_ANALOG_CTRL 9
>> > +#define CLKID_PWR_CTRL 10
>> > +#define CLKID_PAD_CTRL 11
>> > +#define CLKID_SYS_CTRL 12
>> > +#define CLKID_TEMP_SENSOR 13
>> > +#define CLKID_AM2AXI_DIV 14
>> > +#define CLKID_SPICC_B 15
>> > +#define CLKID_SPICC_A 16
>> > +#define CLKID_MSR 17
>> > +#define CLKID_AUDIO 18
>> > +#define CLKID_JTAG_CTRL 19
>> > +#define CLKID_SARADC_EN 20
>> > +#define CLKID_PWM_EF 21
>> > +#define CLKID_PWM_CD 22
>> > +#define CLKID_PWM_AB 23
>> > +#define CLKID_CEC 24
>> > +#define CLKID_I2C_S 25
>> > +#define CLKID_IR_CTRL 26
>> > +#define CLKID_I2C_M_D 27
>> > +#define CLKID_I2C_M_C 28
>> > +#define CLKID_I2C_M_B 29
>> > +#define CLKID_I2C_M_A 30
>> > +#define CLKID_ACODEC 31
>> > +#define CLKID_OTP 32
>> > +#define CLKID_SD_EMMC_A 33
>> > +#define CLKID_USB_PHY 34
>> > +#define CLKID_USB_CTRL 35
>> > +#define CLKID_SYS_DSPB 36
>> > +#define CLKID_SYS_DSPA 37
>> > +#define CLKID_DMA 38
>> > +#define CLKID_IRQ_CTRL 39
>> > +#define CLKID_NIC 40
>> > +#define CLKID_GIC 41
>> > +#define CLKID_UART_C 42
>> > +#define CLKID_UART_B 43
>> > +#define CLKID_UART_A 44
>> > +#define CLKID_SYS_PSRAM 45
>> > +#define CLKID_RSA 46
>> > +#define CLKID_CORESIGHT 47
>> > +#define CLKID_AM2AXI_VAD 48
>> > +#define CLKID_AUDIO_VAD 49
>> > +#define CLKID_AXI_DMC 50
>> > +#define CLKID_AXI_PSRAM 51
>> > +#define CLKID_RAMB 52
>> > +#define CLKID_RAMA 53
>> > +#define CLKID_AXI_SPIFC 54
>> > +#define CLKID_AXI_NIC 55
>> > +#define CLKID_AXI_DMA 56
>> > +#define CLKID_CPU_CTRL 57
>> > +#define CLKID_ROM 58
>> > +#define CLKID_PROC_I2C 59
>> > +#define CLKID_DSPA_EN 60
>> > +#define CLKID_DSPA_EN_NIC 61
>> > +#define CLKID_DSPB_EN 62
>> > +#define CLKID_DSPB_EN_NIC 63
>> > +#define CLKID_RTC 64
>> > +#define CLKID_CECA_32K 65
>> > +#define CLKID_CECB_32K 66
>> > +#define CLKID_24M 67
>> > +#define CLKID_12M 68
>> > +#define CLKID_FCLK_DIV2_DIVN 69
>> > +#define CLKID_GEN 70
>> > +#define CLKID_SARADC 71
>> > +#define CLKID_PWM_A 72
>> > +#define CLKID_PWM_B 73
>> > +#define CLKID_PWM_C 74
>> > +#define CLKID_PWM_D 75
>> > +#define CLKID_PWM_E 76
>> > +#define CLKID_PWM_F 77
>> > +#define CLKID_SPICC 78
>> > +#define CLKID_TS 79
>> > +#define CLKID_SPIFC 80
>> > +#define CLKID_USB_BUS 81
>> > +#define CLKID_SD_EMMC 82
>> > +#define CLKID_PSRAM 83
>> > +#define CLKID_DMC 84
>> > +#define CLKID_GEN_SEL 85
>> > +#define CLKID_PWM_A_SEL 86
>> > +#define CLKID_PWM_B_SEL 87
>> > +#define CLKID_PWM_C_SEL 88
>> > +#define CLKID_PWM_D_SEL 89
>> > +#define CLKID_PWM_E_SEL 90
>> > +#define CLKID_PWM_F_SEL 91
>> > +#define CLKID_DSPA_A_SEL 92
>> > +#define CLKID_DSPA_B_SEL 93
>> > +#define CLKID_DSPB_A_SEL 94
>> > +#define CLKID_DSPB_B_SEL 95
>> > +#define CLKID_CECA_32K_SEL 96
>> > +#define CLKID_CECB_32K_SEL 97
>> > +#define NR_CLKS 98
>> > +
>> > +#endif /* __A1_CLKC_H */
>> > 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..740fe8c4db5d
>> > --- /dev/null
>> > +++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
>> > @@ -0,0 +1,21 @@
>> > +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
>> > +/*
>> > + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
>> > + * Author: Jian Hu <[email protected]>
>> > + *
>> > + * Copyright (c) 2023, SberDevices. All Rights Reserved.
>> > + * Author: Dmitry Rokosov <[email protected]>
>> > + */
>> > +
>> > +#ifndef __A1_PLL_CLKC_H
>> > +#define __A1_PLL_CLKC_H
>> > +
>> > +#define CLKID_FIXED_PLL 0
>> > +#define CLKID_FCLK_DIV2 1
>> > +#define CLKID_FCLK_DIV3 2
>> > +#define CLKID_FCLK_DIV5 3
>> > +#define CLKID_FCLK_DIV7 4
>> > +#define CLKID_HIFI_PLL 5
>> > +#define NR_PLL_CLKS 6
>> > +
>> > +#endif /* __A1_PLL_CLKC_H */
>>

2023-03-27 12:15:24

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

On 27/03/2023 13:39, Jerome Brunet wrote:
>
> On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:
>
>> On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
>>>
>>> On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
>>>
>>>> Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
>>>> clock drivers.
>>>> Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
>>>> bindings and include them to MAINTAINERS.
>>>>
>>>> Signed-off-by: Jian Hu <[email protected]>
>>>> Signed-off-by: Dmitry Rokosov <[email protected]>
>>>> ---
>>>> .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
>>>> .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
>>>> MAINTAINERS | 1 +
>>>> include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
>>>> .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
>>>> 5 files changed, 267 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
>>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
>>>
>>> There is two drivers (and 2 independent patches). There should be 2
>>> bindings patches as well.
>>>
>>
>> Before, in previous versions I had two versions, but it wasn't bisectable
>> approach.
>
> You are confusing bisectable and Rob's robot. Splitting patches is more
> that likely to help bisect (and patches backport) - not the other way around.
>
>> a1-clkc schema depends on a1-pll-clkc headers and vice versa.
>> It means dt schemas checkers will show us failure if we split them into two
>> patchsets.
>
> Only because you are patches are not upstream yet ...
>
>> I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
>> look like production schema and it requires one more patchset above the
>> series with proper CLKID definitons usage and proper header including.
>>
>> BTW, there is an example of Rob's test bot failure found in the previous
>> v10 patch series due to chicken or the egg problem.
>> https://lore.kernel.org/all/[email protected]/
>>
>> Please advise what's the best practice to resolve that..
>
> Don't use the header in your example would solve the problem and
> still be correct DT wise.
>
> The examples are just examples, they are not required to actually
> matches a real HW, as far as I know.

Exact, you can use fake lables instead of defined:

<&clkc_pll CLKID_FCLK_DIV2>,

=>
remove "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"

<&clkc_pll_fclk_div2>,

is perfectly ok and will permit have 2 separate patches.

The dependency is only if you have a common yaml file for
both bindings files, but this is not the case here.

Neil

>
>>
>>>> create mode 100644 include/dt-bindings/clock/amlogic,a1-clkc.h
>>>> create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
>>>> new file mode 100644
>>>> index 000000000000..cb6d8f4eb959
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-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-clkc.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Amlogic Meson A/C serials Peripheral Clock Control Unit
>>>> +
>>>> +maintainers:
>>>> + - Neil Armstrong <[email protected]>
>>>> + - Jerome Brunet <[email protected]>
>>>> + - Jian Hu <[email protected]>
>>>> + - Dmitry Rokosov <[email protected]>
>>>> +
>>>> +properties:
>>>> + compatible:
>>>> + const: amlogic,a1-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-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
>>>> new file mode 100644
>>>> index 000000000000..77a13b1f9d5a
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
>>>> @@ -0,0 +1,59 @@
>>>> +# 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 Meson A/C serials PLL Clock Control Unit
>>>> +
>>>> +maintainers:
>>>> + - Neil Armstrong <[email protected]>
>>>> + - Jerome Brunet <[email protected]>
>>>> + - Jian Hu <[email protected]>
>>>> + - Dmitry Rokosov <[email protected]>
>>>> +
>>>> +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:
>>>> + - |
>>>> + #include <dt-bindings/clock/amlogic,a1-clkc.h>
>>>> + 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 CLKID_FIXPLL_IN>,
>>>> + <&clkc_periphs CLKID_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: [email protected]
>>>> 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-clkc.h b/include/dt-bindings/clock/amlogic,a1-clkc.h
>>>> new file mode 100644
>>>> index 000000000000..95131779982c
>>>> --- /dev/null
>>>> +++ b/include/dt-bindings/clock/amlogic,a1-clkc.h
>>>> @@ -0,0 +1,113 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
>>>> +/*
>>>> + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
>>>> + * Author: Jian Hu <[email protected]>
>>>> + *
>>>> + * Copyright (c) 2023, SberDevices. All Rights Reserved.
>>>> + * Author: Dmitry Rokosov <[email protected]>
>>>> + */
>>>> +
>>>> +#ifndef __A1_CLKC_H
>>>> +#define __A1_CLKC_H
>>>> +
>>>> +#define CLKID_FIXPLL_IN 0
>>>> +#define CLKID_USB_PHY_IN 1
>>>> +#define CLKID_USB_CTRL_IN 2
>>>> +#define CLKID_HIFIPLL_IN 3
>>>> +#define CLKID_SYSPLL_IN 4
>>>> +#define CLKID_DDS_IN 5
>>>> +#define CLKID_SYS 6
>>>> +#define CLKID_CLKTREE 7
>>>> +#define CLKID_RESET_CTRL 8
>>>> +#define CLKID_ANALOG_CTRL 9
>>>> +#define CLKID_PWR_CTRL 10
>>>> +#define CLKID_PAD_CTRL 11
>>>> +#define CLKID_SYS_CTRL 12
>>>> +#define CLKID_TEMP_SENSOR 13
>>>> +#define CLKID_AM2AXI_DIV 14
>>>> +#define CLKID_SPICC_B 15
>>>> +#define CLKID_SPICC_A 16
>>>> +#define CLKID_MSR 17
>>>> +#define CLKID_AUDIO 18
>>>> +#define CLKID_JTAG_CTRL 19
>>>> +#define CLKID_SARADC_EN 20
>>>> +#define CLKID_PWM_EF 21
>>>> +#define CLKID_PWM_CD 22
>>>> +#define CLKID_PWM_AB 23
>>>> +#define CLKID_CEC 24
>>>> +#define CLKID_I2C_S 25
>>>> +#define CLKID_IR_CTRL 26
>>>> +#define CLKID_I2C_M_D 27
>>>> +#define CLKID_I2C_M_C 28
>>>> +#define CLKID_I2C_M_B 29
>>>> +#define CLKID_I2C_M_A 30
>>>> +#define CLKID_ACODEC 31
>>>> +#define CLKID_OTP 32
>>>> +#define CLKID_SD_EMMC_A 33
>>>> +#define CLKID_USB_PHY 34
>>>> +#define CLKID_USB_CTRL 35
>>>> +#define CLKID_SYS_DSPB 36
>>>> +#define CLKID_SYS_DSPA 37
>>>> +#define CLKID_DMA 38
>>>> +#define CLKID_IRQ_CTRL 39
>>>> +#define CLKID_NIC 40
>>>> +#define CLKID_GIC 41
>>>> +#define CLKID_UART_C 42
>>>> +#define CLKID_UART_B 43
>>>> +#define CLKID_UART_A 44
>>>> +#define CLKID_SYS_PSRAM 45
>>>> +#define CLKID_RSA 46
>>>> +#define CLKID_CORESIGHT 47
>>>> +#define CLKID_AM2AXI_VAD 48
>>>> +#define CLKID_AUDIO_VAD 49
>>>> +#define CLKID_AXI_DMC 50
>>>> +#define CLKID_AXI_PSRAM 51
>>>> +#define CLKID_RAMB 52
>>>> +#define CLKID_RAMA 53
>>>> +#define CLKID_AXI_SPIFC 54
>>>> +#define CLKID_AXI_NIC 55
>>>> +#define CLKID_AXI_DMA 56
>>>> +#define CLKID_CPU_CTRL 57
>>>> +#define CLKID_ROM 58
>>>> +#define CLKID_PROC_I2C 59
>>>> +#define CLKID_DSPA_EN 60
>>>> +#define CLKID_DSPA_EN_NIC 61
>>>> +#define CLKID_DSPB_EN 62
>>>> +#define CLKID_DSPB_EN_NIC 63
>>>> +#define CLKID_RTC 64
>>>> +#define CLKID_CECA_32K 65
>>>> +#define CLKID_CECB_32K 66
>>>> +#define CLKID_24M 67
>>>> +#define CLKID_12M 68
>>>> +#define CLKID_FCLK_DIV2_DIVN 69
>>>> +#define CLKID_GEN 70
>>>> +#define CLKID_SARADC 71
>>>> +#define CLKID_PWM_A 72
>>>> +#define CLKID_PWM_B 73
>>>> +#define CLKID_PWM_C 74
>>>> +#define CLKID_PWM_D 75
>>>> +#define CLKID_PWM_E 76
>>>> +#define CLKID_PWM_F 77
>>>> +#define CLKID_SPICC 78
>>>> +#define CLKID_TS 79
>>>> +#define CLKID_SPIFC 80
>>>> +#define CLKID_USB_BUS 81
>>>> +#define CLKID_SD_EMMC 82
>>>> +#define CLKID_PSRAM 83
>>>> +#define CLKID_DMC 84
>>>> +#define CLKID_GEN_SEL 85
>>>> +#define CLKID_PWM_A_SEL 86
>>>> +#define CLKID_PWM_B_SEL 87
>>>> +#define CLKID_PWM_C_SEL 88
>>>> +#define CLKID_PWM_D_SEL 89
>>>> +#define CLKID_PWM_E_SEL 90
>>>> +#define CLKID_PWM_F_SEL 91
>>>> +#define CLKID_DSPA_A_SEL 92
>>>> +#define CLKID_DSPA_B_SEL 93
>>>> +#define CLKID_DSPB_A_SEL 94
>>>> +#define CLKID_DSPB_B_SEL 95
>>>> +#define CLKID_CECA_32K_SEL 96
>>>> +#define CLKID_CECB_32K_SEL 97
>>>> +#define NR_CLKS 98
>>>> +
>>>> +#endif /* __A1_CLKC_H */
>>>> 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..740fe8c4db5d
>>>> --- /dev/null
>>>> +++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h
>>>> @@ -0,0 +1,21 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
>>>> +/*
>>>> + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
>>>> + * Author: Jian Hu <[email protected]>
>>>> + *
>>>> + * Copyright (c) 2023, SberDevices. All Rights Reserved.
>>>> + * Author: Dmitry Rokosov <[email protected]>
>>>> + */
>>>> +
>>>> +#ifndef __A1_PLL_CLKC_H
>>>> +#define __A1_PLL_CLKC_H
>>>> +
>>>> +#define CLKID_FIXED_PLL 0
>>>> +#define CLKID_FCLK_DIV2 1
>>>> +#define CLKID_FCLK_DIV3 2
>>>> +#define CLKID_FCLK_DIV5 3
>>>> +#define CLKID_FCLK_DIV7 4
>>>> +#define CLKID_HIFI_PLL 5
>>>> +#define NR_PLL_CLKS 6
>>>> +
>>>> +#endif /* __A1_PLL_CLKC_H */
>>>
>

2023-03-27 13:24:07

by Dmitry Rokosov

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

On Mon, Mar 27, 2023 at 02:03:25PM +0200, [email protected] wrote:
> On 27/03/2023 13:39, Jerome Brunet wrote:
> >
> > On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:
> >
> > > On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
> > > >
> > > > On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
> > > >
> > > > > Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
> > > > > clock drivers.
> > > > > Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
> > > > > bindings and include them to MAINTAINERS.
> > > > >
> > > > > Signed-off-by: Jian Hu <[email protected]>
> > > > > Signed-off-by: Dmitry Rokosov <[email protected]>
> > > > > ---
> > > > > .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
> > > > > .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
> > > > > MAINTAINERS | 1 +
> > > > > include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
> > > > > .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
> > > > > 5 files changed, 267 insertions(+)
> > > > > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> > > > > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
> > > >
> > > > There is two drivers (and 2 independent patches). There should be 2
> > > > bindings patches as well.
> > > >
> > >
> > > Before, in previous versions I had two versions, but it wasn't bisectable
> > > approach.
> >
> > You are confusing bisectable and Rob's robot. Splitting patches is more
> > that likely to help bisect (and patches backport) - not the other way around.
> >
> > > a1-clkc schema depends on a1-pll-clkc headers and vice versa.
> > > It means dt schemas checkers will show us failure if we split them into two
> > > patchsets.
> >
> > Only because you are patches are not upstream yet ...
> >
> > > I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
> > > look like production schema and it requires one more patchset above the
> > > series with proper CLKID definitons usage and proper header including.
> > >
> > > BTW, there is an example of Rob's test bot failure found in the previous
> > > v10 patch series due to chicken or the egg problem.
> > > https://lore.kernel.org/all/[email protected]/
> > >
> > > Please advise what's the best practice to resolve that..
> >
> > Don't use the header in your example would solve the problem and
> > still be correct DT wise.
> >
> > The examples are just examples, they are not required to actually
> > matches a real HW, as far as I know.
>
> Exact, you can use fake lables instead of defined:
>
> <&clkc_pll CLKID_FCLK_DIV2>,
>
> =>
> remove "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"
>
> <&clkc_pll_fclk_div2>,
>
> is perfectly ok and will permit have 2 separate patches.
>
> The dependency is only if you have a common yaml file for
> both bindings files, but this is not the case here.

Simple removal of "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"
header doesn't work, dt_binding_check make rule is failed:

Error: Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts:28.37-38 syntax error
FATAL ERROR: Unable to parse input tree

It happens, because 'dt_binding_check' generates simple dts example and
tries to compile it:

cat Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts
===

/dts-v1/;
/plugin/; // silence any missing phandle references


/{
compatible = "foo";
model = "foo";
#address-cells = <1>;
#size-cells = <1>;



example-0 {
#address-cells = <1>;
#size-cells = <1>;



apb {
#address-cells = <2>;
#size-cells = <2>;

clock-controller@800 {
compatible = "amlogic,a1-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";
};
};

};
};
===

As you can see, header is required.

But looks like, dt binding checker is happy with the fake references hack :)
Below there is generated example dts:

cat Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts
===

/dts-v1/;
/plugin/; // silence any missing phandle references


/{
compatible = "foo";
model = "foo";
#address-cells = <1>;
#size-cells = <1>;



example-0 {
#address-cells = <1>;
#size-cells = <1>;



apb {
#address-cells = <2>;
#size-cells = <2>;

clock-controller@800 {
compatible = "amlogic,a1-clkc";
reg = <0 0x800 0 0x104>;
#clock-cells = <1>;
clocks = <&clkc_pll_fclk_div2>,
<&clkc_pll_fclk_div3>,
<&clkc_pll_fclk_div5>,
<&clkc_pll_fclk_div7>,
<&clkc_pll_hifi_pll>,
<&xtal>;
clock-names = "fclk_div2", "fclk_div3",
"fclk_div5", "fclk_div7",
"hifi_pll", "xtal";
};
};

};
};
===

Yep, we are able to cheat dt checkers, but we don't help dt developers
with such example.
May be, it's better to prepare two patches in such hierarchy:

1) A1 PLL clkc bindings with fake references without clkc headers
2) A1 clkc bindings with real CLKID bindings + A1 PLL clkc bindings fix
with real CLKID A1 clkc bindings + header.

The such approach resolves DT checkers failures and split DT bindings
into two patchsets.

[...]

--
Thank you,
Dmitry

2023-03-27 13:24:17

by Dmitry Rokosov

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

Don't know why, but my client deleted Jerome from To:. Sorry, added him
back.

On Mon, Mar 27, 2023 at 02:03:25PM +0200, [email protected] wrote:
> On 27/03/2023 13:39, Jerome Brunet wrote:
> >
> > On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:
> >
> > > On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
> > > >
> > > > On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
> > > >
> > > > > Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
> > > > > clock drivers.
> > > > > Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
> > > > > bindings and include them to MAINTAINERS.
> > > > >
> > > > > Signed-off-by: Jian Hu <[email protected]>
> > > > > Signed-off-by: Dmitry Rokosov <[email protected]>
> > > > > ---
> > > > > .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
> > > > > .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
> > > > > MAINTAINERS | 1 +
> > > > > include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
> > > > > .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
> > > > > 5 files changed, 267 insertions(+)
> > > > > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> > > > > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
> > > >
> > > > There is two drivers (and 2 independent patches). There should be 2
> > > > bindings patches as well.
> > > >
> > >
> > > Before, in previous versions I had two versions, but it wasn't bisectable
> > > approach.
> >
> > You are confusing bisectable and Rob's robot. Splitting patches is more
> > that likely to help bisect (and patches backport) - not the other way around.
> >
> > > a1-clkc schema depends on a1-pll-clkc headers and vice versa.
> > > It means dt schemas checkers will show us failure if we split them into two
> > > patchsets.
> >
> > Only because you are patches are not upstream yet ...
> >
> > > I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
> > > look like production schema and it requires one more patchset above the
> > > series with proper CLKID definitons usage and proper header including.
> > >
> > > BTW, there is an example of Rob's test bot failure found in the previous
> > > v10 patch series due to chicken or the egg problem.
> > > https://lore.kernel.org/all/[email protected]/
> > >
> > > Please advise what's the best practice to resolve that..
> >
> > Don't use the header in your example would solve the problem and
> > still be correct DT wise.
> >
> > The examples are just examples, they are not required to actually
> > matches a real HW, as far as I know.
>
> Exact, you can use fake lables instead of defined:
>
> <&clkc_pll CLKID_FCLK_DIV2>,
>
> =>
> remove "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"
>
> <&clkc_pll_fclk_div2>,
>
> is perfectly ok and will permit have 2 separate patches.
>
> The dependency is only if you have a common yaml file for
> both bindings files, but this is not the case here.

Simple removal of "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"
header doesn't work, dt_binding_check make rule is failed:

Error: Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts:28.37-38 syntax error
FATAL ERROR: Unable to parse input tree

It happens, because 'dt_binding_check' generates simple dts example and
tries to compile it:

cat Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts
===

/dts-v1/;
/plugin/; // silence any missing phandle references


/{
compatible = "foo";
model = "foo";
#address-cells = <1>;
#size-cells = <1>;



example-0 {
#address-cells = <1>;
#size-cells = <1>;



apb {
#address-cells = <2>;
#size-cells = <2>;

clock-controller@800 {
compatible = "amlogic,a1-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";
};
};

};
};
===

As you can see, header is required.

But looks like, dt binding checker is happy with the fake references hack :)
Below there is generated example dts:

cat Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts
===

/dts-v1/;
/plugin/; // silence any missing phandle references


/{
compatible = "foo";
model = "foo";
#address-cells = <1>;
#size-cells = <1>;



example-0 {
#address-cells = <1>;
#size-cells = <1>;



apb {
#address-cells = <2>;
#size-cells = <2>;

clock-controller@800 {
compatible = "amlogic,a1-clkc";
reg = <0 0x800 0 0x104>;
#clock-cells = <1>;
clocks = <&clkc_pll_fclk_div2>,
<&clkc_pll_fclk_div3>,
<&clkc_pll_fclk_div5>,
<&clkc_pll_fclk_div7>,
<&clkc_pll_hifi_pll>,
<&xtal>;
clock-names = "fclk_div2", "fclk_div3",
"fclk_div5", "fclk_div7",
"hifi_pll", "xtal";
};
};

};
};
===

Yep, we are able to cheat dt checkers, but we don't help dt developers
with such example.
May be, it's better to prepare two patches in such hierarchy:

1) A1 PLL clkc bindings with fake references without clkc headers
2) A1 clkc bindings with real CLKID bindings + A1 PLL clkc bindings fix
with real CLKID A1 clkc bindings + header.

The such approach resolves DT checkers failures and split DT bindings
into two patchsets.

[...]

--
Thank you,
Dmitry

2023-03-27 13:29:22

by Dmitry Rokosov

[permalink] [raw]
Subject: Re: [PATCH v11 5/5] clk: meson: a1: add Amlogic A1 Peripherals clock controller driver

On Mon, Mar 27, 2023 at 11:58:30AM +0200, Jerome Brunet wrote:
>
> On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
>
> > 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 <[email protected]>
> > Signed-off-by: Dmitry Rokosov <[email protected]>
> > ---
> > drivers/clk/meson/Kconfig | 10 +
> > drivers/clk/meson/Makefile | 1 +
> > drivers/clk/meson/a1.c | 2344 ++++++++++++++++++++++++++++++++++++
> > drivers/clk/meson/a1.h | 49 +
> > 4 files changed, 2404 insertions(+)
> > create mode 100644 drivers/clk/meson/a1.c
> > create mode 100644 drivers/clk/meson/a1.h
> >
>
> [...]
>
> > +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),
> > + /*
> > + * DSPA_B clk can be inherited from more accurate RTC clock,
> > + * so in some situations we may want to freeze its parent.
> > + * Therefore force dsp parent setup on device tree side
> > + */
>
> This gets copy-pasted A LOT.
> Please comment this once and for all ... then reference the comment if
> you need to.
>

Agree. No problem. I'll collapse them in the next version.

> > + .flags = CLK_SET_RATE_NO_REPARENT,
> > + },
> > +};
>
> [...]
>
> > +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,
> > + /*
> > + * CECB_32K clk can be inherited from more accurate RTC clock,
> > + * so in some situations we may want to freeze its parent.
> > + * Therefore force cecb_32k parent setup on device tree side
> > + */
>
> How do you plan on doing that ?
>
> You've made the parent "private" and it is not even available to be
> referenced in DT.
>
> This whole concept of public and private to seems broken to me.
> I would much prefer you keep the existing model, with one big table and
> possibly some IDs not exposed in the bindings.
>
> This gives an hint about the clocks we think consummers should use while
> allowing us to change things if we got it wrong, and keep the IDs stable
> for DT. This has been working so far. I don't see the benefit of
> changing that right now.
>

As we disccused in the IRC, there is two approaches:

1) public/private clock bindings based on splitting bindings headers
2) public/private clock objects based on limited clock hw provider
registration

I'll redesign the whole patch series to the 1st approach with keeping the
following strict rules in the mind:
"There is no option to chage public or private CLKID list numbers.
"Never said you were allowed to change the meaning of the ID, you are just
allowed to have them declared in the bindings (or not)"

[...]

--
Thank you,
Dmitry

2023-03-27 13:48:52

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

On 27/03/2023 13:39, Jerome Brunet wrote:
>
> On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:
>
>> On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
>>>
>>> On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
>>>
>>>> Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
>>>> clock drivers.
>>>> Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
>>>> bindings and include them to MAINTAINERS.
>>>>
>>>> Signed-off-by: Jian Hu <[email protected]>
>>>> Signed-off-by: Dmitry Rokosov <[email protected]>
>>>> ---
>>>> .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
>>>> .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
>>>> MAINTAINERS | 1 +
>>>> include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
>>>> .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
>>>> 5 files changed, 267 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
>>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
>>>
>>> There is two drivers (and 2 independent patches). There should be 2
>>> bindings patches as well.
>>>
>>
>> Before, in previous versions I had two versions, but it wasn't bisectable
>> approach.
>
> You are confusing bisectable and Rob's robot. Splitting patches is more
> that likely to help bisect (and patches backport) - not the other way around.

No, he did not confuse. Splitting patches makes the series
non-bisectable which was visible in the past.

What's more, there is no reason to have bindings patches split just
because you split drivers. Bindings are independent of drivers - we
write them for hardware description.

>
>> a1-clkc schema depends on a1-pll-clkc headers and vice versa.
>> It means dt schemas checkers will show us failure if we split them into two
>> patchsets.
>
> Only because you are patches are not upstream yet ...
>
>> I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
>> look like production schema and it requires one more patchset above the
>> series with proper CLKID definitons usage and proper header including.
>>
>> BTW, there is an example of Rob's test bot failure found in the previous
>> v10 patch series due to chicken or the egg problem.
>> https://lore.kernel.org/all/[email protected]/
>>
>> Please advise what's the best practice to resolve that..
>
> Don't use the header in your example would solve the problem and
> still be correct DT wise.
>
> The examples are just examples, they are not required to actually
> matches a real HW, as far as I know.

Yes, that would work... or just keep them here.


Best regards,
Krzysztof

2023-03-27 13:49:21

by Dmitry Rokosov

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

On Mon, Mar 27, 2023 at 03:41:27PM +0200, Krzysztof Kozlowski wrote:
> On 27/03/2023 13:39, Jerome Brunet wrote:
> >
> > On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:
> >
> >> On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
> >>>
> >>> On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
> >>>
> >>>> Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
> >>>> clock drivers.
> >>>> Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
> >>>> bindings and include them to MAINTAINERS.
> >>>>
> >>>> Signed-off-by: Jian Hu <[email protected]>
> >>>> Signed-off-by: Dmitry Rokosov <[email protected]>
> >>>> ---
> >>>> .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
> >>>> .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
> >>>> MAINTAINERS | 1 +
> >>>> include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
> >>>> .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
> >>>> 5 files changed, 267 insertions(+)
> >>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> >>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
> >>>
> >>> There is two drivers (and 2 independent patches). There should be 2
> >>> bindings patches as well.
> >>>
> >>
> >> Before, in previous versions I had two versions, but it wasn't bisectable
> >> approach.
> >
> > You are confusing bisectable and Rob's robot. Splitting patches is more
> > that likely to help bisect (and patches backport) - not the other way around.
>
> No, he did not confuse. Splitting patches makes the series
> non-bisectable which was visible in the past.
>
> What's more, there is no reason to have bindings patches split just
> because you split drivers. Bindings are independent of drivers - we
> write them for hardware description.
>
> >
> >> a1-clkc schema depends on a1-pll-clkc headers and vice versa.
> >> It means dt schemas checkers will show us failure if we split them into two
> >> patchsets.
> >
> > Only because you are patches are not upstream yet ...
> >
> >> I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
> >> look like production schema and it requires one more patchset above the
> >> series with proper CLKID definitons usage and proper header including.
> >>
> >> BTW, there is an example of Rob's test bot failure found in the previous
> >> v10 patch series due to chicken or the egg problem.
> >> https://lore.kernel.org/all/[email protected]/
> >>
> >> Please advise what's the best practice to resolve that..
> >
> > Don't use the header in your example would solve the problem and
> > still be correct DT wise.
> >
> > The examples are just examples, they are not required to actually
> > matches a real HW, as far as I know.
>
> Yes, that would work... or just keep them here.

I've mentioned it in another reply, by anyway..

Yep, we are able to cheat dt checkers, but we don't help dt developers
with such example. From my point of view, it's more clear for DT
developer to see direct CLKID points instead of "fake references".

May be, it's better to prepare two patches in such hierarchy:

1) A1 PLL clkc bindings with fake references without clkc headers
2) A1 clkc bindings with real CLKID bindings + A1 PLL clkc bindings fix
with real CLKID A1 clkc bindings + header.

The such approach resolves DT checkers failures and split DT bindings
into two patchsets. Also bisectability isn't broken.

--
Thank you,
Dmitry

2023-03-27 13:56:57

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

On 27/03/2023 15:19, Dmitry Rokosov wrote:
> On Mon, Mar 27, 2023 at 02:03:25PM +0200, [email protected] wrote:
>> On 27/03/2023 13:39, Jerome Brunet wrote:
>>>
>>> On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:
>>>
>>>> On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
>>>>>
>>>>> On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
>>>>>
>>>>>> Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
>>>>>> clock drivers.
>>>>>> Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
>>>>>> bindings and include them to MAINTAINERS.
>>>>>>
>>>>>> Signed-off-by: Jian Hu <[email protected]>
>>>>>> Signed-off-by: Dmitry Rokosov <[email protected]>
>>>>>> ---
>>>>>> .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
>>>>>> .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
>>>>>> MAINTAINERS | 1 +
>>>>>> include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
>>>>>> .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
>>>>>> 5 files changed, 267 insertions(+)
>>>>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
>>>>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
>>>>>
>>>>> There is two drivers (and 2 independent patches). There should be 2
>>>>> bindings patches as well.
>>>>>
>>>>
>>>> Before, in previous versions I had two versions, but it wasn't bisectable
>>>> approach.
>>>
>>> You are confusing bisectable and Rob's robot. Splitting patches is more
>>> that likely to help bisect (and patches backport) - not the other way around.
>>>
>>>> a1-clkc schema depends on a1-pll-clkc headers and vice versa.
>>>> It means dt schemas checkers will show us failure if we split them into two
>>>> patchsets.
>>>
>>> Only because you are patches are not upstream yet ...
>>>
>>>> I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
>>>> look like production schema and it requires one more patchset above the
>>>> series with proper CLKID definitons usage and proper header including.
>>>>
>>>> BTW, there is an example of Rob's test bot failure found in the previous
>>>> v10 patch series due to chicken or the egg problem.
>>>> https://lore.kernel.org/all/[email protected]/
>>>>
>>>> Please advise what's the best practice to resolve that..
>>>
>>> Don't use the header in your example would solve the problem and
>>> still be correct DT wise.
>>>
>>> The examples are just examples, they are not required to actually
>>> matches a real HW, as far as I know.
>>
>> Exact, you can use fake lables instead of defined:
>>
>> <&clkc_pll CLKID_FCLK_DIV2>,
>>
>> =>
>> remove "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"
>>
>> <&clkc_pll_fclk_div2>,
>>
>> is perfectly ok and will permit have 2 separate patches.
>>
>> The dependency is only if you have a common yaml file for
>> both bindings files, but this is not the case here.
>
> Simple removal of "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"
> header doesn't work, dt_binding_check make rule is failed:

I never wrote you to only remove the include, adding fake labels phandles was the logical next step.

Neil

>
> Error: Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts:28.37-38 syntax error
> FATAL ERROR: Unable to parse input tree
>
> It happens, because 'dt_binding_check' generates simple dts example and
> tries to compile it:
>
> cat Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts
> ===
>
> /dts-v1/;
> /plugin/; // silence any missing phandle references
>
>
> /{
> compatible = "foo";
> model = "foo";
> #address-cells = <1>;
> #size-cells = <1>;
>
>
>
> example-0 {
> #address-cells = <1>;
> #size-cells = <1>;
>
>
>
> apb {
> #address-cells = <2>;
> #size-cells = <2>;
>
> clock-controller@800 {
> compatible = "amlogic,a1-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";
> };
> };
>
> };
> };
> ===
>
> As you can see, header is required.
>
> But looks like, dt binding checker is happy with the fake references hack :)
> Below there is generated example dts:
>
> cat Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts
> ===
>
> /dts-v1/;
> /plugin/; // silence any missing phandle references
>
>
> /{
> compatible = "foo";
> model = "foo";
> #address-cells = <1>;
> #size-cells = <1>;
>
>
>
> example-0 {
> #address-cells = <1>;
> #size-cells = <1>;
>
>
>
> apb {
> #address-cells = <2>;
> #size-cells = <2>;
>
> clock-controller@800 {
> compatible = "amlogic,a1-clkc";
> reg = <0 0x800 0 0x104>;
> #clock-cells = <1>;
> clocks = <&clkc_pll_fclk_div2>,
> <&clkc_pll_fclk_div3>,
> <&clkc_pll_fclk_div5>,
> <&clkc_pll_fclk_div7>,
> <&clkc_pll_hifi_pll>,
> <&xtal>;
> clock-names = "fclk_div2", "fclk_div3",
> "fclk_div5", "fclk_div7",
> "hifi_pll", "xtal";
> };
> };
>
> };
> };
> ===
>
> Yep, we are able to cheat dt checkers, but we don't help dt developers
> with such example.
> May be, it's better to prepare two patches in such hierarchy:
>
> 1) A1 PLL clkc bindings with fake references without clkc headers
> 2) A1 clkc bindings with real CLKID bindings + A1 PLL clkc bindings fix
> with real CLKID A1 clkc bindings + header.
>
> The such approach resolves DT checkers failures and split DT bindings
> into two patchsets.
>
> [...]
>

2023-03-27 14:09:25

by Dmitry Rokosov

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings

On Mon, Mar 27, 2023 at 03:55:46PM +0200, [email protected] wrote:
> On 27/03/2023 15:19, Dmitry Rokosov wrote:
> > On Mon, Mar 27, 2023 at 02:03:25PM +0200, [email protected] wrote:
> > > On 27/03/2023 13:39, Jerome Brunet wrote:
> > > >
> > > > On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:
> > > >
> > > > > On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
> > > > > >
> > > > > > On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
> > > > > >
> > > > > > > Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
> > > > > > > clock drivers.
> > > > > > > Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
> > > > > > > bindings and include them to MAINTAINERS.
> > > > > > >
> > > > > > > Signed-off-by: Jian Hu <[email protected]>
> > > > > > > Signed-off-by: Dmitry Rokosov <[email protected]>
> > > > > > > ---
> > > > > > > .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
> > > > > > > .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
> > > > > > > MAINTAINERS | 1 +
> > > > > > > include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
> > > > > > > .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
> > > > > > > 5 files changed, 267 insertions(+)
> > > > > > > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> > > > > > > create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
> > > > > >
> > > > > > There is two drivers (and 2 independent patches). There should be 2
> > > > > > bindings patches as well.
> > > > > >
> > > > >
> > > > > Before, in previous versions I had two versions, but it wasn't bisectable
> > > > > approach.
> > > >
> > > > You are confusing bisectable and Rob's robot. Splitting patches is more
> > > > that likely to help bisect (and patches backport) - not the other way around.
> > > >
> > > > > a1-clkc schema depends on a1-pll-clkc headers and vice versa.
> > > > > It means dt schemas checkers will show us failure if we split them into two
> > > > > patchsets.
> > > >
> > > > Only because you are patches are not upstream yet ...
> > > >
> > > > > I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
> > > > > look like production schema and it requires one more patchset above the
> > > > > series with proper CLKID definitons usage and proper header including.
> > > > >
> > > > > BTW, there is an example of Rob's test bot failure found in the previous
> > > > > v10 patch series due to chicken or the egg problem.
> > > > > https://lore.kernel.org/all/[email protected]/
> > > > >
> > > > > Please advise what's the best practice to resolve that..
> > > >
> > > > Don't use the header in your example would solve the problem and
> > > > still be correct DT wise.
> > > >
> > > > The examples are just examples, they are not required to actually
> > > > matches a real HW, as far as I know.
> > >
> > > Exact, you can use fake lables instead of defined:
> > >
> > > <&clkc_pll CLKID_FCLK_DIV2>,
> > >
> > > =>
> > > remove "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"
> > >
> > > <&clkc_pll_fclk_div2>,
> > >
> > > is perfectly ok and will permit have 2 separate patches.
> > >
> > > The dependency is only if you have a common yaml file for
> > > both bindings files, but this is not the case here.
> >
> > Simple removal of "#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>"
> > header doesn't work, dt_binding_check make rule is failed:
>
> I never wrote you to only remove the include, adding fake labels phandles was the logical next step.

Ah, sorry, I've confused. Anyway, the fake labels are working perfectly.
DT checkers are silent.

> >
> > Error: Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts:28.37-38 syntax error
> > FATAL ERROR: Unable to parse input tree
> >
> > It happens, because 'dt_binding_check' generates simple dts example and
> > tries to compile it:
> >
> > cat Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts
> > ===
> >
> > /dts-v1/;
> > /plugin/; // silence any missing phandle references
> >
> >
> > /{
> > compatible = "foo";
> > model = "foo";
> > #address-cells = <1>;
> > #size-cells = <1>;
> >
> >
> >
> > example-0 {
> > #address-cells = <1>;
> > #size-cells = <1>;
> >
> >
> > apb {
> > #address-cells = <2>;
> > #size-cells = <2>;
> > clock-controller@800 {
> > compatible = "amlogic,a1-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";
> > };
> > };
> >
> > };
> > };
> > ===
> >
> > As you can see, header is required.
> >
> > But looks like, dt binding checker is happy with the fake references hack :)
> > Below there is generated example dts:
> >
> > cat Documentation/devicetree/bindings/clock/amlogic,a1-clkc.example.dts
> > ===
> >
> > /dts-v1/;
> > /plugin/; // silence any missing phandle references
> >
> >
> > /{
> > compatible = "foo";
> > model = "foo";
> > #address-cells = <1>;
> > #size-cells = <1>;
> >
> >
> >
> > example-0 {
> > #address-cells = <1>;
> > #size-cells = <1>;
> >
> >
> > apb {
> > #address-cells = <2>;
> > #size-cells = <2>;
> > clock-controller@800 {
> > compatible = "amlogic,a1-clkc";
> > reg = <0 0x800 0 0x104>;
> > #clock-cells = <1>;
> > clocks = <&clkc_pll_fclk_div2>,
> > <&clkc_pll_fclk_div3>,
> > <&clkc_pll_fclk_div5>,
> > <&clkc_pll_fclk_div7>,
> > <&clkc_pll_hifi_pll>,
> > <&xtal>;
> > clock-names = "fclk_div2", "fclk_div3",
> > "fclk_div5", "fclk_div7",
> > "hifi_pll", "xtal";
> > };
> > };
> >
> > };
> > };
> > ===
> >
> > Yep, we are able to cheat dt checkers, but we don't help dt developers
> > with such example.
> > May be, it's better to prepare two patches in such hierarchy:
> >
> > 1) A1 PLL clkc bindings with fake references without clkc headers
> > 2) A1 clkc bindings with real CLKID bindings + A1 PLL clkc bindings fix
> > with real CLKID A1 clkc bindings + header.
> >
> > The such approach resolves DT checkers failures and split DT bindings
> > into two patchsets.

What do you think about patchsets form listed above? Fake labels as a
first step and real CLKIDs as a second. I'm embarrassed only that second
patch fixes the previous in the one patch series...

--
Thank you,
Dmitry

2023-03-27 14:11:33

by Jerome Brunet

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings


On Mon 27 Mar 2023 at 15:41, Krzysztof Kozlowski <[email protected]> wrote:

> On 27/03/2023 13:39, Jerome Brunet wrote:
>>
>> On Mon 27 Mar 2023 at 13:51, Dmitry Rokosov <[email protected]> wrote:
>>
>>> On Mon, Mar 27, 2023 at 11:51:21AM +0200, Jerome Brunet wrote:
>>>>
>>>> On Tue 21 Mar 2023 at 22:30, Dmitry Rokosov <[email protected]> wrote:
>>>>
>>>>> Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
>>>>> clock drivers.
>>>>> Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
>>>>> bindings and include them to MAINTAINERS.
>>>>>
>>>>> Signed-off-by: Jian Hu <[email protected]>
>>>>> Signed-off-by: Dmitry Rokosov <[email protected]>
>>>>> ---
>>>>> .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
>>>>> .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
>>>>> MAINTAINERS | 1 +
>>>>> include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
>>>>> .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
>>>>> 5 files changed, 267 insertions(+)
>>>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
>>>>> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
>>>>
>>>> There is two drivers (and 2 independent patches). There should be 2
>>>> bindings patches as well.
>>>>
>>>
>>> Before, in previous versions I had two versions, but it wasn't bisectable
>>> approach.
>>
>> You are confusing bisectable and Rob's robot. Splitting patches is more
>> that likely to help bisect (and patches backport) - not the other way around.
>
> No, he did not confuse. Splitting patches makes the series
> non-bisectable which was visible in the past.
>
> What's more, there is no reason to have bindings patches split just
> because you split drivers. Bindings are independent of drivers - we
> write them for hardware description.

Patches should do one thing, my comment is a simple application of that.

There no reason to have a single patch provide the bindings for 2
independent pieces of HW, which those components are. If a dependency
has been set, it is one that should not be there.

They do provide inputs to one another, yes but remain independent pieces of
HW. They have a different address space and as a consequences, different
drivers

If we were being strict, it should even be seperate series.

>
>>
>>> a1-clkc schema depends on a1-pll-clkc headers and vice versa.
>>> It means dt schemas checkers will show us failure if we split them into two
>>> patchsets.
>>
>> Only because you are patches are not upstream yet ...
>>
>>> I know, that we can use raw digits instead of CLKID names, but IMO it doesn't
>>> look like production schema and it requires one more patchset above the
>>> series with proper CLKID definitons usage and proper header including.
>>>
>>> BTW, there is an example of Rob's test bot failure found in the previous
>>> v10 patch series due to chicken or the egg problem.
>>> https://lore.kernel.org/all/[email protected]/
>>>
>>> Please advise what's the best practice to resolve that..
>>
>> Don't use the header in your example would solve the problem and
>> still be correct DT wise.
>>
>> The examples are just examples, they are not required to actually
>> matches a real HW, as far as I know.
>
> Yes, that would work... or just keep them here.
>
>
> Best regards,
> Krzysztof
>
>
> _______________________________________________
> linux-amlogic mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-amlogic

2023-03-27 15:30:24

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v11 3/5] dt-bindings: clock: meson: add A1 PLL and Peripherals clkcs bindings


On Tue, 21 Mar 2023 22:30:12 +0300, Dmitry Rokosov wrote:
> Add the documentation for Amlogic A1 PLL and Amlogic A1 Peripherals
> clock drivers.
> Introduce Amlogic A1 PLL and Amlogic A1 Peripherals device tree
> bindings and include them to MAINTAINERS.
>
> Signed-off-by: Jian Hu <[email protected]>
> Signed-off-by: Dmitry Rokosov <[email protected]>
> ---
> .../bindings/clock/amlogic,a1-clkc.yaml | 73 +++++++++++
> .../bindings/clock/amlogic,a1-pll-clkc.yaml | 59 +++++++++
> MAINTAINERS | 1 +
> include/dt-bindings/clock/amlogic,a1-clkc.h | 113 ++++++++++++++++++
> .../dt-bindings/clock/amlogic,a1-pll-clkc.h | 21 ++++
> 5 files changed, 267 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-clkc.yaml
> create mode 100644 Documentation/devicetree/bindings/clock/amlogic,a1-pll-clkc.yaml
> create mode 100644 include/dt-bindings/clock/amlogic,a1-clkc.h
> create mode 100644 include/dt-bindings/clock/amlogic,a1-pll-clkc.h
>

Reviewed-by: Rob Herring <[email protected]>