* [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver
@ 2024-09-13 12:11 Jan Dakinevich
2024-09-13 12:11 ` [RFC PATCH v4 1/5] reset: amlogic: add support for A1 SoC in auxiliary reset driver Jan Dakinevich
` (6 more replies)
0 siblings, 7 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-09-13 12:11 UTC (permalink / raw)
To: Jan Dakinevich, Conor Dooley, devicetree, Jerome Brunet,
Kevin Hilman, Krzysztof Kozlowski, linux-amlogic,
linux-arm-kernel, linux-clk, linux-kernel, Martin Blumenstingl,
Michael Turquette, Neil Armstrong, Philipp Zabel, Rob Herring,
Stephen Boyd
This series adds support for audio clock and reset controllers on A1 SoC family.
Dependency: [4]
Changes v3 [3] -> v4
- Use auxiliary reset device implemented in [4]
- Split the driver into files
- Use common with axg-audio yaml schema
- Unify clock-names with axg-audio
Changes v2 [2] -> v3
- reset:
* added auxiliary device
- yaml:
* added declaration of optional clocks
* fixed names in example and another cosmetics
- clocks:
* reworked naming
* stop using of "core" clock name
* fixed wrong parenting
Changes v1 [1] -> v2:
- Detached from v1's series (patch 2, 3, 4, 25).
- Reuse some of defines from axg-audio;
- Split the controller into two memory regions.
Links:
[1] https://lore.kernel.org/lkml/20240314232201.2102178-1-jan.dakinevich@salutedevices.com/
[2] https://lore.kernel.org/lkml/20240328010831.884487-1-jan.dakinevich@salutedevices.com/
[3] https://lore.kernel.org/lkml/20240419125812.983409-1-jan.dakinevich@salutedevices.com/
[4] https://lore.kernel.org/lkml/9a4377fe27d8eb940399e452b68fb5a6d678929f.camel@pengutronix.de/
Jan Dakinevich (5):
reset: amlogic: add support for A1 SoC in auxiliary reset driver
clk: meson: axg: share the set of audio helper macro
dt-bindings: clock: axg-audio: document A1 SoC audio clock controller
driver
clk: meson: a1: add the audio clock controller driver
arm64: dts: meson: a1: add the audio clock controller
.../clock/amlogic,axg-audio-clkc.yaml | 3 +
arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 48 +++
drivers/clk/meson/Kconfig | 14 +
drivers/clk/meson/Makefile | 3 +
drivers/clk/meson/a1-audio-clkc.c | 359 ++++++++++++++++++
drivers/clk/meson/a1-audio-drv.c | 104 +++++
drivers/clk/meson/a1-audio-vad-clkc.c | 85 +++++
drivers/clk/meson/a1-audio.h | 131 +++++++
drivers/clk/meson/axg-audio.c | 138 +------
drivers/clk/meson/meson-audio.h | 143 +++++++
drivers/reset/amlogic/reset-meson-aux.c | 9 +
.../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++
.../reset/amlogic,meson-a1-audio-reset.h | 29 ++
13 files changed, 1051 insertions(+), 137 deletions(-)
create mode 100644 drivers/clk/meson/a1-audio-clkc.c
create mode 100644 drivers/clk/meson/a1-audio-drv.c
create mode 100644 drivers/clk/meson/a1-audio-vad-clkc.c
create mode 100644 drivers/clk/meson/a1-audio.h
create mode 100644 drivers/clk/meson/meson-audio.h
create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC PATCH v4 1/5] reset: amlogic: add support for A1 SoC in auxiliary reset driver
2024-09-13 12:11 [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
@ 2024-09-13 12:11 ` Jan Dakinevich
2024-10-22 8:42 ` Jerome Brunet
2024-09-13 12:11 ` [RFC PATCH v4 2/5] clk: meson: axg: share the set of audio helper macro Jan Dakinevich
` (5 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Jan Dakinevich @ 2024-09-13 12:11 UTC (permalink / raw)
To: Jan Dakinevich, Conor Dooley, devicetree, Jerome Brunet,
Kevin Hilman, Krzysztof Kozlowski, linux-amlogic,
linux-arm-kernel, linux-clk, linux-kernel, Martin Blumenstingl,
Michael Turquette, Neil Armstrong, Philipp Zabel, Rob Herring,
Stephen Boyd
Add support for the reset controller present in the audio clock
controller of A1 SoC families, using the auxiliary bus.
Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
---
drivers/reset/amlogic/reset-meson-aux.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/reset/amlogic/reset-meson-aux.c b/drivers/reset/amlogic/reset-meson-aux.c
index dd8453001db9..a385c0125836 100644
--- a/drivers/reset/amlogic/reset-meson-aux.c
+++ b/drivers/reset/amlogic/reset-meson-aux.c
@@ -26,6 +26,12 @@ struct meson_reset_adev {
#define to_meson_reset_adev(_adev) \
container_of((_adev), struct meson_reset_adev, adev)
+static const struct meson_reset_param meson_a1_audio_param = {
+ .reset_ops = &meson_reset_toggle_ops,
+ .reset_num = 32,
+ .level_offset = 0x28,
+};
+
static const struct meson_reset_param meson_g12a_audio_param = {
.reset_ops = &meson_reset_toggle_ops,
.reset_num = 26,
@@ -40,6 +46,9 @@ static const struct meson_reset_param meson_sm1_audio_param = {
static const struct auxiliary_device_id meson_reset_aux_ids[] = {
{
+ .name = "a1-audio-clkc.rst-a1",
+ .driver_data = (kernel_ulong_t)&meson_a1_audio_param,
+ }, {
.name = "axg-audio-clkc.rst-g12a",
.driver_data = (kernel_ulong_t)&meson_g12a_audio_param,
}, {
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC PATCH v4 2/5] clk: meson: axg: share the set of audio helper macro
2024-09-13 12:11 [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
2024-09-13 12:11 ` [RFC PATCH v4 1/5] reset: amlogic: add support for A1 SoC in auxiliary reset driver Jan Dakinevich
@ 2024-09-13 12:11 ` Jan Dakinevich
2024-09-13 12:11 ` [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver Jan Dakinevich
` (4 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-09-13 12:11 UTC (permalink / raw)
To: Jan Dakinevich, Conor Dooley, devicetree, Jerome Brunet,
Kevin Hilman, Krzysztof Kozlowski, linux-amlogic,
linux-arm-kernel, linux-clk, linux-kernel, Martin Blumenstingl,
Michael Turquette, Neil Armstrong, Philipp Zabel, Rob Herring,
Stephen Boyd
These macro will be used in upcoming audio clock controller
for Meson A1 SoC.
Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
---
drivers/clk/meson/axg-audio.c | 138 +-----------------------------
drivers/clk/meson/meson-audio.h | 143 ++++++++++++++++++++++++++++++++
2 files changed, 144 insertions(+), 137 deletions(-)
create mode 100644 drivers/clk/meson/meson-audio.h
diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c
index beda86349389..0d911e06a29f 100644
--- a/drivers/clk/meson/axg-audio.c
+++ b/drivers/clk/meson/axg-audio.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include "meson-clkc-utils.h"
+#include "meson-audio.h"
#include "axg-audio.h"
#include "clk-regmap.h"
#include "clk-phase.h"
@@ -23,52 +24,6 @@
#include <dt-bindings/clock/axg-audio-clkc.h>
-#define AUD_GATE(_name, _reg, _bit, _pname, _iflags) { \
- .data = &(struct clk_regmap_gate_data){ \
- .offset = (_reg), \
- .bit_idx = (_bit), \
- }, \
- .hw.init = &(struct clk_init_data) { \
- .name = "aud_"#_name, \
- .ops = &clk_regmap_gate_ops, \
- .parent_names = (const char *[]){ #_pname }, \
- .num_parents = 1, \
- .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
- }, \
-}
-
-#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) { \
- .data = &(struct clk_regmap_mux_data){ \
- .offset = (_reg), \
- .mask = (_mask), \
- .shift = (_shift), \
- .flags = (_dflags), \
- }, \
- .hw.init = &(struct clk_init_data){ \
- .name = "aud_"#_name, \
- .ops = &clk_regmap_mux_ops, \
- .parent_data = _pdata, \
- .num_parents = ARRAY_SIZE(_pdata), \
- .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
- }, \
-}
-
-#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) { \
- .data = &(struct clk_regmap_div_data){ \
- .offset = (_reg), \
- .shift = (_shift), \
- .width = (_width), \
- .flags = (_dflags), \
- }, \
- .hw.init = &(struct clk_init_data){ \
- .name = "aud_"#_name, \
- .ops = &clk_regmap_divider_ops, \
- .parent_names = (const char *[]){ #_pname }, \
- .num_parents = 1, \
- .flags = (_iflags), \
- }, \
-}
-
#define AUD_PCLK_GATE(_name, _reg, _bit) { \
.data = &(struct clk_regmap_gate_data){ \
.offset = (_reg), \
@@ -82,97 +37,6 @@
}, \
}
-#define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \
- _hi_shift, _hi_width, _pname, _iflags) { \
- .data = &(struct meson_sclk_div_data) { \
- .div = { \
- .reg_off = (_reg), \
- .shift = (_div_shift), \
- .width = (_div_width), \
- }, \
- .hi = { \
- .reg_off = (_reg), \
- .shift = (_hi_shift), \
- .width = (_hi_width), \
- }, \
- }, \
- .hw.init = &(struct clk_init_data) { \
- .name = "aud_"#_name, \
- .ops = &meson_sclk_div_ops, \
- .parent_names = (const char *[]){ #_pname }, \
- .num_parents = 1, \
- .flags = (_iflags), \
- }, \
-}
-
-#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \
- _pname, _iflags) { \
- .data = &(struct meson_clk_triphase_data) { \
- .ph0 = { \
- .reg_off = (_reg), \
- .shift = (_shift0), \
- .width = (_width), \
- }, \
- .ph1 = { \
- .reg_off = (_reg), \
- .shift = (_shift1), \
- .width = (_width), \
- }, \
- .ph2 = { \
- .reg_off = (_reg), \
- .shift = (_shift2), \
- .width = (_width), \
- }, \
- }, \
- .hw.init = &(struct clk_init_data) { \
- .name = "aud_"#_name, \
- .ops = &meson_clk_triphase_ops, \
- .parent_names = (const char *[]){ #_pname }, \
- .num_parents = 1, \
- .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
- }, \
-}
-
-#define AUD_PHASE(_name, _reg, _width, _shift, _pname, _iflags) { \
- .data = &(struct meson_clk_phase_data) { \
- .ph = { \
- .reg_off = (_reg), \
- .shift = (_shift), \
- .width = (_width), \
- }, \
- }, \
- .hw.init = &(struct clk_init_data) { \
- .name = "aud_"#_name, \
- .ops = &meson_clk_phase_ops, \
- .parent_names = (const char *[]){ #_pname }, \
- .num_parents = 1, \
- .flags = (_iflags), \
- }, \
-}
-
-#define AUD_SCLK_WS(_name, _reg, _width, _shift_ph, _shift_ws, _pname, \
- _iflags) { \
- .data = &(struct meson_sclk_ws_inv_data) { \
- .ph = { \
- .reg_off = (_reg), \
- .shift = (_shift_ph), \
- .width = (_width), \
- }, \
- .ws = { \
- .reg_off = (_reg), \
- .shift = (_shift_ws), \
- .width = (_width), \
- }, \
- }, \
- .hw.init = &(struct clk_init_data) { \
- .name = "aud_"#_name, \
- .ops = &meson_clk_phase_ops, \
- .parent_names = (const char *[]){ #_pname }, \
- .num_parents = 1, \
- .flags = (_iflags), \
- }, \
-}
-
/* Audio Master Clocks */
static const struct clk_parent_data mst_mux_parent_data[] = {
{ .fw_name = "mst_in0", },
diff --git a/drivers/clk/meson/meson-audio.h b/drivers/clk/meson/meson-audio.h
new file mode 100644
index 000000000000..cbcdbd487d4a
--- /dev/null
+++ b/drivers/clk/meson/meson-audio.h
@@ -0,0 +1,143 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+
+#ifndef __MESON_AUDIO_H__
+#define __MESON_AUDIO_H__
+
+#define AUD_GATE(_name, _reg, _bit, _pname, _iflags) { \
+ .data = &(struct clk_regmap_gate_data){ \
+ .offset = (_reg), \
+ .bit_idx = (_bit), \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = "aud_"#_name, \
+ .ops = &clk_regmap_gate_ops, \
+ .parent_names = (const char *[]){ #_pname }, \
+ .num_parents = 1, \
+ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
+ }, \
+}
+
+#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) { \
+ .data = &(struct clk_regmap_mux_data){ \
+ .offset = (_reg), \
+ .mask = (_mask), \
+ .shift = (_shift), \
+ .flags = (_dflags), \
+ }, \
+ .hw.init = &(struct clk_init_data){ \
+ .name = "aud_"#_name, \
+ .ops = &clk_regmap_mux_ops, \
+ .parent_data = _pdata, \
+ .num_parents = ARRAY_SIZE(_pdata), \
+ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
+ }, \
+}
+
+#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) { \
+ .data = &(struct clk_regmap_div_data){ \
+ .offset = (_reg), \
+ .shift = (_shift), \
+ .width = (_width), \
+ .flags = (_dflags), \
+ }, \
+ .hw.init = &(struct clk_init_data){ \
+ .name = "aud_"#_name, \
+ .ops = &clk_regmap_divider_ops, \
+ .parent_names = (const char *[]){ #_pname }, \
+ .num_parents = 1, \
+ .flags = (_iflags), \
+ }, \
+}
+
+#define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \
+ _hi_shift, _hi_width, _pname, _iflags) { \
+ .data = &(struct meson_sclk_div_data) { \
+ .div = { \
+ .reg_off = (_reg), \
+ .shift = (_div_shift), \
+ .width = (_div_width), \
+ }, \
+ .hi = { \
+ .reg_off = (_reg), \
+ .shift = (_hi_shift), \
+ .width = (_hi_width), \
+ }, \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = "aud_"#_name, \
+ .ops = &meson_sclk_div_ops, \
+ .parent_names = (const char *[]){ #_pname }, \
+ .num_parents = 1, \
+ .flags = (_iflags), \
+ }, \
+}
+
+#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \
+ _pname, _iflags) { \
+ .data = &(struct meson_clk_triphase_data) { \
+ .ph0 = { \
+ .reg_off = (_reg), \
+ .shift = (_shift0), \
+ .width = (_width), \
+ }, \
+ .ph1 = { \
+ .reg_off = (_reg), \
+ .shift = (_shift1), \
+ .width = (_width), \
+ }, \
+ .ph2 = { \
+ .reg_off = (_reg), \
+ .shift = (_shift2), \
+ .width = (_width), \
+ }, \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = "aud_"#_name, \
+ .ops = &meson_clk_triphase_ops, \
+ .parent_names = (const char *[]){ #_pname }, \
+ .num_parents = 1, \
+ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
+ }, \
+}
+
+#define AUD_PHASE(_name, _reg, _width, _shift, _pname, _iflags) { \
+ .data = &(struct meson_clk_phase_data) { \
+ .ph = { \
+ .reg_off = (_reg), \
+ .shift = (_shift), \
+ .width = (_width), \
+ }, \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = "aud_"#_name, \
+ .ops = &meson_clk_phase_ops, \
+ .parent_names = (const char *[]){ #_pname }, \
+ .num_parents = 1, \
+ .flags = (_iflags), \
+ }, \
+}
+
+#define AUD_SCLK_WS(_name, _reg, _width, _shift_ph, _shift_ws, _pname, \
+ _iflags) { \
+ .data = &(struct meson_sclk_ws_inv_data) { \
+ .ph = { \
+ .reg_off = (_reg), \
+ .shift = (_shift_ph), \
+ .width = (_width), \
+ }, \
+ .ws = { \
+ .reg_off = (_reg), \
+ .shift = (_shift_ws), \
+ .width = (_width), \
+ }, \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = "aud_"#_name, \
+ .ops = &meson_clk_phase_ops, \
+ .parent_names = (const char *[]){ #_pname }, \
+ .num_parents = 1, \
+ .flags = (_iflags), \
+ }, \
+}
+
+#endif /* __MESON_AUDIO_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver
2024-09-13 12:11 [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
2024-09-13 12:11 ` [RFC PATCH v4 1/5] reset: amlogic: add support for A1 SoC in auxiliary reset driver Jan Dakinevich
2024-09-13 12:11 ` [RFC PATCH v4 2/5] clk: meson: axg: share the set of audio helper macro Jan Dakinevich
@ 2024-09-13 12:11 ` Jan Dakinevich
2024-09-13 17:23 ` Conor Dooley
` (2 more replies)
2024-09-13 12:11 ` [RFC PATCH v4 4/5] clk: meson: a1: add the " Jan Dakinevich
` (3 subsequent siblings)
6 siblings, 3 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-09-13 12:11 UTC (permalink / raw)
To: Jan Dakinevich, Conor Dooley, devicetree, Jerome Brunet,
Kevin Hilman, Krzysztof Kozlowski, linux-amlogic,
linux-arm-kernel, linux-clk, linux-kernel, Martin Blumenstingl,
Michael Turquette, Neil Armstrong, Philipp Zabel, Rob Herring,
Stephen Boyd
Add device tree bindings for A1 SoC audio clock and reset controllers.
Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
---
.../clock/amlogic,axg-audio-clkc.yaml | 3 +
.../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++++++++++++++
.../reset/amlogic,meson-a1-audio-reset.h | 29 +++++
3 files changed, 154 insertions(+)
create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
index fd7982dd4cea..df9eb8ce28dc 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
+++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
@@ -18,6 +18,8 @@ description:
properties:
compatible:
enum:
+ - amlogic,a1-audio-clkc
+ - amlogic,a1-audio-vad-clkc
- amlogic,axg-audio-clkc
- amlogic,g12a-audio-clkc
- amlogic,sm1-audio-clkc
@@ -114,6 +116,7 @@ allOf:
compatible:
contains:
enum:
+ - amlogic,a1-audio-clkc
- amlogic,g12a-audio-clkc
- amlogic,sm1-audio-clkc
then:
diff --git a/include/dt-bindings/clock/amlogic,a1-audio-clkc.h b/include/dt-bindings/clock/amlogic,a1-audio-clkc.h
new file mode 100644
index 000000000000..6534d1878816
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a1-audio-clkc.h
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
+ */
+
+#ifndef __A1_AUDIO_CLKC_BINDINGS_H
+#define __A1_AUDIO_CLKC_BINDINGS_H
+
+#define AUD_CLKID_DDR_ARB 1
+#define AUD_CLKID_TDMIN_A 2
+#define AUD_CLKID_TDMIN_B 3
+#define AUD_CLKID_TDMIN_LB 4
+#define AUD_CLKID_LOOPBACK 5
+#define AUD_CLKID_TDMOUT_A 6
+#define AUD_CLKID_TDMOUT_B 7
+#define AUD_CLKID_FRDDR_A 8
+#define AUD_CLKID_FRDDR_B 9
+#define AUD_CLKID_TODDR_A 10
+#define AUD_CLKID_TODDR_B 11
+#define AUD_CLKID_SPDIFIN 12
+#define AUD_CLKID_RESAMPLE 13
+#define AUD_CLKID_EQDRC 14
+#define AUD_CLKID_LOCKER 15
+#define AUD_CLKID_MST_A_MCLK_SEL 16
+#define AUD_CLKID_MST_A_MCLK_DIV 17
+#define AUD_CLKID_MST_A_MCLK 18
+#define AUD_CLKID_MST_B_MCLK_SEL 19
+#define AUD_CLKID_MST_B_MCLK_DIV 20
+#define AUD_CLKID_MST_B_MCLK 21
+#define AUD_CLKID_MST_C_MCLK_SEL 22
+#define AUD_CLKID_MST_C_MCLK_DIV 23
+#define AUD_CLKID_MST_C_MCLK 24
+#define AUD_CLKID_MST_D_MCLK_SEL 25
+#define AUD_CLKID_MST_D_MCLK_DIV 26
+#define AUD_CLKID_MST_D_MCLK 27
+#define AUD_CLKID_SPDIFIN_CLK_SEL 28
+#define AUD_CLKID_SPDIFIN_CLK_DIV 29
+#define AUD_CLKID_SPDIFIN_CLK 30
+#define AUD_CLKID_RESAMPLE_CLK_SEL 31
+#define AUD_CLKID_RESAMPLE_CLK_DIV 32
+#define AUD_CLKID_RESAMPLE_CLK 33
+#define AUD_CLKID_LOCKER_IN_CLK_SEL 34
+#define AUD_CLKID_LOCKER_IN_CLK_DIV 35
+#define AUD_CLKID_LOCKER_IN_CLK 36
+#define AUD_CLKID_LOCKER_OUT_CLK_SEL 37
+#define AUD_CLKID_LOCKER_OUT_CLK_DIV 38
+#define AUD_CLKID_LOCKER_OUT_CLK 39
+#define AUD_CLKID_EQDRC_CLK_SEL 40
+#define AUD_CLKID_EQDRC_CLK_DIV 41
+#define AUD_CLKID_EQDRC_CLK 42
+#define AUD_CLKID_MST_A_SCLK_PRE_EN 43
+#define AUD_CLKID_MST_A_SCLK_DIV 44
+#define AUD_CLKID_MST_A_SCLK_POST_EN 45
+#define AUD_CLKID_MST_A_SCLK 46
+#define AUD_CLKID_MST_B_SCLK_PRE_EN 47
+#define AUD_CLKID_MST_B_SCLK_DIV 48
+#define AUD_CLKID_MST_B_SCLK_POST_EN 49
+#define AUD_CLKID_MST_B_SCLK 50
+#define AUD_CLKID_MST_C_SCLK_PRE_EN 51
+#define AUD_CLKID_MST_C_SCLK_DIV 52
+#define AUD_CLKID_MST_C_SCLK_POST_EN 53
+#define AUD_CLKID_MST_C_SCLK 54
+#define AUD_CLKID_MST_D_SCLK_PRE_EN 55
+#define AUD_CLKID_MST_D_SCLK_DIV 56
+#define AUD_CLKID_MST_D_SCLK_POST_EN 57
+#define AUD_CLKID_MST_D_SCLK 58
+#define AUD_CLKID_MST_A_LRCLK_DIV 59
+#define AUD_CLKID_MST_A_LRCLK 60
+#define AUD_CLKID_MST_B_LRCLK_DIV 61
+#define AUD_CLKID_MST_B_LRCLK 62
+#define AUD_CLKID_MST_C_LRCLK_DIV 63
+#define AUD_CLKID_MST_C_LRCLK 64
+#define AUD_CLKID_MST_D_LRCLK_DIV 65
+#define AUD_CLKID_MST_D_LRCLK 66
+#define AUD_CLKID_TDMIN_A_SCLK_SEL 67
+#define AUD_CLKID_TDMIN_A_SCLK_PRE_EN 68
+#define AUD_CLKID_TDMIN_A_SCLK_POST_EN 69
+#define AUD_CLKID_TDMIN_A_SCLK 70
+#define AUD_CLKID_TDMIN_A_LRCLK 71
+#define AUD_CLKID_TDMIN_B_SCLK_SEL 72
+#define AUD_CLKID_TDMIN_B_SCLK_PRE_EN 73
+#define AUD_CLKID_TDMIN_B_SCLK_POST_EN 74
+#define AUD_CLKID_TDMIN_B_SCLK 75
+#define AUD_CLKID_TDMIN_B_LRCLK 76
+#define AUD_CLKID_TDMIN_LB_SCLK_SEL 77
+#define AUD_CLKID_TDMIN_LB_SCLK_PRE_EN 78
+#define AUD_CLKID_TDMIN_LB_SCLK_POST_EN 79
+#define AUD_CLKID_TDMIN_LB_SCLK 80
+#define AUD_CLKID_TDMIN_LB_LRCLK 81
+#define AUD_CLKID_TDMOUT_A_SCLK_SEL 82
+#define AUD_CLKID_TDMOUT_A_SCLK_PRE_EN 83
+#define AUD_CLKID_TDMOUT_A_SCLK_POST_EN 84
+#define AUD_CLKID_TDMOUT_A_SCLK 85
+#define AUD_CLKID_TDMOUT_A_LRCLK 86
+#define AUD_CLKID_TDMOUT_B_SCLK_SEL 87
+#define AUD_CLKID_TDMOUT_B_SCLK_PRE_EN 88
+#define AUD_CLKID_TDMOUT_B_SCLK_POST_EN 89
+#define AUD_CLKID_TDMOUT_B_SCLK 90
+#define AUD_CLKID_TDMOUT_B_LRCLK 91
+
+#define AUD_CLKID_VAD_DDR_ARB 1
+#define AUD_CLKID_VAD_PDM 2
+#define AUD_CLKID_VAD_TDMIN 3
+#define AUD_CLKID_VAD_TODDR 4
+#define AUD_CLKID_VAD 5
+#define AUD_CLKID_VAD_AUDIOTOP 6
+#define AUD_CLKID_VAD_MCLK_SEL 7
+#define AUD_CLKID_VAD_MCLK_DIV 8
+#define AUD_CLKID_VAD_MCLK 9
+#define AUD_CLKID_VAD_CLK_SEL 10
+#define AUD_CLKID_VAD_CLK_DIV 11
+#define AUD_CLKID_VAD_CLK 12
+#define AUD_CLKID_VAD_PDM_DCLK_SEL 13
+#define AUD_CLKID_VAD_PDM_DCLK_DIV 14
+#define AUD_CLKID_VAD_PDM_DCLK 15
+#define AUD_CLKID_VAD_PDM_SYSCLK_SEL 16
+#define AUD_CLKID_VAD_PDM_SYSCLK_DIV 17
+#define AUD_CLKID_VAD_PDM_SYSCLK 18
+
+#endif /* __A1_AUDIO_CLKC_BINDINGS_H */
diff --git a/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
new file mode 100644
index 000000000000..653fddba1d8f
--- /dev/null
+++ b/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H
+
+#define AUD_RESET_DDRARB 0
+#define AUD_RESET_TDMIN_A 1
+#define AUD_RESET_TDMIN_B 2
+#define AUD_RESET_TDMIN_LB 3
+#define AUD_RESET_LOOPBACK 4
+#define AUD_RESET_TDMOUT_A 5
+#define AUD_RESET_TDMOUT_B 6
+#define AUD_RESET_FRDDR_A 7
+#define AUD_RESET_FRDDR_B 8
+#define AUD_RESET_TODDR_A 9
+#define AUD_RESET_TODDR_B 10
+#define AUD_RESET_SPDIFIN 11
+#define AUD_RESET_RESAMPLE 12
+#define AUD_RESET_EQDRC 13
+#define AUD_RESET_LOCKER 14
+#define AUD_RESET_TOACODEC 30
+#define AUD_RESET_CLKTREE 31
+
+#endif /* _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC PATCH v4 4/5] clk: meson: a1: add the audio clock controller driver
2024-09-13 12:11 [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
` (2 preceding siblings ...)
2024-09-13 12:11 ` [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver Jan Dakinevich
@ 2024-09-13 12:11 ` Jan Dakinevich
2024-09-18 11:05 ` Jan Dakinevich
2024-10-22 9:47 ` Jerome Brunet
2024-09-13 12:11 ` [RFC PATCH v4 5/5] arm64: dts: meson: a1: add the audio clock controller Jan Dakinevich
` (2 subsequent siblings)
6 siblings, 2 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-09-13 12:11 UTC (permalink / raw)
To: Jan Dakinevich, Conor Dooley, devicetree, Jerome Brunet,
Kevin Hilman, Krzysztof Kozlowski, linux-amlogic,
linux-arm-kernel, linux-clk, linux-kernel, Martin Blumenstingl,
Michael Turquette, Neil Armstrong, Philipp Zabel, Rob Herring,
Stephen Boyd
This controller provides clocks and reset functionality for audio
peripherals on Amlogic A1 SoC family.
The driver is almost identical to 'axg-audio', however it would be better
to keep it separate due to following reasons:
- significant amount of bits has another definition. I will bring there
a mess of new defines with A1_ suffixes.
- registers of this controller are located in two separate regions. It
will give a lot of complications for 'axg-audio' to support this.
Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
---
drivers/clk/meson/Kconfig | 14 +
drivers/clk/meson/Makefile | 3 +
drivers/clk/meson/a1-audio-clkc.c | 359 ++++++++++++++++++++++++++
drivers/clk/meson/a1-audio-drv.c | 104 ++++++++
drivers/clk/meson/a1-audio-vad-clkc.c | 85 ++++++
drivers/clk/meson/a1-audio.h | 131 ++++++++++
6 files changed, 696 insertions(+)
create mode 100644 drivers/clk/meson/a1-audio-clkc.c
create mode 100644 drivers/clk/meson/a1-audio-drv.c
create mode 100644 drivers/clk/meson/a1-audio-vad-clkc.c
create mode 100644 drivers/clk/meson/a1-audio.h
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 78f648c9c97d..b558288a6b78 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -132,6 +132,20 @@ config COMMON_CLK_A1_PERIPHERALS
device, A1 SoC Family. Say Y if you want A1 Peripherals clock
controller to work.
+config COMMON_CLK_A1_AUDIO
+ tristate "Amlogic A1 SoC Audio clock controller support"
+ depends on ARM64
+ select COMMON_CLK_MESON_REGMAP
+ select COMMON_CLK_MESON_PHASE
+ select COMMON_CLK_MESON_SCLK_DIV
+ select COMMON_CLK_MESON_CLKC_UTILS
+ select REGMAP_MMIO
+ imply RESET_MESON_AUX
+ help
+ Support for the Audio clock controller on Amlogic A113L based
+ device, A1 SoC Family. Say Y if you want A1 Audio clock controller
+ to work.
+
config COMMON_CLK_C3_PLL
tristate "Amlogic C3 PLL clock controller"
depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index bc56a47931c1..f7ea11df1de3 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -16,10 +16,13 @@ obj-$(CONFIG_COMMON_CLK_MESON_VCLK) += vclk.o
# Amlogic Clock controllers
+a1-audio-y := a1-audio-drv.o a1-audio-clkc.o a1-audio-vad-clkc.o
+
obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
+obj-$(CONFIG_COMMON_CLK_A1_AUDIO) += a1-audio.o
obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/a1-audio-clkc.c b/drivers/clk/meson/a1-audio-clkc.c
new file mode 100644
index 000000000000..48160dcb7f47
--- /dev/null
+++ b/drivers/clk/meson/a1-audio-clkc.c
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
+ */
+
+#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
+
+#include "a1-audio.h"
+
+#define AUDIO_CLK_GATE_EN0 0x000
+#define AUDIO_MCLK_A_CTRL 0x008
+#define AUDIO_MCLK_B_CTRL 0x00c
+#define AUDIO_MCLK_C_CTRL 0x010
+#define AUDIO_MCLK_D_CTRL 0x014
+#define AUDIO_MCLK_E_CTRL 0x018
+#define AUDIO_MCLK_F_CTRL 0x01c
+#define AUDIO_SW_RESET0 0x028
+#define AUDIO_MST_A_SCLK_CTRL0 0x040
+#define AUDIO_MST_A_SCLK_CTRL1 0x044
+#define AUDIO_MST_B_SCLK_CTRL0 0x048
+#define AUDIO_MST_B_SCLK_CTRL1 0x04c
+#define AUDIO_MST_C_SCLK_CTRL0 0x050
+#define AUDIO_MST_C_SCLK_CTRL1 0x054
+#define AUDIO_MST_D_SCLK_CTRL0 0x058
+#define AUDIO_MST_D_SCLK_CTRL1 0x05c
+#define AUDIO_CLK_TDMIN_A_CTRL 0x080
+#define AUDIO_CLK_TDMIN_B_CTRL 0x084
+#define AUDIO_CLK_TDMIN_LB_CTRL 0x08c
+#define AUDIO_CLK_TDMOUT_A_CTRL 0x090
+#define AUDIO_CLK_TDMOUT_B_CTRL 0x094
+#define AUDIO_CLK_SPDIFIN_CTRL 0x09c
+#define AUDIO_CLK_RESAMPLE_CTRL 0x0a4
+#define AUDIO_CLK_LOCKER_CTRL 0x0a8
+#define AUDIO_CLK_EQDRC_CTRL 0x0c0
+
+struct clk_regmap aud_ddr_arb =
+ AUD_PCLK_GATE(ddr_arb, AUDIO_CLK_GATE_EN0, 0);
+struct clk_regmap aud_tdmin_a =
+ AUD_PCLK_GATE(tdmin_a, AUDIO_CLK_GATE_EN0, 1);
+struct clk_regmap aud_tdmin_b =
+ AUD_PCLK_GATE(tdmin_b, AUDIO_CLK_GATE_EN0, 2);
+struct clk_regmap aud_tdmin_lb =
+ AUD_PCLK_GATE(tdmin_lb, AUDIO_CLK_GATE_EN0, 3);
+struct clk_regmap aud_loopback =
+ AUD_PCLK_GATE(loopback, AUDIO_CLK_GATE_EN0, 4);
+struct clk_regmap aud_tdmout_a =
+ AUD_PCLK_GATE(tdmout_a, AUDIO_CLK_GATE_EN0, 5);
+struct clk_regmap aud_tdmout_b =
+ AUD_PCLK_GATE(tdmout_b, AUDIO_CLK_GATE_EN0, 6);
+struct clk_regmap aud_frddr_a =
+ AUD_PCLK_GATE(frddr_a, AUDIO_CLK_GATE_EN0, 7);
+struct clk_regmap aud_frddr_b =
+ AUD_PCLK_GATE(frddr_b, AUDIO_CLK_GATE_EN0, 8);
+struct clk_regmap aud_toddr_a =
+ AUD_PCLK_GATE(toddr_a, AUDIO_CLK_GATE_EN0, 9);
+struct clk_regmap aud_toddr_b =
+ AUD_PCLK_GATE(toddr_b, AUDIO_CLK_GATE_EN0, 10);
+struct clk_regmap aud_spdifin =
+ AUD_PCLK_GATE(spdifin, AUDIO_CLK_GATE_EN0, 11);
+struct clk_regmap aud_resample =
+ AUD_PCLK_GATE(resample, AUDIO_CLK_GATE_EN0, 12);
+struct clk_regmap aud_eqdrc =
+ AUD_PCLK_GATE(eqdrc, AUDIO_CLK_GATE_EN0, 13);
+struct clk_regmap aud_audiolocker =
+ AUD_PCLK_GATE(audiolocker, AUDIO_CLK_GATE_EN0, 14);
+
+struct clk_regmap aud_mst_a_mclk_sel =
+ AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL);
+struct clk_regmap aud_mst_a_mclk_div =
+ AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL);
+struct clk_regmap aud_mst_a_mclk =
+ AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL);
+
+struct clk_regmap aud_mst_b_mclk_sel =
+ AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL);
+struct clk_regmap aud_mst_b_mclk_div =
+ AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL);
+struct clk_regmap aud_mst_b_mclk =
+ AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL);
+
+struct clk_regmap aud_mst_c_mclk_sel =
+ AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL);
+struct clk_regmap aud_mst_c_mclk_div =
+ AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL);
+struct clk_regmap aud_mst_c_mclk =
+ AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL);
+
+struct clk_regmap aud_mst_d_mclk_sel =
+ AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL);
+struct clk_regmap aud_mst_d_mclk_div =
+ AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL);
+struct clk_regmap aud_mst_d_mclk =
+ AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL);
+
+struct clk_regmap aud_spdifin_clk_sel =
+ AUD_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
+struct clk_regmap aud_spdifin_clk_div =
+ AUD_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
+struct clk_regmap aud_spdifin_clk =
+ AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
+
+struct clk_regmap aud_eqdrc_clk_sel =
+ AUD_MST_MCLK_MUX(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
+struct clk_regmap aud_eqdrc_clk_div =
+ AUD_MST_MCLK_DIV(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
+struct clk_regmap aud_eqdrc_clk =
+ AUD_MST_MCLK_GATE(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
+
+struct clk_regmap aud_resample_clk_sel =
+ AUD_MUX(resample_clk_sel, AUDIO_CLK_RESAMPLE_CTRL, 0xf, 24,
+ CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
+struct clk_regmap aud_resample_clk_div =
+ AUD_DIV(resample_clk_div, AUDIO_CLK_RESAMPLE_CTRL, 0, 8,
+ CLK_DIVIDER_ROUND_CLOSEST, aud_resample_clk_sel,
+ CLK_SET_RATE_PARENT);
+struct clk_regmap aud_resample_clk =
+ AUD_GATE(resample_clk, AUDIO_CLK_RESAMPLE_CTRL, 31,
+ aud_resample_clk_div, CLK_SET_RATE_PARENT);
+
+struct clk_regmap aud_locker_in_clk_sel =
+ AUD_MUX(locker_in_clk_sel, AUDIO_CLK_LOCKER_CTRL, 0xf, 8,
+ CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
+struct clk_regmap aud_locker_in_clk_div =
+ AUD_DIV(locker_in_clk_div, AUDIO_CLK_LOCKER_CTRL, 0, 8,
+ CLK_DIVIDER_ROUND_CLOSEST, aud_locker_in_clk_sel,
+ CLK_SET_RATE_PARENT);
+struct clk_regmap aud_locker_in_clk =
+ AUD_GATE(locker_in_clk, AUDIO_CLK_LOCKER_CTRL, 15,
+ aud_locker_in_clk_div, CLK_SET_RATE_PARENT);
+
+struct clk_regmap aud_locker_out_clk_sel =
+ AUD_MUX(locker_out_clk_sel, AUDIO_CLK_LOCKER_CTRL, 0xf, 24,
+ CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
+struct clk_regmap aud_locker_out_clk_div =
+ AUD_DIV(locker_out_clk_div, AUDIO_CLK_LOCKER_CTRL, 16, 8,
+ CLK_DIVIDER_ROUND_CLOSEST, aud_locker_out_clk_sel,
+ CLK_SET_RATE_PARENT);
+struct clk_regmap aud_locker_out_clk =
+ AUD_GATE(locker_out_clk, AUDIO_CLK_LOCKER_CTRL, 31,
+ aud_locker_out_clk_div, CLK_SET_RATE_PARENT);
+
+struct clk_regmap aud_mst_a_sclk_pre_en =
+ AUD_MST_SCLK_PRE_EN(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0, mst_a_mclk);
+struct clk_regmap aud_mst_a_sclk_div =
+ AUD_MST_SCLK_DIV(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0);
+struct clk_regmap aud_mst_a_sclk_post_en =
+ AUD_MST_SCLK_POST_EN(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0);
+struct clk_regmap aud_mst_a_sclk =
+ AUD_MST_SCLK(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL1);
+
+struct clk_regmap aud_mst_b_sclk_pre_en =
+ AUD_MST_SCLK_PRE_EN(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0, mst_b_mclk);
+struct clk_regmap aud_mst_b_sclk_div =
+ AUD_MST_SCLK_DIV(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0);
+struct clk_regmap aud_mst_b_sclk_post_en =
+ AUD_MST_SCLK_POST_EN(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0);
+struct clk_regmap aud_mst_b_sclk =
+ AUD_MST_SCLK(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL1);
+
+struct clk_regmap aud_mst_c_sclk_pre_en =
+ AUD_MST_SCLK_PRE_EN(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0, mst_c_mclk);
+struct clk_regmap aud_mst_c_sclk_div =
+ AUD_MST_SCLK_DIV(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0);
+struct clk_regmap aud_mst_c_sclk_post_en =
+ AUD_MST_SCLK_POST_EN(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0);
+struct clk_regmap aud_mst_c_sclk =
+ AUD_MST_SCLK(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL1);
+
+struct clk_regmap aud_mst_d_sclk_pre_en =
+ AUD_MST_SCLK_PRE_EN(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0, mst_d_mclk);
+struct clk_regmap aud_mst_d_sclk_div =
+ AUD_MST_SCLK_DIV(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0);
+struct clk_regmap aud_mst_d_sclk_post_en =
+ AUD_MST_SCLK_POST_EN(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0);
+struct clk_regmap aud_mst_d_sclk =
+ AUD_MST_SCLK(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL1);
+
+struct clk_regmap aud_mst_a_lrclk_div =
+ AUD_MST_LRCLK_DIV(mst_a_lrclk, AUDIO_MST_A_SCLK_CTRL0,
+ mst_a_sclk_post_en);
+struct clk_regmap aud_mst_a_lrclk =
+ AUD_MST_LRCLK(mst_a_lrclk, AUDIO_MST_A_SCLK_CTRL1);
+
+struct clk_regmap aud_mst_b_lrclk_div =
+ AUD_MST_LRCLK_DIV(mst_b_lrclk, AUDIO_MST_B_SCLK_CTRL0,
+ mst_b_sclk_post_en);
+struct clk_regmap aud_mst_b_lrclk =
+ AUD_MST_LRCLK(mst_b_lrclk, AUDIO_MST_B_SCLK_CTRL1);
+
+struct clk_regmap aud_mst_c_lrclk_div =
+ AUD_MST_LRCLK_DIV(mst_c_lrclk, AUDIO_MST_C_SCLK_CTRL0,
+ mst_c_sclk_post_en);
+struct clk_regmap aud_mst_c_lrclk =
+ AUD_MST_LRCLK(mst_c_lrclk, AUDIO_MST_C_SCLK_CTRL1);
+
+struct clk_regmap aud_mst_d_lrclk_div =
+ AUD_MST_LRCLK_DIV(mst_d_lrclk, AUDIO_MST_D_SCLK_CTRL0,
+ mst_d_sclk_post_en);
+struct clk_regmap aud_mst_d_lrclk =
+ AUD_MST_LRCLK(mst_d_lrclk, AUDIO_MST_D_SCLK_CTRL1);
+
+struct clk_regmap aud_tdmin_a_sclk_sel =
+ AUD_TDM_SCLK_MUX(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
+struct clk_regmap aud_tdmin_a_sclk_pre_en =
+ AUD_TDM_SCLK_PRE_EN(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
+struct clk_regmap aud_tdmin_a_sclk_post_en =
+ AUD_TDM_SCLK_POST_EN(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
+struct clk_regmap aud_tdmin_a_sclk =
+ AUD_TDM_SCLK_WS(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
+struct clk_regmap aud_tdmin_a_lrclk =
+ AUD_TDM_LRLCK(tdmin_a_lrclk, AUDIO_CLK_TDMIN_A_CTRL);
+
+struct clk_regmap aud_tdmin_b_sclk_sel =
+ AUD_TDM_SCLK_MUX(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
+struct clk_regmap aud_tdmin_b_sclk_pre_en =
+ AUD_TDM_SCLK_PRE_EN(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
+struct clk_regmap aud_tdmin_b_sclk_post_en =
+ AUD_TDM_SCLK_POST_EN(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
+struct clk_regmap aud_tdmin_b_sclk =
+ AUD_TDM_SCLK_WS(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
+struct clk_regmap aud_tdmin_b_lrclk =
+ AUD_TDM_LRLCK(tdmin_b_lrclk, AUDIO_CLK_TDMIN_B_CTRL);
+
+struct clk_regmap aud_tdmin_lb_sclk_sel =
+ AUD_TDM_SCLK_MUX(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
+struct clk_regmap aud_tdmin_lb_sclk_pre_en =
+ AUD_TDM_SCLK_PRE_EN(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
+struct clk_regmap aud_tdmin_lb_sclk_post_en =
+ AUD_TDM_SCLK_POST_EN(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
+struct clk_regmap aud_tdmin_lb_sclk =
+ AUD_TDM_SCLK_WS(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
+struct clk_regmap aud_tdmin_lb_lrclk =
+ AUD_TDM_LRLCK(tdmin_lb_lrclk, AUDIO_CLK_TDMIN_LB_CTRL);
+
+struct clk_regmap aud_tdmout_a_sclk_sel =
+ AUD_TDM_SCLK_MUX(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
+struct clk_regmap aud_tdmout_a_sclk_pre_en =
+ AUD_TDM_SCLK_PRE_EN(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
+struct clk_regmap aud_tdmout_a_sclk_post_en =
+ AUD_TDM_SCLK_POST_EN(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
+struct clk_regmap aud_tdmout_a_sclk =
+ AUD_TDM_SCLK_WS(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
+struct clk_regmap aud_tdmout_a_lrclk =
+ AUD_TDM_LRLCK(tdmout_a_lrclk, AUDIO_CLK_TDMOUT_A_CTRL);
+
+struct clk_regmap aud_tdmout_b_sclk_sel =
+ AUD_TDM_SCLK_MUX(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
+struct clk_regmap aud_tdmout_b_sclk_pre_en =
+ AUD_TDM_SCLK_PRE_EN(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
+struct clk_regmap aud_tdmout_b_sclk_post_en =
+ AUD_TDM_SCLK_POST_EN(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
+struct clk_regmap aud_tdmout_b_sclk =
+ AUD_TDM_SCLK_WS(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
+struct clk_regmap aud_tdmout_b_lrclk =
+ AUD_TDM_LRLCK(tdmout_b_lrclk, AUDIO_CLK_TDMOUT_B_CTRL);
+
+static struct clk_hw *a1_audio_clkc_hws[] = {
+ [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw,
+ [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw,
+ [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw,
+ [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw,
+ [AUD_CLKID_LOOPBACK] = &aud_loopback.hw,
+ [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw,
+ [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw,
+ [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw,
+ [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw,
+ [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw,
+ [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw,
+ [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw,
+ [AUD_CLKID_RESAMPLE] = &aud_resample.hw,
+ [AUD_CLKID_EQDRC] = &aud_eqdrc.hw,
+ [AUD_CLKID_LOCKER] = &aud_audiolocker.hw,
+ [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw,
+ [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw,
+ [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw,
+ [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw,
+ [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw,
+ [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw,
+ [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw,
+ [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw,
+ [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw,
+ [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw,
+ [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw,
+ [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw,
+ [AUD_CLKID_RESAMPLE_CLK_SEL] = &aud_resample_clk_sel.hw,
+ [AUD_CLKID_RESAMPLE_CLK_DIV] = &aud_resample_clk_div.hw,
+ [AUD_CLKID_RESAMPLE_CLK] = &aud_resample_clk.hw,
+ [AUD_CLKID_LOCKER_IN_CLK_SEL] = &aud_locker_in_clk_sel.hw,
+ [AUD_CLKID_LOCKER_IN_CLK_DIV] = &aud_locker_in_clk_div.hw,
+ [AUD_CLKID_LOCKER_IN_CLK] = &aud_locker_in_clk.hw,
+ [AUD_CLKID_LOCKER_OUT_CLK_SEL] = &aud_locker_out_clk_sel.hw,
+ [AUD_CLKID_LOCKER_OUT_CLK_DIV] = &aud_locker_out_clk_div.hw,
+ [AUD_CLKID_LOCKER_OUT_CLK] = &aud_locker_out_clk.hw,
+ [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw,
+ [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw,
+ [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw,
+ [AUD_CLKID_EQDRC_CLK_SEL] = &aud_eqdrc_clk_sel.hw,
+ [AUD_CLKID_EQDRC_CLK_DIV] = &aud_eqdrc_clk_div.hw,
+ [AUD_CLKID_EQDRC_CLK] = &aud_eqdrc_clk.hw,
+ [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw,
+ [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw,
+ [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw,
+ [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw,
+ [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw,
+ [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw,
+ [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw,
+ [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw,
+ [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw,
+ [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw,
+ [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw,
+ [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw,
+ [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw,
+ [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw,
+ [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw,
+ [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw,
+ [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw,
+ [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw,
+ [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw,
+ [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw,
+ [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw,
+ [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw,
+ [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw,
+ [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw,
+ [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw,
+ [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw,
+ [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw,
+ [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw,
+ [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw,
+ [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw,
+ [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw,
+ [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw,
+ [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw,
+ [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw,
+ [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw,
+ [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw,
+ [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw,
+ [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw,
+ [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw,
+ [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw,
+ [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw,
+ [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw,
+ [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw,
+ [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw,
+ [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw,
+ [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw,
+ [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw,
+ [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw,
+ [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw,
+};
+
+struct a1_audio_data a1_audio_clkc = {
+ .hw_clks = {
+ .hws = a1_audio_clkc_hws,
+ .num = ARRAY_SIZE(a1_audio_clkc_hws),
+ },
+ .rst_drvname = "rst-a1",
+};
diff --git a/drivers/clk/meson/a1-audio-drv.c b/drivers/clk/meson/a1-audio-drv.c
new file mode 100644
index 000000000000..879a9d7bed72
--- /dev/null
+++ b/drivers/clk/meson/a1-audio-drv.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include <soc/amlogic/reset-meson-aux.h>
+
+#include "a1-audio.h"
+
+static const struct regmap_config a1_audio_regmap_cfg = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static int a1_audio_clkc_probe(struct platform_device *pdev)
+{
+ const struct a1_audio_data *data;
+ struct regmap *map;
+ void __iomem *base;
+ struct clk *clk;
+ unsigned int i;
+ int ret;
+
+ data = device_get_match_data(&pdev->dev);
+ if (!data)
+ return -EINVAL;
+
+ clk = devm_clk_get_enabled(&pdev->dev, "pclk");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ map = devm_regmap_init_mmio(&pdev->dev, base, &a1_audio_regmap_cfg);
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+
+ ret = device_reset(&pdev->dev);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "failed to reset device");
+
+ for (i = 0; i < data->hw_clks.num; i++) {
+ struct clk_hw *hw = data->hw_clks.hws[i];
+ struct clk_regmap *clk_regmap = to_clk_regmap(hw);
+
+ if (!hw)
+ continue;
+
+ clk_regmap->map = map;
+
+ ret = devm_clk_hw_register(&pdev->dev, hw);
+ if (ret)
+ return ret;
+ }
+
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, meson_clk_hw_get,
+ (void *)&data->hw_clks);
+ if (ret)
+ return ret;
+
+ if (!data->rst_drvname)
+ return 0;
+
+ return devm_meson_rst_aux_register(&pdev->dev, map, data->rst_drvname);
+}
+
+static const struct of_device_id a1_audio_clkc_match_table[] = {
+ {
+ .compatible = "amlogic,a1-audio-clkc",
+ .data = &a1_audio_clkc,
+ },
+ {
+ .compatible = "amlogic,a1-audio-vad-clkc",
+ .data = &a1_audio_vad_clkc,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, a1_audio_clkc_match_table);
+
+static struct platform_driver a1_audio_clkc_driver = {
+ .probe = a1_audio_clkc_probe,
+ .driver = {
+ .name = "a1-audio-clkc",
+ .of_match_table = a1_audio_clkc_match_table,
+ },
+};
+module_platform_driver(a1_audio_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic A1 Audio Clock driver");
+MODULE_AUTHOR("Jan Dakinevich <jan.dakinevich@salutedevices.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/a1-audio-vad-clkc.c b/drivers/clk/meson/a1-audio-vad-clkc.c
new file mode 100644
index 000000000000..0b1365d30ce1
--- /dev/null
+++ b/drivers/clk/meson/a1-audio-vad-clkc.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
+ */
+
+#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
+
+#include "a1-audio.h"
+
+#define AUDIO_VAD_CLK_GATE_EN0 0x00c
+#define AUDIO_VAD_MCLK_CTRL 0x040
+#define AUDIO_VAD_CLK_CTRL 0x044
+#define AUDIO_VAD_CLK_PDMIN_CTRL0 0x058
+#define AUDIO_CLK_VAD_PDMIN_CTRL1 0x05c
+
+struct clk_regmap aud_vad_ddr_arb =
+ AUD_PCLK_GATE(vad_ddr_arb, AUDIO_VAD_CLK_GATE_EN0, 0);
+struct clk_regmap aud_vad_pdm =
+ AUD_PCLK_GATE(vad_pdm, AUDIO_VAD_CLK_GATE_EN0, 1);
+struct clk_regmap aud_vad_tdmin_vad =
+ AUD_PCLK_GATE(vad_tdmin_vad, AUDIO_VAD_CLK_GATE_EN0, 2);
+struct clk_regmap aud_vad_toddr_vad =
+ AUD_PCLK_GATE(vad_toddr_vad, AUDIO_VAD_CLK_GATE_EN0, 3);
+struct clk_regmap aud_vad =
+ AUD_PCLK_GATE(vad, AUDIO_VAD_CLK_GATE_EN0, 4);
+struct clk_regmap aud_vad_audiotop =
+ AUD_PCLK_GATE(vad_audiotop, AUDIO_VAD_CLK_GATE_EN0, 7);
+
+struct clk_regmap aud_vad_mclk_sel =
+ AUD_MST_MCLK_MUX(vad_mclk, AUDIO_VAD_MCLK_CTRL);
+struct clk_regmap aud_vad_mclk_div =
+ AUD_MST_MCLK_DIV(vad_mclk, AUDIO_VAD_MCLK_CTRL);
+struct clk_regmap aud_vad_mclk =
+ AUD_MST_MCLK_GATE(vad_mclk, AUDIO_VAD_MCLK_CTRL);
+
+struct clk_regmap aud_vad_clk_sel =
+ AUD_MST_MCLK_MUX(vad_clk, AUDIO_VAD_CLK_CTRL);
+struct clk_regmap aud_vad_clk_div =
+ AUD_MST_MCLK_DIV(vad_clk, AUDIO_VAD_CLK_CTRL);
+struct clk_regmap aud_vad_clk =
+ AUD_MST_MCLK_GATE(vad_clk, AUDIO_VAD_CLK_CTRL);
+
+struct clk_regmap aud_vad_pdm_dclk_sel =
+ AUD_MST_MCLK_MUX(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
+struct clk_regmap aud_vad_pdm_dclk_div =
+ AUD_MST_MCLK_DIV(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
+struct clk_regmap aud_vad_pdm_dclk =
+ AUD_MST_MCLK_GATE(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
+
+struct clk_regmap aud_vad_pdm_sysclk_sel =
+ AUD_MST_MCLK_MUX(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
+struct clk_regmap aud_vad_pdm_sysclk_div =
+ AUD_MST_MCLK_DIV(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
+struct clk_regmap aud_vad_pdm_sysclk =
+ AUD_MST_MCLK_GATE(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
+
+static struct clk_hw *a1_audio_vad_clkc_hws[] = {
+ [AUD_CLKID_VAD_DDR_ARB] = &aud_vad_ddr_arb.hw,
+ [AUD_CLKID_VAD_PDM] = &aud_vad_pdm.hw,
+ [AUD_CLKID_VAD_TDMIN] = &aud_vad_tdmin_vad.hw,
+ [AUD_CLKID_VAD_TODDR] = &aud_vad_toddr_vad.hw,
+ [AUD_CLKID_VAD] = &aud_vad.hw,
+ [AUD_CLKID_VAD_AUDIOTOP] = &aud_vad_audiotop.hw,
+ [AUD_CLKID_VAD_MCLK_SEL] = &aud_vad_mclk_sel.hw,
+ [AUD_CLKID_VAD_MCLK_DIV] = &aud_vad_mclk_div.hw,
+ [AUD_CLKID_VAD_MCLK] = &aud_vad_mclk.hw,
+ [AUD_CLKID_VAD_CLK_SEL] = &aud_vad_clk_sel.hw,
+ [AUD_CLKID_VAD_CLK_DIV] = &aud_vad_clk_div.hw,
+ [AUD_CLKID_VAD_CLK] = &aud_vad_clk.hw,
+ [AUD_CLKID_VAD_PDM_DCLK_SEL] = &aud_vad_pdm_dclk_sel.hw,
+ [AUD_CLKID_VAD_PDM_DCLK_DIV] = &aud_vad_pdm_dclk_div.hw,
+ [AUD_CLKID_VAD_PDM_DCLK] = &aud_vad_pdm_dclk.hw,
+ [AUD_CLKID_VAD_PDM_SYSCLK_SEL] = &aud_vad_pdm_sysclk_sel.hw,
+ [AUD_CLKID_VAD_PDM_SYSCLK_DIV] = &aud_vad_pdm_sysclk_div.hw,
+ [AUD_CLKID_VAD_PDM_SYSCLK] = &aud_vad_pdm_sysclk.hw,
+};
+
+struct a1_audio_data a1_audio_vad_clkc = {
+ .hw_clks = {
+ .hws = a1_audio_vad_clkc_hws,
+ .num = ARRAY_SIZE(a1_audio_vad_clkc_hws),
+ },
+};
diff --git a/drivers/clk/meson/a1-audio.h b/drivers/clk/meson/a1-audio.h
new file mode 100644
index 000000000000..ecd0b1ea4aea
--- /dev/null
+++ b/drivers/clk/meson/a1-audio.h
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
+ */
+
+#ifndef __MESON_CLK_A1_AUDIO_H
+#define __MESON_CLK_A1_AUDIO_H
+
+#include "clk-phase.h"
+#include "clk-regmap.h"
+#include "meson-audio.h"
+#include "meson-clkc-utils.h"
+#include "sclk-div.h"
+
+#define AUD_PCLK_GATE(_name, _reg, _bit) { \
+ .data = &(struct clk_regmap_gate_data){ \
+ .offset = (_reg), \
+ .bit_idx = (_bit), \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = "aud_"#_name, \
+ .ops = &clk_regmap_gate_ops, \
+ .parent_data = &(const struct clk_parent_data) { \
+ .fw_name = "pclk" \
+ }, \
+ .num_parents = 1, \
+ }, \
+}
+
+#define AUD_MST_MCLK_PDATA ((const struct clk_parent_data[]) { \
+ { .fw_name = "mst_in0" }, \
+ { .fw_name = "mst_in1" }, \
+ { .fw_name = "mst_in2" }, \
+ { .fw_name = "mst_in3" }, \
+ { .fw_name = "mst_in4" }, \
+})
+#define AUD_MST_MCLK_MUX(_name, _reg) \
+ AUD_MUX(_name##_sel, (_reg), 0x7, 24, CLK_MUX_ROUND_CLOSEST, \
+ AUD_MST_MCLK_PDATA, 0)
+#define AUD_MST_MCLK_DIV(_name, _reg) \
+ AUD_DIV(_name##_div, (_reg), 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \
+ aud_##_name##_sel, CLK_SET_RATE_PARENT)
+#define AUD_MST_MCLK_GATE(_name, _reg) \
+ AUD_GATE(_name, (_reg), 31, \
+ aud_##_name##_div, CLK_SET_RATE_PARENT)
+
+#define AUD_MST_SCLK_PRE_EN(_name, _reg, _pname) \
+ AUD_GATE(_name##_pre_en, (_reg), 31, \
+ aud_##_pname, 0)
+#define AUD_MST_SCLK_DIV(_name, _reg) \
+ AUD_SCLK_DIV(_name##_div, (_reg), 20, 10, 0, 0, \
+ aud_##_name##_pre_en, CLK_SET_RATE_PARENT)
+#define AUD_MST_SCLK_POST_EN(_name, _reg) \
+ AUD_GATE(_name##_post_en, (_reg), 30, \
+ aud_##_name##_div, CLK_SET_RATE_PARENT)
+#define AUD_MST_SCLK(_name, _reg) \
+ AUD_TRIPHASE(_name, (_reg), 1, 0, 2, 4, \
+ aud_##_name##_post_en, CLK_SET_RATE_PARENT)
+
+#define AUD_MST_LRCLK_DIV(_name, _reg, _pname) \
+ AUD_SCLK_DIV(_name##_div, (_reg), 0, 10, 10, 10, \
+ aud_##_pname, 0)
+#define AUD_MST_LRCLK(_name, _reg) \
+ AUD_TRIPHASE(_name, (_reg), 1, 1, 3, 5, \
+ aud_##_name##_div, CLK_SET_RATE_PARENT)
+
+#define AUD_MST_SCLK_PDATA ((const struct clk_parent_data[]) { \
+ { .hw = &aud_mst_a_sclk.hw, .index = -1 }, \
+ { .hw = &aud_mst_b_sclk.hw, .index = -1 }, \
+ { .hw = &aud_mst_c_sclk.hw, .index = -1 }, \
+ { .hw = &aud_mst_d_sclk.hw, .index = -1 }, \
+ { .hw = NULL }, \
+ { .hw = NULL }, \
+ { .fw_name = "slv_sclk0" }, \
+ { .fw_name = "slv_sclk1" }, \
+ { .fw_name = "slv_sclk2" }, \
+ { .fw_name = "slv_sclk3" }, \
+ { .fw_name = "slv_sclk4" }, \
+ { .fw_name = "slv_sclk5" }, \
+ { .fw_name = "slv_sclk6" }, \
+ { .fw_name = "slv_sclk7" }, \
+ { .fw_name = "slv_sclk8" }, \
+ { .fw_name = "slv_sclk9" }, \
+})
+#define AUD_TDM_SCLK_MUX(_name, _reg) \
+ AUD_MUX(_name##_sel, (_reg), 0xf, 24, CLK_MUX_ROUND_CLOSEST, \
+ AUD_MST_SCLK_PDATA, 0)
+#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \
+ AUD_GATE(_name##_pre_en, (_reg), 31, \
+ aud_##_name##_sel, CLK_SET_RATE_PARENT)
+#define AUD_TDM_SCLK_POST_EN(_name, _reg) \
+ AUD_GATE(_name##_post_en, (_reg), 30, \
+ aud_##_name##_pre_en, CLK_SET_RATE_PARENT)
+#define AUD_TDM_SCLK_WS(_name, _reg) \
+ AUD_SCLK_WS(_name, (_reg), 1, 29, 28, \
+ aud_##_name##_post_en, \
+ CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
+
+#define AUD_MST_LRCLK_PDATA ((const struct clk_parent_data[]) { \
+ { .hw = &aud_mst_a_lrclk.hw, .index = -1 }, \
+ { .hw = &aud_mst_b_lrclk.hw, .index = -1 }, \
+ { .hw = &aud_mst_c_lrclk.hw, .index = -1 }, \
+ { .hw = &aud_mst_d_lrclk.hw, .index = -1 }, \
+ { .hw = NULL }, \
+ { .hw = NULL }, \
+ { .fw_name = "slv_lrclk0" }, \
+ { .fw_name = "slv_lrclk1" }, \
+ { .fw_name = "slv_lrclk2" }, \
+ { .fw_name = "slv_lrclk3" }, \
+ { .fw_name = "slv_lrclk4" }, \
+ { .fw_name = "slv_lrclk5" }, \
+ { .fw_name = "slv_lrclk6" }, \
+ { .fw_name = "slv_lrclk7" }, \
+ { .fw_name = "slv_lrclk8" }, \
+ { .fw_name = "slv_lrclk9" }, \
+})
+#define AUD_TDM_LRLCK(_name, _reg) \
+ AUD_MUX(_name, (_reg), 0xf, 20, CLK_MUX_ROUND_CLOSEST, \
+ AUD_MST_LRCLK_PDATA, CLK_SET_RATE_PARENT)
+
+struct a1_audio_data {
+ struct meson_clk_hw_data hw_clks;
+ const char *rst_drvname;
+};
+
+extern struct a1_audio_data a1_audio_clkc;
+extern struct a1_audio_data a1_audio_vad_clkc;
+
+#endif /* __MESON_CLK_A1_AUDIO_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC PATCH v4 5/5] arm64: dts: meson: a1: add the audio clock controller
2024-09-13 12:11 [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
` (3 preceding siblings ...)
2024-09-13 12:11 ` [RFC PATCH v4 4/5] clk: meson: a1: add the " Jan Dakinevich
@ 2024-09-13 12:11 ` Jan Dakinevich
2024-10-07 14:59 ` [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
2024-10-22 9:51 ` Jerome Brunet
6 siblings, 0 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-09-13 12:11 UTC (permalink / raw)
To: Jan Dakinevich, Conor Dooley, devicetree, Jerome Brunet,
Kevin Hilman, Krzysztof Kozlowski, linux-amlogic,
linux-arm-kernel, linux-clk, linux-kernel, Martin Blumenstingl,
Michael Turquette, Neil Armstrong, Philipp Zabel, Rob Herring,
Stephen Boyd
Add the bus and audio clock controllers' device tree nodes.
Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
---
arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 48 +++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
index e5366d4239b1..b22cd5330606 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -5,6 +5,7 @@
#include <dt-bindings/clock/amlogic,a1-pll-clkc.h>
#include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
+#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
#include <dt-bindings/gpio/meson-a1-gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
@@ -448,6 +449,53 @@ sd_emmc: mmc@10000 {
power-domains = <&pwrc PWRC_SD_EMMC_ID>;
status = "disabled";
};
+
+ audio: bus@50000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0x50000 0 0x4980>;
+ power-domains = <&pwrc PWRC_AUDIO_ID>;
+
+ clkc_audio: clock-controller@0 {
+ compatible = "amlogic,a1-audio-clkc";
+ reg = <0x0 0x0 0x0 0xb0>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ clocks = <&clkc_audio_vad AUD_CLKID_VAD_AUDIOTOP>,
+ <&clkc_periphs CLKID_DDS_IN>,
+ <&clkc_pll CLKID_FCLK_DIV2>,
+ <&clkc_pll CLKID_FCLK_DIV3>,
+ <&clkc_pll CLKID_HIFI_PLL>,
+ <&xtal>;
+ clock-names = "pclk",
+ "mst_in0",
+ "mst_in1",
+ "mst_in2",
+ "mst_in3",
+ "mst_in4";
+ resets = <&reset RESET_AUDIO>;
+ };
+
+ clkc_audio_vad: clock-controller@4800 {
+ compatible = "amlogic,a1-audio-vad-clkc";
+ reg = <0x0 0x4800 0x0 0x20>;
+ #clock-cells = <1>;
+ clocks = <&clkc_periphs CLKID_AUDIO>,
+ <&clkc_periphs CLKID_DDS_IN>,
+ <&clkc_pll CLKID_FCLK_DIV2>,
+ <&clkc_pll CLKID_FCLK_DIV3>,
+ <&clkc_pll CLKID_HIFI_PLL>,
+ <&xtal>;
+ clock-names = "pclk",
+ "mst_in0",
+ "mst_in1",
+ "mst_in2",
+ "mst_in3",
+ "mst_in4";
+ resets = <&reset RESET_AUDIO_VAD>;
+ };
+ };
};
usb: usb@fe004400 {
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver
2024-09-13 12:11 ` [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver Jan Dakinevich
@ 2024-09-13 17:23 ` Conor Dooley
2024-10-22 8:45 ` Jerome Brunet
2024-10-22 9:34 ` Jerome Brunet
2 siblings, 0 replies; 18+ messages in thread
From: Conor Dooley @ 2024-09-13 17:23 UTC (permalink / raw)
To: Jan Dakinevich
Cc: Conor Dooley, devicetree, Jerome Brunet, Kevin Hilman,
Krzysztof Kozlowski, linux-amlogic, linux-arm-kernel, linux-clk,
linux-kernel, Martin Blumenstingl, Michael Turquette,
Neil Armstrong, Philipp Zabel, Rob Herring, Stephen Boyd
[-- Attachment #1: Type: text/plain, Size: 266 bytes --]
On Fri, Sep 13, 2024 at 03:11:50PM +0300, Jan Dakinevich wrote:
> Add device tree bindings for A1 SoC audio clock and reset controllers.
>
> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 4/5] clk: meson: a1: add the audio clock controller driver
2024-09-13 12:11 ` [RFC PATCH v4 4/5] clk: meson: a1: add the " Jan Dakinevich
@ 2024-09-18 11:05 ` Jan Dakinevich
2024-10-22 9:47 ` Jerome Brunet
1 sibling, 0 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-09-18 11:05 UTC (permalink / raw)
To: Conor Dooley, devicetree, Jerome Brunet, Kevin Hilman,
Krzysztof Kozlowski, linux-amlogic, linux-arm-kernel, linux-clk,
linux-kernel, Martin Blumenstingl, Michael Turquette,
Neil Armstrong, Philipp Zabel, Rob Herring, Stephen Boyd
Also I forgot this:
+MODULE_IMPORT_NS(CLK_MESON);
Without it building of module fails on 'next'. I'll add it on next resend.
On 9/13/24 15:11, Jan Dakinevich wrote:
> This controller provides clocks and reset functionality for audio
> peripherals on Amlogic A1 SoC family.
>
> The driver is almost identical to 'axg-audio', however it would be better
> to keep it separate due to following reasons:
>
> - significant amount of bits has another definition. I will bring there
> a mess of new defines with A1_ suffixes.
>
> - registers of this controller are located in two separate regions. It
> will give a lot of complications for 'axg-audio' to support this.
>
> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> ---
> drivers/clk/meson/Kconfig | 14 +
> drivers/clk/meson/Makefile | 3 +
> drivers/clk/meson/a1-audio-clkc.c | 359 ++++++++++++++++++++++++++
> drivers/clk/meson/a1-audio-drv.c | 104 ++++++++
> drivers/clk/meson/a1-audio-vad-clkc.c | 85 ++++++
> drivers/clk/meson/a1-audio.h | 131 ++++++++++
> 6 files changed, 696 insertions(+)
> create mode 100644 drivers/clk/meson/a1-audio-clkc.c
> create mode 100644 drivers/clk/meson/a1-audio-drv.c
> create mode 100644 drivers/clk/meson/a1-audio-vad-clkc.c
> create mode 100644 drivers/clk/meson/a1-audio.h
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 78f648c9c97d..b558288a6b78 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -132,6 +132,20 @@ config COMMON_CLK_A1_PERIPHERALS
> device, A1 SoC Family. Say Y if you want A1 Peripherals clock
> controller to work.
>
> +config COMMON_CLK_A1_AUDIO
> + tristate "Amlogic A1 SoC Audio clock controller support"
> + depends on ARM64
> + select COMMON_CLK_MESON_REGMAP
> + select COMMON_CLK_MESON_PHASE
> + select COMMON_CLK_MESON_SCLK_DIV
> + select COMMON_CLK_MESON_CLKC_UTILS
> + select REGMAP_MMIO
> + imply RESET_MESON_AUX
> + help
> + Support for the Audio clock controller on Amlogic A113L based
> + device, A1 SoC Family. Say Y if you want A1 Audio clock controller
> + to work.
> +
> config COMMON_CLK_C3_PLL
> tristate "Amlogic C3 PLL clock controller"
> depends on ARM64
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index bc56a47931c1..f7ea11df1de3 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -16,10 +16,13 @@ obj-$(CONFIG_COMMON_CLK_MESON_VCLK) += vclk.o
>
> # Amlogic Clock controllers
>
> +a1-audio-y := a1-audio-drv.o a1-audio-clkc.o a1-audio-vad-clkc.o
> +
> obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
> obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
> obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
> obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
> +obj-$(CONFIG_COMMON_CLK_A1_AUDIO) += a1-audio.o
> obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
> obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
> obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
> diff --git a/drivers/clk/meson/a1-audio-clkc.c b/drivers/clk/meson/a1-audio-clkc.c
> new file mode 100644
> index 000000000000..48160dcb7f47
> --- /dev/null
> +++ b/drivers/clk/meson/a1-audio-clkc.c
> @@ -0,0 +1,359 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
> +
> +#include "a1-audio.h"
> +
> +#define AUDIO_CLK_GATE_EN0 0x000
> +#define AUDIO_MCLK_A_CTRL 0x008
> +#define AUDIO_MCLK_B_CTRL 0x00c
> +#define AUDIO_MCLK_C_CTRL 0x010
> +#define AUDIO_MCLK_D_CTRL 0x014
> +#define AUDIO_MCLK_E_CTRL 0x018
> +#define AUDIO_MCLK_F_CTRL 0x01c
> +#define AUDIO_SW_RESET0 0x028
> +#define AUDIO_MST_A_SCLK_CTRL0 0x040
> +#define AUDIO_MST_A_SCLK_CTRL1 0x044
> +#define AUDIO_MST_B_SCLK_CTRL0 0x048
> +#define AUDIO_MST_B_SCLK_CTRL1 0x04c
> +#define AUDIO_MST_C_SCLK_CTRL0 0x050
> +#define AUDIO_MST_C_SCLK_CTRL1 0x054
> +#define AUDIO_MST_D_SCLK_CTRL0 0x058
> +#define AUDIO_MST_D_SCLK_CTRL1 0x05c
> +#define AUDIO_CLK_TDMIN_A_CTRL 0x080
> +#define AUDIO_CLK_TDMIN_B_CTRL 0x084
> +#define AUDIO_CLK_TDMIN_LB_CTRL 0x08c
> +#define AUDIO_CLK_TDMOUT_A_CTRL 0x090
> +#define AUDIO_CLK_TDMOUT_B_CTRL 0x094
> +#define AUDIO_CLK_SPDIFIN_CTRL 0x09c
> +#define AUDIO_CLK_RESAMPLE_CTRL 0x0a4
> +#define AUDIO_CLK_LOCKER_CTRL 0x0a8
> +#define AUDIO_CLK_EQDRC_CTRL 0x0c0
> +
> +struct clk_regmap aud_ddr_arb =
> + AUD_PCLK_GATE(ddr_arb, AUDIO_CLK_GATE_EN0, 0);
> +struct clk_regmap aud_tdmin_a =
> + AUD_PCLK_GATE(tdmin_a, AUDIO_CLK_GATE_EN0, 1);
> +struct clk_regmap aud_tdmin_b =
> + AUD_PCLK_GATE(tdmin_b, AUDIO_CLK_GATE_EN0, 2);
> +struct clk_regmap aud_tdmin_lb =
> + AUD_PCLK_GATE(tdmin_lb, AUDIO_CLK_GATE_EN0, 3);
> +struct clk_regmap aud_loopback =
> + AUD_PCLK_GATE(loopback, AUDIO_CLK_GATE_EN0, 4);
> +struct clk_regmap aud_tdmout_a =
> + AUD_PCLK_GATE(tdmout_a, AUDIO_CLK_GATE_EN0, 5);
> +struct clk_regmap aud_tdmout_b =
> + AUD_PCLK_GATE(tdmout_b, AUDIO_CLK_GATE_EN0, 6);
> +struct clk_regmap aud_frddr_a =
> + AUD_PCLK_GATE(frddr_a, AUDIO_CLK_GATE_EN0, 7);
> +struct clk_regmap aud_frddr_b =
> + AUD_PCLK_GATE(frddr_b, AUDIO_CLK_GATE_EN0, 8);
> +struct clk_regmap aud_toddr_a =
> + AUD_PCLK_GATE(toddr_a, AUDIO_CLK_GATE_EN0, 9);
> +struct clk_regmap aud_toddr_b =
> + AUD_PCLK_GATE(toddr_b, AUDIO_CLK_GATE_EN0, 10);
> +struct clk_regmap aud_spdifin =
> + AUD_PCLK_GATE(spdifin, AUDIO_CLK_GATE_EN0, 11);
> +struct clk_regmap aud_resample =
> + AUD_PCLK_GATE(resample, AUDIO_CLK_GATE_EN0, 12);
> +struct clk_regmap aud_eqdrc =
> + AUD_PCLK_GATE(eqdrc, AUDIO_CLK_GATE_EN0, 13);
> +struct clk_regmap aud_audiolocker =
> + AUD_PCLK_GATE(audiolocker, AUDIO_CLK_GATE_EN0, 14);
> +
> +struct clk_regmap aud_mst_a_mclk_sel =
> + AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL);
> +struct clk_regmap aud_mst_a_mclk_div =
> + AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL);
> +struct clk_regmap aud_mst_a_mclk =
> + AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL);
> +
> +struct clk_regmap aud_mst_b_mclk_sel =
> + AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL);
> +struct clk_regmap aud_mst_b_mclk_div =
> + AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL);
> +struct clk_regmap aud_mst_b_mclk =
> + AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL);
> +
> +struct clk_regmap aud_mst_c_mclk_sel =
> + AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL);
> +struct clk_regmap aud_mst_c_mclk_div =
> + AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL);
> +struct clk_regmap aud_mst_c_mclk =
> + AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL);
> +
> +struct clk_regmap aud_mst_d_mclk_sel =
> + AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL);
> +struct clk_regmap aud_mst_d_mclk_div =
> + AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL);
> +struct clk_regmap aud_mst_d_mclk =
> + AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL);
> +
> +struct clk_regmap aud_spdifin_clk_sel =
> + AUD_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
> +struct clk_regmap aud_spdifin_clk_div =
> + AUD_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
> +struct clk_regmap aud_spdifin_clk =
> + AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
> +
> +struct clk_regmap aud_eqdrc_clk_sel =
> + AUD_MST_MCLK_MUX(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
> +struct clk_regmap aud_eqdrc_clk_div =
> + AUD_MST_MCLK_DIV(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
> +struct clk_regmap aud_eqdrc_clk =
> + AUD_MST_MCLK_GATE(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
> +
> +struct clk_regmap aud_resample_clk_sel =
> + AUD_MUX(resample_clk_sel, AUDIO_CLK_RESAMPLE_CTRL, 0xf, 24,
> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
> +struct clk_regmap aud_resample_clk_div =
> + AUD_DIV(resample_clk_div, AUDIO_CLK_RESAMPLE_CTRL, 0, 8,
> + CLK_DIVIDER_ROUND_CLOSEST, aud_resample_clk_sel,
> + CLK_SET_RATE_PARENT);
> +struct clk_regmap aud_resample_clk =
> + AUD_GATE(resample_clk, AUDIO_CLK_RESAMPLE_CTRL, 31,
> + aud_resample_clk_div, CLK_SET_RATE_PARENT);
> +
> +struct clk_regmap aud_locker_in_clk_sel =
> + AUD_MUX(locker_in_clk_sel, AUDIO_CLK_LOCKER_CTRL, 0xf, 8,
> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
> +struct clk_regmap aud_locker_in_clk_div =
> + AUD_DIV(locker_in_clk_div, AUDIO_CLK_LOCKER_CTRL, 0, 8,
> + CLK_DIVIDER_ROUND_CLOSEST, aud_locker_in_clk_sel,
> + CLK_SET_RATE_PARENT);
> +struct clk_regmap aud_locker_in_clk =
> + AUD_GATE(locker_in_clk, AUDIO_CLK_LOCKER_CTRL, 15,
> + aud_locker_in_clk_div, CLK_SET_RATE_PARENT);
> +
> +struct clk_regmap aud_locker_out_clk_sel =
> + AUD_MUX(locker_out_clk_sel, AUDIO_CLK_LOCKER_CTRL, 0xf, 24,
> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
> +struct clk_regmap aud_locker_out_clk_div =
> + AUD_DIV(locker_out_clk_div, AUDIO_CLK_LOCKER_CTRL, 16, 8,
> + CLK_DIVIDER_ROUND_CLOSEST, aud_locker_out_clk_sel,
> + CLK_SET_RATE_PARENT);
> +struct clk_regmap aud_locker_out_clk =
> + AUD_GATE(locker_out_clk, AUDIO_CLK_LOCKER_CTRL, 31,
> + aud_locker_out_clk_div, CLK_SET_RATE_PARENT);
> +
> +struct clk_regmap aud_mst_a_sclk_pre_en =
> + AUD_MST_SCLK_PRE_EN(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0, mst_a_mclk);
> +struct clk_regmap aud_mst_a_sclk_div =
> + AUD_MST_SCLK_DIV(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0);
> +struct clk_regmap aud_mst_a_sclk_post_en =
> + AUD_MST_SCLK_POST_EN(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0);
> +struct clk_regmap aud_mst_a_sclk =
> + AUD_MST_SCLK(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_b_sclk_pre_en =
> + AUD_MST_SCLK_PRE_EN(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0, mst_b_mclk);
> +struct clk_regmap aud_mst_b_sclk_div =
> + AUD_MST_SCLK_DIV(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0);
> +struct clk_regmap aud_mst_b_sclk_post_en =
> + AUD_MST_SCLK_POST_EN(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0);
> +struct clk_regmap aud_mst_b_sclk =
> + AUD_MST_SCLK(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_c_sclk_pre_en =
> + AUD_MST_SCLK_PRE_EN(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0, mst_c_mclk);
> +struct clk_regmap aud_mst_c_sclk_div =
> + AUD_MST_SCLK_DIV(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0);
> +struct clk_regmap aud_mst_c_sclk_post_en =
> + AUD_MST_SCLK_POST_EN(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0);
> +struct clk_regmap aud_mst_c_sclk =
> + AUD_MST_SCLK(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_d_sclk_pre_en =
> + AUD_MST_SCLK_PRE_EN(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0, mst_d_mclk);
> +struct clk_regmap aud_mst_d_sclk_div =
> + AUD_MST_SCLK_DIV(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0);
> +struct clk_regmap aud_mst_d_sclk_post_en =
> + AUD_MST_SCLK_POST_EN(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0);
> +struct clk_regmap aud_mst_d_sclk =
> + AUD_MST_SCLK(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_a_lrclk_div =
> + AUD_MST_LRCLK_DIV(mst_a_lrclk, AUDIO_MST_A_SCLK_CTRL0,
> + mst_a_sclk_post_en);
> +struct clk_regmap aud_mst_a_lrclk =
> + AUD_MST_LRCLK(mst_a_lrclk, AUDIO_MST_A_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_b_lrclk_div =
> + AUD_MST_LRCLK_DIV(mst_b_lrclk, AUDIO_MST_B_SCLK_CTRL0,
> + mst_b_sclk_post_en);
> +struct clk_regmap aud_mst_b_lrclk =
> + AUD_MST_LRCLK(mst_b_lrclk, AUDIO_MST_B_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_c_lrclk_div =
> + AUD_MST_LRCLK_DIV(mst_c_lrclk, AUDIO_MST_C_SCLK_CTRL0,
> + mst_c_sclk_post_en);
> +struct clk_regmap aud_mst_c_lrclk =
> + AUD_MST_LRCLK(mst_c_lrclk, AUDIO_MST_C_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_d_lrclk_div =
> + AUD_MST_LRCLK_DIV(mst_d_lrclk, AUDIO_MST_D_SCLK_CTRL0,
> + mst_d_sclk_post_en);
> +struct clk_regmap aud_mst_d_lrclk =
> + AUD_MST_LRCLK(mst_d_lrclk, AUDIO_MST_D_SCLK_CTRL1);
> +
> +struct clk_regmap aud_tdmin_a_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
> +struct clk_regmap aud_tdmin_a_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
> +struct clk_regmap aud_tdmin_a_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
> +struct clk_regmap aud_tdmin_a_sclk =
> + AUD_TDM_SCLK_WS(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
> +struct clk_regmap aud_tdmin_a_lrclk =
> + AUD_TDM_LRLCK(tdmin_a_lrclk, AUDIO_CLK_TDMIN_A_CTRL);
> +
> +struct clk_regmap aud_tdmin_b_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
> +struct clk_regmap aud_tdmin_b_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
> +struct clk_regmap aud_tdmin_b_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
> +struct clk_regmap aud_tdmin_b_sclk =
> + AUD_TDM_SCLK_WS(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
> +struct clk_regmap aud_tdmin_b_lrclk =
> + AUD_TDM_LRLCK(tdmin_b_lrclk, AUDIO_CLK_TDMIN_B_CTRL);
> +
> +struct clk_regmap aud_tdmin_lb_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +struct clk_regmap aud_tdmin_lb_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +struct clk_regmap aud_tdmin_lb_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +struct clk_regmap aud_tdmin_lb_sclk =
> + AUD_TDM_SCLK_WS(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +struct clk_regmap aud_tdmin_lb_lrclk =
> + AUD_TDM_LRLCK(tdmin_lb_lrclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +
> +struct clk_regmap aud_tdmout_a_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +struct clk_regmap aud_tdmout_a_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +struct clk_regmap aud_tdmout_a_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +struct clk_regmap aud_tdmout_a_sclk =
> + AUD_TDM_SCLK_WS(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +struct clk_regmap aud_tdmout_a_lrclk =
> + AUD_TDM_LRLCK(tdmout_a_lrclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +
> +struct clk_regmap aud_tdmout_b_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +struct clk_regmap aud_tdmout_b_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +struct clk_regmap aud_tdmout_b_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +struct clk_regmap aud_tdmout_b_sclk =
> + AUD_TDM_SCLK_WS(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +struct clk_regmap aud_tdmout_b_lrclk =
> + AUD_TDM_LRLCK(tdmout_b_lrclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +
> +static struct clk_hw *a1_audio_clkc_hws[] = {
> + [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw,
> + [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw,
> + [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw,
> + [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw,
> + [AUD_CLKID_LOOPBACK] = &aud_loopback.hw,
> + [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw,
> + [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw,
> + [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw,
> + [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw,
> + [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw,
> + [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw,
> + [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw,
> + [AUD_CLKID_RESAMPLE] = &aud_resample.hw,
> + [AUD_CLKID_EQDRC] = &aud_eqdrc.hw,
> + [AUD_CLKID_LOCKER] = &aud_audiolocker.hw,
> + [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw,
> + [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw,
> + [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw,
> + [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw,
> + [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw,
> + [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw,
> + [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw,
> + [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw,
> + [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw,
> + [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw,
> + [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw,
> + [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw,
> + [AUD_CLKID_RESAMPLE_CLK_SEL] = &aud_resample_clk_sel.hw,
> + [AUD_CLKID_RESAMPLE_CLK_DIV] = &aud_resample_clk_div.hw,
> + [AUD_CLKID_RESAMPLE_CLK] = &aud_resample_clk.hw,
> + [AUD_CLKID_LOCKER_IN_CLK_SEL] = &aud_locker_in_clk_sel.hw,
> + [AUD_CLKID_LOCKER_IN_CLK_DIV] = &aud_locker_in_clk_div.hw,
> + [AUD_CLKID_LOCKER_IN_CLK] = &aud_locker_in_clk.hw,
> + [AUD_CLKID_LOCKER_OUT_CLK_SEL] = &aud_locker_out_clk_sel.hw,
> + [AUD_CLKID_LOCKER_OUT_CLK_DIV] = &aud_locker_out_clk_div.hw,
> + [AUD_CLKID_LOCKER_OUT_CLK] = &aud_locker_out_clk.hw,
> + [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw,
> + [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw,
> + [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw,
> + [AUD_CLKID_EQDRC_CLK_SEL] = &aud_eqdrc_clk_sel.hw,
> + [AUD_CLKID_EQDRC_CLK_DIV] = &aud_eqdrc_clk_div.hw,
> + [AUD_CLKID_EQDRC_CLK] = &aud_eqdrc_clk.hw,
> + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw,
> + [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw,
> + [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw,
> + [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw,
> + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw,
> + [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw,
> + [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw,
> + [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw,
> + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw,
> + [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw,
> + [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw,
> + [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw,
> + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw,
> + [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw,
> + [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw,
> + [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw,
> + [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw,
> + [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw,
> + [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw,
> + [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw,
> + [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw,
> + [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw,
> + [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw,
> + [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw,
> + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw,
> + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw,
> + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw,
> + [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw,
> + [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw,
> + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw,
> + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw,
> + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw,
> + [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw,
> + [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw,
> + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw,
> + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw,
> + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw,
> + [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw,
> + [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw,
> + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw,
> + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw,
> + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw,
> + [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw,
> + [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw,
> + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw,
> + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw,
> + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw,
> + [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw,
> + [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw,
> +};
> +
> +struct a1_audio_data a1_audio_clkc = {
> + .hw_clks = {
> + .hws = a1_audio_clkc_hws,
> + .num = ARRAY_SIZE(a1_audio_clkc_hws),
> + },
> + .rst_drvname = "rst-a1",
> +};
> diff --git a/drivers/clk/meson/a1-audio-drv.c b/drivers/clk/meson/a1-audio-drv.c
> new file mode 100644
> index 000000000000..879a9d7bed72
> --- /dev/null
> +++ b/drivers/clk/meson/a1-audio-drv.c
> @@ -0,0 +1,104 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include <soc/amlogic/reset-meson-aux.h>
> +
> +#include "a1-audio.h"
> +
> +static const struct regmap_config a1_audio_regmap_cfg = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> +};
> +
> +static int a1_audio_clkc_probe(struct platform_device *pdev)
> +{
> + const struct a1_audio_data *data;
> + struct regmap *map;
> + void __iomem *base;
> + struct clk *clk;
> + unsigned int i;
> + int ret;
> +
> + data = device_get_match_data(&pdev->dev);
> + if (!data)
> + return -EINVAL;
> +
> + clk = devm_clk_get_enabled(&pdev->dev, "pclk");
> + if (IS_ERR(clk))
> + return PTR_ERR(clk);
> +
> + base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + map = devm_regmap_init_mmio(&pdev->dev, base, &a1_audio_regmap_cfg);
> + if (IS_ERR(map))
> + return PTR_ERR(map);
> +
> + ret = device_reset(&pdev->dev);
> + if (ret)
> + return dev_err_probe(&pdev->dev, ret, "failed to reset device");
> +
> + for (i = 0; i < data->hw_clks.num; i++) {
> + struct clk_hw *hw = data->hw_clks.hws[i];
> + struct clk_regmap *clk_regmap = to_clk_regmap(hw);
> +
> + if (!hw)
> + continue;
> +
> + clk_regmap->map = map;
> +
> + ret = devm_clk_hw_register(&pdev->dev, hw);
> + if (ret)
> + return ret;
> + }
> +
> + ret = devm_of_clk_add_hw_provider(&pdev->dev, meson_clk_hw_get,
> + (void *)&data->hw_clks);
> + if (ret)
> + return ret;
> +
> + if (!data->rst_drvname)
> + return 0;
> +
> + return devm_meson_rst_aux_register(&pdev->dev, map, data->rst_drvname);
> +}
> +
> +static const struct of_device_id a1_audio_clkc_match_table[] = {
> + {
> + .compatible = "amlogic,a1-audio-clkc",
> + .data = &a1_audio_clkc,
> + },
> + {
> + .compatible = "amlogic,a1-audio-vad-clkc",
> + .data = &a1_audio_vad_clkc,
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, a1_audio_clkc_match_table);
> +
> +static struct platform_driver a1_audio_clkc_driver = {
> + .probe = a1_audio_clkc_probe,
> + .driver = {
> + .name = "a1-audio-clkc",
> + .of_match_table = a1_audio_clkc_match_table,
> + },
> +};
> +module_platform_driver(a1_audio_clkc_driver);
> +
> +MODULE_DESCRIPTION("Amlogic A1 Audio Clock driver");
> +MODULE_AUTHOR("Jan Dakinevich <jan.dakinevich@salutedevices.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/clk/meson/a1-audio-vad-clkc.c b/drivers/clk/meson/a1-audio-vad-clkc.c
> new file mode 100644
> index 000000000000..0b1365d30ce1
> --- /dev/null
> +++ b/drivers/clk/meson/a1-audio-vad-clkc.c
> @@ -0,0 +1,85 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
> +
> +#include "a1-audio.h"
> +
> +#define AUDIO_VAD_CLK_GATE_EN0 0x00c
> +#define AUDIO_VAD_MCLK_CTRL 0x040
> +#define AUDIO_VAD_CLK_CTRL 0x044
> +#define AUDIO_VAD_CLK_PDMIN_CTRL0 0x058
> +#define AUDIO_CLK_VAD_PDMIN_CTRL1 0x05c
> +
> +struct clk_regmap aud_vad_ddr_arb =
> + AUD_PCLK_GATE(vad_ddr_arb, AUDIO_VAD_CLK_GATE_EN0, 0);
> +struct clk_regmap aud_vad_pdm =
> + AUD_PCLK_GATE(vad_pdm, AUDIO_VAD_CLK_GATE_EN0, 1);
> +struct clk_regmap aud_vad_tdmin_vad =
> + AUD_PCLK_GATE(vad_tdmin_vad, AUDIO_VAD_CLK_GATE_EN0, 2);
> +struct clk_regmap aud_vad_toddr_vad =
> + AUD_PCLK_GATE(vad_toddr_vad, AUDIO_VAD_CLK_GATE_EN0, 3);
> +struct clk_regmap aud_vad =
> + AUD_PCLK_GATE(vad, AUDIO_VAD_CLK_GATE_EN0, 4);
> +struct clk_regmap aud_vad_audiotop =
> + AUD_PCLK_GATE(vad_audiotop, AUDIO_VAD_CLK_GATE_EN0, 7);
> +
> +struct clk_regmap aud_vad_mclk_sel =
> + AUD_MST_MCLK_MUX(vad_mclk, AUDIO_VAD_MCLK_CTRL);
> +struct clk_regmap aud_vad_mclk_div =
> + AUD_MST_MCLK_DIV(vad_mclk, AUDIO_VAD_MCLK_CTRL);
> +struct clk_regmap aud_vad_mclk =
> + AUD_MST_MCLK_GATE(vad_mclk, AUDIO_VAD_MCLK_CTRL);
> +
> +struct clk_regmap aud_vad_clk_sel =
> + AUD_MST_MCLK_MUX(vad_clk, AUDIO_VAD_CLK_CTRL);
> +struct clk_regmap aud_vad_clk_div =
> + AUD_MST_MCLK_DIV(vad_clk, AUDIO_VAD_CLK_CTRL);
> +struct clk_regmap aud_vad_clk =
> + AUD_MST_MCLK_GATE(vad_clk, AUDIO_VAD_CLK_CTRL);
> +
> +struct clk_regmap aud_vad_pdm_dclk_sel =
> + AUD_MST_MCLK_MUX(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
> +struct clk_regmap aud_vad_pdm_dclk_div =
> + AUD_MST_MCLK_DIV(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
> +struct clk_regmap aud_vad_pdm_dclk =
> + AUD_MST_MCLK_GATE(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
> +
> +struct clk_regmap aud_vad_pdm_sysclk_sel =
> + AUD_MST_MCLK_MUX(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
> +struct clk_regmap aud_vad_pdm_sysclk_div =
> + AUD_MST_MCLK_DIV(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
> +struct clk_regmap aud_vad_pdm_sysclk =
> + AUD_MST_MCLK_GATE(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
> +
> +static struct clk_hw *a1_audio_vad_clkc_hws[] = {
> + [AUD_CLKID_VAD_DDR_ARB] = &aud_vad_ddr_arb.hw,
> + [AUD_CLKID_VAD_PDM] = &aud_vad_pdm.hw,
> + [AUD_CLKID_VAD_TDMIN] = &aud_vad_tdmin_vad.hw,
> + [AUD_CLKID_VAD_TODDR] = &aud_vad_toddr_vad.hw,
> + [AUD_CLKID_VAD] = &aud_vad.hw,
> + [AUD_CLKID_VAD_AUDIOTOP] = &aud_vad_audiotop.hw,
> + [AUD_CLKID_VAD_MCLK_SEL] = &aud_vad_mclk_sel.hw,
> + [AUD_CLKID_VAD_MCLK_DIV] = &aud_vad_mclk_div.hw,
> + [AUD_CLKID_VAD_MCLK] = &aud_vad_mclk.hw,
> + [AUD_CLKID_VAD_CLK_SEL] = &aud_vad_clk_sel.hw,
> + [AUD_CLKID_VAD_CLK_DIV] = &aud_vad_clk_div.hw,
> + [AUD_CLKID_VAD_CLK] = &aud_vad_clk.hw,
> + [AUD_CLKID_VAD_PDM_DCLK_SEL] = &aud_vad_pdm_dclk_sel.hw,
> + [AUD_CLKID_VAD_PDM_DCLK_DIV] = &aud_vad_pdm_dclk_div.hw,
> + [AUD_CLKID_VAD_PDM_DCLK] = &aud_vad_pdm_dclk.hw,
> + [AUD_CLKID_VAD_PDM_SYSCLK_SEL] = &aud_vad_pdm_sysclk_sel.hw,
> + [AUD_CLKID_VAD_PDM_SYSCLK_DIV] = &aud_vad_pdm_sysclk_div.hw,
> + [AUD_CLKID_VAD_PDM_SYSCLK] = &aud_vad_pdm_sysclk.hw,
> +};
> +
> +struct a1_audio_data a1_audio_vad_clkc = {
> + .hw_clks = {
> + .hws = a1_audio_vad_clkc_hws,
> + .num = ARRAY_SIZE(a1_audio_vad_clkc_hws),
> + },
> +};
> diff --git a/drivers/clk/meson/a1-audio.h b/drivers/clk/meson/a1-audio.h
> new file mode 100644
> index 000000000000..ecd0b1ea4aea
> --- /dev/null
> +++ b/drivers/clk/meson/a1-audio.h
> @@ -0,0 +1,131 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#ifndef __MESON_CLK_A1_AUDIO_H
> +#define __MESON_CLK_A1_AUDIO_H
> +
> +#include "clk-phase.h"
> +#include "clk-regmap.h"
> +#include "meson-audio.h"
> +#include "meson-clkc-utils.h"
> +#include "sclk-div.h"
> +
> +#define AUD_PCLK_GATE(_name, _reg, _bit) { \
> + .data = &(struct clk_regmap_gate_data){ \
> + .offset = (_reg), \
> + .bit_idx = (_bit), \
> + }, \
> + .hw.init = &(struct clk_init_data) { \
> + .name = "aud_"#_name, \
> + .ops = &clk_regmap_gate_ops, \
> + .parent_data = &(const struct clk_parent_data) { \
> + .fw_name = "pclk" \
> + }, \
> + .num_parents = 1, \
> + }, \
> +}
> +
> +#define AUD_MST_MCLK_PDATA ((const struct clk_parent_data[]) { \
> + { .fw_name = "mst_in0" }, \
> + { .fw_name = "mst_in1" }, \
> + { .fw_name = "mst_in2" }, \
> + { .fw_name = "mst_in3" }, \
> + { .fw_name = "mst_in4" }, \
> +})
> +#define AUD_MST_MCLK_MUX(_name, _reg) \
> + AUD_MUX(_name##_sel, (_reg), 0x7, 24, CLK_MUX_ROUND_CLOSEST, \
> + AUD_MST_MCLK_PDATA, 0)
> +#define AUD_MST_MCLK_DIV(_name, _reg) \
> + AUD_DIV(_name##_div, (_reg), 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \
> + aud_##_name##_sel, CLK_SET_RATE_PARENT)
> +#define AUD_MST_MCLK_GATE(_name, _reg) \
> + AUD_GATE(_name, (_reg), 31, \
> + aud_##_name##_div, CLK_SET_RATE_PARENT)
> +
> +#define AUD_MST_SCLK_PRE_EN(_name, _reg, _pname) \
> + AUD_GATE(_name##_pre_en, (_reg), 31, \
> + aud_##_pname, 0)
> +#define AUD_MST_SCLK_DIV(_name, _reg) \
> + AUD_SCLK_DIV(_name##_div, (_reg), 20, 10, 0, 0, \
> + aud_##_name##_pre_en, CLK_SET_RATE_PARENT)
> +#define AUD_MST_SCLK_POST_EN(_name, _reg) \
> + AUD_GATE(_name##_post_en, (_reg), 30, \
> + aud_##_name##_div, CLK_SET_RATE_PARENT)
> +#define AUD_MST_SCLK(_name, _reg) \
> + AUD_TRIPHASE(_name, (_reg), 1, 0, 2, 4, \
> + aud_##_name##_post_en, CLK_SET_RATE_PARENT)
> +
> +#define AUD_MST_LRCLK_DIV(_name, _reg, _pname) \
> + AUD_SCLK_DIV(_name##_div, (_reg), 0, 10, 10, 10, \
> + aud_##_pname, 0)
> +#define AUD_MST_LRCLK(_name, _reg) \
> + AUD_TRIPHASE(_name, (_reg), 1, 1, 3, 5, \
> + aud_##_name##_div, CLK_SET_RATE_PARENT)
> +
> +#define AUD_MST_SCLK_PDATA ((const struct clk_parent_data[]) { \
> + { .hw = &aud_mst_a_sclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_b_sclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_c_sclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_d_sclk.hw, .index = -1 }, \
> + { .hw = NULL }, \
> + { .hw = NULL }, \
> + { .fw_name = "slv_sclk0" }, \
> + { .fw_name = "slv_sclk1" }, \
> + { .fw_name = "slv_sclk2" }, \
> + { .fw_name = "slv_sclk3" }, \
> + { .fw_name = "slv_sclk4" }, \
> + { .fw_name = "slv_sclk5" }, \
> + { .fw_name = "slv_sclk6" }, \
> + { .fw_name = "slv_sclk7" }, \
> + { .fw_name = "slv_sclk8" }, \
> + { .fw_name = "slv_sclk9" }, \
> +})
> +#define AUD_TDM_SCLK_MUX(_name, _reg) \
> + AUD_MUX(_name##_sel, (_reg), 0xf, 24, CLK_MUX_ROUND_CLOSEST, \
> + AUD_MST_SCLK_PDATA, 0)
> +#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \
> + AUD_GATE(_name##_pre_en, (_reg), 31, \
> + aud_##_name##_sel, CLK_SET_RATE_PARENT)
> +#define AUD_TDM_SCLK_POST_EN(_name, _reg) \
> + AUD_GATE(_name##_post_en, (_reg), 30, \
> + aud_##_name##_pre_en, CLK_SET_RATE_PARENT)
> +#define AUD_TDM_SCLK_WS(_name, _reg) \
> + AUD_SCLK_WS(_name, (_reg), 1, 29, 28, \
> + aud_##_name##_post_en, \
> + CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
> +
> +#define AUD_MST_LRCLK_PDATA ((const struct clk_parent_data[]) { \
> + { .hw = &aud_mst_a_lrclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_b_lrclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_c_lrclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_d_lrclk.hw, .index = -1 }, \
> + { .hw = NULL }, \
> + { .hw = NULL }, \
> + { .fw_name = "slv_lrclk0" }, \
> + { .fw_name = "slv_lrclk1" }, \
> + { .fw_name = "slv_lrclk2" }, \
> + { .fw_name = "slv_lrclk3" }, \
> + { .fw_name = "slv_lrclk4" }, \
> + { .fw_name = "slv_lrclk5" }, \
> + { .fw_name = "slv_lrclk6" }, \
> + { .fw_name = "slv_lrclk7" }, \
> + { .fw_name = "slv_lrclk8" }, \
> + { .fw_name = "slv_lrclk9" }, \
> +})
> +#define AUD_TDM_LRLCK(_name, _reg) \
> + AUD_MUX(_name, (_reg), 0xf, 20, CLK_MUX_ROUND_CLOSEST, \
> + AUD_MST_LRCLK_PDATA, CLK_SET_RATE_PARENT)
> +
> +struct a1_audio_data {
> + struct meson_clk_hw_data hw_clks;
> + const char *rst_drvname;
> +};
> +
> +extern struct a1_audio_data a1_audio_clkc;
> +extern struct a1_audio_data a1_audio_vad_clkc;
> +
> +#endif /* __MESON_CLK_A1_AUDIO_H */
--
Best regards
Jan Dakinevich
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver
2024-09-13 12:11 [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
` (4 preceding siblings ...)
2024-09-13 12:11 ` [RFC PATCH v4 5/5] arm64: dts: meson: a1: add the audio clock controller Jan Dakinevich
@ 2024-10-07 14:59 ` Jan Dakinevich
2024-10-22 9:51 ` Jerome Brunet
6 siblings, 0 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-10-07 14:59 UTC (permalink / raw)
To: Jerome Brunet
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
Hi, Jerome! Could you take a look at this patch series?
On 9/13/24 15:11, Jan Dakinevich wrote:
> This series adds support for audio clock and reset controllers on A1 SoC family.
>
> Dependency: [4]
>
> Changes v3 [3] -> v4
> - Use auxiliary reset device implemented in [4]
> - Split the driver into files
> - Use common with axg-audio yaml schema
> - Unify clock-names with axg-audio
>
> Changes v2 [2] -> v3
> - reset:
> * added auxiliary device
> - yaml:
> * added declaration of optional clocks
> * fixed names in example and another cosmetics
> - clocks:
> * reworked naming
> * stop using of "core" clock name
> * fixed wrong parenting
>
> Changes v1 [1] -> v2:
> - Detached from v1's series (patch 2, 3, 4, 25).
> - Reuse some of defines from axg-audio;
> - Split the controller into two memory regions.
>
> Links:
> [1] https://lore.kernel.org/lkml/20240314232201.2102178-1-jan.dakinevich@salutedevices.com/
> [2] https://lore.kernel.org/lkml/20240328010831.884487-1-jan.dakinevich@salutedevices.com/
> [3] https://lore.kernel.org/lkml/20240419125812.983409-1-jan.dakinevich@salutedevices.com/
> [4] https://lore.kernel.org/lkml/9a4377fe27d8eb940399e452b68fb5a6d678929f.camel@pengutronix.de/
>
> Jan Dakinevich (5):
> reset: amlogic: add support for A1 SoC in auxiliary reset driver
> clk: meson: axg: share the set of audio helper macro
> dt-bindings: clock: axg-audio: document A1 SoC audio clock controller
> driver
> clk: meson: a1: add the audio clock controller driver
> arm64: dts: meson: a1: add the audio clock controller
>
> .../clock/amlogic,axg-audio-clkc.yaml | 3 +
> arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 48 +++
> drivers/clk/meson/Kconfig | 14 +
> drivers/clk/meson/Makefile | 3 +
> drivers/clk/meson/a1-audio-clkc.c | 359 ++++++++++++++++++
> drivers/clk/meson/a1-audio-drv.c | 104 +++++
> drivers/clk/meson/a1-audio-vad-clkc.c | 85 +++++
> drivers/clk/meson/a1-audio.h | 131 +++++++
> drivers/clk/meson/axg-audio.c | 138 +------
> drivers/clk/meson/meson-audio.h | 143 +++++++
> drivers/reset/amlogic/reset-meson-aux.c | 9 +
> .../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++
> .../reset/amlogic,meson-a1-audio-reset.h | 29 ++
> 13 files changed, 1051 insertions(+), 137 deletions(-)
> create mode 100644 drivers/clk/meson/a1-audio-clkc.c
> create mode 100644 drivers/clk/meson/a1-audio-drv.c
> create mode 100644 drivers/clk/meson/a1-audio-vad-clkc.c
> create mode 100644 drivers/clk/meson/a1-audio.h
> create mode 100644 drivers/clk/meson/meson-audio.h
> create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
> create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
>
--
Best regards
Jan Dakinevich
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 1/5] reset: amlogic: add support for A1 SoC in auxiliary reset driver
2024-09-13 12:11 ` [RFC PATCH v4 1/5] reset: amlogic: add support for A1 SoC in auxiliary reset driver Jan Dakinevich
@ 2024-10-22 8:42 ` Jerome Brunet
0 siblings, 0 replies; 18+ messages in thread
From: Jerome Brunet @ 2024-10-22 8:42 UTC (permalink / raw)
To: Jan Dakinevich
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
> Add support for the reset controller present in the audio clock
> controller of A1 SoC families, using the auxiliary bus.
>
> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
Independent of clock controller. Should be sent separately
> ---
> drivers/reset/amlogic/reset-meson-aux.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/reset/amlogic/reset-meson-aux.c b/drivers/reset/amlogic/reset-meson-aux.c
> index dd8453001db9..a385c0125836 100644
> --- a/drivers/reset/amlogic/reset-meson-aux.c
> +++ b/drivers/reset/amlogic/reset-meson-aux.c
> @@ -26,6 +26,12 @@ struct meson_reset_adev {
> #define to_meson_reset_adev(_adev) \
> container_of((_adev), struct meson_reset_adev, adev)
>
> +static const struct meson_reset_param meson_a1_audio_param = {
> + .reset_ops = &meson_reset_toggle_ops,
> + .reset_num = 32,
> + .level_offset = 0x28,
> +};
> +
> static const struct meson_reset_param meson_g12a_audio_param = {
> .reset_ops = &meson_reset_toggle_ops,
> .reset_num = 26,
> @@ -40,6 +46,9 @@ static const struct meson_reset_param meson_sm1_audio_param = {
>
> static const struct auxiliary_device_id meson_reset_aux_ids[] = {
> {
> + .name = "a1-audio-clkc.rst-a1",
> + .driver_data = (kernel_ulong_t)&meson_a1_audio_param,
> + }, {
> .name = "axg-audio-clkc.rst-g12a",
> .driver_data = (kernel_ulong_t)&meson_g12a_audio_param,
> }, {
--
Jerome
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver
2024-09-13 12:11 ` [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver Jan Dakinevich
2024-09-13 17:23 ` Conor Dooley
@ 2024-10-22 8:45 ` Jerome Brunet
2024-10-24 4:48 ` Jan Dakinevich
2024-10-22 9:34 ` Jerome Brunet
2 siblings, 1 reply; 18+ messages in thread
From: Jerome Brunet @ 2024-10-22 8:45 UTC (permalink / raw)
To: Jan Dakinevich
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
> Add device tree bindings for A1 SoC audio clock and reset controllers.
>
> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
Reset and clock are now independent.
Please split the patch and send the changes in the related series,
bindings before the driver change.
> ---
> .../clock/amlogic,axg-audio-clkc.yaml | 3 +
> .../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++++++++++++++
> .../reset/amlogic,meson-a1-audio-reset.h | 29 +++++
> 3 files changed, 154 insertions(+)
> create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
> create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
>
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
> index fd7982dd4cea..df9eb8ce28dc 100644
> --- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
> +++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
> @@ -18,6 +18,8 @@ description:
> properties:
> compatible:
> enum:
> + - amlogic,a1-audio-clkc
> + - amlogic,a1-audio-vad-clkc
> - amlogic,axg-audio-clkc
> - amlogic,g12a-audio-clkc
> - amlogic,sm1-audio-clkc
> @@ -114,6 +116,7 @@ allOf:
> compatible:
> contains:
> enum:
> + - amlogic,a1-audio-clkc
> - amlogic,g12a-audio-clkc
> - amlogic,sm1-audio-clkc
> then:
> diff --git a/include/dt-bindings/clock/amlogic,a1-audio-clkc.h b/include/dt-bindings/clock/amlogic,a1-audio-clkc.h
> new file mode 100644
> index 000000000000..6534d1878816
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,a1-audio-clkc.h
> @@ -0,0 +1,122 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#ifndef __A1_AUDIO_CLKC_BINDINGS_H
> +#define __A1_AUDIO_CLKC_BINDINGS_H
> +
> +#define AUD_CLKID_DDR_ARB 1
> +#define AUD_CLKID_TDMIN_A 2
> +#define AUD_CLKID_TDMIN_B 3
> +#define AUD_CLKID_TDMIN_LB 4
> +#define AUD_CLKID_LOOPBACK 5
> +#define AUD_CLKID_TDMOUT_A 6
> +#define AUD_CLKID_TDMOUT_B 7
> +#define AUD_CLKID_FRDDR_A 8
> +#define AUD_CLKID_FRDDR_B 9
> +#define AUD_CLKID_TODDR_A 10
> +#define AUD_CLKID_TODDR_B 11
> +#define AUD_CLKID_SPDIFIN 12
> +#define AUD_CLKID_RESAMPLE 13
> +#define AUD_CLKID_EQDRC 14
> +#define AUD_CLKID_LOCKER 15
> +#define AUD_CLKID_MST_A_MCLK_SEL 16
> +#define AUD_CLKID_MST_A_MCLK_DIV 17
> +#define AUD_CLKID_MST_A_MCLK 18
> +#define AUD_CLKID_MST_B_MCLK_SEL 19
> +#define AUD_CLKID_MST_B_MCLK_DIV 20
> +#define AUD_CLKID_MST_B_MCLK 21
> +#define AUD_CLKID_MST_C_MCLK_SEL 22
> +#define AUD_CLKID_MST_C_MCLK_DIV 23
> +#define AUD_CLKID_MST_C_MCLK 24
> +#define AUD_CLKID_MST_D_MCLK_SEL 25
> +#define AUD_CLKID_MST_D_MCLK_DIV 26
> +#define AUD_CLKID_MST_D_MCLK 27
> +#define AUD_CLKID_SPDIFIN_CLK_SEL 28
> +#define AUD_CLKID_SPDIFIN_CLK_DIV 29
> +#define AUD_CLKID_SPDIFIN_CLK 30
> +#define AUD_CLKID_RESAMPLE_CLK_SEL 31
> +#define AUD_CLKID_RESAMPLE_CLK_DIV 32
> +#define AUD_CLKID_RESAMPLE_CLK 33
> +#define AUD_CLKID_LOCKER_IN_CLK_SEL 34
> +#define AUD_CLKID_LOCKER_IN_CLK_DIV 35
> +#define AUD_CLKID_LOCKER_IN_CLK 36
> +#define AUD_CLKID_LOCKER_OUT_CLK_SEL 37
> +#define AUD_CLKID_LOCKER_OUT_CLK_DIV 38
> +#define AUD_CLKID_LOCKER_OUT_CLK 39
> +#define AUD_CLKID_EQDRC_CLK_SEL 40
> +#define AUD_CLKID_EQDRC_CLK_DIV 41
> +#define AUD_CLKID_EQDRC_CLK 42
> +#define AUD_CLKID_MST_A_SCLK_PRE_EN 43
> +#define AUD_CLKID_MST_A_SCLK_DIV 44
> +#define AUD_CLKID_MST_A_SCLK_POST_EN 45
> +#define AUD_CLKID_MST_A_SCLK 46
> +#define AUD_CLKID_MST_B_SCLK_PRE_EN 47
> +#define AUD_CLKID_MST_B_SCLK_DIV 48
> +#define AUD_CLKID_MST_B_SCLK_POST_EN 49
> +#define AUD_CLKID_MST_B_SCLK 50
> +#define AUD_CLKID_MST_C_SCLK_PRE_EN 51
> +#define AUD_CLKID_MST_C_SCLK_DIV 52
> +#define AUD_CLKID_MST_C_SCLK_POST_EN 53
> +#define AUD_CLKID_MST_C_SCLK 54
> +#define AUD_CLKID_MST_D_SCLK_PRE_EN 55
> +#define AUD_CLKID_MST_D_SCLK_DIV 56
> +#define AUD_CLKID_MST_D_SCLK_POST_EN 57
> +#define AUD_CLKID_MST_D_SCLK 58
> +#define AUD_CLKID_MST_A_LRCLK_DIV 59
> +#define AUD_CLKID_MST_A_LRCLK 60
> +#define AUD_CLKID_MST_B_LRCLK_DIV 61
> +#define AUD_CLKID_MST_B_LRCLK 62
> +#define AUD_CLKID_MST_C_LRCLK_DIV 63
> +#define AUD_CLKID_MST_C_LRCLK 64
> +#define AUD_CLKID_MST_D_LRCLK_DIV 65
> +#define AUD_CLKID_MST_D_LRCLK 66
> +#define AUD_CLKID_TDMIN_A_SCLK_SEL 67
> +#define AUD_CLKID_TDMIN_A_SCLK_PRE_EN 68
> +#define AUD_CLKID_TDMIN_A_SCLK_POST_EN 69
> +#define AUD_CLKID_TDMIN_A_SCLK 70
> +#define AUD_CLKID_TDMIN_A_LRCLK 71
> +#define AUD_CLKID_TDMIN_B_SCLK_SEL 72
> +#define AUD_CLKID_TDMIN_B_SCLK_PRE_EN 73
> +#define AUD_CLKID_TDMIN_B_SCLK_POST_EN 74
> +#define AUD_CLKID_TDMIN_B_SCLK 75
> +#define AUD_CLKID_TDMIN_B_LRCLK 76
> +#define AUD_CLKID_TDMIN_LB_SCLK_SEL 77
> +#define AUD_CLKID_TDMIN_LB_SCLK_PRE_EN 78
> +#define AUD_CLKID_TDMIN_LB_SCLK_POST_EN 79
> +#define AUD_CLKID_TDMIN_LB_SCLK 80
> +#define AUD_CLKID_TDMIN_LB_LRCLK 81
> +#define AUD_CLKID_TDMOUT_A_SCLK_SEL 82
> +#define AUD_CLKID_TDMOUT_A_SCLK_PRE_EN 83
> +#define AUD_CLKID_TDMOUT_A_SCLK_POST_EN 84
> +#define AUD_CLKID_TDMOUT_A_SCLK 85
> +#define AUD_CLKID_TDMOUT_A_LRCLK 86
> +#define AUD_CLKID_TDMOUT_B_SCLK_SEL 87
> +#define AUD_CLKID_TDMOUT_B_SCLK_PRE_EN 88
> +#define AUD_CLKID_TDMOUT_B_SCLK_POST_EN 89
> +#define AUD_CLKID_TDMOUT_B_SCLK 90
> +#define AUD_CLKID_TDMOUT_B_LRCLK 91
> +
> +#define AUD_CLKID_VAD_DDR_ARB 1
> +#define AUD_CLKID_VAD_PDM 2
> +#define AUD_CLKID_VAD_TDMIN 3
> +#define AUD_CLKID_VAD_TODDR 4
> +#define AUD_CLKID_VAD 5
> +#define AUD_CLKID_VAD_AUDIOTOP 6
> +#define AUD_CLKID_VAD_MCLK_SEL 7
> +#define AUD_CLKID_VAD_MCLK_DIV 8
> +#define AUD_CLKID_VAD_MCLK 9
> +#define AUD_CLKID_VAD_CLK_SEL 10
> +#define AUD_CLKID_VAD_CLK_DIV 11
> +#define AUD_CLKID_VAD_CLK 12
> +#define AUD_CLKID_VAD_PDM_DCLK_SEL 13
> +#define AUD_CLKID_VAD_PDM_DCLK_DIV 14
> +#define AUD_CLKID_VAD_PDM_DCLK 15
> +#define AUD_CLKID_VAD_PDM_SYSCLK_SEL 16
> +#define AUD_CLKID_VAD_PDM_SYSCLK_DIV 17
> +#define AUD_CLKID_VAD_PDM_SYSCLK 18
> +
> +#endif /* __A1_AUDIO_CLKC_BINDINGS_H */
> diff --git a/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
> new file mode 100644
> index 000000000000..653fddba1d8f
> --- /dev/null
> +++ b/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
> @@ -0,0 +1,29 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#ifndef _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H
> +#define _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H
> +
> +#define AUD_RESET_DDRARB 0
> +#define AUD_RESET_TDMIN_A 1
> +#define AUD_RESET_TDMIN_B 2
> +#define AUD_RESET_TDMIN_LB 3
> +#define AUD_RESET_LOOPBACK 4
> +#define AUD_RESET_TDMOUT_A 5
> +#define AUD_RESET_TDMOUT_B 6
> +#define AUD_RESET_FRDDR_A 7
> +#define AUD_RESET_FRDDR_B 8
> +#define AUD_RESET_TODDR_A 9
> +#define AUD_RESET_TODDR_B 10
> +#define AUD_RESET_SPDIFIN 11
> +#define AUD_RESET_RESAMPLE 12
> +#define AUD_RESET_EQDRC 13
> +#define AUD_RESET_LOCKER 14
> +#define AUD_RESET_TOACODEC 30
> +#define AUD_RESET_CLKTREE 31
> +
> +#endif /* _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H */
--
Jerome
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver
2024-09-13 12:11 ` [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver Jan Dakinevich
2024-09-13 17:23 ` Conor Dooley
2024-10-22 8:45 ` Jerome Brunet
@ 2024-10-22 9:34 ` Jerome Brunet
2024-10-22 9:36 ` Jerome Brunet
2 siblings, 1 reply; 18+ messages in thread
From: Jerome Brunet @ 2024-10-22 9:34 UTC (permalink / raw)
To: Jan Dakinevich
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
> Add device tree bindings for A1 SoC audio clock and reset controllers.
>
> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> ---
> .../clock/amlogic,axg-audio-clkc.yaml | 3 +
> .../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++++++++++++++
> .../reset/amlogic,meson-a1-audio-reset.h | 29 +++++
> 3 files changed, 154 insertions(+)
> create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
> create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
>
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
> index fd7982dd4cea..df9eb8ce28dc 100644
> --- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
> +++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
> @@ -18,6 +18,8 @@ description:
> properties:
> compatible:
> enum:
> + - amlogic,a1-audio-clkc
This controller is missing aud_top clock input coming from the vad
controller, AFAICT.
> + - amlogic,a1-audio-vad-clkc
> - amlogic,axg-audio-clkc
> - amlogic,g12a-audio-clkc
> - amlogic,sm1-audio-clkc
> @@ -114,6 +116,7 @@ allOf:
> compatible:
> contains:
> enum:
> + - amlogic,a1-audio-clkc
> - amlogic,g12a-audio-clkc
> - amlogic,sm1-audio-clkc
> then:
> diff --git a/include/dt-bindings/clock/amlogic,a1-audio-clkc.h b/include/dt-bindings/clock/amlogic,a1-audio-clkc.h
> new file mode 100644
> index 000000000000..6534d1878816
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,a1-audio-clkc.h
> @@ -0,0 +1,122 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#ifndef __A1_AUDIO_CLKC_BINDINGS_H
> +#define __A1_AUDIO_CLKC_BINDINGS_H
> +
> +#define AUD_CLKID_DDR_ARB 1
> +#define AUD_CLKID_TDMIN_A 2
> +#define AUD_CLKID_TDMIN_B 3
> +#define AUD_CLKID_TDMIN_LB 4
> +#define AUD_CLKID_LOOPBACK 5
> +#define AUD_CLKID_TDMOUT_A 6
> +#define AUD_CLKID_TDMOUT_B 7
> +#define AUD_CLKID_FRDDR_A 8
> +#define AUD_CLKID_FRDDR_B 9
> +#define AUD_CLKID_TODDR_A 10
> +#define AUD_CLKID_TODDR_B 11
> +#define AUD_CLKID_SPDIFIN 12
> +#define AUD_CLKID_RESAMPLE 13
> +#define AUD_CLKID_EQDRC 14
> +#define AUD_CLKID_LOCKER 15
> +#define AUD_CLKID_MST_A_MCLK_SEL 16
> +#define AUD_CLKID_MST_A_MCLK_DIV 17
> +#define AUD_CLKID_MST_A_MCLK 18
> +#define AUD_CLKID_MST_B_MCLK_SEL 19
> +#define AUD_CLKID_MST_B_MCLK_DIV 20
> +#define AUD_CLKID_MST_B_MCLK 21
> +#define AUD_CLKID_MST_C_MCLK_SEL 22
> +#define AUD_CLKID_MST_C_MCLK_DIV 23
> +#define AUD_CLKID_MST_C_MCLK 24
> +#define AUD_CLKID_MST_D_MCLK_SEL 25
> +#define AUD_CLKID_MST_D_MCLK_DIV 26
> +#define AUD_CLKID_MST_D_MCLK 27
> +#define AUD_CLKID_SPDIFIN_CLK_SEL 28
> +#define AUD_CLKID_SPDIFIN_CLK_DIV 29
> +#define AUD_CLKID_SPDIFIN_CLK 30
> +#define AUD_CLKID_RESAMPLE_CLK_SEL 31
> +#define AUD_CLKID_RESAMPLE_CLK_DIV 32
> +#define AUD_CLKID_RESAMPLE_CLK 33
> +#define AUD_CLKID_LOCKER_IN_CLK_SEL 34
> +#define AUD_CLKID_LOCKER_IN_CLK_DIV 35
> +#define AUD_CLKID_LOCKER_IN_CLK 36
> +#define AUD_CLKID_LOCKER_OUT_CLK_SEL 37
> +#define AUD_CLKID_LOCKER_OUT_CLK_DIV 38
> +#define AUD_CLKID_LOCKER_OUT_CLK 39
> +#define AUD_CLKID_EQDRC_CLK_SEL 40
> +#define AUD_CLKID_EQDRC_CLK_DIV 41
> +#define AUD_CLKID_EQDRC_CLK 42
> +#define AUD_CLKID_MST_A_SCLK_PRE_EN 43
> +#define AUD_CLKID_MST_A_SCLK_DIV 44
> +#define AUD_CLKID_MST_A_SCLK_POST_EN 45
> +#define AUD_CLKID_MST_A_SCLK 46
> +#define AUD_CLKID_MST_B_SCLK_PRE_EN 47
> +#define AUD_CLKID_MST_B_SCLK_DIV 48
> +#define AUD_CLKID_MST_B_SCLK_POST_EN 49
> +#define AUD_CLKID_MST_B_SCLK 50
> +#define AUD_CLKID_MST_C_SCLK_PRE_EN 51
> +#define AUD_CLKID_MST_C_SCLK_DIV 52
> +#define AUD_CLKID_MST_C_SCLK_POST_EN 53
> +#define AUD_CLKID_MST_C_SCLK 54
> +#define AUD_CLKID_MST_D_SCLK_PRE_EN 55
> +#define AUD_CLKID_MST_D_SCLK_DIV 56
> +#define AUD_CLKID_MST_D_SCLK_POST_EN 57
> +#define AUD_CLKID_MST_D_SCLK 58
> +#define AUD_CLKID_MST_A_LRCLK_DIV 59
> +#define AUD_CLKID_MST_A_LRCLK 60
> +#define AUD_CLKID_MST_B_LRCLK_DIV 61
> +#define AUD_CLKID_MST_B_LRCLK 62
> +#define AUD_CLKID_MST_C_LRCLK_DIV 63
> +#define AUD_CLKID_MST_C_LRCLK 64
> +#define AUD_CLKID_MST_D_LRCLK_DIV 65
> +#define AUD_CLKID_MST_D_LRCLK 66
> +#define AUD_CLKID_TDMIN_A_SCLK_SEL 67
> +#define AUD_CLKID_TDMIN_A_SCLK_PRE_EN 68
> +#define AUD_CLKID_TDMIN_A_SCLK_POST_EN 69
> +#define AUD_CLKID_TDMIN_A_SCLK 70
> +#define AUD_CLKID_TDMIN_A_LRCLK 71
> +#define AUD_CLKID_TDMIN_B_SCLK_SEL 72
> +#define AUD_CLKID_TDMIN_B_SCLK_PRE_EN 73
> +#define AUD_CLKID_TDMIN_B_SCLK_POST_EN 74
> +#define AUD_CLKID_TDMIN_B_SCLK 75
> +#define AUD_CLKID_TDMIN_B_LRCLK 76
> +#define AUD_CLKID_TDMIN_LB_SCLK_SEL 77
> +#define AUD_CLKID_TDMIN_LB_SCLK_PRE_EN 78
> +#define AUD_CLKID_TDMIN_LB_SCLK_POST_EN 79
> +#define AUD_CLKID_TDMIN_LB_SCLK 80
> +#define AUD_CLKID_TDMIN_LB_LRCLK 81
> +#define AUD_CLKID_TDMOUT_A_SCLK_SEL 82
> +#define AUD_CLKID_TDMOUT_A_SCLK_PRE_EN 83
> +#define AUD_CLKID_TDMOUT_A_SCLK_POST_EN 84
> +#define AUD_CLKID_TDMOUT_A_SCLK 85
> +#define AUD_CLKID_TDMOUT_A_LRCLK 86
> +#define AUD_CLKID_TDMOUT_B_SCLK_SEL 87
> +#define AUD_CLKID_TDMOUT_B_SCLK_PRE_EN 88
> +#define AUD_CLKID_TDMOUT_B_SCLK_POST_EN 89
> +#define AUD_CLKID_TDMOUT_B_SCLK 90
> +#define AUD_CLKID_TDMOUT_B_LRCLK 91
> +
> +#define AUD_CLKID_VAD_DDR_ARB 1
> +#define AUD_CLKID_VAD_PDM 2
> +#define AUD_CLKID_VAD_TDMIN 3
> +#define AUD_CLKID_VAD_TODDR 4
> +#define AUD_CLKID_VAD 5
> +#define AUD_CLKID_VAD_AUDIOTOP 6
> +#define AUD_CLKID_VAD_MCLK_SEL 7
> +#define AUD_CLKID_VAD_MCLK_DIV 8
> +#define AUD_CLKID_VAD_MCLK 9
> +#define AUD_CLKID_VAD_CLK_SEL 10
> +#define AUD_CLKID_VAD_CLK_DIV 11
> +#define AUD_CLKID_VAD_CLK 12
> +#define AUD_CLKID_VAD_PDM_DCLK_SEL 13
> +#define AUD_CLKID_VAD_PDM_DCLK_DIV 14
> +#define AUD_CLKID_VAD_PDM_DCLK 15
> +#define AUD_CLKID_VAD_PDM_SYSCLK_SEL 16
> +#define AUD_CLKID_VAD_PDM_SYSCLK_DIV 17
> +#define AUD_CLKID_VAD_PDM_SYSCLK 18
> +
> +#endif /* __A1_AUDIO_CLKC_BINDINGS_H */
> diff --git a/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
> new file mode 100644
> index 000000000000..653fddba1d8f
> --- /dev/null
> +++ b/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
> @@ -0,0 +1,29 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#ifndef _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H
> +#define _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H
> +
> +#define AUD_RESET_DDRARB 0
> +#define AUD_RESET_TDMIN_A 1
> +#define AUD_RESET_TDMIN_B 2
> +#define AUD_RESET_TDMIN_LB 3
> +#define AUD_RESET_LOOPBACK 4
> +#define AUD_RESET_TDMOUT_A 5
> +#define AUD_RESET_TDMOUT_B 6
> +#define AUD_RESET_FRDDR_A 7
> +#define AUD_RESET_FRDDR_B 8
> +#define AUD_RESET_TODDR_A 9
> +#define AUD_RESET_TODDR_B 10
> +#define AUD_RESET_SPDIFIN 11
> +#define AUD_RESET_RESAMPLE 12
> +#define AUD_RESET_EQDRC 13
> +#define AUD_RESET_LOCKER 14
> +#define AUD_RESET_TOACODEC 30
> +#define AUD_RESET_CLKTREE 31
> +
> +#endif /* _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H */
--
Jerome
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver
2024-10-22 9:34 ` Jerome Brunet
@ 2024-10-22 9:36 ` Jerome Brunet
0 siblings, 0 replies; 18+ messages in thread
From: Jerome Brunet @ 2024-10-22 9:36 UTC (permalink / raw)
To: Jan Dakinevich
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On Tue 22 Oct 2024 at 11:34, Jerome Brunet <jbrunet@baylibre.com> wrote:
> On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
>
>> Add device tree bindings for A1 SoC audio clock and reset controllers.
>>
>> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>> ---
>> .../clock/amlogic,axg-audio-clkc.yaml | 3 +
>> .../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++++++++++++++
>> .../reset/amlogic,meson-a1-audio-reset.h | 29 +++++
>> 3 files changed, 154 insertions(+)
>> create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
>> create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
>>
>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
>> index fd7982dd4cea..df9eb8ce28dc 100644
>> --- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
>> @@ -18,6 +18,8 @@ description:
>> properties:
>> compatible:
>> enum:
>> + - amlogic,a1-audio-clkc
>
> This controller is missing aud_top clock input coming from the vad
> controller, AFAICT.
>
You are passing it thourgh pclk so it is fine
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 4/5] clk: meson: a1: add the audio clock controller driver
2024-09-13 12:11 ` [RFC PATCH v4 4/5] clk: meson: a1: add the " Jan Dakinevich
2024-09-18 11:05 ` Jan Dakinevich
@ 2024-10-22 9:47 ` Jerome Brunet
2024-10-24 5:15 ` Jan Dakinevich
1 sibling, 1 reply; 18+ messages in thread
From: Jerome Brunet @ 2024-10-22 9:47 UTC (permalink / raw)
To: Jan Dakinevich
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
> This controller provides clocks and reset functionality for audio
> peripherals on Amlogic A1 SoC family.
>
> The driver is almost identical to 'axg-audio', however it would be better
> to keep it separate due to following reasons:
>
> - significant amount of bits has another definition. I will bring there
> a mess of new defines with A1_ suffixes.
>
> - registers of this controller are located in two separate regions. It
> will give a lot of complications for 'axg-audio' to support this.
>
> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> ---
> drivers/clk/meson/Kconfig | 14 +
> drivers/clk/meson/Makefile | 3 +
> drivers/clk/meson/a1-audio-clkc.c | 359 ++++++++++++++++++++++++++
> drivers/clk/meson/a1-audio-drv.c | 104 ++++++++
> drivers/clk/meson/a1-audio-vad-clkc.c | 85 ++++++
This split over 3 files appears unnecessary, especially since you've got
a single configuration option for both drivers.
a1-audio.c is enough AFAICT.
> drivers/clk/meson/a1-audio.h | 131 ++++++++++
not necessary.
> 6 files changed, 696 insertions(+)
> create mode 100644 drivers/clk/meson/a1-audio-clkc.c
> create mode 100644 drivers/clk/meson/a1-audio-drv.c
> create mode 100644 drivers/clk/meson/a1-audio-vad-clkc.c
> create mode 100644 drivers/clk/meson/a1-audio.h
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 78f648c9c97d..b558288a6b78 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -132,6 +132,20 @@ config COMMON_CLK_A1_PERIPHERALS
> device, A1 SoC Family. Say Y if you want A1 Peripherals clock
> controller to work.
>
> +config COMMON_CLK_A1_AUDIO
> + tristate "Amlogic A1 SoC Audio clock controller support"
> + depends on ARM64
> + select COMMON_CLK_MESON_REGMAP
> + select COMMON_CLK_MESON_PHASE
> + select COMMON_CLK_MESON_SCLK_DIV
> + select COMMON_CLK_MESON_CLKC_UTILS
> + select REGMAP_MMIO
> + imply RESET_MESON_AUX
> + help
> + Support for the Audio clock controller on Amlogic A113L based
> + device, A1 SoC Family. Say Y if you want A1 Audio clock controller
> + to work.
> +
> config COMMON_CLK_C3_PLL
> tristate "Amlogic C3 PLL clock controller"
> depends on ARM64
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index bc56a47931c1..f7ea11df1de3 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -16,10 +16,13 @@ obj-$(CONFIG_COMMON_CLK_MESON_VCLK) += vclk.o
>
> # Amlogic Clock controllers
>
> +a1-audio-y := a1-audio-drv.o a1-audio-clkc.o a1-audio-vad-clkc.o
> +
> obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
> obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
> obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
> obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
> +obj-$(CONFIG_COMMON_CLK_A1_AUDIO) += a1-audio.o
> obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
> obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
> obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
> diff --git a/drivers/clk/meson/a1-audio-clkc.c b/drivers/clk/meson/a1-audio-clkc.c
> new file mode 100644
> index 000000000000..48160dcb7f47
> --- /dev/null
> +++ b/drivers/clk/meson/a1-audio-clkc.c
> @@ -0,0 +1,359 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
> +
> +#include "a1-audio.h"
> +
> +#define AUDIO_CLK_GATE_EN0 0x000
> +#define AUDIO_MCLK_A_CTRL 0x008
> +#define AUDIO_MCLK_B_CTRL 0x00c
> +#define AUDIO_MCLK_C_CTRL 0x010
> +#define AUDIO_MCLK_D_CTRL 0x014
> +#define AUDIO_MCLK_E_CTRL 0x018
> +#define AUDIO_MCLK_F_CTRL 0x01c
> +#define AUDIO_SW_RESET0 0x028
> +#define AUDIO_MST_A_SCLK_CTRL0 0x040
> +#define AUDIO_MST_A_SCLK_CTRL1 0x044
> +#define AUDIO_MST_B_SCLK_CTRL0 0x048
> +#define AUDIO_MST_B_SCLK_CTRL1 0x04c
> +#define AUDIO_MST_C_SCLK_CTRL0 0x050
> +#define AUDIO_MST_C_SCLK_CTRL1 0x054
> +#define AUDIO_MST_D_SCLK_CTRL0 0x058
> +#define AUDIO_MST_D_SCLK_CTRL1 0x05c
> +#define AUDIO_CLK_TDMIN_A_CTRL 0x080
> +#define AUDIO_CLK_TDMIN_B_CTRL 0x084
> +#define AUDIO_CLK_TDMIN_LB_CTRL 0x08c
> +#define AUDIO_CLK_TDMOUT_A_CTRL 0x090
> +#define AUDIO_CLK_TDMOUT_B_CTRL 0x094
> +#define AUDIO_CLK_SPDIFIN_CTRL 0x09c
> +#define AUDIO_CLK_RESAMPLE_CTRL 0x0a4
> +#define AUDIO_CLK_LOCKER_CTRL 0x0a8
> +#define AUDIO_CLK_EQDRC_CTRL 0x0c0
> +
> +struct clk_regmap aud_ddr_arb =
> + AUD_PCLK_GATE(ddr_arb, AUDIO_CLK_GATE_EN0, 0);
> +struct clk_regmap aud_tdmin_a =
> + AUD_PCLK_GATE(tdmin_a, AUDIO_CLK_GATE_EN0, 1);
> +struct clk_regmap aud_tdmin_b =
> + AUD_PCLK_GATE(tdmin_b, AUDIO_CLK_GATE_EN0, 2);
> +struct clk_regmap aud_tdmin_lb =
> + AUD_PCLK_GATE(tdmin_lb, AUDIO_CLK_GATE_EN0, 3);
> +struct clk_regmap aud_loopback =
> + AUD_PCLK_GATE(loopback, AUDIO_CLK_GATE_EN0, 4);
> +struct clk_regmap aud_tdmout_a =
> + AUD_PCLK_GATE(tdmout_a, AUDIO_CLK_GATE_EN0, 5);
> +struct clk_regmap aud_tdmout_b =
> + AUD_PCLK_GATE(tdmout_b, AUDIO_CLK_GATE_EN0, 6);
> +struct clk_regmap aud_frddr_a =
> + AUD_PCLK_GATE(frddr_a, AUDIO_CLK_GATE_EN0, 7);
> +struct clk_regmap aud_frddr_b =
> + AUD_PCLK_GATE(frddr_b, AUDIO_CLK_GATE_EN0, 8);
> +struct clk_regmap aud_toddr_a =
> + AUD_PCLK_GATE(toddr_a, AUDIO_CLK_GATE_EN0, 9);
> +struct clk_regmap aud_toddr_b =
> + AUD_PCLK_GATE(toddr_b, AUDIO_CLK_GATE_EN0, 10);
> +struct clk_regmap aud_spdifin =
> + AUD_PCLK_GATE(spdifin, AUDIO_CLK_GATE_EN0, 11);
> +struct clk_regmap aud_resample =
> + AUD_PCLK_GATE(resample, AUDIO_CLK_GATE_EN0, 12);
> +struct clk_regmap aud_eqdrc =
> + AUD_PCLK_GATE(eqdrc, AUDIO_CLK_GATE_EN0, 13);
> +struct clk_regmap aud_audiolocker =
> + AUD_PCLK_GATE(audiolocker, AUDIO_CLK_GATE_EN0, 14);
> +
> +struct clk_regmap aud_mst_a_mclk_sel =
> + AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL);
> +struct clk_regmap aud_mst_a_mclk_div =
> + AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL);
> +struct clk_regmap aud_mst_a_mclk =
> + AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL);
> +
> +struct clk_regmap aud_mst_b_mclk_sel =
> + AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL);
> +struct clk_regmap aud_mst_b_mclk_div =
> + AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL);
> +struct clk_regmap aud_mst_b_mclk =
> + AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL);
> +
> +struct clk_regmap aud_mst_c_mclk_sel =
> + AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL);
> +struct clk_regmap aud_mst_c_mclk_div =
> + AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL);
> +struct clk_regmap aud_mst_c_mclk =
> + AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL);
> +
> +struct clk_regmap aud_mst_d_mclk_sel =
> + AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL);
> +struct clk_regmap aud_mst_d_mclk_div =
> + AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL);
> +struct clk_regmap aud_mst_d_mclk =
> + AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL);
> +
> +struct clk_regmap aud_spdifin_clk_sel =
> + AUD_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
> +struct clk_regmap aud_spdifin_clk_div =
> + AUD_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
> +struct clk_regmap aud_spdifin_clk =
> + AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
> +
> +struct clk_regmap aud_eqdrc_clk_sel =
> + AUD_MST_MCLK_MUX(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
> +struct clk_regmap aud_eqdrc_clk_div =
> + AUD_MST_MCLK_DIV(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
> +struct clk_regmap aud_eqdrc_clk =
> + AUD_MST_MCLK_GATE(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
> +
> +struct clk_regmap aud_resample_clk_sel =
> + AUD_MUX(resample_clk_sel, AUDIO_CLK_RESAMPLE_CTRL, 0xf, 24,
> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
> +struct clk_regmap aud_resample_clk_div =
> + AUD_DIV(resample_clk_div, AUDIO_CLK_RESAMPLE_CTRL, 0, 8,
> + CLK_DIVIDER_ROUND_CLOSEST, aud_resample_clk_sel,
> + CLK_SET_RATE_PARENT);
> +struct clk_regmap aud_resample_clk =
> + AUD_GATE(resample_clk, AUDIO_CLK_RESAMPLE_CTRL, 31,
> + aud_resample_clk_div, CLK_SET_RATE_PARENT);
> +
> +struct clk_regmap aud_locker_in_clk_sel =
> + AUD_MUX(locker_in_clk_sel, AUDIO_CLK_LOCKER_CTRL, 0xf, 8,
> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
> +struct clk_regmap aud_locker_in_clk_div =
> + AUD_DIV(locker_in_clk_div, AUDIO_CLK_LOCKER_CTRL, 0, 8,
> + CLK_DIVIDER_ROUND_CLOSEST, aud_locker_in_clk_sel,
> + CLK_SET_RATE_PARENT);
> +struct clk_regmap aud_locker_in_clk =
> + AUD_GATE(locker_in_clk, AUDIO_CLK_LOCKER_CTRL, 15,
> + aud_locker_in_clk_div, CLK_SET_RATE_PARENT);
> +
> +struct clk_regmap aud_locker_out_clk_sel =
> + AUD_MUX(locker_out_clk_sel, AUDIO_CLK_LOCKER_CTRL, 0xf, 24,
> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
> +struct clk_regmap aud_locker_out_clk_div =
> + AUD_DIV(locker_out_clk_div, AUDIO_CLK_LOCKER_CTRL, 16, 8,
> + CLK_DIVIDER_ROUND_CLOSEST, aud_locker_out_clk_sel,
> + CLK_SET_RATE_PARENT);
> +struct clk_regmap aud_locker_out_clk =
> + AUD_GATE(locker_out_clk, AUDIO_CLK_LOCKER_CTRL, 31,
> + aud_locker_out_clk_div, CLK_SET_RATE_PARENT);
> +
> +struct clk_regmap aud_mst_a_sclk_pre_en =
> + AUD_MST_SCLK_PRE_EN(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0, mst_a_mclk);
> +struct clk_regmap aud_mst_a_sclk_div =
> + AUD_MST_SCLK_DIV(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0);
> +struct clk_regmap aud_mst_a_sclk_post_en =
> + AUD_MST_SCLK_POST_EN(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0);
> +struct clk_regmap aud_mst_a_sclk =
> + AUD_MST_SCLK(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_b_sclk_pre_en =
> + AUD_MST_SCLK_PRE_EN(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0, mst_b_mclk);
> +struct clk_regmap aud_mst_b_sclk_div =
> + AUD_MST_SCLK_DIV(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0);
> +struct clk_regmap aud_mst_b_sclk_post_en =
> + AUD_MST_SCLK_POST_EN(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0);
> +struct clk_regmap aud_mst_b_sclk =
> + AUD_MST_SCLK(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_c_sclk_pre_en =
> + AUD_MST_SCLK_PRE_EN(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0, mst_c_mclk);
> +struct clk_regmap aud_mst_c_sclk_div =
> + AUD_MST_SCLK_DIV(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0);
> +struct clk_regmap aud_mst_c_sclk_post_en =
> + AUD_MST_SCLK_POST_EN(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0);
> +struct clk_regmap aud_mst_c_sclk =
> + AUD_MST_SCLK(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_d_sclk_pre_en =
> + AUD_MST_SCLK_PRE_EN(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0, mst_d_mclk);
> +struct clk_regmap aud_mst_d_sclk_div =
> + AUD_MST_SCLK_DIV(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0);
> +struct clk_regmap aud_mst_d_sclk_post_en =
> + AUD_MST_SCLK_POST_EN(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0);
> +struct clk_regmap aud_mst_d_sclk =
> + AUD_MST_SCLK(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_a_lrclk_div =
> + AUD_MST_LRCLK_DIV(mst_a_lrclk, AUDIO_MST_A_SCLK_CTRL0,
> + mst_a_sclk_post_en);
> +struct clk_regmap aud_mst_a_lrclk =
> + AUD_MST_LRCLK(mst_a_lrclk, AUDIO_MST_A_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_b_lrclk_div =
> + AUD_MST_LRCLK_DIV(mst_b_lrclk, AUDIO_MST_B_SCLK_CTRL0,
> + mst_b_sclk_post_en);
> +struct clk_regmap aud_mst_b_lrclk =
> + AUD_MST_LRCLK(mst_b_lrclk, AUDIO_MST_B_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_c_lrclk_div =
> + AUD_MST_LRCLK_DIV(mst_c_lrclk, AUDIO_MST_C_SCLK_CTRL0,
> + mst_c_sclk_post_en);
> +struct clk_regmap aud_mst_c_lrclk =
> + AUD_MST_LRCLK(mst_c_lrclk, AUDIO_MST_C_SCLK_CTRL1);
> +
> +struct clk_regmap aud_mst_d_lrclk_div =
> + AUD_MST_LRCLK_DIV(mst_d_lrclk, AUDIO_MST_D_SCLK_CTRL0,
> + mst_d_sclk_post_en);
> +struct clk_regmap aud_mst_d_lrclk =
> + AUD_MST_LRCLK(mst_d_lrclk, AUDIO_MST_D_SCLK_CTRL1);
> +
> +struct clk_regmap aud_tdmin_a_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
> +struct clk_regmap aud_tdmin_a_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
> +struct clk_regmap aud_tdmin_a_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
> +struct clk_regmap aud_tdmin_a_sclk =
> + AUD_TDM_SCLK_WS(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
> +struct clk_regmap aud_tdmin_a_lrclk =
> + AUD_TDM_LRLCK(tdmin_a_lrclk, AUDIO_CLK_TDMIN_A_CTRL);
> +
> +struct clk_regmap aud_tdmin_b_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
> +struct clk_regmap aud_tdmin_b_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
> +struct clk_regmap aud_tdmin_b_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
> +struct clk_regmap aud_tdmin_b_sclk =
> + AUD_TDM_SCLK_WS(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
> +struct clk_regmap aud_tdmin_b_lrclk =
> + AUD_TDM_LRLCK(tdmin_b_lrclk, AUDIO_CLK_TDMIN_B_CTRL);
> +
> +struct clk_regmap aud_tdmin_lb_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +struct clk_regmap aud_tdmin_lb_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +struct clk_regmap aud_tdmin_lb_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +struct clk_regmap aud_tdmin_lb_sclk =
> + AUD_TDM_SCLK_WS(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +struct clk_regmap aud_tdmin_lb_lrclk =
> + AUD_TDM_LRLCK(tdmin_lb_lrclk, AUDIO_CLK_TDMIN_LB_CTRL);
> +
> +struct clk_regmap aud_tdmout_a_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +struct clk_regmap aud_tdmout_a_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +struct clk_regmap aud_tdmout_a_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +struct clk_regmap aud_tdmout_a_sclk =
> + AUD_TDM_SCLK_WS(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +struct clk_regmap aud_tdmout_a_lrclk =
> + AUD_TDM_LRLCK(tdmout_a_lrclk, AUDIO_CLK_TDMOUT_A_CTRL);
> +
> +struct clk_regmap aud_tdmout_b_sclk_sel =
> + AUD_TDM_SCLK_MUX(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +struct clk_regmap aud_tdmout_b_sclk_pre_en =
> + AUD_TDM_SCLK_PRE_EN(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +struct clk_regmap aud_tdmout_b_sclk_post_en =
> + AUD_TDM_SCLK_POST_EN(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +struct clk_regmap aud_tdmout_b_sclk =
> + AUD_TDM_SCLK_WS(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +struct clk_regmap aud_tdmout_b_lrclk =
> + AUD_TDM_LRLCK(tdmout_b_lrclk, AUDIO_CLK_TDMOUT_B_CTRL);
> +
> +static struct clk_hw *a1_audio_clkc_hws[] = {
> + [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw,
> + [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw,
> + [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw,
> + [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw,
> + [AUD_CLKID_LOOPBACK] = &aud_loopback.hw,
> + [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw,
> + [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw,
> + [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw,
> + [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw,
> + [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw,
> + [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw,
> + [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw,
> + [AUD_CLKID_RESAMPLE] = &aud_resample.hw,
> + [AUD_CLKID_EQDRC] = &aud_eqdrc.hw,
> + [AUD_CLKID_LOCKER] = &aud_audiolocker.hw,
> + [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw,
> + [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw,
> + [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw,
> + [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw,
> + [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw,
> + [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw,
> + [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw,
> + [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw,
> + [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw,
> + [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw,
> + [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw,
> + [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw,
> + [AUD_CLKID_RESAMPLE_CLK_SEL] = &aud_resample_clk_sel.hw,
> + [AUD_CLKID_RESAMPLE_CLK_DIV] = &aud_resample_clk_div.hw,
> + [AUD_CLKID_RESAMPLE_CLK] = &aud_resample_clk.hw,
> + [AUD_CLKID_LOCKER_IN_CLK_SEL] = &aud_locker_in_clk_sel.hw,
> + [AUD_CLKID_LOCKER_IN_CLK_DIV] = &aud_locker_in_clk_div.hw,
> + [AUD_CLKID_LOCKER_IN_CLK] = &aud_locker_in_clk.hw,
> + [AUD_CLKID_LOCKER_OUT_CLK_SEL] = &aud_locker_out_clk_sel.hw,
> + [AUD_CLKID_LOCKER_OUT_CLK_DIV] = &aud_locker_out_clk_div.hw,
> + [AUD_CLKID_LOCKER_OUT_CLK] = &aud_locker_out_clk.hw,
> + [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw,
> + [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw,
> + [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw,
> + [AUD_CLKID_EQDRC_CLK_SEL] = &aud_eqdrc_clk_sel.hw,
> + [AUD_CLKID_EQDRC_CLK_DIV] = &aud_eqdrc_clk_div.hw,
> + [AUD_CLKID_EQDRC_CLK] = &aud_eqdrc_clk.hw,
> + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw,
> + [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw,
> + [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw,
> + [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw,
> + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw,
> + [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw,
> + [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw,
> + [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw,
> + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw,
> + [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw,
> + [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw,
> + [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw,
> + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw,
> + [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw,
> + [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw,
> + [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw,
> + [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw,
> + [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw,
> + [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw,
> + [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw,
> + [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw,
> + [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw,
> + [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw,
> + [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw,
> + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw,
> + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw,
> + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw,
> + [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw,
> + [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw,
> + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw,
> + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw,
> + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw,
> + [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw,
> + [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw,
> + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw,
> + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw,
> + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw,
> + [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw,
> + [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw,
> + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw,
> + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw,
> + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw,
> + [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw,
> + [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw,
> + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw,
> + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw,
> + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw,
> + [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw,
> + [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw,
> +};
> +
> +struct a1_audio_data a1_audio_clkc = {
> + .hw_clks = {
> + .hws = a1_audio_clkc_hws,
> + .num = ARRAY_SIZE(a1_audio_clkc_hws),
> + },
> + .rst_drvname = "rst-a1",
> +};
> diff --git a/drivers/clk/meson/a1-audio-drv.c b/drivers/clk/meson/a1-audio-drv.c
> new file mode 100644
> index 000000000000..879a9d7bed72
> --- /dev/null
> +++ b/drivers/clk/meson/a1-audio-drv.c
> @@ -0,0 +1,104 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include <soc/amlogic/reset-meson-aux.h>
> +
> +#include "a1-audio.h"
> +
> +static const struct regmap_config a1_audio_regmap_cfg = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> +};
> +
> +static int a1_audio_clkc_probe(struct platform_device *pdev)
> +{
> + const struct a1_audio_data *data;
> + struct regmap *map;
> + void __iomem *base;
> + struct clk *clk;
> + unsigned int i;
> + int ret;
> +
> + data = device_get_match_data(&pdev->dev);
> + if (!data)
> + return -EINVAL;
> +
> + clk = devm_clk_get_enabled(&pdev->dev, "pclk");
> + if (IS_ERR(clk))
> + return PTR_ERR(clk);
> +
> + base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + map = devm_regmap_init_mmio(&pdev->dev, base, &a1_audio_regmap_cfg);
> + if (IS_ERR(map))
> + return PTR_ERR(map);
> +
> + ret = device_reset(&pdev->dev);
> + if (ret)
> + return dev_err_probe(&pdev->dev, ret, "failed to reset device");
> +
> + for (i = 0; i < data->hw_clks.num; i++) {
> + struct clk_hw *hw = data->hw_clks.hws[i];
> + struct clk_regmap *clk_regmap = to_clk_regmap(hw);
> +
> + if (!hw)
> + continue;
> +
> + clk_regmap->map = map;
> +
> + ret = devm_clk_hw_register(&pdev->dev, hw);
> + if (ret)
> + return ret;
> + }
> +
> + ret = devm_of_clk_add_hw_provider(&pdev->dev, meson_clk_hw_get,
> + (void *)&data->hw_clks);
> + if (ret)
> + return ret;
> +
> + if (!data->rst_drvname)
> + return 0;
> +
> + return devm_meson_rst_aux_register(&pdev->dev, map, data->rst_drvname);
> +}
> +
> +static const struct of_device_id a1_audio_clkc_match_table[] = {
> + {
> + .compatible = "amlogic,a1-audio-clkc",
> + .data = &a1_audio_clkc,
> + },
> + {
> + .compatible = "amlogic,a1-audio-vad-clkc",
> + .data = &a1_audio_vad_clkc,
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, a1_audio_clkc_match_table);
> +
> +static struct platform_driver a1_audio_clkc_driver = {
> + .probe = a1_audio_clkc_probe,
> + .driver = {
> + .name = "a1-audio-clkc",
> + .of_match_table = a1_audio_clkc_match_table,
> + },
> +};
> +module_platform_driver(a1_audio_clkc_driver);
> +
> +MODULE_DESCRIPTION("Amlogic A1 Audio Clock driver");
> +MODULE_AUTHOR("Jan Dakinevich <jan.dakinevich@salutedevices.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/clk/meson/a1-audio-vad-clkc.c b/drivers/clk/meson/a1-audio-vad-clkc.c
> new file mode 100644
> index 000000000000..0b1365d30ce1
> --- /dev/null
> +++ b/drivers/clk/meson/a1-audio-vad-clkc.c
> @@ -0,0 +1,85 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
> +
> +#include "a1-audio.h"
> +
> +#define AUDIO_VAD_CLK_GATE_EN0 0x00c
> +#define AUDIO_VAD_MCLK_CTRL 0x040
> +#define AUDIO_VAD_CLK_CTRL 0x044
> +#define AUDIO_VAD_CLK_PDMIN_CTRL0 0x058
> +#define AUDIO_CLK_VAD_PDMIN_CTRL1 0x05c
> +
> +struct clk_regmap aud_vad_ddr_arb =
> + AUD_PCLK_GATE(vad_ddr_arb, AUDIO_VAD_CLK_GATE_EN0, 0);
> +struct clk_regmap aud_vad_pdm =
> + AUD_PCLK_GATE(vad_pdm, AUDIO_VAD_CLK_GATE_EN0, 1);
> +struct clk_regmap aud_vad_tdmin_vad =
> + AUD_PCLK_GATE(vad_tdmin_vad, AUDIO_VAD_CLK_GATE_EN0, 2);
> +struct clk_regmap aud_vad_toddr_vad =
> + AUD_PCLK_GATE(vad_toddr_vad, AUDIO_VAD_CLK_GATE_EN0, 3);
> +struct clk_regmap aud_vad =
> + AUD_PCLK_GATE(vad, AUDIO_VAD_CLK_GATE_EN0, 4);
> +struct clk_regmap aud_vad_audiotop =
> + AUD_PCLK_GATE(vad_audiotop, AUDIO_VAD_CLK_GATE_EN0, 7);
> +
> +struct clk_regmap aud_vad_mclk_sel =
> + AUD_MST_MCLK_MUX(vad_mclk, AUDIO_VAD_MCLK_CTRL);
> +struct clk_regmap aud_vad_mclk_div =
> + AUD_MST_MCLK_DIV(vad_mclk, AUDIO_VAD_MCLK_CTRL);
> +struct clk_regmap aud_vad_mclk =
> + AUD_MST_MCLK_GATE(vad_mclk, AUDIO_VAD_MCLK_CTRL);
> +
> +struct clk_regmap aud_vad_clk_sel =
> + AUD_MST_MCLK_MUX(vad_clk, AUDIO_VAD_CLK_CTRL);
> +struct clk_regmap aud_vad_clk_div =
> + AUD_MST_MCLK_DIV(vad_clk, AUDIO_VAD_CLK_CTRL);
> +struct clk_regmap aud_vad_clk =
> + AUD_MST_MCLK_GATE(vad_clk, AUDIO_VAD_CLK_CTRL);
> +
> +struct clk_regmap aud_vad_pdm_dclk_sel =
> + AUD_MST_MCLK_MUX(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
> +struct clk_regmap aud_vad_pdm_dclk_div =
> + AUD_MST_MCLK_DIV(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
> +struct clk_regmap aud_vad_pdm_dclk =
> + AUD_MST_MCLK_GATE(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
> +
> +struct clk_regmap aud_vad_pdm_sysclk_sel =
> + AUD_MST_MCLK_MUX(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
> +struct clk_regmap aud_vad_pdm_sysclk_div =
> + AUD_MST_MCLK_DIV(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
> +struct clk_regmap aud_vad_pdm_sysclk =
> + AUD_MST_MCLK_GATE(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
> +
> +static struct clk_hw *a1_audio_vad_clkc_hws[] = {
> + [AUD_CLKID_VAD_DDR_ARB] = &aud_vad_ddr_arb.hw,
> + [AUD_CLKID_VAD_PDM] = &aud_vad_pdm.hw,
> + [AUD_CLKID_VAD_TDMIN] = &aud_vad_tdmin_vad.hw,
> + [AUD_CLKID_VAD_TODDR] = &aud_vad_toddr_vad.hw,
> + [AUD_CLKID_VAD] = &aud_vad.hw,
> + [AUD_CLKID_VAD_AUDIOTOP] = &aud_vad_audiotop.hw,
> + [AUD_CLKID_VAD_MCLK_SEL] = &aud_vad_mclk_sel.hw,
> + [AUD_CLKID_VAD_MCLK_DIV] = &aud_vad_mclk_div.hw,
> + [AUD_CLKID_VAD_MCLK] = &aud_vad_mclk.hw,
> + [AUD_CLKID_VAD_CLK_SEL] = &aud_vad_clk_sel.hw,
> + [AUD_CLKID_VAD_CLK_DIV] = &aud_vad_clk_div.hw,
> + [AUD_CLKID_VAD_CLK] = &aud_vad_clk.hw,
> + [AUD_CLKID_VAD_PDM_DCLK_SEL] = &aud_vad_pdm_dclk_sel.hw,
> + [AUD_CLKID_VAD_PDM_DCLK_DIV] = &aud_vad_pdm_dclk_div.hw,
> + [AUD_CLKID_VAD_PDM_DCLK] = &aud_vad_pdm_dclk.hw,
> + [AUD_CLKID_VAD_PDM_SYSCLK_SEL] = &aud_vad_pdm_sysclk_sel.hw,
> + [AUD_CLKID_VAD_PDM_SYSCLK_DIV] = &aud_vad_pdm_sysclk_div.hw,
> + [AUD_CLKID_VAD_PDM_SYSCLK] = &aud_vad_pdm_sysclk.hw,
> +};
> +
> +struct a1_audio_data a1_audio_vad_clkc = {
> + .hw_clks = {
> + .hws = a1_audio_vad_clkc_hws,
> + .num = ARRAY_SIZE(a1_audio_vad_clkc_hws),
> + },
No reset for VAD ? The documentation shows some.
> +};
> diff --git a/drivers/clk/meson/a1-audio.h b/drivers/clk/meson/a1-audio.h
> new file mode 100644
> index 000000000000..ecd0b1ea4aea
> --- /dev/null
> +++ b/drivers/clk/meson/a1-audio.h
> @@ -0,0 +1,131 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +/*
> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
> + *
> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
> + */
> +
> +#ifndef __MESON_CLK_A1_AUDIO_H
> +#define __MESON_CLK_A1_AUDIO_H
> +
> +#include "clk-phase.h"
> +#include "clk-regmap.h"
> +#include "meson-audio.h"
> +#include "meson-clkc-utils.h"
> +#include "sclk-div.h"
> +
> +#define AUD_PCLK_GATE(_name, _reg, _bit) { \
> + .data = &(struct clk_regmap_gate_data){ \
> + .offset = (_reg), \
> + .bit_idx = (_bit), \
> + }, \
> + .hw.init = &(struct clk_init_data) { \
> + .name = "aud_"#_name, \
> + .ops = &clk_regmap_gate_ops, \
> + .parent_data = &(const struct clk_parent_data) { \
> + .fw_name = "pclk" \
> + }, \
> + .num_parents = 1, \
> + }, \
> +}
No reason to leave this out of the common solely because of the parent
name. Add argument.
BUT checking more carefully, the chip does have audio top clocks, one for
each controller, plus a common one. Check EE_AUDIO2_CLK81_EN and
EE_AUDIO2_GATE_EN0. There is a tree to properly implement, same as sm1.
* EE_AUDIO2_CLK81_CTRL (which you skipped) feeds EE_AUDIO2_CLK81_EN
* EE_AUDIO2_CLK81_EN should be the parent of audio_top
* audio_top the parent of pclks - VAD is pclks are skipping it, is
intentional ?
All that seems critical for the audio tree to be properly clocked.
> +
> +#define AUD_MST_MCLK_PDATA ((const struct clk_parent_data[]) { \
> + { .fw_name = "mst_in0" }, \
> + { .fw_name = "mst_in1" }, \
> + { .fw_name = "mst_in2" }, \
> + { .fw_name = "mst_in3" }, \
> + { .fw_name = "mst_in4" }, \
> +})
> +#define AUD_MST_MCLK_MUX(_name, _reg) \
> + AUD_MUX(_name##_sel, (_reg), 0x7, 24, CLK_MUX_ROUND_CLOSEST, \
> + AUD_MST_MCLK_PDATA, 0)
> +#define AUD_MST_MCLK_DIV(_name, _reg) \
> + AUD_DIV(_name##_div, (_reg), 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \
> + aud_##_name##_sel, CLK_SET_RATE_PARENT)
> +#define AUD_MST_MCLK_GATE(_name, _reg) \
> + AUD_GATE(_name, (_reg), 31, \
> + aud_##_name##_div, CLK_SET_RATE_PARENT)
> +
> +#define AUD_MST_SCLK_PRE_EN(_name, _reg, _pname) \
> + AUD_GATE(_name##_pre_en, (_reg), 31, \
> + aud_##_pname, 0)
> +#define AUD_MST_SCLK_DIV(_name, _reg) \
> + AUD_SCLK_DIV(_name##_div, (_reg), 20, 10, 0, 0, \
> + aud_##_name##_pre_en, CLK_SET_RATE_PARENT)
> +#define AUD_MST_SCLK_POST_EN(_name, _reg) \
> + AUD_GATE(_name##_post_en, (_reg), 30, \
> + aud_##_name##_div, CLK_SET_RATE_PARENT)
> +#define AUD_MST_SCLK(_name, _reg) \
> + AUD_TRIPHASE(_name, (_reg), 1, 0, 2, 4, \
> + aud_##_name##_post_en, CLK_SET_RATE_PARENT)
> +
> +#define AUD_MST_LRCLK_DIV(_name, _reg, _pname) \
> + AUD_SCLK_DIV(_name##_div, (_reg), 0, 10, 10, 10, \
> + aud_##_pname, 0)
> +#define AUD_MST_LRCLK(_name, _reg) \
> + AUD_TRIPHASE(_name, (_reg), 1, 1, 3, 5, \
> + aud_##_name##_div, CLK_SET_RATE_PARENT)
> +
> +#define AUD_MST_SCLK_PDATA ((const struct clk_parent_data[]) { \
> + { .hw = &aud_mst_a_sclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_b_sclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_c_sclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_d_sclk.hw, .index = -1 }, \
> + { .hw = NULL }, \
> + { .hw = NULL }, \
> + { .fw_name = "slv_sclk0" }, \
> + { .fw_name = "slv_sclk1" }, \
> + { .fw_name = "slv_sclk2" }, \
> + { .fw_name = "slv_sclk3" }, \
> + { .fw_name = "slv_sclk4" }, \
> + { .fw_name = "slv_sclk5" }, \
> + { .fw_name = "slv_sclk6" }, \
> + { .fw_name = "slv_sclk7" }, \
> + { .fw_name = "slv_sclk8" }, \
> + { .fw_name = "slv_sclk9" }, \
> +})
> +#define AUD_TDM_SCLK_MUX(_name, _reg) \
> + AUD_MUX(_name##_sel, (_reg), 0xf, 24, CLK_MUX_ROUND_CLOSEST, \
> + AUD_MST_SCLK_PDATA, 0)
> +#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \
> + AUD_GATE(_name##_pre_en, (_reg), 31, \
> + aud_##_name##_sel, CLK_SET_RATE_PARENT)
> +#define AUD_TDM_SCLK_POST_EN(_name, _reg) \
> + AUD_GATE(_name##_post_en, (_reg), 30, \
> + aud_##_name##_pre_en, CLK_SET_RATE_PARENT)
> +#define AUD_TDM_SCLK_WS(_name, _reg) \
> + AUD_SCLK_WS(_name, (_reg), 1, 29, 28, \
> + aud_##_name##_post_en, \
> + CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
> +
> +#define AUD_MST_LRCLK_PDATA ((const struct clk_parent_data[]) { \
> + { .hw = &aud_mst_a_lrclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_b_lrclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_c_lrclk.hw, .index = -1 }, \
> + { .hw = &aud_mst_d_lrclk.hw, .index = -1 }, \
> + { .hw = NULL }, \
> + { .hw = NULL }, \
> + { .fw_name = "slv_lrclk0" }, \
> + { .fw_name = "slv_lrclk1" }, \
> + { .fw_name = "slv_lrclk2" }, \
> + { .fw_name = "slv_lrclk3" }, \
> + { .fw_name = "slv_lrclk4" }, \
> + { .fw_name = "slv_lrclk5" }, \
> + { .fw_name = "slv_lrclk6" }, \
> + { .fw_name = "slv_lrclk7" }, \
> + { .fw_name = "slv_lrclk8" }, \
> + { .fw_name = "slv_lrclk9" }, \
> +})
> +#define AUD_TDM_LRLCK(_name, _reg) \
> + AUD_MUX(_name, (_reg), 0xf, 20, CLK_MUX_ROUND_CLOSEST, \
> + AUD_MST_LRCLK_PDATA, CLK_SET_RATE_PARENT)
> +
> +struct a1_audio_data {
> + struct meson_clk_hw_data hw_clks;
> + const char *rst_drvname;
> +};
> +
> +extern struct a1_audio_data a1_audio_clkc;
> +extern struct a1_audio_data a1_audio_vad_clkc;
> +
> +#endif /* __MESON_CLK_A1_AUDIO_H */
--
Jerome
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver
2024-09-13 12:11 [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
` (5 preceding siblings ...)
2024-10-07 14:59 ` [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
@ 2024-10-22 9:51 ` Jerome Brunet
2024-10-24 5:18 ` Jan Dakinevich
6 siblings, 1 reply; 18+ messages in thread
From: Jerome Brunet @ 2024-10-22 9:51 UTC (permalink / raw)
To: Jan Dakinevich
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
> This series adds support for audio clock and reset controllers on A1 SoC family.
>
Split the reset part out of the series (I'd suggest adding VAD reset
support while at it). Also remove the DT patch, since it will depends on
both patchset.
Drop the RFC tag, at v4 I think that phase is over.
> Dependency: [4]
>
> Changes v3 [3] -> v4
> - Use auxiliary reset device implemented in [4]
> - Split the driver into files
> - Use common with axg-audio yaml schema
> - Unify clock-names with axg-audio
>
> Changes v2 [2] -> v3
> - reset:
> * added auxiliary device
> - yaml:
> * added declaration of optional clocks
> * fixed names in example and another cosmetics
> - clocks:
> * reworked naming
> * stop using of "core" clock name
> * fixed wrong parenting
>
> Changes v1 [1] -> v2:
> - Detached from v1's series (patch 2, 3, 4, 25).
> - Reuse some of defines from axg-audio;
> - Split the controller into two memory regions.
>
> Links:
> [1] https://lore.kernel.org/lkml/20240314232201.2102178-1-jan.dakinevich@salutedevices.com/
> [2] https://lore.kernel.org/lkml/20240328010831.884487-1-jan.dakinevich@salutedevices.com/
> [3] https://lore.kernel.org/lkml/20240419125812.983409-1-jan.dakinevich@salutedevices.com/
> [4] https://lore.kernel.org/lkml/9a4377fe27d8eb940399e452b68fb5a6d678929f.camel@pengutronix.de/
>
> Jan Dakinevich (5):
> reset: amlogic: add support for A1 SoC in auxiliary reset driver
> clk: meson: axg: share the set of audio helper macro
> dt-bindings: clock: axg-audio: document A1 SoC audio clock controller
> driver
> clk: meson: a1: add the audio clock controller driver
> arm64: dts: meson: a1: add the audio clock controller
>
> .../clock/amlogic,axg-audio-clkc.yaml | 3 +
> arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 48 +++
> drivers/clk/meson/Kconfig | 14 +
> drivers/clk/meson/Makefile | 3 +
> drivers/clk/meson/a1-audio-clkc.c | 359 ++++++++++++++++++
> drivers/clk/meson/a1-audio-drv.c | 104 +++++
> drivers/clk/meson/a1-audio-vad-clkc.c | 85 +++++
> drivers/clk/meson/a1-audio.h | 131 +++++++
> drivers/clk/meson/axg-audio.c | 138 +------
> drivers/clk/meson/meson-audio.h | 143 +++++++
> drivers/reset/amlogic/reset-meson-aux.c | 9 +
> .../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++
> .../reset/amlogic,meson-a1-audio-reset.h | 29 ++
> 13 files changed, 1051 insertions(+), 137 deletions(-)
> create mode 100644 drivers/clk/meson/a1-audio-clkc.c
> create mode 100644 drivers/clk/meson/a1-audio-drv.c
> create mode 100644 drivers/clk/meson/a1-audio-vad-clkc.c
> create mode 100644 drivers/clk/meson/a1-audio.h
> create mode 100644 drivers/clk/meson/meson-audio.h
> create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
> create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
--
Jerome
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver
2024-10-22 8:45 ` Jerome Brunet
@ 2024-10-24 4:48 ` Jan Dakinevich
0 siblings, 0 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-10-24 4:48 UTC (permalink / raw)
To: Jerome Brunet
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On 10/22/24 11:45, Jerome Brunet wrote:
> On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
>
>> Add device tree bindings for A1 SoC audio clock and reset controllers.
>>
>> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>
> Reset and clock are now independent.
>
> Please split the patch and send the changes in the related series,
> bindings before the driver change.
>
I can cut "include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h"
header and send it at the same series with modifications to reset aux
device. Is it correct?
>> ---
>> .../clock/amlogic,axg-audio-clkc.yaml | 3 +
>> .../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++++++++++++++
>> .../reset/amlogic,meson-a1-audio-reset.h | 29 +++++
>> 3 files changed, 154 insertions(+)
>> create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
>> create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
>>
>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
>> index fd7982dd4cea..df9eb8ce28dc 100644
>> --- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.yaml
>> @@ -18,6 +18,8 @@ description:
>> properties:
>> compatible:
>> enum:
>> + - amlogic,a1-audio-clkc
>> + - amlogic,a1-audio-vad-clkc
>> - amlogic,axg-audio-clkc
>> - amlogic,g12a-audio-clkc
>> - amlogic,sm1-audio-clkc
>> @@ -114,6 +116,7 @@ allOf:
>> compatible:
>> contains:
>> enum:
>> + - amlogic,a1-audio-clkc
>> - amlogic,g12a-audio-clkc
>> - amlogic,sm1-audio-clkc
>> then:
>> diff --git a/include/dt-bindings/clock/amlogic,a1-audio-clkc.h b/include/dt-bindings/clock/amlogic,a1-audio-clkc.h
>> new file mode 100644
>> index 000000000000..6534d1878816
>> --- /dev/null
>> +++ b/include/dt-bindings/clock/amlogic,a1-audio-clkc.h
>> @@ -0,0 +1,122 @@
>> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
>> +/*
>> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
>> + *
>> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>> + */
>> +
>> +#ifndef __A1_AUDIO_CLKC_BINDINGS_H
>> +#define __A1_AUDIO_CLKC_BINDINGS_H
>> +
>> +#define AUD_CLKID_DDR_ARB 1
>> +#define AUD_CLKID_TDMIN_A 2
>> +#define AUD_CLKID_TDMIN_B 3
>> +#define AUD_CLKID_TDMIN_LB 4
>> +#define AUD_CLKID_LOOPBACK 5
>> +#define AUD_CLKID_TDMOUT_A 6
>> +#define AUD_CLKID_TDMOUT_B 7
>> +#define AUD_CLKID_FRDDR_A 8
>> +#define AUD_CLKID_FRDDR_B 9
>> +#define AUD_CLKID_TODDR_A 10
>> +#define AUD_CLKID_TODDR_B 11
>> +#define AUD_CLKID_SPDIFIN 12
>> +#define AUD_CLKID_RESAMPLE 13
>> +#define AUD_CLKID_EQDRC 14
>> +#define AUD_CLKID_LOCKER 15
>> +#define AUD_CLKID_MST_A_MCLK_SEL 16
>> +#define AUD_CLKID_MST_A_MCLK_DIV 17
>> +#define AUD_CLKID_MST_A_MCLK 18
>> +#define AUD_CLKID_MST_B_MCLK_SEL 19
>> +#define AUD_CLKID_MST_B_MCLK_DIV 20
>> +#define AUD_CLKID_MST_B_MCLK 21
>> +#define AUD_CLKID_MST_C_MCLK_SEL 22
>> +#define AUD_CLKID_MST_C_MCLK_DIV 23
>> +#define AUD_CLKID_MST_C_MCLK 24
>> +#define AUD_CLKID_MST_D_MCLK_SEL 25
>> +#define AUD_CLKID_MST_D_MCLK_DIV 26
>> +#define AUD_CLKID_MST_D_MCLK 27
>> +#define AUD_CLKID_SPDIFIN_CLK_SEL 28
>> +#define AUD_CLKID_SPDIFIN_CLK_DIV 29
>> +#define AUD_CLKID_SPDIFIN_CLK 30
>> +#define AUD_CLKID_RESAMPLE_CLK_SEL 31
>> +#define AUD_CLKID_RESAMPLE_CLK_DIV 32
>> +#define AUD_CLKID_RESAMPLE_CLK 33
>> +#define AUD_CLKID_LOCKER_IN_CLK_SEL 34
>> +#define AUD_CLKID_LOCKER_IN_CLK_DIV 35
>> +#define AUD_CLKID_LOCKER_IN_CLK 36
>> +#define AUD_CLKID_LOCKER_OUT_CLK_SEL 37
>> +#define AUD_CLKID_LOCKER_OUT_CLK_DIV 38
>> +#define AUD_CLKID_LOCKER_OUT_CLK 39
>> +#define AUD_CLKID_EQDRC_CLK_SEL 40
>> +#define AUD_CLKID_EQDRC_CLK_DIV 41
>> +#define AUD_CLKID_EQDRC_CLK 42
>> +#define AUD_CLKID_MST_A_SCLK_PRE_EN 43
>> +#define AUD_CLKID_MST_A_SCLK_DIV 44
>> +#define AUD_CLKID_MST_A_SCLK_POST_EN 45
>> +#define AUD_CLKID_MST_A_SCLK 46
>> +#define AUD_CLKID_MST_B_SCLK_PRE_EN 47
>> +#define AUD_CLKID_MST_B_SCLK_DIV 48
>> +#define AUD_CLKID_MST_B_SCLK_POST_EN 49
>> +#define AUD_CLKID_MST_B_SCLK 50
>> +#define AUD_CLKID_MST_C_SCLK_PRE_EN 51
>> +#define AUD_CLKID_MST_C_SCLK_DIV 52
>> +#define AUD_CLKID_MST_C_SCLK_POST_EN 53
>> +#define AUD_CLKID_MST_C_SCLK 54
>> +#define AUD_CLKID_MST_D_SCLK_PRE_EN 55
>> +#define AUD_CLKID_MST_D_SCLK_DIV 56
>> +#define AUD_CLKID_MST_D_SCLK_POST_EN 57
>> +#define AUD_CLKID_MST_D_SCLK 58
>> +#define AUD_CLKID_MST_A_LRCLK_DIV 59
>> +#define AUD_CLKID_MST_A_LRCLK 60
>> +#define AUD_CLKID_MST_B_LRCLK_DIV 61
>> +#define AUD_CLKID_MST_B_LRCLK 62
>> +#define AUD_CLKID_MST_C_LRCLK_DIV 63
>> +#define AUD_CLKID_MST_C_LRCLK 64
>> +#define AUD_CLKID_MST_D_LRCLK_DIV 65
>> +#define AUD_CLKID_MST_D_LRCLK 66
>> +#define AUD_CLKID_TDMIN_A_SCLK_SEL 67
>> +#define AUD_CLKID_TDMIN_A_SCLK_PRE_EN 68
>> +#define AUD_CLKID_TDMIN_A_SCLK_POST_EN 69
>> +#define AUD_CLKID_TDMIN_A_SCLK 70
>> +#define AUD_CLKID_TDMIN_A_LRCLK 71
>> +#define AUD_CLKID_TDMIN_B_SCLK_SEL 72
>> +#define AUD_CLKID_TDMIN_B_SCLK_PRE_EN 73
>> +#define AUD_CLKID_TDMIN_B_SCLK_POST_EN 74
>> +#define AUD_CLKID_TDMIN_B_SCLK 75
>> +#define AUD_CLKID_TDMIN_B_LRCLK 76
>> +#define AUD_CLKID_TDMIN_LB_SCLK_SEL 77
>> +#define AUD_CLKID_TDMIN_LB_SCLK_PRE_EN 78
>> +#define AUD_CLKID_TDMIN_LB_SCLK_POST_EN 79
>> +#define AUD_CLKID_TDMIN_LB_SCLK 80
>> +#define AUD_CLKID_TDMIN_LB_LRCLK 81
>> +#define AUD_CLKID_TDMOUT_A_SCLK_SEL 82
>> +#define AUD_CLKID_TDMOUT_A_SCLK_PRE_EN 83
>> +#define AUD_CLKID_TDMOUT_A_SCLK_POST_EN 84
>> +#define AUD_CLKID_TDMOUT_A_SCLK 85
>> +#define AUD_CLKID_TDMOUT_A_LRCLK 86
>> +#define AUD_CLKID_TDMOUT_B_SCLK_SEL 87
>> +#define AUD_CLKID_TDMOUT_B_SCLK_PRE_EN 88
>> +#define AUD_CLKID_TDMOUT_B_SCLK_POST_EN 89
>> +#define AUD_CLKID_TDMOUT_B_SCLK 90
>> +#define AUD_CLKID_TDMOUT_B_LRCLK 91
>> +
>> +#define AUD_CLKID_VAD_DDR_ARB 1
>> +#define AUD_CLKID_VAD_PDM 2
>> +#define AUD_CLKID_VAD_TDMIN 3
>> +#define AUD_CLKID_VAD_TODDR 4
>> +#define AUD_CLKID_VAD 5
>> +#define AUD_CLKID_VAD_AUDIOTOP 6
>> +#define AUD_CLKID_VAD_MCLK_SEL 7
>> +#define AUD_CLKID_VAD_MCLK_DIV 8
>> +#define AUD_CLKID_VAD_MCLK 9
>> +#define AUD_CLKID_VAD_CLK_SEL 10
>> +#define AUD_CLKID_VAD_CLK_DIV 11
>> +#define AUD_CLKID_VAD_CLK 12
>> +#define AUD_CLKID_VAD_PDM_DCLK_SEL 13
>> +#define AUD_CLKID_VAD_PDM_DCLK_DIV 14
>> +#define AUD_CLKID_VAD_PDM_DCLK 15
>> +#define AUD_CLKID_VAD_PDM_SYSCLK_SEL 16
>> +#define AUD_CLKID_VAD_PDM_SYSCLK_DIV 17
>> +#define AUD_CLKID_VAD_PDM_SYSCLK 18
>> +
>> +#endif /* __A1_AUDIO_CLKC_BINDINGS_H */
>> diff --git a/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
>> new file mode 100644
>> index 000000000000..653fddba1d8f
>> --- /dev/null
>> +++ b/include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
>> @@ -0,0 +1,29 @@
>> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
>> +/*
>> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
>> + *
>> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>> + */
>> +
>> +#ifndef _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H
>> +#define _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H
>> +
>> +#define AUD_RESET_DDRARB 0
>> +#define AUD_RESET_TDMIN_A 1
>> +#define AUD_RESET_TDMIN_B 2
>> +#define AUD_RESET_TDMIN_LB 3
>> +#define AUD_RESET_LOOPBACK 4
>> +#define AUD_RESET_TDMOUT_A 5
>> +#define AUD_RESET_TDMOUT_B 6
>> +#define AUD_RESET_FRDDR_A 7
>> +#define AUD_RESET_FRDDR_B 8
>> +#define AUD_RESET_TODDR_A 9
>> +#define AUD_RESET_TODDR_B 10
>> +#define AUD_RESET_SPDIFIN 11
>> +#define AUD_RESET_RESAMPLE 12
>> +#define AUD_RESET_EQDRC 13
>> +#define AUD_RESET_LOCKER 14
>> +#define AUD_RESET_TOACODEC 30
>> +#define AUD_RESET_CLKTREE 31
>> +
>> +#endif /* _DT_BINDINGS_AMLOGIC_MESON_A1_AUDIO_RESET_H */
>
--
Best regards
Jan Dakinevich
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 4/5] clk: meson: a1: add the audio clock controller driver
2024-10-22 9:47 ` Jerome Brunet
@ 2024-10-24 5:15 ` Jan Dakinevich
0 siblings, 0 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-10-24 5:15 UTC (permalink / raw)
To: Jerome Brunet
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On 10/22/24 12:47, Jerome Brunet wrote:
> On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
>
>> This controller provides clocks and reset functionality for audio
>> peripherals on Amlogic A1 SoC family.
>>
>> The driver is almost identical to 'axg-audio', however it would be better
>> to keep it separate due to following reasons:
>>
>> - significant amount of bits has another definition. I will bring there
>> a mess of new defines with A1_ suffixes.
>>
>> - registers of this controller are located in two separate regions. It
>> will give a lot of complications for 'axg-audio' to support this.
>>
>> Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>> ---
>> drivers/clk/meson/Kconfig | 14 +
>> drivers/clk/meson/Makefile | 3 +
>> drivers/clk/meson/a1-audio-clkc.c | 359 ++++++++++++++++++++++++++
>> drivers/clk/meson/a1-audio-drv.c | 104 ++++++++
>> drivers/clk/meson/a1-audio-vad-clkc.c | 85 ++++++
>
> This split over 3 files appears unnecessary, especially since you've got
> a single configuration option for both drivers.
>
> a1-audio.c is enough AFAICT.
>
>> drivers/clk/meson/a1-audio.h | 131 ++++++++++
>
> not necessary.
>
Perhaps I misunderstood you. I thought you wanted a1 and a1-vad to live
in separate files.
>> 6 files changed, 696 insertions(+)
>> create mode 100644 drivers/clk/meson/a1-audio-clkc.c
>> create mode 100644 drivers/clk/meson/a1-audio-drv.c
>> create mode 100644 drivers/clk/meson/a1-audio-vad-clkc.c
>> create mode 100644 drivers/clk/meson/a1-audio.h
>>
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index 78f648c9c97d..b558288a6b78 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -132,6 +132,20 @@ config COMMON_CLK_A1_PERIPHERALS
>> device, A1 SoC Family. Say Y if you want A1 Peripherals clock
>> controller to work.
>>
>> +config COMMON_CLK_A1_AUDIO
>> + tristate "Amlogic A1 SoC Audio clock controller support"
>> + depends on ARM64
>> + select COMMON_CLK_MESON_REGMAP
>> + select COMMON_CLK_MESON_PHASE
>> + select COMMON_CLK_MESON_SCLK_DIV
>> + select COMMON_CLK_MESON_CLKC_UTILS
>> + select REGMAP_MMIO
>> + imply RESET_MESON_AUX
>> + help
>> + Support for the Audio clock controller on Amlogic A113L based
>> + device, A1 SoC Family. Say Y if you want A1 Audio clock controller
>> + to work.
>> +
>> config COMMON_CLK_C3_PLL
>> tristate "Amlogic C3 PLL clock controller"
>> depends on ARM64
>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> index bc56a47931c1..f7ea11df1de3 100644
>> --- a/drivers/clk/meson/Makefile
>> +++ b/drivers/clk/meson/Makefile
>> @@ -16,10 +16,13 @@ obj-$(CONFIG_COMMON_CLK_MESON_VCLK) += vclk.o
>>
>> # Amlogic Clock controllers
>>
>> +a1-audio-y := a1-audio-drv.o a1-audio-clkc.o a1-audio-vad-clkc.o
>> +
>> obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
>> obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
>> obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
>> obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
>> +obj-$(CONFIG_COMMON_CLK_A1_AUDIO) += a1-audio.o
>> obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
>> obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>> obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>> diff --git a/drivers/clk/meson/a1-audio-clkc.c b/drivers/clk/meson/a1-audio-clkc.c
>> new file mode 100644
>> index 000000000000..48160dcb7f47
>> --- /dev/null
>> +++ b/drivers/clk/meson/a1-audio-clkc.c
>> @@ -0,0 +1,359 @@
>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
>> +/*
>> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
>> + *
>> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>> + */
>> +
>> +#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
>> +
>> +#include "a1-audio.h"
>> +
>> +#define AUDIO_CLK_GATE_EN0 0x000
>> +#define AUDIO_MCLK_A_CTRL 0x008
>> +#define AUDIO_MCLK_B_CTRL 0x00c
>> +#define AUDIO_MCLK_C_CTRL 0x010
>> +#define AUDIO_MCLK_D_CTRL 0x014
>> +#define AUDIO_MCLK_E_CTRL 0x018
>> +#define AUDIO_MCLK_F_CTRL 0x01c
>> +#define AUDIO_SW_RESET0 0x028
>> +#define AUDIO_MST_A_SCLK_CTRL0 0x040
>> +#define AUDIO_MST_A_SCLK_CTRL1 0x044
>> +#define AUDIO_MST_B_SCLK_CTRL0 0x048
>> +#define AUDIO_MST_B_SCLK_CTRL1 0x04c
>> +#define AUDIO_MST_C_SCLK_CTRL0 0x050
>> +#define AUDIO_MST_C_SCLK_CTRL1 0x054
>> +#define AUDIO_MST_D_SCLK_CTRL0 0x058
>> +#define AUDIO_MST_D_SCLK_CTRL1 0x05c
>> +#define AUDIO_CLK_TDMIN_A_CTRL 0x080
>> +#define AUDIO_CLK_TDMIN_B_CTRL 0x084
>> +#define AUDIO_CLK_TDMIN_LB_CTRL 0x08c
>> +#define AUDIO_CLK_TDMOUT_A_CTRL 0x090
>> +#define AUDIO_CLK_TDMOUT_B_CTRL 0x094
>> +#define AUDIO_CLK_SPDIFIN_CTRL 0x09c
>> +#define AUDIO_CLK_RESAMPLE_CTRL 0x0a4
>> +#define AUDIO_CLK_LOCKER_CTRL 0x0a8
>> +#define AUDIO_CLK_EQDRC_CTRL 0x0c0
>> +
>> +struct clk_regmap aud_ddr_arb =
>> + AUD_PCLK_GATE(ddr_arb, AUDIO_CLK_GATE_EN0, 0);
>> +struct clk_regmap aud_tdmin_a =
>> + AUD_PCLK_GATE(tdmin_a, AUDIO_CLK_GATE_EN0, 1);
>> +struct clk_regmap aud_tdmin_b =
>> + AUD_PCLK_GATE(tdmin_b, AUDIO_CLK_GATE_EN0, 2);
>> +struct clk_regmap aud_tdmin_lb =
>> + AUD_PCLK_GATE(tdmin_lb, AUDIO_CLK_GATE_EN0, 3);
>> +struct clk_regmap aud_loopback =
>> + AUD_PCLK_GATE(loopback, AUDIO_CLK_GATE_EN0, 4);
>> +struct clk_regmap aud_tdmout_a =
>> + AUD_PCLK_GATE(tdmout_a, AUDIO_CLK_GATE_EN0, 5);
>> +struct clk_regmap aud_tdmout_b =
>> + AUD_PCLK_GATE(tdmout_b, AUDIO_CLK_GATE_EN0, 6);
>> +struct clk_regmap aud_frddr_a =
>> + AUD_PCLK_GATE(frddr_a, AUDIO_CLK_GATE_EN0, 7);
>> +struct clk_regmap aud_frddr_b =
>> + AUD_PCLK_GATE(frddr_b, AUDIO_CLK_GATE_EN0, 8);
>> +struct clk_regmap aud_toddr_a =
>> + AUD_PCLK_GATE(toddr_a, AUDIO_CLK_GATE_EN0, 9);
>> +struct clk_regmap aud_toddr_b =
>> + AUD_PCLK_GATE(toddr_b, AUDIO_CLK_GATE_EN0, 10);
>> +struct clk_regmap aud_spdifin =
>> + AUD_PCLK_GATE(spdifin, AUDIO_CLK_GATE_EN0, 11);
>> +struct clk_regmap aud_resample =
>> + AUD_PCLK_GATE(resample, AUDIO_CLK_GATE_EN0, 12);
>> +struct clk_regmap aud_eqdrc =
>> + AUD_PCLK_GATE(eqdrc, AUDIO_CLK_GATE_EN0, 13);
>> +struct clk_regmap aud_audiolocker =
>> + AUD_PCLK_GATE(audiolocker, AUDIO_CLK_GATE_EN0, 14);
>> +
>> +struct clk_regmap aud_mst_a_mclk_sel =
>> + AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL);
>> +struct clk_regmap aud_mst_a_mclk_div =
>> + AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL);
>> +struct clk_regmap aud_mst_a_mclk =
>> + AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL);
>> +
>> +struct clk_regmap aud_mst_b_mclk_sel =
>> + AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL);
>> +struct clk_regmap aud_mst_b_mclk_div =
>> + AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL);
>> +struct clk_regmap aud_mst_b_mclk =
>> + AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL);
>> +
>> +struct clk_regmap aud_mst_c_mclk_sel =
>> + AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL);
>> +struct clk_regmap aud_mst_c_mclk_div =
>> + AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL);
>> +struct clk_regmap aud_mst_c_mclk =
>> + AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL);
>> +
>> +struct clk_regmap aud_mst_d_mclk_sel =
>> + AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL);
>> +struct clk_regmap aud_mst_d_mclk_div =
>> + AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL);
>> +struct clk_regmap aud_mst_d_mclk =
>> + AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL);
>> +
>> +struct clk_regmap aud_spdifin_clk_sel =
>> + AUD_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
>> +struct clk_regmap aud_spdifin_clk_div =
>> + AUD_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
>> +struct clk_regmap aud_spdifin_clk =
>> + AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
>> +
>> +struct clk_regmap aud_eqdrc_clk_sel =
>> + AUD_MST_MCLK_MUX(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
>> +struct clk_regmap aud_eqdrc_clk_div =
>> + AUD_MST_MCLK_DIV(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
>> +struct clk_regmap aud_eqdrc_clk =
>> + AUD_MST_MCLK_GATE(eqdrc_clk, AUDIO_CLK_EQDRC_CTRL);
>> +
>> +struct clk_regmap aud_resample_clk_sel =
>> + AUD_MUX(resample_clk_sel, AUDIO_CLK_RESAMPLE_CTRL, 0xf, 24,
>> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
>> +struct clk_regmap aud_resample_clk_div =
>> + AUD_DIV(resample_clk_div, AUDIO_CLK_RESAMPLE_CTRL, 0, 8,
>> + CLK_DIVIDER_ROUND_CLOSEST, aud_resample_clk_sel,
>> + CLK_SET_RATE_PARENT);
>> +struct clk_regmap aud_resample_clk =
>> + AUD_GATE(resample_clk, AUDIO_CLK_RESAMPLE_CTRL, 31,
>> + aud_resample_clk_div, CLK_SET_RATE_PARENT);
>> +
>> +struct clk_regmap aud_locker_in_clk_sel =
>> + AUD_MUX(locker_in_clk_sel, AUDIO_CLK_LOCKER_CTRL, 0xf, 8,
>> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
>> +struct clk_regmap aud_locker_in_clk_div =
>> + AUD_DIV(locker_in_clk_div, AUDIO_CLK_LOCKER_CTRL, 0, 8,
>> + CLK_DIVIDER_ROUND_CLOSEST, aud_locker_in_clk_sel,
>> + CLK_SET_RATE_PARENT);
>> +struct clk_regmap aud_locker_in_clk =
>> + AUD_GATE(locker_in_clk, AUDIO_CLK_LOCKER_CTRL, 15,
>> + aud_locker_in_clk_div, CLK_SET_RATE_PARENT);
>> +
>> +struct clk_regmap aud_locker_out_clk_sel =
>> + AUD_MUX(locker_out_clk_sel, AUDIO_CLK_LOCKER_CTRL, 0xf, 24,
>> + CLK_MUX_ROUND_CLOSEST, AUD_MST_MCLK_PDATA, 0);
>> +struct clk_regmap aud_locker_out_clk_div =
>> + AUD_DIV(locker_out_clk_div, AUDIO_CLK_LOCKER_CTRL, 16, 8,
>> + CLK_DIVIDER_ROUND_CLOSEST, aud_locker_out_clk_sel,
>> + CLK_SET_RATE_PARENT);
>> +struct clk_regmap aud_locker_out_clk =
>> + AUD_GATE(locker_out_clk, AUDIO_CLK_LOCKER_CTRL, 31,
>> + aud_locker_out_clk_div, CLK_SET_RATE_PARENT);
>> +
>> +struct clk_regmap aud_mst_a_sclk_pre_en =
>> + AUD_MST_SCLK_PRE_EN(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0, mst_a_mclk);
>> +struct clk_regmap aud_mst_a_sclk_div =
>> + AUD_MST_SCLK_DIV(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0);
>> +struct clk_regmap aud_mst_a_sclk_post_en =
>> + AUD_MST_SCLK_POST_EN(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL0);
>> +struct clk_regmap aud_mst_a_sclk =
>> + AUD_MST_SCLK(mst_a_sclk, AUDIO_MST_A_SCLK_CTRL1);
>> +
>> +struct clk_regmap aud_mst_b_sclk_pre_en =
>> + AUD_MST_SCLK_PRE_EN(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0, mst_b_mclk);
>> +struct clk_regmap aud_mst_b_sclk_div =
>> + AUD_MST_SCLK_DIV(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0);
>> +struct clk_regmap aud_mst_b_sclk_post_en =
>> + AUD_MST_SCLK_POST_EN(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL0);
>> +struct clk_regmap aud_mst_b_sclk =
>> + AUD_MST_SCLK(mst_b_sclk, AUDIO_MST_B_SCLK_CTRL1);
>> +
>> +struct clk_regmap aud_mst_c_sclk_pre_en =
>> + AUD_MST_SCLK_PRE_EN(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0, mst_c_mclk);
>> +struct clk_regmap aud_mst_c_sclk_div =
>> + AUD_MST_SCLK_DIV(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0);
>> +struct clk_regmap aud_mst_c_sclk_post_en =
>> + AUD_MST_SCLK_POST_EN(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL0);
>> +struct clk_regmap aud_mst_c_sclk =
>> + AUD_MST_SCLK(mst_c_sclk, AUDIO_MST_C_SCLK_CTRL1);
>> +
>> +struct clk_regmap aud_mst_d_sclk_pre_en =
>> + AUD_MST_SCLK_PRE_EN(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0, mst_d_mclk);
>> +struct clk_regmap aud_mst_d_sclk_div =
>> + AUD_MST_SCLK_DIV(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0);
>> +struct clk_regmap aud_mst_d_sclk_post_en =
>> + AUD_MST_SCLK_POST_EN(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL0);
>> +struct clk_regmap aud_mst_d_sclk =
>> + AUD_MST_SCLK(mst_d_sclk, AUDIO_MST_D_SCLK_CTRL1);
>> +
>> +struct clk_regmap aud_mst_a_lrclk_div =
>> + AUD_MST_LRCLK_DIV(mst_a_lrclk, AUDIO_MST_A_SCLK_CTRL0,
>> + mst_a_sclk_post_en);
>> +struct clk_regmap aud_mst_a_lrclk =
>> + AUD_MST_LRCLK(mst_a_lrclk, AUDIO_MST_A_SCLK_CTRL1);
>> +
>> +struct clk_regmap aud_mst_b_lrclk_div =
>> + AUD_MST_LRCLK_DIV(mst_b_lrclk, AUDIO_MST_B_SCLK_CTRL0,
>> + mst_b_sclk_post_en);
>> +struct clk_regmap aud_mst_b_lrclk =
>> + AUD_MST_LRCLK(mst_b_lrclk, AUDIO_MST_B_SCLK_CTRL1);
>> +
>> +struct clk_regmap aud_mst_c_lrclk_div =
>> + AUD_MST_LRCLK_DIV(mst_c_lrclk, AUDIO_MST_C_SCLK_CTRL0,
>> + mst_c_sclk_post_en);
>> +struct clk_regmap aud_mst_c_lrclk =
>> + AUD_MST_LRCLK(mst_c_lrclk, AUDIO_MST_C_SCLK_CTRL1);
>> +
>> +struct clk_regmap aud_mst_d_lrclk_div =
>> + AUD_MST_LRCLK_DIV(mst_d_lrclk, AUDIO_MST_D_SCLK_CTRL0,
>> + mst_d_sclk_post_en);
>> +struct clk_regmap aud_mst_d_lrclk =
>> + AUD_MST_LRCLK(mst_d_lrclk, AUDIO_MST_D_SCLK_CTRL1);
>> +
>> +struct clk_regmap aud_tdmin_a_sclk_sel =
>> + AUD_TDM_SCLK_MUX(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
>> +struct clk_regmap aud_tdmin_a_sclk_pre_en =
>> + AUD_TDM_SCLK_PRE_EN(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
>> +struct clk_regmap aud_tdmin_a_sclk_post_en =
>> + AUD_TDM_SCLK_POST_EN(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
>> +struct clk_regmap aud_tdmin_a_sclk =
>> + AUD_TDM_SCLK_WS(tdmin_a_sclk, AUDIO_CLK_TDMIN_A_CTRL);
>> +struct clk_regmap aud_tdmin_a_lrclk =
>> + AUD_TDM_LRLCK(tdmin_a_lrclk, AUDIO_CLK_TDMIN_A_CTRL);
>> +
>> +struct clk_regmap aud_tdmin_b_sclk_sel =
>> + AUD_TDM_SCLK_MUX(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
>> +struct clk_regmap aud_tdmin_b_sclk_pre_en =
>> + AUD_TDM_SCLK_PRE_EN(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
>> +struct clk_regmap aud_tdmin_b_sclk_post_en =
>> + AUD_TDM_SCLK_POST_EN(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
>> +struct clk_regmap aud_tdmin_b_sclk =
>> + AUD_TDM_SCLK_WS(tdmin_b_sclk, AUDIO_CLK_TDMIN_B_CTRL);
>> +struct clk_regmap aud_tdmin_b_lrclk =
>> + AUD_TDM_LRLCK(tdmin_b_lrclk, AUDIO_CLK_TDMIN_B_CTRL);
>> +
>> +struct clk_regmap aud_tdmin_lb_sclk_sel =
>> + AUD_TDM_SCLK_MUX(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
>> +struct clk_regmap aud_tdmin_lb_sclk_pre_en =
>> + AUD_TDM_SCLK_PRE_EN(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
>> +struct clk_regmap aud_tdmin_lb_sclk_post_en =
>> + AUD_TDM_SCLK_POST_EN(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
>> +struct clk_regmap aud_tdmin_lb_sclk =
>> + AUD_TDM_SCLK_WS(tdmin_lb_sclk, AUDIO_CLK_TDMIN_LB_CTRL);
>> +struct clk_regmap aud_tdmin_lb_lrclk =
>> + AUD_TDM_LRLCK(tdmin_lb_lrclk, AUDIO_CLK_TDMIN_LB_CTRL);
>> +
>> +struct clk_regmap aud_tdmout_a_sclk_sel =
>> + AUD_TDM_SCLK_MUX(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
>> +struct clk_regmap aud_tdmout_a_sclk_pre_en =
>> + AUD_TDM_SCLK_PRE_EN(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
>> +struct clk_regmap aud_tdmout_a_sclk_post_en =
>> + AUD_TDM_SCLK_POST_EN(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
>> +struct clk_regmap aud_tdmout_a_sclk =
>> + AUD_TDM_SCLK_WS(tdmout_a_sclk, AUDIO_CLK_TDMOUT_A_CTRL);
>> +struct clk_regmap aud_tdmout_a_lrclk =
>> + AUD_TDM_LRLCK(tdmout_a_lrclk, AUDIO_CLK_TDMOUT_A_CTRL);
>> +
>> +struct clk_regmap aud_tdmout_b_sclk_sel =
>> + AUD_TDM_SCLK_MUX(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
>> +struct clk_regmap aud_tdmout_b_sclk_pre_en =
>> + AUD_TDM_SCLK_PRE_EN(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
>> +struct clk_regmap aud_tdmout_b_sclk_post_en =
>> + AUD_TDM_SCLK_POST_EN(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
>> +struct clk_regmap aud_tdmout_b_sclk =
>> + AUD_TDM_SCLK_WS(tdmout_b_sclk, AUDIO_CLK_TDMOUT_B_CTRL);
>> +struct clk_regmap aud_tdmout_b_lrclk =
>> + AUD_TDM_LRLCK(tdmout_b_lrclk, AUDIO_CLK_TDMOUT_B_CTRL);
>> +
>> +static struct clk_hw *a1_audio_clkc_hws[] = {
>> + [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw,
>> + [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw,
>> + [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw,
>> + [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw,
>> + [AUD_CLKID_LOOPBACK] = &aud_loopback.hw,
>> + [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw,
>> + [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw,
>> + [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw,
>> + [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw,
>> + [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw,
>> + [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw,
>> + [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw,
>> + [AUD_CLKID_RESAMPLE] = &aud_resample.hw,
>> + [AUD_CLKID_EQDRC] = &aud_eqdrc.hw,
>> + [AUD_CLKID_LOCKER] = &aud_audiolocker.hw,
>> + [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw,
>> + [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw,
>> + [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw,
>> + [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw,
>> + [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw,
>> + [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw,
>> + [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw,
>> + [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw,
>> + [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw,
>> + [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw,
>> + [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw,
>> + [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw,
>> + [AUD_CLKID_RESAMPLE_CLK_SEL] = &aud_resample_clk_sel.hw,
>> + [AUD_CLKID_RESAMPLE_CLK_DIV] = &aud_resample_clk_div.hw,
>> + [AUD_CLKID_RESAMPLE_CLK] = &aud_resample_clk.hw,
>> + [AUD_CLKID_LOCKER_IN_CLK_SEL] = &aud_locker_in_clk_sel.hw,
>> + [AUD_CLKID_LOCKER_IN_CLK_DIV] = &aud_locker_in_clk_div.hw,
>> + [AUD_CLKID_LOCKER_IN_CLK] = &aud_locker_in_clk.hw,
>> + [AUD_CLKID_LOCKER_OUT_CLK_SEL] = &aud_locker_out_clk_sel.hw,
>> + [AUD_CLKID_LOCKER_OUT_CLK_DIV] = &aud_locker_out_clk_div.hw,
>> + [AUD_CLKID_LOCKER_OUT_CLK] = &aud_locker_out_clk.hw,
>> + [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw,
>> + [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw,
>> + [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw,
>> + [AUD_CLKID_EQDRC_CLK_SEL] = &aud_eqdrc_clk_sel.hw,
>> + [AUD_CLKID_EQDRC_CLK_DIV] = &aud_eqdrc_clk_div.hw,
>> + [AUD_CLKID_EQDRC_CLK] = &aud_eqdrc_clk.hw,
>> + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw,
>> + [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw,
>> + [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw,
>> + [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw,
>> + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw,
>> + [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw,
>> + [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw,
>> + [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw,
>> + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw,
>> + [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw,
>> + [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw,
>> + [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw,
>> + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw,
>> + [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw,
>> + [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw,
>> + [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw,
>> + [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw,
>> + [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw,
>> + [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw,
>> + [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw,
>> + [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw,
>> + [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw,
>> + [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw,
>> + [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw,
>> + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw,
>> + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw,
>> + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw,
>> + [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw,
>> + [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw,
>> + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw,
>> + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw,
>> + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw,
>> + [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw,
>> + [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw,
>> + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw,
>> + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw,
>> + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw,
>> + [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw,
>> + [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw,
>> + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw,
>> + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw,
>> + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw,
>> + [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw,
>> + [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw,
>> + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw,
>> + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw,
>> + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw,
>> + [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw,
>> + [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw,
>> +};
>> +
>> +struct a1_audio_data a1_audio_clkc = {
>> + .hw_clks = {
>> + .hws = a1_audio_clkc_hws,
>> + .num = ARRAY_SIZE(a1_audio_clkc_hws),
>> + },
>> + .rst_drvname = "rst-a1",
>> +};
>> diff --git a/drivers/clk/meson/a1-audio-drv.c b/drivers/clk/meson/a1-audio-drv.c
>> new file mode 100644
>> index 000000000000..879a9d7bed72
>> --- /dev/null
>> +++ b/drivers/clk/meson/a1-audio-drv.c
>> @@ -0,0 +1,104 @@
>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
>> +/*
>> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
>> + *
>> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/init.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/reset.h>
>> +
>> +#include <soc/amlogic/reset-meson-aux.h>
>> +
>> +#include "a1-audio.h"
>> +
>> +static const struct regmap_config a1_audio_regmap_cfg = {
>> + .reg_bits = 32,
>> + .val_bits = 32,
>> + .reg_stride = 4,
>> +};
>> +
>> +static int a1_audio_clkc_probe(struct platform_device *pdev)
>> +{
>> + const struct a1_audio_data *data;
>> + struct regmap *map;
>> + void __iomem *base;
>> + struct clk *clk;
>> + unsigned int i;
>> + int ret;
>> +
>> + data = device_get_match_data(&pdev->dev);
>> + if (!data)
>> + return -EINVAL;
>> +
>> + clk = devm_clk_get_enabled(&pdev->dev, "pclk");
>> + if (IS_ERR(clk))
>> + return PTR_ERR(clk);
>> +
>> + base = devm_platform_ioremap_resource(pdev, 0);
>> + if (IS_ERR(base))
>> + return PTR_ERR(base);
>> +
>> + map = devm_regmap_init_mmio(&pdev->dev, base, &a1_audio_regmap_cfg);
>> + if (IS_ERR(map))
>> + return PTR_ERR(map);
>> +
>> + ret = device_reset(&pdev->dev);
>> + if (ret)
>> + return dev_err_probe(&pdev->dev, ret, "failed to reset device");
>> +
>> + for (i = 0; i < data->hw_clks.num; i++) {
>> + struct clk_hw *hw = data->hw_clks.hws[i];
>> + struct clk_regmap *clk_regmap = to_clk_regmap(hw);
>> +
>> + if (!hw)
>> + continue;
>> +
>> + clk_regmap->map = map;
>> +
>> + ret = devm_clk_hw_register(&pdev->dev, hw);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + ret = devm_of_clk_add_hw_provider(&pdev->dev, meson_clk_hw_get,
>> + (void *)&data->hw_clks);
>> + if (ret)
>> + return ret;
>> +
>> + if (!data->rst_drvname)
>> + return 0;
>> +
>> + return devm_meson_rst_aux_register(&pdev->dev, map, data->rst_drvname);
>> +}
>> +
>> +static const struct of_device_id a1_audio_clkc_match_table[] = {
>> + {
>> + .compatible = "amlogic,a1-audio-clkc",
>> + .data = &a1_audio_clkc,
>> + },
>> + {
>> + .compatible = "amlogic,a1-audio-vad-clkc",
>> + .data = &a1_audio_vad_clkc,
>> + },
>> + {}
>> +};
>> +MODULE_DEVICE_TABLE(of, a1_audio_clkc_match_table);
>> +
>> +static struct platform_driver a1_audio_clkc_driver = {
>> + .probe = a1_audio_clkc_probe,
>> + .driver = {
>> + .name = "a1-audio-clkc",
>> + .of_match_table = a1_audio_clkc_match_table,
>> + },
>> +};
>> +module_platform_driver(a1_audio_clkc_driver);
>> +
>> +MODULE_DESCRIPTION("Amlogic A1 Audio Clock driver");
>> +MODULE_AUTHOR("Jan Dakinevich <jan.dakinevich@salutedevices.com>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/clk/meson/a1-audio-vad-clkc.c b/drivers/clk/meson/a1-audio-vad-clkc.c
>> new file mode 100644
>> index 000000000000..0b1365d30ce1
>> --- /dev/null
>> +++ b/drivers/clk/meson/a1-audio-vad-clkc.c
>> @@ -0,0 +1,85 @@
>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
>> +/*
>> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
>> + *
>> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>> + */
>> +
>> +#include <dt-bindings/clock/amlogic,a1-audio-clkc.h>
>> +
>> +#include "a1-audio.h"
>> +
>> +#define AUDIO_VAD_CLK_GATE_EN0 0x00c
>> +#define AUDIO_VAD_MCLK_CTRL 0x040
>> +#define AUDIO_VAD_CLK_CTRL 0x044
>> +#define AUDIO_VAD_CLK_PDMIN_CTRL0 0x058
>> +#define AUDIO_CLK_VAD_PDMIN_CTRL1 0x05c
>> +
>> +struct clk_regmap aud_vad_ddr_arb =
>> + AUD_PCLK_GATE(vad_ddr_arb, AUDIO_VAD_CLK_GATE_EN0, 0);
>> +struct clk_regmap aud_vad_pdm =
>> + AUD_PCLK_GATE(vad_pdm, AUDIO_VAD_CLK_GATE_EN0, 1);
>> +struct clk_regmap aud_vad_tdmin_vad =
>> + AUD_PCLK_GATE(vad_tdmin_vad, AUDIO_VAD_CLK_GATE_EN0, 2);
>> +struct clk_regmap aud_vad_toddr_vad =
>> + AUD_PCLK_GATE(vad_toddr_vad, AUDIO_VAD_CLK_GATE_EN0, 3);
>> +struct clk_regmap aud_vad =
>> + AUD_PCLK_GATE(vad, AUDIO_VAD_CLK_GATE_EN0, 4);
>> +struct clk_regmap aud_vad_audiotop =
>> + AUD_PCLK_GATE(vad_audiotop, AUDIO_VAD_CLK_GATE_EN0, 7);
>> +
>> +struct clk_regmap aud_vad_mclk_sel =
>> + AUD_MST_MCLK_MUX(vad_mclk, AUDIO_VAD_MCLK_CTRL);
>> +struct clk_regmap aud_vad_mclk_div =
>> + AUD_MST_MCLK_DIV(vad_mclk, AUDIO_VAD_MCLK_CTRL);
>> +struct clk_regmap aud_vad_mclk =
>> + AUD_MST_MCLK_GATE(vad_mclk, AUDIO_VAD_MCLK_CTRL);
>> +
>> +struct clk_regmap aud_vad_clk_sel =
>> + AUD_MST_MCLK_MUX(vad_clk, AUDIO_VAD_CLK_CTRL);
>> +struct clk_regmap aud_vad_clk_div =
>> + AUD_MST_MCLK_DIV(vad_clk, AUDIO_VAD_CLK_CTRL);
>> +struct clk_regmap aud_vad_clk =
>> + AUD_MST_MCLK_GATE(vad_clk, AUDIO_VAD_CLK_CTRL);
>> +
>> +struct clk_regmap aud_vad_pdm_dclk_sel =
>> + AUD_MST_MCLK_MUX(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
>> +struct clk_regmap aud_vad_pdm_dclk_div =
>> + AUD_MST_MCLK_DIV(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
>> +struct clk_regmap aud_vad_pdm_dclk =
>> + AUD_MST_MCLK_GATE(vad_pdm_dclk, AUDIO_VAD_CLK_PDMIN_CTRL0);
>> +
>> +struct clk_regmap aud_vad_pdm_sysclk_sel =
>> + AUD_MST_MCLK_MUX(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
>> +struct clk_regmap aud_vad_pdm_sysclk_div =
>> + AUD_MST_MCLK_DIV(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
>> +struct clk_regmap aud_vad_pdm_sysclk =
>> + AUD_MST_MCLK_GATE(vad_pdm_sysclk, AUDIO_CLK_VAD_PDMIN_CTRL1);
>> +
>> +static struct clk_hw *a1_audio_vad_clkc_hws[] = {
>> + [AUD_CLKID_VAD_DDR_ARB] = &aud_vad_ddr_arb.hw,
>> + [AUD_CLKID_VAD_PDM] = &aud_vad_pdm.hw,
>> + [AUD_CLKID_VAD_TDMIN] = &aud_vad_tdmin_vad.hw,
>> + [AUD_CLKID_VAD_TODDR] = &aud_vad_toddr_vad.hw,
>> + [AUD_CLKID_VAD] = &aud_vad.hw,
>> + [AUD_CLKID_VAD_AUDIOTOP] = &aud_vad_audiotop.hw,
>> + [AUD_CLKID_VAD_MCLK_SEL] = &aud_vad_mclk_sel.hw,
>> + [AUD_CLKID_VAD_MCLK_DIV] = &aud_vad_mclk_div.hw,
>> + [AUD_CLKID_VAD_MCLK] = &aud_vad_mclk.hw,
>> + [AUD_CLKID_VAD_CLK_SEL] = &aud_vad_clk_sel.hw,
>> + [AUD_CLKID_VAD_CLK_DIV] = &aud_vad_clk_div.hw,
>> + [AUD_CLKID_VAD_CLK] = &aud_vad_clk.hw,
>> + [AUD_CLKID_VAD_PDM_DCLK_SEL] = &aud_vad_pdm_dclk_sel.hw,
>> + [AUD_CLKID_VAD_PDM_DCLK_DIV] = &aud_vad_pdm_dclk_div.hw,
>> + [AUD_CLKID_VAD_PDM_DCLK] = &aud_vad_pdm_dclk.hw,
>> + [AUD_CLKID_VAD_PDM_SYSCLK_SEL] = &aud_vad_pdm_sysclk_sel.hw,
>> + [AUD_CLKID_VAD_PDM_SYSCLK_DIV] = &aud_vad_pdm_sysclk_div.hw,
>> + [AUD_CLKID_VAD_PDM_SYSCLK] = &aud_vad_pdm_sysclk.hw,
>> +};
>> +
>> +struct a1_audio_data a1_audio_vad_clkc = {
>> + .hw_clks = {
>> + .hws = a1_audio_vad_clkc_hws,
>> + .num = ARRAY_SIZE(a1_audio_vad_clkc_hws),
>> + },
>
> No reset for VAD ? The documentation shows some.
>
You're right, VAD part has several useful reset handles.
>> +};
>> diff --git a/drivers/clk/meson/a1-audio.h b/drivers/clk/meson/a1-audio.h
>> new file mode 100644
>> index 000000000000..ecd0b1ea4aea
>> --- /dev/null
>> +++ b/drivers/clk/meson/a1-audio.h
>> @@ -0,0 +1,131 @@
>> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
>> +/*
>> + * Copyright (c) 2024, SaluteDevices. All Rights Reserved.
>> + *
>> + * Author: Jan Dakinevich <jan.dakinevich@salutedevices.com>
>> + */
>> +
>> +#ifndef __MESON_CLK_A1_AUDIO_H
>> +#define __MESON_CLK_A1_AUDIO_H
>> +
>> +#include "clk-phase.h"
>> +#include "clk-regmap.h"
>> +#include "meson-audio.h"
>> +#include "meson-clkc-utils.h"
>> +#include "sclk-div.h"
>> +
>> +#define AUD_PCLK_GATE(_name, _reg, _bit) { \
>> + .data = &(struct clk_regmap_gate_data){ \
>> + .offset = (_reg), \
>> + .bit_idx = (_bit), \
>> + }, \
>> + .hw.init = &(struct clk_init_data) { \
>> + .name = "aud_"#_name, \
>> + .ops = &clk_regmap_gate_ops, \
>> + .parent_data = &(const struct clk_parent_data) { \
>> + .fw_name = "pclk" \
>> + }, \
>> + .num_parents = 1, \
>> + }, \
>> +}
>
> No reason to leave this out of the common solely because of the parent
> name. Add argument.
>
It's not just because of the different parent name. axg-audio uses
"parent_name" but a1-audio uses "parent_data->fw_name". I can unify
them, but it would require quite more then an extra argument.
> BUT checking more carefully, the chip does have audio top clocks, one for
> each controller, plus a common one. Check EE_AUDIO2_CLK81_EN and
> EE_AUDIO2_GATE_EN0. There is a tree to properly implement, same as sm1.
>
> * EE_AUDIO2_CLK81_CTRL (which you skipped) feeds EE_AUDIO2_CLK81_EN
> * EE_AUDIO2_CLK81_EN should be the parent of audio_top
> * audio_top the parent of pclks - VAD is pclks are skipping it, is
> intentional ?
>
> All that seems critical for the audio tree to be properly clocked.
>
Nothing to answer. I need to walk through the doc again.
>> +
>> +#define AUD_MST_MCLK_PDATA ((const struct clk_parent_data[]) { \
>> + { .fw_name = "mst_in0" }, \
>> + { .fw_name = "mst_in1" }, \
>> + { .fw_name = "mst_in2" }, \
>> + { .fw_name = "mst_in3" }, \
>> + { .fw_name = "mst_in4" }, \
>> +})
>> +#define AUD_MST_MCLK_MUX(_name, _reg) \
>> + AUD_MUX(_name##_sel, (_reg), 0x7, 24, CLK_MUX_ROUND_CLOSEST, \
>> + AUD_MST_MCLK_PDATA, 0)
>> +#define AUD_MST_MCLK_DIV(_name, _reg) \
>> + AUD_DIV(_name##_div, (_reg), 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \
>> + aud_##_name##_sel, CLK_SET_RATE_PARENT)
>> +#define AUD_MST_MCLK_GATE(_name, _reg) \
>> + AUD_GATE(_name, (_reg), 31, \
>> + aud_##_name##_div, CLK_SET_RATE_PARENT)
>> +
>> +#define AUD_MST_SCLK_PRE_EN(_name, _reg, _pname) \
>> + AUD_GATE(_name##_pre_en, (_reg), 31, \
>> + aud_##_pname, 0)
>> +#define AUD_MST_SCLK_DIV(_name, _reg) \
>> + AUD_SCLK_DIV(_name##_div, (_reg), 20, 10, 0, 0, \
>> + aud_##_name##_pre_en, CLK_SET_RATE_PARENT)
>> +#define AUD_MST_SCLK_POST_EN(_name, _reg) \
>> + AUD_GATE(_name##_post_en, (_reg), 30, \
>> + aud_##_name##_div, CLK_SET_RATE_PARENT)
>> +#define AUD_MST_SCLK(_name, _reg) \
>> + AUD_TRIPHASE(_name, (_reg), 1, 0, 2, 4, \
>> + aud_##_name##_post_en, CLK_SET_RATE_PARENT)
>> +
>> +#define AUD_MST_LRCLK_DIV(_name, _reg, _pname) \
>> + AUD_SCLK_DIV(_name##_div, (_reg), 0, 10, 10, 10, \
>> + aud_##_pname, 0)
>> +#define AUD_MST_LRCLK(_name, _reg) \
>> + AUD_TRIPHASE(_name, (_reg), 1, 1, 3, 5, \
>> + aud_##_name##_div, CLK_SET_RATE_PARENT)
>> +
>> +#define AUD_MST_SCLK_PDATA ((const struct clk_parent_data[]) { \
>> + { .hw = &aud_mst_a_sclk.hw, .index = -1 }, \
>> + { .hw = &aud_mst_b_sclk.hw, .index = -1 }, \
>> + { .hw = &aud_mst_c_sclk.hw, .index = -1 }, \
>> + { .hw = &aud_mst_d_sclk.hw, .index = -1 }, \
>> + { .hw = NULL }, \
>> + { .hw = NULL }, \
>> + { .fw_name = "slv_sclk0" }, \
>> + { .fw_name = "slv_sclk1" }, \
>> + { .fw_name = "slv_sclk2" }, \
>> + { .fw_name = "slv_sclk3" }, \
>> + { .fw_name = "slv_sclk4" }, \
>> + { .fw_name = "slv_sclk5" }, \
>> + { .fw_name = "slv_sclk6" }, \
>> + { .fw_name = "slv_sclk7" }, \
>> + { .fw_name = "slv_sclk8" }, \
>> + { .fw_name = "slv_sclk9" }, \
>> +})
>> +#define AUD_TDM_SCLK_MUX(_name, _reg) \
>> + AUD_MUX(_name##_sel, (_reg), 0xf, 24, CLK_MUX_ROUND_CLOSEST, \
>> + AUD_MST_SCLK_PDATA, 0)
>> +#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \
>> + AUD_GATE(_name##_pre_en, (_reg), 31, \
>> + aud_##_name##_sel, CLK_SET_RATE_PARENT)
>> +#define AUD_TDM_SCLK_POST_EN(_name, _reg) \
>> + AUD_GATE(_name##_post_en, (_reg), 30, \
>> + aud_##_name##_pre_en, CLK_SET_RATE_PARENT)
>> +#define AUD_TDM_SCLK_WS(_name, _reg) \
>> + AUD_SCLK_WS(_name, (_reg), 1, 29, 28, \
>> + aud_##_name##_post_en, \
>> + CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
>> +
>> +#define AUD_MST_LRCLK_PDATA ((const struct clk_parent_data[]) { \
>> + { .hw = &aud_mst_a_lrclk.hw, .index = -1 }, \
>> + { .hw = &aud_mst_b_lrclk.hw, .index = -1 }, \
>> + { .hw = &aud_mst_c_lrclk.hw, .index = -1 }, \
>> + { .hw = &aud_mst_d_lrclk.hw, .index = -1 }, \
>> + { .hw = NULL }, \
>> + { .hw = NULL }, \
>> + { .fw_name = "slv_lrclk0" }, \
>> + { .fw_name = "slv_lrclk1" }, \
>> + { .fw_name = "slv_lrclk2" }, \
>> + { .fw_name = "slv_lrclk3" }, \
>> + { .fw_name = "slv_lrclk4" }, \
>> + { .fw_name = "slv_lrclk5" }, \
>> + { .fw_name = "slv_lrclk6" }, \
>> + { .fw_name = "slv_lrclk7" }, \
>> + { .fw_name = "slv_lrclk8" }, \
>> + { .fw_name = "slv_lrclk9" }, \
>> +})
>> +#define AUD_TDM_LRLCK(_name, _reg) \
>> + AUD_MUX(_name, (_reg), 0xf, 20, CLK_MUX_ROUND_CLOSEST, \
>> + AUD_MST_LRCLK_PDATA, CLK_SET_RATE_PARENT)
>> +
>> +struct a1_audio_data {
>> + struct meson_clk_hw_data hw_clks;
>> + const char *rst_drvname;
>> +};
>> +
>> +extern struct a1_audio_data a1_audio_clkc;
>> +extern struct a1_audio_data a1_audio_vad_clkc;
>> +
>> +#endif /* __MESON_CLK_A1_AUDIO_H */
>
--
Best regards
Jan Dakinevich
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver
2024-10-22 9:51 ` Jerome Brunet
@ 2024-10-24 5:18 ` Jan Dakinevich
0 siblings, 0 replies; 18+ messages in thread
From: Jan Dakinevich @ 2024-10-24 5:18 UTC (permalink / raw)
To: Jerome Brunet
Cc: Conor Dooley, devicetree, Kevin Hilman, Krzysztof Kozlowski,
linux-amlogic, linux-arm-kernel, linux-clk, linux-kernel,
Martin Blumenstingl, Michael Turquette, Neil Armstrong,
Philipp Zabel, Rob Herring, Stephen Boyd
On 10/22/24 12:51, Jerome Brunet wrote:
> On Fri 13 Sep 2024 at 15:11, Jan Dakinevich <jan.dakinevich@salutedevices.com> wrote:
>
>> This series adds support for audio clock and reset controllers on A1 SoC family.
>>
>
> Split the reset part out of the series (I'd suggest adding VAD reset
> support while at it). Also remove the DT patch, since it will depends on
> both patchset.
>
> Drop the RFC tag, at v4 I think that phase is over.
>
Jerome, thank you for review.
>> Dependency: [4]
>>
>> Changes v3 [3] -> v4
>> - Use auxiliary reset device implemented in [4]
>> - Split the driver into files
>> - Use common with axg-audio yaml schema
>> - Unify clock-names with axg-audio
>>
>> Changes v2 [2] -> v3
>> - reset:
>> * added auxiliary device
>> - yaml:
>> * added declaration of optional clocks
>> * fixed names in example and another cosmetics
>> - clocks:
>> * reworked naming
>> * stop using of "core" clock name
>> * fixed wrong parenting
>>
>> Changes v1 [1] -> v2:
>> - Detached from v1's series (patch 2, 3, 4, 25).
>> - Reuse some of defines from axg-audio;
>> - Split the controller into two memory regions.
>>
>> Links:
>> [1] https://lore.kernel.org/lkml/20240314232201.2102178-1-jan.dakinevich@salutedevices.com/
>> [2] https://lore.kernel.org/lkml/20240328010831.884487-1-jan.dakinevich@salutedevices.com/
>> [3] https://lore.kernel.org/lkml/20240419125812.983409-1-jan.dakinevich@salutedevices.com/
>> [4] https://lore.kernel.org/lkml/9a4377fe27d8eb940399e452b68fb5a6d678929f.camel@pengutronix.de/
>>
>> Jan Dakinevich (5):
>> reset: amlogic: add support for A1 SoC in auxiliary reset driver
>> clk: meson: axg: share the set of audio helper macro
>> dt-bindings: clock: axg-audio: document A1 SoC audio clock controller
>> driver
>> clk: meson: a1: add the audio clock controller driver
>> arm64: dts: meson: a1: add the audio clock controller
>>
>> .../clock/amlogic,axg-audio-clkc.yaml | 3 +
>> arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 48 +++
>> drivers/clk/meson/Kconfig | 14 +
>> drivers/clk/meson/Makefile | 3 +
>> drivers/clk/meson/a1-audio-clkc.c | 359 ++++++++++++++++++
>> drivers/clk/meson/a1-audio-drv.c | 104 +++++
>> drivers/clk/meson/a1-audio-vad-clkc.c | 85 +++++
>> drivers/clk/meson/a1-audio.h | 131 +++++++
>> drivers/clk/meson/axg-audio.c | 138 +------
>> drivers/clk/meson/meson-audio.h | 143 +++++++
>> drivers/reset/amlogic/reset-meson-aux.c | 9 +
>> .../dt-bindings/clock/amlogic,a1-audio-clkc.h | 122 ++++++
>> .../reset/amlogic,meson-a1-audio-reset.h | 29 ++
>> 13 files changed, 1051 insertions(+), 137 deletions(-)
>> create mode 100644 drivers/clk/meson/a1-audio-clkc.c
>> create mode 100644 drivers/clk/meson/a1-audio-drv.c
>> create mode 100644 drivers/clk/meson/a1-audio-vad-clkc.c
>> create mode 100644 drivers/clk/meson/a1-audio.h
>> create mode 100644 drivers/clk/meson/meson-audio.h
>> create mode 100644 include/dt-bindings/clock/amlogic,a1-audio-clkc.h
>> create mode 100644 include/dt-bindings/reset/amlogic,meson-a1-audio-reset.h
>
--
Best regards
Jan Dakinevich
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2024-10-24 5:20 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-13 12:11 [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
2024-09-13 12:11 ` [RFC PATCH v4 1/5] reset: amlogic: add support for A1 SoC in auxiliary reset driver Jan Dakinevich
2024-10-22 8:42 ` Jerome Brunet
2024-09-13 12:11 ` [RFC PATCH v4 2/5] clk: meson: axg: share the set of audio helper macro Jan Dakinevich
2024-09-13 12:11 ` [RFC PATCH v4 3/5] dt-bindings: clock: axg-audio: document A1 SoC audio clock controller driver Jan Dakinevich
2024-09-13 17:23 ` Conor Dooley
2024-10-22 8:45 ` Jerome Brunet
2024-10-24 4:48 ` Jan Dakinevich
2024-10-22 9:34 ` Jerome Brunet
2024-10-22 9:36 ` Jerome Brunet
2024-09-13 12:11 ` [RFC PATCH v4 4/5] clk: meson: a1: add the " Jan Dakinevich
2024-09-18 11:05 ` Jan Dakinevich
2024-10-22 9:47 ` Jerome Brunet
2024-10-24 5:15 ` Jan Dakinevich
2024-09-13 12:11 ` [RFC PATCH v4 5/5] arm64: dts: meson: a1: add the audio clock controller Jan Dakinevich
2024-10-07 14:59 ` [RFC PATCH v4 0/5] Add A1 Soc audio clock controller driver Jan Dakinevich
2024-10-22 9:51 ` Jerome Brunet
2024-10-24 5:18 ` Jan Dakinevich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).