* [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support
@ 2026-05-30 2:16 joakim.zhang
2026-05-30 2:16 ` [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller joakim.zhang
` (7 more replies)
0 siblings, 8 replies; 21+ messages in thread
From: joakim.zhang @ 2026-05-30 2:16 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
This series adds devicetree bindings, clock/reset drivers, and board
description for the Cix Sky1 Audio Subsystem (AUDSS).
The AUDSS groups audio-related peripherals (HDA, I2S, DSP-related clocks,
DMA, mailboxes, watchdog, timer, etc.) behind a single Clock and Reset Unit
(CRU) register block. Board software obtains the CRU MMIO range through a
cix,sky1-audss-cru syscon/MFD parent; clock mux/divider/gate and software
reset control are implemented as child providers that share the parent
regmap.
* Patch 1 describes the CRU parent (cix,sky1-audss-cru) and how clock and
reset child nodes hang off it.
* Patches 2-3 add the AUDSS clock binding, clock IDs, and the
cix,sky1-audss-clock driver.
* Patches 4-5 add the AUDSS reset binding, reset IDs, and the
cix,sky1-audss-reset driver.
* Patch 6 extends the existing cix,sky1-ipbloq-hda binding so boards can
supply a reserved memory-region for HDA DMA buffers.
* Patch 7 wires the AUDSS nodes into sky1.dtsi and enables clock, reset, and
HDA on the Radxa Orion O6 reference board.
Joakim Zhang (7):
dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller
dt-bindings: clock: cix,sky1-audss-clock: add audss clock controller
clk: cix: add sky1 audss clock controller
dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller
reset: cix: add sky1 audss reset controller
dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region
arm64: dts: cix: sky1: add audss device nodes
.../bindings/clock/cix,sky1-audss-clock.yaml | 86 ++
.../bindings/reset/cix,sky1-audss-reset.yaml | 50 +
.../bindings/soc/cix/cix,sky1-audss-cru.yaml | 72 ++
.../bindings/sound/cix,sky1-ipbloq-hda.yaml | 6 +
arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 34 +
arch/arm64/boot/dts/cix/sky1.dtsi | 56 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/cix/Kconfig | 17 +
drivers/clk/cix/Makefile | 3 +
drivers/clk/cix/clk-sky1-audss.c | 1123 +++++++++++++++++
drivers/reset/Kconfig | 10 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-sky1-audss.c | 172 +++
include/dt-bindings/clock/sky1-audss.h | 64 +
include/dt-bindings/reset/sky1-reset-audss.h | 29 +
16 files changed, 1725 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml
create mode 100644 Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
create mode 100644 Documentation/devicetree/bindings/soc/cix/cix,sky1-audss-cru.yaml
create mode 100644 drivers/clk/cix/Kconfig
create mode 100644 drivers/clk/cix/Makefile
create mode 100644 drivers/clk/cix/clk-sky1-audss.c
create mode 100644 drivers/reset/reset-sky1-audss.c
create mode 100644 include/dt-bindings/clock/sky1-audss.h
create mode 100644 include/dt-bindings/reset/sky1-reset-audss.h
--
2.50.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
@ 2026-05-30 2:16 ` joakim.zhang
2026-05-30 9:07 ` Krzysztof Kozlowski
2026-05-30 2:16 ` [PATCH v1 2/7] dt-bindings: clock: cix,sky1-audss-clock: add audss clock controller joakim.zhang
` (6 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: joakim.zhang @ 2026-05-30 2:16 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add devicetree schema for the Cix Sky1 audio subsystem CRU syscon/MFD
parent. Child clock-controller and reset-controller nodes are described
via references to the AUDSS clock and reset bindings.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
.../bindings/soc/cix/cix,sky1-audss-cru.yaml | 72 +++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/cix/cix,sky1-audss-cru.yaml
diff --git a/Documentation/devicetree/bindings/soc/cix/cix,sky1-audss-cru.yaml b/Documentation/devicetree/bindings/soc/cix/cix,sky1-audss-cru.yaml
new file mode 100644
index 000000000000..889e77fabcbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/cix/cix,sky1-audss-cru.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/cix/cix,sky1-audss-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cix Sky1 audio subsystem clock reset unit (CRU)
+
+maintainers:
+ - Joakim Zhang <joakim.zhang@cixtech.com>
+
+description: |
+ The Cix Sky1 audio subsystem (AUDSS) Clock Reset Unit (CRU) groups clock
+ mux/divider/gate and software reset control into one MMIO register block.
+
+ This binding describes the syscon/MFD parent. Board DTS must instantiate
+ a cix,sky1-audss-cru node with a reg property; clock and reset providers
+ are child nodes without their own reg ranges:
+
+ - cix,sky1-audss-clock (see cix,sky1-audss-clock.yaml)
+ - cix,sky1-audss-reset (see cix,sky1-audss-reset.yaml)
+
+properties:
+ compatible:
+ items:
+ - const: cix,sky1-audss-cru
+ - const: simple-mfd
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ clock-controller:
+ $ref: /schemas/clock/cix,sky1-audss-clock.yaml#
+ unevaluatedProperties: false
+
+ reset-controller:
+ $ref: /schemas/reset/cix,sky1-audss-reset.yaml#
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/cix,sky1.h>
+ #include <dt-bindings/reset/cix,sky1-s5-system-control.h>
+
+ cru: syscon@7110000 {
+ compatible = "cix,sky1-audss-cru", "simple-mfd", "syscon";
+ reg = <0x7110000 0x10000>;
+
+ audss_clk: clock-controller {
+ compatible = "cix,sky1-audss-clock";
+ power-domains = <&smc_devpd 0>;
+ #clock-cells = <1>;
+ clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>, <&scmi_clk CLK_TREE_AUDIO_CLK1>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK2>, <&scmi_clk CLK_TREE_AUDIO_CLK3>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK4>, <&scmi_clk CLK_TREE_AUDIO_CLK5>;
+ clock-names = "audio_clk0", "audio_clk1", "audio_clk2",
+ "audio_clk3", "audio_clk4", "audio_clk5";
+ resets = <&src SKY1_AUDIO_HIFI5_NOC_RESET_N>;
+ };
+
+ audss_rst: reset-controller {
+ compatible = "cix,sky1-audss-reset";
+ #reset-cells = <1>;
+ };
+ };
--
2.50.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 2/7] dt-bindings: clock: cix,sky1-audss-clock: add audss clock controller
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
2026-05-30 2:16 ` [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller joakim.zhang
@ 2026-05-30 2:16 ` joakim.zhang
2026-05-30 2:16 ` [PATCH v1 3/7] clk: cix: add sky1 " joakim.zhang
` (5 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: joakim.zhang @ 2026-05-30 2:16 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add schema and clock IDs for the Cix Sky1 audio subsystem (AUDSS)
clock controller.
The compatible string is cix,sky1-audss-clock. Clock indices are
defined in include/dt-bindings/clock/sky1-audss.h.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
.../bindings/clock/cix,sky1-audss-clock.yaml | 86 +++++++++++++++++++
include/dt-bindings/clock/sky1-audss.h | 64 ++++++++++++++
2 files changed, 150 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml
create mode 100644 include/dt-bindings/clock/sky1-audss.h
diff --git a/Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml b/Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml
new file mode 100644
index 000000000000..fb12c71381e7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/cix,sky1-audss-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cix Sky1 audio subsystem clock controller
+
+maintainers:
+ - Joakim Zhang <joakim.zhang@cixtech.com>
+
+description: |
+ Clock provider for the Cix Sky1 audio subsystem (AUDSS).
+
+ This node is a child of a cix,sky1-audss-cru MFD/syscon node (see
+ cix,sky1-audss-cru.yaml). It does not have a reg property; clock mux,
+ divider and gate fields are accessed through the parent CRU regmap.
+
+ Six SoC-level reference clocks listed in clocks/clock-names feed the AUDSS
+ clock tree. The provider exposes the internal AUDSS clocks to other devices
+ via #clock-cells; indices are defined in sky1-audss.h.
+
+properties:
+ compatible:
+ const: cix,sky1-audss-clock
+
+ '#clock-cells':
+ const: 1
+ description:
+ Clock indices are defined in include/dt-bindings/clock/sky1-audss.h.
+
+ clocks:
+ minItems: 6
+ maxItems: 6
+ description:
+ Six SoC-level audio reference clocks that feed the audio subsystem,
+ in the same order as clock-names.
+
+ clock-names:
+ items:
+ - const: audio_clk0
+ - const: audio_clk1
+ - const: audio_clk2
+ - const: audio_clk3
+ - const: audio_clk4
+ - const: audio_clk5
+
+ resets:
+ maxItems: 1
+ description: Audio subsystem NoC (or bus) reset line.
+
+ power-domains:
+ maxItems: 1
+ description: Audio subsystem power domain.
+
+required:
+ - compatible
+ - '#clock-cells'
+ - clocks
+ - clock-names
+ - resets
+ - power-domains
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/cix,sky1.h>
+ #include <dt-bindings/reset/cix,sky1-s5-system-control.h>
+
+ cru: syscon@7110000 {
+ compatible = "cix,sky1-audss-cru", "simple-mfd", "syscon";
+ reg = <0x7110000 0x10000>;
+
+ audss_clk: clock-controller {
+ compatible = "cix,sky1-audss-clock";
+ power-domains = <&smc_devpd 0>;
+ #clock-cells = <1>;
+ clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>, <&scmi_clk CLK_TREE_AUDIO_CLK1>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK2>, <&scmi_clk CLK_TREE_AUDIO_CLK3>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK4>, <&scmi_clk CLK_TREE_AUDIO_CLK5>;
+ clock-names = "audio_clk0", "audio_clk1", "audio_clk2",
+ "audio_clk3", "audio_clk4", "audio_clk5";
+ resets = <&src SKY1_AUDIO_HIFI5_NOC_RESET_N>;
+ };
+ };
diff --git a/include/dt-bindings/clock/sky1-audss.h b/include/dt-bindings/clock/sky1-audss.h
new file mode 100644
index 000000000000..5609b28db24b
--- /dev/null
+++ b/include/dt-bindings/clock/sky1-audss.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright 2026 Cix Technology Group Co., Ltd.
+ *
+ * This header provides constants for Cixtech Sky1 audio subsystem clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SKY1_AUDSS_H_
+#define _DT_BINDINGS_CLOCK_SKY1_AUDSS_H_
+
+#define CLK_AUD_CLK4_DIV2 0
+#define CLK_AUD_CLK4_DIV4 1
+#define CLK_AUD_CLK5_DIV2 2
+
+#define CLK_DSP_CLK 3
+#define CLK_DSP_BCLK 4
+#define CLK_DSP_PBCLK 5
+
+#define CLK_SRAM_AXI 6
+
+#define CLK_HDA_SYS 7
+#define CLK_HDA_HDA 8
+
+#define CLK_DMAC_AXI 9
+
+#define CLK_WDG_APB 10
+#define CLK_WDG_WDG 11
+
+#define CLK_TIMER_APB 12
+#define CLK_TIMER_TIMER 13
+
+#define CLK_MB_0_APB 14 /* MB0: ap->dsp */
+#define CLK_MB_1_APB 15 /* MB1: dsp->ap */
+
+#define CLK_I2S0_APB 16
+#define CLK_I2S1_APB 17
+#define CLK_I2S2_APB 18
+#define CLK_I2S3_APB 19
+#define CLK_I2S4_APB 20
+#define CLK_I2S5_APB 21
+#define CLK_I2S6_APB 22
+#define CLK_I2S7_APB 23
+#define CLK_I2S8_APB 24
+#define CLK_I2S9_APB 25
+#define CLK_I2S0 26
+#define CLK_I2S1 27
+#define CLK_I2S2 28
+#define CLK_I2S3 29
+#define CLK_I2S4 30
+#define CLK_I2S5 31
+#define CLK_I2S6 32
+#define CLK_I2S7 33
+#define CLK_I2S8 34
+#define CLK_I2S9 35
+
+#define CLK_MCLK0 36
+#define CLK_MCLK1 37
+#define CLK_MCLK2 38
+#define CLK_MCLK3 39
+#define CLK_MCLK4 40
+
+#define AUDSS_MAX_CLKS 41
+
+#endif
--
2.50.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 3/7] clk: cix: add sky1 audss clock controller
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
2026-05-30 2:16 ` [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller joakim.zhang
2026-05-30 2:16 ` [PATCH v1 2/7] dt-bindings: clock: cix,sky1-audss-clock: add audss clock controller joakim.zhang
@ 2026-05-30 2:16 ` joakim.zhang
2026-06-01 17:28 ` Brian Masney
2026-05-30 2:16 ` [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller joakim.zhang
` (4 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: joakim.zhang @ 2026-05-30 2:16 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add clock controller driver for the Cix Sky1 audio subsystem (AUDSS).
The driver controls mux, divider and gate clocks in the audio CRU via
the parent syscon regmap and registers clock outputs for audio IPs.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/cix/Kconfig | 17 +
drivers/clk/cix/Makefile | 3 +
drivers/clk/cix/clk-sky1-audss.c | 1123 ++++++++++++++++++++++++++++++
5 files changed, 1145 insertions(+)
create mode 100644 drivers/clk/cix/Kconfig
create mode 100644 drivers/clk/cix/Makefile
create mode 100644 drivers/clk/cix/clk-sky1-audss.c
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index b2efbe9f6acb..ead41e45c0f6 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -503,6 +503,7 @@ source "drivers/clk/actions/Kconfig"
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/aspeed/Kconfig"
source "drivers/clk/bcm/Kconfig"
+source "drivers/clk/cix/Kconfig"
source "drivers/clk/eswin/Kconfig"
source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/imgtec/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index a3e2862ebd7e..9135ea6e5a8f 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -118,6 +118,7 @@ obj-$(CONFIG_ARCH_ARTPEC) += axis/
obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
obj-y += bcm/
obj-$(CONFIG_ARCH_BERLIN) += berlin/
+obj-y += cix/
obj-$(CONFIG_ARCH_DAVINCI) += davinci/
obj-$(CONFIG_COMMON_CLK_ESWIN) += eswin/
obj-$(CONFIG_ARCH_HISI) += hisilicon/
diff --git a/drivers/clk/cix/Kconfig b/drivers/clk/cix/Kconfig
new file mode 100644
index 000000000000..d248f109c051
--- /dev/null
+++ b/drivers/clk/cix/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
+# Audio subsystem clock support for Cixtech SoC family
+menu "Clock support for Cixtech audss"
+
+comment "Clock options for Cixtech audss:"
+
+config CLK_SKY1_AUDSS
+ tristate "Cixtech Sky1 Audio Subsystem Clock Driver"
+ depends on ARCH_CIX || COMPILE_TEST
+ select REGMAP_MMIO
+ select RESET_CONTROLLER
+ help
+ Support for the Audio Subsystem clock controller present on
+ Cixtech Sky1 SoC. This driver provides mux, divider and gate
+ clocks for DSP, I2S, HDA and related blocks in the audio
+ subsystem. Say M or Y here if you want to build this driver.
+endmenu
diff --git a/drivers/clk/cix/Makefile b/drivers/clk/cix/Makefile
new file mode 100644
index 000000000000..bc612f1d08b2
--- /dev/null
+++ b/drivers/clk/cix/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_CLK_SKY1_AUDSS) += clk-sky1-audss.o
diff --git a/drivers/clk/cix/clk-sky1-audss.c b/drivers/clk/cix/clk-sky1-audss.c
new file mode 100644
index 000000000000..ab6ec7338ebe
--- /dev/null
+++ b/drivers/clk/cix/clk-sky1-audss.c
@@ -0,0 +1,1123 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2026 Cix Technology Group Co., Ltd.
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include <dt-bindings/clock/sky1-audss.h>
+
+#define INFO_HIFI0 0x00
+#define INFO_CLK_GATE 0x10
+#define INFO_CLK_DIV 0x14
+#define INFO_CLK_MUX 0x18
+#define INFO_MCLK 0x70
+
+#define SKY1_AUDSS_CLK_PARENTS_CNT 6
+#define AUDSS_CLK_PARENTS_MAX SKY1_AUDSS_CLK_PARENTS_CNT
+
+static u32 sky1_reg_save[][2] = {
+ { INFO_HIFI0, 0 },
+ { INFO_CLK_GATE, 0 },
+ { INFO_CLK_DIV, 0 },
+ { INFO_CLK_MUX, 0 },
+ { INFO_MCLK, 0 },
+};
+
+static const char *sky1_audss_clk_names[SKY1_AUDSS_CLK_PARENTS_CNT] = {
+ "audio_clk0", "audio_clk1", "audio_clk2",
+ "audio_clk3", "audio_clk4", "audio_clk5",
+};
+
+static const u32 sky1_clk_rate_default[SKY1_AUDSS_CLK_PARENTS_CNT] = {
+ 294912000,
+ 344064000,
+ 270950400,
+ 316108800,
+ 800000000,
+ 48000000,
+};
+
+static DEFINE_SPINLOCK(lock);
+static struct clk_hw_onecell_data *clk_data;
+
+static const char * const dsp_clk_parent[] = {
+ "audio_clk4"
+};
+
+static const char * const dsp_bclk_parent[] = {
+ "audio_clk4_div2"
+};
+
+static const char * const dsp_pbclk_parent[] = {
+ "audio_clk4_div4"
+};
+
+static const char * const sram_axi_parent[] = {
+ "audio_clk4_div2"
+};
+
+static const char * const hda_sys_parent[] = {
+ "audio_clk4_div2"
+};
+
+static const char * const hda_hda_parent[] = {
+ "audio_clk5"
+};
+
+static const char * const dmac_axi_parent[] = {
+ "audio_clk4_div2"
+};
+
+static const char * const wdg_apb_parent[] = {
+ "audio_clk5_div2"
+};
+
+static const char * const wdg_wdg_parent[] = {
+ "audio_clk5_div2"
+};
+
+static const char * const timer_apb_parent[] = {
+ "audio_clk4_div4"
+};
+
+static const char * const timer_timer_parent[] = {
+ "audio_clk5_div2"
+};
+
+static const char * const mailbox_apb_parent[] = {
+ "audio_clk4_div4"
+};
+
+static const char * const i2s_apb_parent[] = {
+ "audio_clk4_div4"
+};
+
+static const char * const i2s0_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+static const char * const i2s1_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+static const char * const i2s2_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+static const char * const i2s3_parents[] = {
+ "audio_clk0", "audio_clk1", "audio_clk2", "audio_clk3"
+};
+
+static const char * const i2s4_parents[] = {
+ "audio_clk0", "audio_clk1", "audio_clk2", "audio_clk3"
+};
+
+static const char * const i2s5_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+static const char * const i2s6_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+static const char * const i2s7_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+static const char * const i2s8_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+static const char * const i2s9_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+static const char * const mclk_parents[] = {
+ "audio_clk0", "audio_clk2"
+};
+
+/*
+ * audss composite clock definition
+ */
+struct muxdiv_cfg {
+ int offset;
+ u8 shift;
+ u8 width;
+ u8 flags;
+};
+
+struct gate_cfg {
+ int offset;
+ u8 shift;
+ u8 flags;
+};
+
+struct composite_clk_cfg {
+ u32 id;
+ const char *name;
+ const char * const *parent_names;
+ int num_parents;
+ struct muxdiv_cfg *mux_cfg;
+ struct muxdiv_cfg *div_cfg;
+ struct gate_cfg *gate_cfg;
+ unsigned long flags;
+};
+
+#define CFG(_id,\
+ _name,\
+ _parent_names,\
+ _mux_offset, _mux_shift, _mux_width, _mux_flags,\
+ _div_offset, _div_shift, _div_width, _div_flags,\
+ _gate_offset, _gate_shift, _gate_flags,\
+ _flags)\
+{\
+ .id = _id,\
+ .name = _name,\
+ .parent_names = _parent_names,\
+ .num_parents = ARRAY_SIZE(_parent_names),\
+ .mux_cfg = &(struct muxdiv_cfg) { _mux_offset, _mux_shift, _mux_width, _mux_flags },\
+ .div_cfg = &(struct muxdiv_cfg) { _div_offset, _div_shift, _div_width, _div_flags },\
+ .gate_cfg = &(struct gate_cfg) { _gate_offset, _gate_shift, _gate_flags },\
+ .flags = _flags,\
+}
+
+static const struct composite_clk_cfg sky1_audss_clks[] = {
+ /* dsp */
+ CFG(CLK_DSP_CLK,
+ "audss_dsp_clk",
+ dsp_clk_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_HIFI0, 0, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_DSP_BCLK,
+ "audss_dsp_bclk",
+ dsp_bclk_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ -1, 0, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_DSP_PBCLK,
+ "audss_dsp_pbclk",
+ dsp_pbclk_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ -1, 0, 0,
+ CLK_GET_RATE_NOCACHE),
+ /* sram */
+ CFG(CLK_SRAM_AXI,
+ "audss_sram_axi",
+ sram_axi_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 16, 0,
+ CLK_GET_RATE_NOCACHE),
+ /* hda */
+ CFG(CLK_HDA_SYS,
+ "audss_hda_sys",
+ hda_sys_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 14, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_HDA_HDA,
+ "audss_hda_hda",
+ hda_hda_parent,
+ -1, 0, 0, 0,
+ -1, 0, 0, 0,
+ INFO_CLK_GATE, 14, 0,
+ CLK_GET_RATE_NOCACHE),
+ /* dmac */
+ CFG(CLK_DMAC_AXI,
+ "audss_dmac_axi",
+ dmac_axi_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 15, 0,
+ CLK_GET_RATE_NOCACHE),
+ /* wdg */
+ CFG(CLK_WDG_APB,
+ "audss_wdg_apb",
+ wdg_apb_parent,
+ -1, 0, 0, 0,
+ -1, 0, 0, 0,
+ INFO_CLK_GATE, 10, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_WDG_WDG,
+ "audss_wdg_wdg",
+ wdg_wdg_parent,
+ -1, 0, 0, 0,
+ -1, 0, 0, 0,
+ INFO_CLK_GATE, 10, 0,
+ CLK_GET_RATE_NOCACHE),
+ /* timer */
+ CFG(CLK_TIMER_APB,
+ "audss_timer_apb",
+ timer_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 11, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_TIMER_TIMER,
+ "audss_timer_timer",
+ timer_timer_parent,
+ -1, 0, 0, 0,
+ -1, 0, 0, 0,
+ INFO_CLK_GATE, 11, 0,
+ CLK_GET_RATE_NOCACHE),
+ /* mailbox: mb0(ap->dsp), mb1(dsp->ap) */
+ CFG(CLK_MB_0_APB,
+ "audss_mb_0_apb",
+ mailbox_apb_parent,
+ -1, 0, 0, 0,
+ -1, 0, 0, 0,
+ INFO_CLK_GATE, 12, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_MB_1_APB,
+ "audss_mb_1_apb",
+ mailbox_apb_parent,
+ -1, 0, 0, 0,
+ -1, 0, 0, 0,
+ INFO_CLK_GATE, 13, 0,
+ CLK_GET_RATE_NOCACHE),
+ /* i2s */
+ CFG(CLK_I2S0_APB,
+ "audss_i2s0_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 0, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S1_APB,
+ "audss_i2s1_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 1, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S2_APB,
+ "audss_i2s2_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 2, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S3_APB,
+ "audss_i2s3_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 3, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S4_APB,
+ "audss_i2s4_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 4, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S5_APB,
+ "audss_i2s5_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 5, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S6_APB,
+ "audss_i2s6_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 6, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S7_APB,
+ "audss_i2s7_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 7, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S8_APB,
+ "audss_i2s8_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 8, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S9_APB,
+ "audss_i2s9_apb",
+ i2s_apb_parent,
+ -1, 0, 0, 0,
+ INFO_CLK_DIV, 0, 2, 0,
+ INFO_CLK_GATE, 9, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S0,
+ "audss_i2s0",
+ i2s0_parents,
+ INFO_CLK_MUX, 0, 2, 0,
+ INFO_CLK_DIV, 2, 2, 0,
+ INFO_CLK_GATE, 0, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S1,
+ "audss_i2s1",
+ i2s1_parents,
+ INFO_CLK_MUX, 2, 2, 0,
+ INFO_CLK_DIV, 4, 2, 0,
+ INFO_CLK_GATE, 1, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S2,
+ "audss_i2s2",
+ i2s2_parents,
+ INFO_CLK_MUX, 4, 2, 0,
+ INFO_CLK_DIV, 6, 2, 0,
+ INFO_CLK_GATE, 2, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S3,
+ "audss_i2s3",
+ i2s3_parents,
+ INFO_CLK_MUX, 6, 2, 0,
+ INFO_CLK_DIV, 8, 2, 0,
+ INFO_CLK_GATE, 3, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S4,
+ "audss_i2s4",
+ i2s4_parents,
+ INFO_CLK_MUX, 8, 2, 0,
+ INFO_CLK_DIV, 10, 2, 0,
+ INFO_CLK_GATE, 4, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S5,
+ "audss_i2s5",
+ i2s5_parents,
+ INFO_CLK_MUX, 10, 2, 0,
+ INFO_CLK_DIV, 12, 2, 0,
+ INFO_CLK_GATE, 5, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S6,
+ "audss_i2s6",
+ i2s6_parents,
+ INFO_CLK_MUX, 12, 2, 0,
+ INFO_CLK_DIV, 14, 2, 0,
+ INFO_CLK_GATE, 6, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S7,
+ "audss_i2s7",
+ i2s7_parents,
+ INFO_CLK_MUX, 14, 2, 0,
+ INFO_CLK_DIV, 16, 2, 0,
+ INFO_CLK_GATE, 7, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S8,
+ "audss_i2s8",
+ i2s8_parents,
+ INFO_CLK_MUX, 16, 2, 0,
+ INFO_CLK_DIV, 18, 2, 0,
+ INFO_CLK_GATE, 8, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_I2S9,
+ "audss_i2s9",
+ i2s9_parents,
+ INFO_CLK_MUX, 18, 2, 0,
+ INFO_CLK_DIV, 20, 2, 0,
+ INFO_CLK_GATE, 9, 0,
+ CLK_GET_RATE_NOCACHE),
+ /* mclk */
+ CFG(CLK_MCLK0,
+ "audss_mclk0",
+ mclk_parents,
+ INFO_MCLK, 5, 1, 0,
+ -1, 0, 0, 0,
+ INFO_MCLK, 0, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_MCLK1,
+ "audss_mclk1",
+ mclk_parents,
+ INFO_MCLK, 6, 1, 0,
+ -1, 0, 0, 0,
+ INFO_MCLK, 1, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_MCLK2,
+ "audss_mclk2",
+ mclk_parents,
+ INFO_MCLK, 7, 1, 0,
+ -1, 0, 0, 0,
+ INFO_MCLK, 2, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_MCLK3,
+ "audss_mclk3",
+ mclk_parents,
+ INFO_MCLK, 8, 1, 0,
+ -1, 0, 0, 0,
+ INFO_MCLK, 3, 0,
+ CLK_GET_RATE_NOCACHE),
+ CFG(CLK_MCLK4,
+ "audss_mclk4",
+ mclk_parents,
+ INFO_MCLK, 9, 1, 0,
+ -1, 0, 0, 0,
+ INFO_MCLK, 4, 0,
+ CLK_GET_RATE_NOCACHE),
+};
+
+struct sky1_audss_clks_devtype_data {
+ u32 (*reg_save)[2];
+ size_t reg_save_size;
+ const char **clk_names;
+ size_t clk_num;
+ const u32 *clk_rate_default;
+ const struct composite_clk_cfg *clk_cfg;
+ size_t clk_cfg_size;
+};
+
+struct sky1_audss_clks_priv {
+ struct device *dev;
+ struct regmap *regmap_cru;
+ struct clk *clks[AUDSS_CLK_PARENTS_MAX];
+ struct reset_control *rst_noc;
+ const struct sky1_audss_clks_devtype_data *devtype_data;
+};
+
+/*
+ * clk_ops for audss clock mux/divicer/gate
+ */
+struct sky1_clk_divider {
+ struct clk_divider div;
+ struct regmap *regmap;
+ int offset;
+};
+
+struct sky1_clk_gate {
+ struct clk_gate gate;
+ struct regmap *regmap;
+ int offset;
+};
+
+struct sky1_clk_mux {
+ struct clk_mux mux;
+ struct regmap *regmap;
+ int offset;
+};
+
+static inline struct sky1_clk_mux *to_sky1_clk_mux(struct clk_mux *mux)
+{
+ return container_of(mux, struct sky1_clk_mux, mux);
+}
+
+static u8 sky1_audss_clk_mux_get_parent(struct clk_hw *hw)
+{
+ struct clk_mux *mux = to_clk_mux(hw);
+ struct sky1_clk_mux *sky1_mux = to_sky1_clk_mux(mux);
+ u32 val;
+
+ regmap_read(sky1_mux->regmap, sky1_mux->offset, &val);
+ val = val >> mux->shift;
+ val &= mux->mask;
+
+ return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
+}
+
+static int sky1_audss_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_mux *mux = to_clk_mux(hw);
+ struct sky1_clk_mux *sky1_mux = to_sky1_clk_mux(mux);
+ u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
+ unsigned long flags = 0;
+ u32 reg;
+
+ if (mux->lock)
+ spin_lock_irqsave(mux->lock, flags);
+ else
+ __acquire(mux->lock);
+
+ if (mux->flags & CLK_MUX_HIWORD_MASK) {
+ reg = mux->mask << (mux->shift + 16);
+ } else {
+ regmap_read(sky1_mux->regmap, sky1_mux->offset, ®);
+ reg &= ~(mux->mask << mux->shift);
+ }
+ val = val << mux->shift;
+ reg |= val;
+ regmap_write(sky1_mux->regmap, sky1_mux->offset, reg);
+
+ if (mux->lock)
+ spin_unlock_irqrestore(mux->lock, flags);
+ else
+ __release(mux->lock);
+
+ return 0;
+}
+
+static int sky1_audss_clk_mux_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_mux *mux = to_clk_mux(hw);
+
+ return clk_mux_determine_rate_flags(hw, req, mux->flags);
+}
+
+static const struct clk_ops sky1_audss_clk_mux_ops = {
+ .get_parent = sky1_audss_clk_mux_get_parent,
+ .set_parent = sky1_audss_clk_mux_set_parent,
+ .determine_rate = sky1_audss_clk_mux_determine_rate,
+};
+
+static inline struct sky1_clk_divider *to_sky1_clk_divider(struct clk_divider *div)
+{
+ return container_of(div, struct sky1_clk_divider, div);
+}
+
+static unsigned long sky1_audss_clk_divider_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+ struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider);
+ unsigned int val;
+
+ regmap_read(sky1_div->regmap, sky1_div->offset, &val);
+ val = val >> divider->shift;
+ val &= clk_div_mask(divider->width);
+
+ return divider_recalc_rate(hw, parent_rate, val, divider->table,
+ divider->flags, divider->width);
+}
+
+static int sky1_audss_clk_divider_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+ struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider);
+
+ /* if read only, just return current value */
+ if (divider->flags & CLK_DIVIDER_READ_ONLY) {
+ u32 val;
+
+ regmap_read(sky1_div->regmap, sky1_div->offset, &val);
+ val = val >> divider->shift;
+ val &= clk_div_mask(divider->width);
+
+ return divider_ro_determine_rate(hw, req, divider->table,
+ divider->width,
+ divider->flags, val);
+ }
+
+ return divider_determine_rate(hw, req, divider->table, divider->width,
+ divider->flags);
+}
+
+static int sky1_audss_clk_divider_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+ struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider);
+ int value;
+ unsigned long flags = 0;
+ u32 val;
+
+ value = divider_get_val(rate, parent_rate, divider->table,
+ divider->width, divider->flags);
+ if (value < 0)
+ return value;
+
+ if (divider->lock)
+ spin_lock_irqsave(divider->lock, flags);
+ else
+ __acquire(divider->lock);
+
+ if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
+ val = clk_div_mask(divider->width) << (divider->shift + 16);
+ } else {
+ regmap_read(sky1_div->regmap, sky1_div->offset, &val);
+ val &= ~(clk_div_mask(divider->width) << divider->shift);
+ }
+ val |= (u32)value << divider->shift;
+ regmap_write(sky1_div->regmap, sky1_div->offset, val);
+
+ if (divider->lock)
+ spin_unlock_irqrestore(divider->lock, flags);
+ else
+ __release(divider->lock);
+
+ return 0;
+}
+
+static const struct clk_ops sky1_audss_clk_divider_ops = {
+ .recalc_rate = sky1_audss_clk_divider_recalc_rate,
+ .determine_rate = sky1_audss_clk_divider_determine_rate,
+ .set_rate = sky1_audss_clk_divider_set_rate,
+};
+
+static inline struct sky1_clk_gate *to_sky1_clk_gate(struct clk_gate *gate)
+{
+ return container_of(gate, struct sky1_clk_gate, gate);
+}
+
+static void sky1_audss_clk_gate_endisable(struct clk_hw *hw, int enable)
+{
+ struct clk_gate *gate = to_clk_gate(hw);
+ struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate);
+ int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
+ unsigned long flags;
+ u32 reg;
+
+ set ^= enable;
+
+ if (gate->lock)
+ spin_lock_irqsave(gate->lock, flags);
+ else
+ __acquire(gate->lock);
+
+ if (gate->flags & CLK_GATE_HIWORD_MASK) {
+ reg = BIT(gate->bit_idx + 16);
+ if (set)
+ reg |= BIT(gate->bit_idx);
+ } else {
+ regmap_read(sky1_gate->regmap, sky1_gate->offset, ®);
+
+ if (set)
+ reg |= BIT(gate->bit_idx);
+ else
+ reg &= ~BIT(gate->bit_idx);
+ }
+
+ regmap_write(sky1_gate->regmap, sky1_gate->offset, reg);
+
+ if (gate->lock)
+ spin_unlock_irqrestore(gate->lock, flags);
+ else
+ __release(gate->lock);
+}
+
+static int sky1_audss_clk_gate_enable(struct clk_hw *hw)
+{
+ sky1_audss_clk_gate_endisable(hw, 1);
+
+ return 0;
+}
+
+static void sky1_audss_clk_gate_disable(struct clk_hw *hw)
+{
+ sky1_audss_clk_gate_endisable(hw, 0);
+}
+
+static int sky1_audss_clk_gate_is_enabled(struct clk_hw *hw)
+{
+ u32 reg;
+ struct clk_gate *gate = to_clk_gate(hw);
+ struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate);
+
+ regmap_read(sky1_gate->regmap, sky1_gate->offset, ®);
+
+ /* if a set bit disables this clk, flip it before masking */
+ if (gate->flags & CLK_GATE_SET_TO_DISABLE)
+ reg ^= BIT(gate->bit_idx);
+
+ reg &= BIT(gate->bit_idx);
+
+ return reg ? 1 : 0;
+}
+
+static const struct clk_ops sky1_audss_clk_gate_ops = {
+ .enable = sky1_audss_clk_gate_enable,
+ .disable = sky1_audss_clk_gate_disable,
+ .is_enabled = sky1_audss_clk_gate_is_enabled,
+};
+
+static struct clk_hw *sky1_audss_clk_register(struct device *dev,
+ const char *name,
+ const char * const *parent_names,
+ int num_parents,
+ struct regmap *regmap,
+ struct muxdiv_cfg *mux_cfg,
+ struct muxdiv_cfg *div_cfg,
+ struct gate_cfg *gate_cfg,
+ unsigned long flags,
+ spinlock_t *lock)
+{
+ const struct clk_ops *sky1_mux_ops = NULL;
+ const struct clk_ops *sky1_div_ops = NULL;
+ const struct clk_ops *sky1_gate_ops = NULL;
+ struct clk_hw *hw = ERR_PTR(-ENOMEM);
+ struct sky1_clk_divider *sky1_div = NULL;
+ struct sky1_clk_gate *sky1_gate = NULL;
+ struct sky1_clk_mux *sky1_mux = NULL;
+
+ if (mux_cfg->offset >= 0) {
+ sky1_mux = devm_kzalloc(dev, sizeof(*sky1_mux), GFP_KERNEL);
+ if (!sky1_mux)
+ return ERR_PTR(-ENOMEM);
+
+ sky1_mux->mux.reg = NULL;
+ sky1_mux->mux.shift = mux_cfg->shift;
+ sky1_mux->mux.mask = BIT(mux_cfg->width) - 1;
+ sky1_mux->mux.flags = mux_cfg->flags;
+ sky1_mux->mux.lock = lock;
+ sky1_mux_ops = &sky1_audss_clk_mux_ops;
+ sky1_mux->regmap = regmap;
+ sky1_mux->offset = mux_cfg->offset;
+ }
+
+ if (div_cfg->offset >= 0) {
+ sky1_div = devm_kzalloc(dev, sizeof(*sky1_div), GFP_KERNEL);
+ if (!sky1_div)
+ return ERR_PTR(-ENOMEM);
+
+ sky1_div->div.reg = NULL;
+ sky1_div->div.shift = div_cfg->shift;
+ sky1_div->div.width = div_cfg->width;
+ sky1_div->div.flags = div_cfg->flags | CLK_DIVIDER_POWER_OF_TWO;
+ sky1_div->div.lock = lock;
+ sky1_div_ops = &sky1_audss_clk_divider_ops;
+ sky1_div->regmap = regmap;
+ sky1_div->offset = div_cfg->offset;
+ }
+
+ if (gate_cfg->offset >= 0) {
+ sky1_gate = devm_kzalloc(dev, sizeof(*sky1_gate), GFP_KERNEL);
+ if (!sky1_gate)
+ return ERR_PTR(-ENOMEM);
+
+ sky1_gate->gate.reg = NULL;
+ sky1_gate->gate.bit_idx = gate_cfg->shift;
+ sky1_gate->gate.flags = gate_cfg->flags;
+ sky1_gate->gate.lock = lock;
+ sky1_gate_ops = &sky1_audss_clk_gate_ops;
+ sky1_gate->regmap = regmap;
+ sky1_gate->offset = gate_cfg->offset;
+ }
+
+ hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
+ sky1_mux ? &sky1_mux->mux.hw : NULL, sky1_mux_ops,
+ sky1_div ? &sky1_div->div.hw : NULL, sky1_div_ops,
+ sky1_gate ? &sky1_gate->gate.hw : NULL, sky1_gate_ops,
+ flags);
+ if (IS_ERR(hw)) {
+ dev_err(dev, "register %s clock failed with err = %ld\n",
+ name, PTR_ERR(hw));
+ return ERR_CAST(hw);
+ }
+
+ return hw;
+}
+
+static int sky1_audss_clks_get(struct sky1_audss_clks_priv *priv)
+{
+ const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
+ int i;
+
+ for (i = 0; i < devtype_data->clk_num; i++) {
+ priv->clks[i] = devm_clk_get(priv->dev, devtype_data->clk_names[i]);
+ if (IS_ERR(priv->clks[i]))
+ return dev_err_probe(priv->dev, PTR_ERR(priv->clks[i]),
+ "failed to get clock %s", devtype_data->clk_names[i]);
+ }
+
+ return 0;
+}
+
+static int sky1_audss_clks_enable(struct sky1_audss_clks_priv *priv)
+{
+ const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
+ int i, err;
+
+ for (i = 0; i < devtype_data->clk_num; i++) {
+ err = clk_prepare_enable(priv->clks[i]);
+ if (err) {
+ dev_err(priv->dev, "failed to enable clock %s\n",
+ devtype_data->clk_names[i]);
+ goto err_clks;
+ }
+ }
+
+ return 0;
+
+err_clks:
+ while (--i >= 0)
+ clk_disable_unprepare(priv->clks[i]);
+
+ return err;
+}
+
+static void sky1_audss_clks_disable(struct sky1_audss_clks_priv *priv)
+{
+ const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
+ int i;
+
+ for (i = 0; i < devtype_data->clk_num; i++)
+ clk_disable_unprepare(priv->clks[i]);
+}
+
+static int sky1_audss_clks_set_rate(struct sky1_audss_clks_priv *priv)
+{
+ const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
+ int i, err;
+
+ for (i = 0; i < devtype_data->clk_num; i++) {
+ err = clk_set_rate(priv->clks[i], devtype_data->clk_rate_default[i]);
+ if (err) {
+ dev_err(priv->dev, "failed to set clock rate %s\n",
+ devtype_data->clk_names[i]);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/* register sky1 audio subsystem clocks */
+static int sky1_audss_clk_probe(struct platform_device *pdev)
+{
+ const struct sky1_audss_clks_devtype_data *devtype_data;
+ struct sky1_audss_clks_priv *priv;
+ struct device_node *parent_np;
+ struct device *dev = &pdev->dev;
+ struct reset_control *rst_noc;
+ struct clk_hw **clk_table;
+ struct regmap *regmap_cru;
+ int i, ret;
+
+ parent_np = of_get_parent(pdev->dev.of_node);
+ regmap_cru = syscon_node_to_regmap(parent_np);
+ of_node_put(parent_np);
+ if (IS_ERR(regmap_cru))
+ return dev_err_probe(dev, PTR_ERR(regmap_cru),
+ "unable to get audss cru regmap");
+
+ devtype_data = of_device_get_match_data(dev);
+ if (!devtype_data)
+ return -ENODEV;
+
+ clk_data = devm_kzalloc(&pdev->dev,
+ struct_size(clk_data, hws, AUDSS_MAX_CLKS),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->num = AUDSS_MAX_CLKS;
+ clk_table = clk_data->hws;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = dev;
+ priv->regmap_cru = regmap_cru;
+ priv->devtype_data = devtype_data;
+
+ ret = sky1_audss_clks_get(priv);
+ if (ret)
+ return ret;
+
+ rst_noc = devm_reset_control_get(dev, NULL);
+ if (IS_ERR(rst_noc))
+ return dev_err_probe(dev, PTR_ERR(rst_noc),
+ "failed to get noc reset");
+ priv->rst_noc = rst_noc;
+
+ platform_set_drvdata(pdev, priv);
+
+ /*
+ * Enable runtime PM here to allow the clock core using runtime PM
+ * for the registered clocks.
+ */
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ ret = sky1_audss_clks_enable(priv);
+ if (ret) {
+ dev_err(dev, "failed to enable clocks\n");
+ goto fail_clks_enable;
+ }
+
+ ret = sky1_audss_clks_set_rate(priv);
+ if (ret) {
+ dev_err(dev, "failed to set clocks rate\n");
+ goto fail_clks_set;
+ }
+
+ /* assert reset */
+ reset_control_assert(rst_noc);
+ usleep_range(1, 2);
+
+ /* deassert reset */
+ reset_control_deassert(rst_noc);
+
+ /* audio_clk4 clock fixed divider */
+ clk_table[CLK_AUD_CLK4_DIV2] =
+ devm_clk_hw_register_fixed_factor(dev,
+ "audio_clk4_div2",
+ "audio_clk4",
+ CLK_GET_RATE_NOCACHE,
+ 1, 2);
+ if (IS_ERR(clk_table[CLK_AUD_CLK4_DIV2])) {
+ ret = PTR_ERR(clk_table[CLK_AUD_CLK4_DIV2]);
+ dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK4_DIV2, ret);
+ goto fail_fixed_clk;
+ }
+
+ clk_table[CLK_AUD_CLK4_DIV4] =
+ devm_clk_hw_register_fixed_factor(dev,
+ "audio_clk4_div4",
+ "audio_clk4",
+ CLK_GET_RATE_NOCACHE,
+ 1, 4);
+ if (IS_ERR(clk_table[CLK_AUD_CLK4_DIV4])) {
+ ret = PTR_ERR(clk_table[CLK_AUD_CLK4_DIV4]);
+ dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK4_DIV4, ret);
+ goto fail_fixed_clk;
+ }
+
+ /* audio_clk5 clock fixed divider */
+ clk_table[CLK_AUD_CLK5_DIV2] =
+ devm_clk_hw_register_fixed_factor(dev,
+ "audio_clk5_div2",
+ "audio_clk5",
+ CLK_GET_RATE_NOCACHE,
+ 1, 2);
+ if (IS_ERR(clk_table[CLK_AUD_CLK5_DIV2])) {
+ ret = PTR_ERR(clk_table[CLK_AUD_CLK5_DIV2]);
+ dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK5_DIV2, ret);
+ goto fail_fixed_clk;
+ }
+
+ for (i = 0; i < devtype_data->clk_cfg_size; i++) {
+ clk_table[devtype_data->clk_cfg[i].id] =
+ sky1_audss_clk_register(dev,
+ devtype_data->clk_cfg[i].name,
+ devtype_data->clk_cfg[i].parent_names,
+ devtype_data->clk_cfg[i].num_parents,
+ regmap_cru,
+ devtype_data->clk_cfg[i].mux_cfg,
+ devtype_data->clk_cfg[i].div_cfg,
+ devtype_data->clk_cfg[i].gate_cfg,
+ devtype_data->clk_cfg[i].flags,
+ &lock);
+ if (IS_ERR(clk_table[devtype_data->clk_cfg[i].id])) {
+ ret = PTR_ERR(clk_table[devtype_data->clk_cfg[i].id]);
+ dev_err(dev, "failed to register clock %d, ret:%d\n",
+ devtype_data->clk_cfg[i].id, ret);
+ goto fail_array_clk;
+ }
+ }
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+ if (ret) {
+ dev_err(dev, "failed to add clock provider: %d\n", ret);
+ goto fail_register;
+ }
+
+ pm_runtime_put_sync(dev);
+
+ return 0;
+
+fail_register:
+fail_array_clk:
+ while (i--)
+ clk_hw_unregister_composite(clk_table[devtype_data->clk_cfg[i].id]);
+fail_fixed_clk:
+fail_clks_set:
+ pm_runtime_put_sync(dev);
+fail_clks_enable:
+ pm_runtime_disable(dev);
+ return ret;
+}
+
+static void sky1_audss_clk_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev);
+ const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
+ int i = 0;
+
+ for (i = 0; i < devtype_data->clk_cfg_size; i++)
+ clk_hw_unregister_composite(clk_data->hws[devtype_data->clk_cfg[i].id]);
+
+ if (!pm_runtime_status_suspended(dev))
+ pm_runtime_force_suspend(dev);
+
+ pm_runtime_disable(dev);
+}
+
+static int __maybe_unused sky1_audss_clk_runtime_suspend(struct device *dev)
+{
+ struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev);
+ const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
+ int i;
+
+ for (i = 0; i < devtype_data->reg_save_size; i++)
+ regmap_read(priv->regmap_cru,
+ devtype_data->reg_save[i][0], &devtype_data->reg_save[i][1]);
+
+ sky1_audss_clks_disable(priv);
+
+ return 0;
+}
+
+static int __maybe_unused sky1_audss_clk_runtime_resume(struct device *dev)
+{
+ struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev);
+ const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
+ int i, ret;
+
+ ret = sky1_audss_clks_enable(priv);
+ if (ret) {
+ dev_err(dev, "failed to enable clocks\n");
+ return ret;
+ }
+
+ reset_control_deassert(priv->rst_noc);
+
+ for (i = 0; i < priv->devtype_data->reg_save_size; i++)
+ regmap_write(priv->regmap_cru,
+ devtype_data->reg_save[i][0], devtype_data->reg_save[i][1]);
+
+ return 0;
+}
+
+static const struct dev_pm_ops sky1_audss_clk_pm_ops = {
+ SET_RUNTIME_PM_OPS(sky1_audss_clk_runtime_suspend,
+ sky1_audss_clk_runtime_resume, NULL)
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+};
+
+static const struct sky1_audss_clks_devtype_data sky1_devtype_data = {
+ .reg_save = sky1_reg_save,
+ .reg_save_size = ARRAY_SIZE(sky1_reg_save),
+ .clk_names = sky1_audss_clk_names,
+ .clk_num = ARRAY_SIZE(sky1_audss_clk_names),
+ .clk_rate_default = sky1_clk_rate_default,
+ .clk_cfg = sky1_audss_clks,
+ .clk_cfg_size = ARRAY_SIZE(sky1_audss_clks),
+};
+
+static const struct of_device_id sky1_audss_clk_of_match[] = {
+ { .compatible = "cix,sky1-audss-clock", .data = &sky1_devtype_data, },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sky1_audss_clk_of_match);
+
+static struct platform_driver sky1_audss_clk_driver = {
+ .probe = sky1_audss_clk_probe,
+ .remove = sky1_audss_clk_remove,
+ .driver = {
+ .name = "sky1-audss-clk",
+ .suppress_bind_attrs = true,
+ .of_match_table = sky1_audss_clk_of_match,
+ .pm = &sky1_audss_clk_pm_ops,
+ },
+};
+module_platform_driver(sky1_audss_clk_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Joakim Zhang <joakim.zhang@cixtech.com>");
+MODULE_DESCRIPTION("Cixtech Sky1 Audio Subsystem Clock Controller Driver");
--
2.50.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
` (2 preceding siblings ...)
2026-05-30 2:16 ` [PATCH v1 3/7] clk: cix: add sky1 " joakim.zhang
@ 2026-05-30 2:16 ` joakim.zhang
2026-05-30 9:11 ` Krzysztof Kozlowski
2026-05-30 2:16 ` [PATCH v1 5/7] reset: cix: add sky1 audss " joakim.zhang
` (3 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: joakim.zhang @ 2026-05-30 2:16 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add schema and reset IDs for the Cix Sky1 audio subsystem (AUDSS)
reset controller.
The compatible string is cix,sky1-audss-reset. Reset indices are
defined in include/dt-bindings/reset/sky1-reset-audss.h.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
.../bindings/reset/cix,sky1-audss-reset.yaml | 50 +++++++++++++++++++
include/dt-bindings/reset/sky1-reset-audss.h | 29 +++++++++++
2 files changed, 79 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
create mode 100644 include/dt-bindings/reset/sky1-reset-audss.h
diff --git a/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml b/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
new file mode 100644
index 000000000000..8e02ddd2517d
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/cix,sky1-audss-reset.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cix Sky1 audio subsystem reset controller
+
+maintainers:
+ - Joakim Zhang <joakim.zhang@cixtech.com>
+
+description: |
+ Reset provider for the Cix Sky1 audio subsystem (AUDSS).
+
+ This node is a child of a cix,sky1-audss-cru MFD/syscon node (see
+ cix,sky1-audss-cru.yaml). It does not have a reg property; software reset
+ bits are accessed through the parent CRU regmap.
+
+ Each #reset-cells index maps to a software reset line for an AUDSS block
+ (I2S, HDA, DMA, mailbox, watchdog, timer, etc.). Indices are defined in
+ sky1-reset-audss.h.
+
+properties:
+ compatible:
+ const: cix,sky1-audss-reset
+
+ '#reset-cells':
+ const: 1
+ description:
+ Reset indices are defined in include/dt-bindings/reset/sky1-reset-audss.h.
+
+required:
+ - compatible
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/reset/sky1-reset-audss.h>
+
+ cru: syscon@7110000 {
+ compatible = "cix,sky1-audss-cru", "simple-mfd", "syscon";
+ reg = <0x7110000 0x10000>;
+
+ audss_rst: reset-controller {
+ compatible = "cix,sky1-audss-reset";
+ #reset-cells = <1>;
+ };
+ };
diff --git a/include/dt-bindings/reset/sky1-reset-audss.h b/include/dt-bindings/reset/sky1-reset-audss.h
new file mode 100644
index 000000000000..7f1cf36d45e5
--- /dev/null
+++ b/include/dt-bindings/reset/sky1-reset-audss.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright 2026 Cix Technology Group Co., Ltd.
+ *
+ * This header provides constants for Cixtech Sky1 audio subsystem reset controller.
+ */
+#ifndef DT_BINDING_RESET_AUDSS_SKY1_H
+#define DT_BINDING_RESET_AUDSS_SKY1_H
+
+#define AUDSS_I2S0_SW_RST_N 0
+#define AUDSS_I2S1_SW_RST_N 1
+#define AUDSS_I2S2_SW_RST_N 2
+#define AUDSS_I2S3_SW_RST_N 3
+#define AUDSS_I2S4_SW_RST_N 4
+#define AUDSS_I2S5_SW_RST_N 5
+#define AUDSS_I2S6_SW_RST_N 6
+#define AUDSS_I2S7_SW_RST_N 7
+#define AUDSS_I2S8_SW_RST_N 8
+#define AUDSS_I2S9_SW_RST_N 9
+#define AUDSS_WDT_SW_RST_N 10
+#define AUDSS_TIMER_SW_RST_N 11
+#define AUDSS_MB0_SW_RST_N 12
+#define AUDSS_MB1_SW_RST_N 13
+#define AUDSS_HDA_SW_RST_N 14
+#define AUDSS_DMAC_SW_RST_N 15
+
+#define SKY1_AUDSS_SW_RESET_NUM 16
+
+#endif
--
2.50.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 5/7] reset: cix: add sky1 audss reset controller
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
` (3 preceding siblings ...)
2026-05-30 2:16 ` [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller joakim.zhang
@ 2026-05-30 2:16 ` joakim.zhang
2026-05-30 2:16 ` [PATCH v1 6/7] dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region joakim.zhang
` (2 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: joakim.zhang @ 2026-05-30 2:16 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add reset controller driver for the Cix Sky1 audio subsystem (AUDSS).
The driver controls software reset bits in the audio CRU register block
via the parent syscon regmap and registers a reset controller for SoC
audio IP consumers.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
drivers/reset/Kconfig | 10 ++
drivers/reset/Makefile | 1 +
drivers/reset/reset-sky1-audss.c | 172 +++++++++++++++++++++++++++++++
3 files changed, 183 insertions(+)
create mode 100644 drivers/reset/reset-sky1-audss.c
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index d009eb0849a3..a3fefcdffb37 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -300,6 +300,16 @@ config RESET_SKY1
help
This enables the reset controller for Cix Sky1.
+config RESET_SKY1_AUDSS
+ tristate "Cix Sky1 Audio Subsystem reset controller"
+ depends on ARCH_CIX || COMPILE_TEST
+ select REGMAP_MMIO
+ help
+ Support for the Audio Subsystem reset controller present on
+ Cixtech Sky1 SoC. This driver exposes software reset lines for
+ I2S, HDA, DMA, mailbox and related blocks in the audio CRU.
+ Say M or Y here if you want to build this driver.
+
config RESET_SOCFPGA
bool "SoCFPGA Reset Driver" if COMPILE_TEST && (!ARM || !ARCH_INTEL_SOCFPGA)
default ARM && ARCH_INTEL_SOCFPGA
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 3e52569bd276..e81407ea3e29 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_RESET_RZV2H_USB2PHY) += reset-rzv2h-usb2phy.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
obj-$(CONFIG_RESET_SKY1) += reset-sky1.o
+obj-$(CONFIG_RESET_SKY1_AUDSS) += reset-sky1-audss.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
diff --git a/drivers/reset/reset-sky1-audss.c b/drivers/reset/reset-sky1-audss.c
new file mode 100644
index 000000000000..c18cb4e1a61e
--- /dev/null
+++ b/drivers/reset/reset-sky1-audss.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2026 Cix Technology Group Co., Ltd.
+
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/reset/sky1-reset-audss.h>
+
+#define SKY1_RESET_SLEEP_MIN_US 50
+#define SKY1_RESET_SLEEP_MAX_US 100
+
+struct sky1_audss_signal {
+ unsigned int offset;
+ unsigned int bit;
+};
+
+struct sky1_audss_variant {
+ const struct sky1_audss_signal *signals;
+ unsigned int signals_num;
+};
+
+struct sky1_audss {
+ struct reset_controller_dev rcdev;
+ const struct sky1_audss_signal *signals;
+ struct regmap *regmap;
+};
+
+enum {
+ AUDSS_SW_RST = 0x78,
+};
+
+static const struct sky1_audss_signal sky1_audss_signals[SKY1_AUDSS_SW_RESET_NUM] = {
+ [AUDSS_I2S0_SW_RST_N] = { AUDSS_SW_RST, BIT(0) },
+ [AUDSS_I2S1_SW_RST_N] = { AUDSS_SW_RST, BIT(1) },
+ [AUDSS_I2S2_SW_RST_N] = { AUDSS_SW_RST, BIT(2) },
+ [AUDSS_I2S3_SW_RST_N] = { AUDSS_SW_RST, BIT(3) },
+ [AUDSS_I2S4_SW_RST_N] = { AUDSS_SW_RST, BIT(4) },
+ [AUDSS_I2S5_SW_RST_N] = { AUDSS_SW_RST, BIT(5) },
+ [AUDSS_I2S6_SW_RST_N] = { AUDSS_SW_RST, BIT(6) },
+ [AUDSS_I2S7_SW_RST_N] = { AUDSS_SW_RST, BIT(7) },
+ [AUDSS_I2S8_SW_RST_N] = { AUDSS_SW_RST, BIT(8) },
+ [AUDSS_I2S9_SW_RST_N] = { AUDSS_SW_RST, BIT(9) },
+ [AUDSS_WDT_SW_RST_N] = { AUDSS_SW_RST, BIT(10) },
+ [AUDSS_TIMER_SW_RST_N] = { AUDSS_SW_RST, BIT(11) },
+ [AUDSS_MB0_SW_RST_N] = { AUDSS_SW_RST, BIT(12) },
+ [AUDSS_MB1_SW_RST_N] = { AUDSS_SW_RST, BIT(13) },
+ [AUDSS_HDA_SW_RST_N] = { AUDSS_SW_RST, BIT(14) },
+ [AUDSS_DMAC_SW_RST_N] = { AUDSS_SW_RST, BIT(15) },
+};
+
+static const struct sky1_audss_variant variant_sky1_audss = {
+ .signals = sky1_audss_signals,
+ .signals_num = ARRAY_SIZE(sky1_audss_signals),
+};
+
+static struct sky1_audss *to_sky1_audss(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct sky1_audss, rcdev);
+}
+
+static int sky1_reset_set(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ struct sky1_audss *sky1rst = to_sky1_audss(rcdev);
+ const struct sky1_audss_signal *signal = &sky1rst->signals[id];
+ unsigned int value = assert ? 0 : signal->bit;
+
+ return regmap_update_bits(sky1rst->regmap,
+ signal->offset, signal->bit, value);
+}
+
+static int sky1_audss_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ sky1_reset_set(rcdev, id, true);
+ usleep_range(SKY1_RESET_SLEEP_MIN_US,
+ SKY1_RESET_SLEEP_MAX_US);
+ return 0;
+}
+
+static int sky1_audss_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ sky1_reset_set(rcdev, id, false);
+ usleep_range(SKY1_RESET_SLEEP_MIN_US,
+ SKY1_RESET_SLEEP_MAX_US);
+ return 0;
+}
+
+static int sky1_audss_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ sky1_audss_reset_assert(rcdev, id);
+ sky1_audss_reset_deassert(rcdev, id);
+ return 0;
+}
+
+static int sky1_audss_reset_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ unsigned int value = 0;
+ struct sky1_audss *sky1rst = to_sky1_audss(rcdev);
+ const struct sky1_audss_signal *signal = &sky1rst->signals[id];
+
+ regmap_read(sky1rst->regmap, signal->offset, &value);
+ return !(value & signal->bit);
+}
+
+static const struct reset_control_ops sky1_audss_ops = {
+ .reset = sky1_audss_reset,
+ .assert = sky1_audss_reset_assert,
+ .deassert = sky1_audss_reset_deassert,
+ .status = sky1_audss_reset_status
+};
+
+static int sky1_audss_reset_probe(struct platform_device *pdev)
+{
+ const struct sky1_audss_variant *variant;
+ struct device *dev = &pdev->dev;
+ struct sky1_audss *sky1rst;
+ struct device_node *parent_np;
+ struct regmap *regmap_cru;
+
+ parent_np = of_get_parent(pdev->dev.of_node);
+ regmap_cru = syscon_node_to_regmap(parent_np);
+ of_node_put(parent_np);
+ if (IS_ERR(regmap_cru))
+ return dev_err_probe(dev, PTR_ERR(regmap_cru),
+ "unable to get audss_cru regmap");
+
+ sky1rst = devm_kzalloc(dev, sizeof(*sky1rst), GFP_KERNEL);
+ if (!sky1rst)
+ return -ENOMEM;
+
+ variant = of_device_get_match_data(dev);
+ if (!variant)
+ return -ENODEV;
+
+ sky1rst->regmap = regmap_cru;
+ sky1rst->signals = variant->signals;
+ sky1rst->rcdev.owner = THIS_MODULE;
+ sky1rst->rcdev.nr_resets = variant->signals_num;
+ sky1rst->rcdev.ops = &sky1_audss_ops;
+ sky1rst->rcdev.of_node = dev->of_node;
+ sky1rst->rcdev.dev = dev;
+
+ return devm_reset_controller_register(dev, &sky1rst->rcdev);
+}
+
+static const struct of_device_id sky1_audss_reset_of_match[] = {
+ { .compatible = "cix,sky1-audss-reset", .data = &variant_sky1_audss},
+ {},
+};
+MODULE_DEVICE_TABLE(of, sky1_audss_reset_of_match);
+
+static struct platform_driver sky1_audss_reset_driver = {
+ .probe = sky1_audss_reset_probe,
+ .driver = {
+ .name = "sky1-audss-rst",
+ .of_match_table = sky1_audss_reset_of_match,
+ },
+};
+module_platform_driver(sky1_audss_reset_driver)
+
+MODULE_AUTHOR("Joakim Zhang <joakim.zhang@cixtech.com>");
+MODULE_DESCRIPTION("Cix Sky1 audss reset driver");
+MODULE_LICENSE("GPL");
--
2.50.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 6/7] dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
` (4 preceding siblings ...)
2026-05-30 2:16 ` [PATCH v1 5/7] reset: cix: add sky1 audss " joakim.zhang
@ 2026-05-30 2:16 ` joakim.zhang
2026-06-01 11:58 ` Mark Brown
2026-06-01 19:34 ` Rob Herring
2026-05-30 2:16 ` [PATCH v1 7/7] arm64: dts: cix: sky1: add audss device nodes joakim.zhang
2026-05-30 9:10 ` [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support Krzysztof Kozlowski
7 siblings, 2 replies; 21+ messages in thread
From: joakim.zhang @ 2026-05-30 2:16 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Document the reserved memory region used for IPBLOQ HDA DMA buffers and
require it in board DTS.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
.../devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml b/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml
index 02ac5f1aa926..512250290ca3 100644
--- a/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml
+++ b/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml
@@ -36,6 +36,10 @@ properties:
resets:
maxItems: 1
+ memory-region:
+ maxItems: 1
+ description: Reserved memory region used for HDA DMA buffers.
+
required:
- compatible
- reg
@@ -43,6 +47,7 @@ required:
- clocks
- clock-names
- resets
+ - memory-region
unevaluatedProperties: false
@@ -59,4 +64,5 @@ examples:
clock-names = "ipg", "per";
resets = <&audss_rst 14>;
model = "CIX SKY1 EVB HDA";
+ memory-region = <&audio_alsa_hda>;
};
--
2.50.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 7/7] arm64: dts: cix: sky1: add audss device nodes
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
` (5 preceding siblings ...)
2026-05-30 2:16 ` [PATCH v1 6/7] dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region joakim.zhang
@ 2026-05-30 2:16 ` joakim.zhang
2026-05-30 9:07 ` Krzysztof Kozlowski
2026-05-30 9:10 ` [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support Krzysztof Kozlowski
7 siblings, 1 reply; 21+ messages in thread
From: joakim.zhang @ 2026-05-30 2:16 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add audss support for cix sky1 platform, including
clock, reset and hda controllers.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 34 ++++++++++++++
arch/arm64/boot/dts/cix/sky1.dtsi | 56 +++++++++++++++++++++++
2 files changed, 90 insertions(+)
diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
index e39c87774c12..1700ecbfa1ce 100644
--- a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
+++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
@@ -66,6 +66,20 @@ pins {
drive-strength = <8>;
};
};
+
+ pinctrl_audss_hda: hda-cfg {
+ pins {
+ pinmux = <CIX_PAD_HDA_BITCLK_FUNC_HDA_BITCLK>,
+ <CIX_PAD_HDA_RST_L_FUNC_HDA_RST_L>,
+ <CIX_PAD_HDA_SDIN0_FUNC_HDA_SDIN0>,
+ <CIX_PAD_HDA_SDOUT0_FUNC_HDA_SDOUT0>,
+ <CIX_PAD_HDA_SYNC_FUNC_HDA_SYNC>,
+ <CIX_PAD_HDA_SDIN1_FUNC_HDA_SDIN1>,
+ <CIX_PAD_HDA_SDOUT1_FUNC_HDA_SDOUT1>;
+ bias-pull-down;
+ drive-strength = <20>;
+ };
+ };
};
&iomuxc_s5 {
@@ -82,6 +96,26 @@ pins {
};
};
+&audss_cru {
+ status = "okay";
+};
+
+&audss_clk {
+ status = "okay";
+};
+
+&audss_rst {
+ status = "okay";
+};
+
+&audss_ipb_hda {
+ model = "Radxa Orion O6 HDA";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audss_hda>;
+ memory-region = <&audio_alsa_hda>;
+ status = "okay";
+};
+
&pcie_x8_rc {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi
index bb5cfb1f2113..fe096ab95f3b 100644
--- a/arch/arm64/boot/dts/cix/sky1.dtsi
+++ b/arch/arm64/boot/dts/cix/sky1.dtsi
@@ -6,6 +6,10 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/cix,sky1.h>
+#include <dt-bindings/clock/sky1-audss.h>
+#include <dt-bindings/reset/cix,sky1-system-control.h>
+#include <dt-bindings/reset/cix,sky1-s5-system-control.h>
+#include <dt-bindings/reset/sky1-reset-audss.h>
#include "sky1-power.h"
/ {
@@ -155,6 +159,18 @@ core11 {
};
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ audio_alsa_hda: audio_alsa_hda@d0c00000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0xd0c00000 0x0 0x200000>;
+ no-map;
+ };
+ };
+
firmware {
ap_to_pm_scmi: scmi {
compatible = "arm,scmi";
@@ -488,6 +504,46 @@ mbox_pm2ap: mailbox@65a0080 {
cix,mbox-dir = "rx";
};
+ audss_ipb_hda: hda@70c0000 {
+ compatible = "cix,sky1-ipbloq-hda";
+ reg = <0x0 0x070c0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&audss_clk CLK_HDA_SYS>,
+ <&audss_clk CLK_HDA_HDA>;
+ clock-names = "ipg", "per";
+ resets = <&audss_rst AUDSS_HDA_SW_RST_N>;
+ status = "disabled";
+ };
+
+ audss_cru: system-controller@7110000 {
+ compatible = "cix,sky1-audss-cru", "simple-mfd", "syscon";
+ reg = <0x0 0x07110000 0x0 0x10000>;
+ status = "disabled";
+
+ audss_clk: clock-controller {
+ compatible = "cix,sky1-audss-clock";
+ power-domains = <&smc_devpd SKY1_PD_AUDIO>;
+ resets = <&s5_syscon SKY1_AUDIO_HIFI5_NOC_RESET_N>;
+ clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK1>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK2>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK3>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK4>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK5>;
+ clock-names = "audio_clk0", "audio_clk1",
+ "audio_clk2", "audio_clk3",
+ "audio_clk4", "audio_clk5";
+ #clock-cells = <1>;
+ status = "disabled";
+ };
+
+ audss_rst: reset-controller {
+ compatible = "cix,sky1-audss-reset";
+ #reset-cells = <1>;
+ status = "disabled";
+ };
+ };
+
mbox_sfh2ap: mailbox@8090000 {
compatible = "cix,sky1-mbox";
reg = <0x0 0x08090000 0x0 0x10000>;
--
2.50.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller
2026-05-30 2:16 ` [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller joakim.zhang
@ 2026-05-30 9:07 ` Krzysztof Kozlowski
2026-05-30 12:04 ` Joakim Zhang
0 siblings, 1 reply; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-05-30 9:07 UTC (permalink / raw)
To: joakim.zhang, mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel,
lgirdwood, broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound
On 30/05/2026 04:16, joakim.zhang@cixtech.com wrote:
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> Add devicetree schema for the Cix Sky1 audio subsystem CRU syscon/MFD
> parent. Child clock-controller and reset-controller nodes are described
> via references to the AUDSS clock and reset bindings.
>
> Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
This wasn't ever tested and obviously fails (non-bisectable).
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.
Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.
You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.
Please kindly resend and include all necessary To/Cc entries.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 7/7] arm64: dts: cix: sky1: add audss device nodes
2026-05-30 2:16 ` [PATCH v1 7/7] arm64: dts: cix: sky1: add audss device nodes joakim.zhang
@ 2026-05-30 9:07 ` Krzysztof Kozlowski
2026-05-30 12:04 ` Joakim Zhang
0 siblings, 1 reply; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-05-30 9:07 UTC (permalink / raw)
To: joakim.zhang, mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel,
lgirdwood, broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound
On 30/05/2026 04:16, joakim.zhang@cixtech.com wrote:
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> Add audss support for cix sky1 platform, including
> clock, reset and hda controllers.
>
> Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
> ---
> arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 34 ++++++++++++++
> arch/arm64/boot/dts/cix/sky1.dtsi | 56 +++++++++++++++++++++++
> 2 files changed, 90 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> index e39c87774c12..1700ecbfa1ce 100644
> --- a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> +++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> @@ -66,6 +66,20 @@ pins {
> drive-strength = <8>;
> };
> };
> +
> + pinctrl_audss_hda: hda-cfg {
> + pins {
> + pinmux = <CIX_PAD_HDA_BITCLK_FUNC_HDA_BITCLK>,
> + <CIX_PAD_HDA_RST_L_FUNC_HDA_RST_L>,
> + <CIX_PAD_HDA_SDIN0_FUNC_HDA_SDIN0>,
> + <CIX_PAD_HDA_SDOUT0_FUNC_HDA_SDOUT0>,
> + <CIX_PAD_HDA_SYNC_FUNC_HDA_SYNC>,
> + <CIX_PAD_HDA_SDIN1_FUNC_HDA_SDIN1>,
> + <CIX_PAD_HDA_SDOUT1_FUNC_HDA_SDOUT1>;
> + bias-pull-down;
> + drive-strength = <20>;
> + };
> + };
> };
>
> &iomuxc_s5 {
> @@ -82,6 +96,26 @@ pins {
> };
> };
>
> +&audss_cru {
> + status = "okay";
> +};
> +
> +&audss_clk {
> + status = "okay";
> +};
> +
> +&audss_rst {
> + status = "okay";
> +};
> +
> +&audss_ipb_hda {
> + model = "Radxa Orion O6 HDA";
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_audss_hda>;
> + memory-region = <&audio_alsa_hda>;
> + status = "okay";
> +};
> +
> &pcie_x8_rc {
> status = "okay";
> };
> diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi
> index bb5cfb1f2113..fe096ab95f3b 100644
> --- a/arch/arm64/boot/dts/cix/sky1.dtsi
> +++ b/arch/arm64/boot/dts/cix/sky1.dtsi
> @@ -6,6 +6,10 @@
>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> #include <dt-bindings/clock/cix,sky1.h>
> +#include <dt-bindings/clock/sky1-audss.h>
> +#include <dt-bindings/reset/cix,sky1-system-control.h>
> +#include <dt-bindings/reset/cix,sky1-s5-system-control.h>
> +#include <dt-bindings/reset/sky1-reset-audss.h>
> #include "sky1-power.h"
>
> / {
> @@ -155,6 +159,18 @@ core11 {
> };
> };
>
> + reserved-memory {
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges;
> +
> + audio_alsa_hda: audio_alsa_hda@d0c00000 {
> + compatible = "shared-dma-pool";
> + reg = <0x0 0xd0c00000 0x0 0x200000>;
> + no-map;
> + };
> + };
> +
> firmware {
> ap_to_pm_scmi: scmi {
> compatible = "arm,scmi";
> @@ -488,6 +504,46 @@ mbox_pm2ap: mailbox@65a0080 {
> cix,mbox-dir = "rx";
> };
>
> + audss_ipb_hda: hda@70c0000 {
> + compatible = "cix,sky1-ipbloq-hda";
> + reg = <0x0 0x070c0000 0x0 0x10000>;
> + interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>;
> + clocks = <&audss_clk CLK_HDA_SYS>,
> + <&audss_clk CLK_HDA_HDA>;
> + clock-names = "ipg", "per";
> + resets = <&audss_rst AUDSS_HDA_SW_RST_N>;
> + status = "disabled";
> + };
> +
> + audss_cru: system-controller@7110000 {
> + compatible = "cix,sky1-audss-cru", "simple-mfd", "syscon";
> + reg = <0x0 0x07110000 0x0 0x10000>;
> + status = "disabled";
What is missing on the board side? Why SoC component is disabled?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
` (6 preceding siblings ...)
2026-05-30 2:16 ` [PATCH v1 7/7] arm64: dts: cix: sky1: add audss device nodes joakim.zhang
@ 2026-05-30 9:10 ` Krzysztof Kozlowski
2026-05-30 12:02 ` Joakim Zhang
7 siblings, 1 reply; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-05-30 9:10 UTC (permalink / raw)
To: joakim.zhang, mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel,
lgirdwood, broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound
On 30/05/2026 04:16, joakim.zhang@cixtech.com wrote:
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> This series adds devicetree bindings, clock/reset drivers, and board
> description for the Cix Sky1 Audio Subsystem (AUDSS).
You just combined patches for FOUR independent subsystems into one
patchset. Please don't. Organize your patches correctly... or describe
explicitly the dependencies and merging constraints. Nothing here
explains that and it is THE MOST important information.
>
> The AUDSS groups audio-related peripherals (HDA, I2S, DSP-related clocks,
> DMA, mailboxes, watchdog, timer, etc.) behind a single Clock and Reset Unit
> (CRU) register block. Board software obtains the CRU MMIO range through a
> cix,sky1-audss-cru syscon/MFD parent; clock mux/divider/gate and software
> reset control are implemented as child providers that share the parent
> regmap.
>
> * Patch 1 describes the CRU parent (cix,sky1-audss-cru) and how clock and
> reset child nodes hang off it.
> * Patches 2-3 add the AUDSS clock binding, clock IDs, and the
> cix,sky1-audss-clock driver.
> * Patches 4-5 add the AUDSS reset binding, reset IDs, and the
> cix,sky1-audss-reset driver.
> * Patch 6 extends the existing cix,sky1-ipbloq-hda binding so boards can
> supply a reserved memory-region for HDA DMA buffers.
> * Patch 7 wires the AUDSS nodes into sky1.dtsi and enables clock, reset, and
> HDA on the Radxa Orion O6 reference board.
And this is completely redundant. So instead of writing something useful
- what we can do with this patchset - you duplicated commit
messages/subjects.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller
2026-05-30 2:16 ` [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller joakim.zhang
@ 2026-05-30 9:11 ` Krzysztof Kozlowski
2026-05-30 12:04 ` Joakim Zhang
0 siblings, 1 reply; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-05-30 9:11 UTC (permalink / raw)
To: joakim.zhang, mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel,
lgirdwood, broonie
Cc: cix-kernel-upstream, linux-clk, linux-sound
On 30/05/2026 04:16, joakim.zhang@cixtech.com wrote:
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> Add schema and reset IDs for the Cix Sky1 audio subsystem (AUDSS)
> reset controller.
>
> The compatible string is cix,sky1-audss-reset. Reset indices are
> defined in include/dt-bindings/reset/sky1-reset-audss.h.
>
> Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
> ---
> .../bindings/reset/cix,sky1-audss-reset.yaml | 50 +++++++++++++++++++
> include/dt-bindings/reset/sky1-reset-audss.h | 29 +++++++++++
> 2 files changed, 79 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
> create mode 100644 include/dt-bindings/reset/sky1-reset-audss.h
>
> diff --git a/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml b/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
> new file mode 100644
> index 000000000000..8e02ddd2517d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
> @@ -0,0 +1,50 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/reset/cix,sky1-audss-reset.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Cix Sky1 audio subsystem reset controller
> +
> +maintainers:
> + - Joakim Zhang <joakim.zhang@cixtech.com>
> +
> +description: |
> + Reset provider for the Cix Sky1 audio subsystem (AUDSS).
> +
> + This node is a child of a cix,sky1-audss-cru MFD/syscon node (see
> + cix,sky1-audss-cru.yaml). It does not have a reg property; software reset
> + bits are accessed through the parent CRU regmap.
> +
> + Each #reset-cells index maps to a software reset line for an AUDSS block
> + (I2S, HDA, DMA, mailbox, watchdog, timer, etc.). Indices are defined in
> + sky1-reset-audss.h.
> +
> +properties:
> + compatible:
> + const: cix,sky1-audss-reset
> +
> + '#reset-cells':
> + const: 1
> + description:
> + Reset indices are defined in include/dt-bindings/reset/sky1-reset-audss.h.
> +
I am not really reviewing this, since you never tested it and did not
follow the process, but to spare you one review cycle - no resources
here, so this is NOT a separate node. Please read writing bindings or
DTS101 slides.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support
2026-05-30 9:10 ` [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support Krzysztof Kozlowski
@ 2026-05-30 12:02 ` Joakim Zhang
0 siblings, 0 replies; 21+ messages in thread
From: Joakim Zhang @ 2026-05-30 12:02 UTC (permalink / raw)
To: Krzysztof Kozlowski, mturquette@baylibre.com, sboyd@kernel.org,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
p.zabel@pengutronix.de, lgirdwood@gmail.com, broonie@kernel.org
Cc: cix-kernel-upstream, linux-clk@vger.kernel.org,
linux-sound@vger.kernel.org
Hi,
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Saturday, May 30, 2026 5:10 PM
> To: Joakim Zhang <joakim.zhang@cixtech.com>; mturquette@baylibre.com;
> sboyd@kernel.org; robh@kernel.org; krzk+dt@kernel.org;
> conor+dt@kernel.org; p.zabel@pengutronix.de; lgirdwood@gmail.com;
> broonie@kernel.org
> Cc: cix-kernel-upstream <cix-kernel-upstream@cixtech.com>; linux-
> clk@vger.kernel.org; linux-sound@vger.kernel.org
> Subject: Re: [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support
>
> EXTERNAL EMAIL
>
> On 30/05/2026 04:16, joakim.zhang@cixtech.com wrote:
> > From: Joakim Zhang <joakim.zhang@cixtech.com>
> >
> > This series adds devicetree bindings, clock/reset drivers, and board
> > description for the Cix Sky1 Audio Subsystem (AUDSS).
>
>
> You just combined patches for FOUR independent subsystems into one
> patchset. Please don't. Organize your patches correctly... or describe explicitly
> the dependencies and merging constraints. Nothing here explains that and it is
> THE MOST important information.
OK. The original intention was to submit the entire subsystem together (this patch set based on latest clk-next). However, that approach is not ideal. I will release the patches one by one for review.
>
>
> >
> > The AUDSS groups audio-related peripherals (HDA, I2S, DSP-related
> > clocks, DMA, mailboxes, watchdog, timer, etc.) behind a single Clock
> > and Reset Unit
> > (CRU) register block. Board software obtains the CRU MMIO range
> > through a cix,sky1-audss-cru syscon/MFD parent; clock mux/divider/gate
> > and software reset control are implemented as child providers that
> > share the parent regmap.
> >
> > * Patch 1 describes the CRU parent (cix,sky1-audss-cru) and how clock and
> > reset child nodes hang off it.
> > * Patches 2-3 add the AUDSS clock binding, clock IDs, and the
> > cix,sky1-audss-clock driver.
> > * Patches 4-5 add the AUDSS reset binding, reset IDs, and the
> > cix,sky1-audss-reset driver.
> > * Patch 6 extends the existing cix,sky1-ipbloq-hda binding so boards can
> > supply a reserved memory-region for HDA DMA buffers.
> > * Patch 7 wires the AUDSS nodes into sky1.dtsi and enables clock, reset, and
> > HDA on the Radxa Orion O6 reference board.
>
> And this is completely redundant. So instead of writing something useful
> - what we can do with this patchset - you duplicated commit
> messages/subjects.
OK. Will be distributed in batches.
Thanks,
Joakim
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller
2026-05-30 9:07 ` Krzysztof Kozlowski
@ 2026-05-30 12:04 ` Joakim Zhang
0 siblings, 0 replies; 21+ messages in thread
From: Joakim Zhang @ 2026-05-30 12:04 UTC (permalink / raw)
To: Krzysztof Kozlowski, mturquette@baylibre.com, sboyd@kernel.org,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
p.zabel@pengutronix.de, lgirdwood@gmail.com, broonie@kernel.org
Cc: cix-kernel-upstream, linux-clk@vger.kernel.org,
linux-sound@vger.kernel.org
Hi,
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Saturday, May 30, 2026 5:07 PM
> To: Joakim Zhang <joakim.zhang@cixtech.com>; mturquette@baylibre.com;
> sboyd@kernel.org; robh@kernel.org; krzk+dt@kernel.org;
> conor+dt@kernel.org; p.zabel@pengutronix.de; lgirdwood@gmail.com;
> broonie@kernel.org
> Cc: cix-kernel-upstream <cix-kernel-upstream@cixtech.com>; linux-
> clk@vger.kernel.org; linux-sound@vger.kernel.org
> Subject: Re: [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru
> system controller
>
> EXTERNAL EMAIL
>
> On 30/05/2026 04:16, joakim.zhang@cixtech.com wrote:
> > From: Joakim Zhang <joakim.zhang@cixtech.com>
> >
> > Add devicetree schema for the Cix Sky1 audio subsystem CRU syscon/MFD
> > parent. Child clock-controller and reset-controller nodes are
> > described via references to the AUDSS clock and reset bindings.
> >
> > Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
>
>
> This wasn't ever tested and obviously fails (non-bisectable).
>
> Please use scripts/get_maintainers.pl to get a list of necessary people and lists
> to CC. It might happen, that command when run on an older kernel, gives you
> outdated entries. Therefore please be sure you base your patches on recent
> Linux kernel.
>
> Tools like b4 or scripts/get_maintainer.pl provide you proper list of people, so
> fix your workflow. Tools might also fail if you work on some ancient tree (don't,
> instead use mainline) or work on fork of kernel (don't, instead use mainline).
> Just use b4 and everything should be fine, although remember about `b4 prep -
> -auto-to-cc` if you added new patches to the patchset.
>
> You missed at least devicetree list (maybe more), so this won't be tested by
> automated tooling. Performing review on untested code might be a waste of
> time.
>
> Please kindly resend and include all necessary To/Cc entries.
Sorry, will submit the patches in batches and To/Cc all entries.
Thanks,
Joakim
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller
2026-05-30 9:11 ` Krzysztof Kozlowski
@ 2026-05-30 12:04 ` Joakim Zhang
2026-05-30 12:20 ` Krzysztof Kozlowski
0 siblings, 1 reply; 21+ messages in thread
From: Joakim Zhang @ 2026-05-30 12:04 UTC (permalink / raw)
To: Krzysztof Kozlowski, mturquette@baylibre.com, sboyd@kernel.org,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
p.zabel@pengutronix.de, lgirdwood@gmail.com, broonie@kernel.org
Cc: cix-kernel-upstream, linux-clk@vger.kernel.org,
linux-sound@vger.kernel.org
Hi,
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Saturday, May 30, 2026 5:11 PM
> To: Joakim Zhang <joakim.zhang@cixtech.com>; mturquette@baylibre.com;
> sboyd@kernel.org; robh@kernel.org; krzk+dt@kernel.org;
> conor+dt@kernel.org; p.zabel@pengutronix.de; lgirdwood@gmail.com;
> broonie@kernel.org
> Cc: cix-kernel-upstream <cix-kernel-upstream@cixtech.com>; linux-
> clk@vger.kernel.org; linux-sound@vger.kernel.org
> Subject: Re: [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss
> reset controller
>
> EXTERNAL EMAIL
>
> On 30/05/2026 04:16, joakim.zhang@cixtech.com wrote:
> > From: Joakim Zhang <joakim.zhang@cixtech.com>
> >
> > Add schema and reset IDs for the Cix Sky1 audio subsystem (AUDSS)
> > reset controller.
> >
> > The compatible string is cix,sky1-audss-reset. Reset indices are
> > defined in include/dt-bindings/reset/sky1-reset-audss.h.
> >
> > Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
> > ---
> > .../bindings/reset/cix,sky1-audss-reset.yaml | 50
> > +++++++++++++++++++ include/dt-bindings/reset/sky1-reset-audss.h |
> > 29 +++++++++++
> > 2 files changed, 79 insertions(+)
> > create mode 100644
> > Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
> > create mode 100644 include/dt-bindings/reset/sky1-reset-audss.h
> >
> > diff --git
> > a/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
> > b/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yaml
> > new file mode 100644
> > index 000000000000..8e02ddd2517d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/reset/cix,sky1-audss-reset.yam
> > +++ l
> > @@ -0,0 +1,50 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/reset/cix,sky1-audss-reset.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Cix Sky1 audio subsystem reset controller
> > +
> > +maintainers:
> > + - Joakim Zhang <joakim.zhang@cixtech.com>
> > +
> > +description: |
> > + Reset provider for the Cix Sky1 audio subsystem (AUDSS).
> > +
> > + This node is a child of a cix,sky1-audss-cru MFD/syscon node (see
> > + cix,sky1-audss-cru.yaml). It does not have a reg property; software
> > + reset bits are accessed through the parent CRU regmap.
> > +
> > + Each #reset-cells index maps to a software reset line for an AUDSS
> > + block (I2S, HDA, DMA, mailbox, watchdog, timer, etc.). Indices are
> > + defined in sky1-reset-audss.h.
> > +
> > +properties:
> > + compatible:
> > + const: cix,sky1-audss-reset
> > +
> > + '#reset-cells':
> > + const: 1
> > + description:
> > + Reset indices are defined in include/dt-bindings/reset/sky1-reset-
> audss.h.
> > +
>
>
> I am not really reviewing this, since you never tested it and did not follow the
> process, but to spare you one review cycle - no resources here, so this is NOT a
> separate node. Please read writing bindings or
> DTS101 slides.
Sorry, that's the meaning of " so this is NOT a separate node ", could you please explain it more, so I can update later.
Thanks,
Joakim
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v1 7/7] arm64: dts: cix: sky1: add audss device nodes
2026-05-30 9:07 ` Krzysztof Kozlowski
@ 2026-05-30 12:04 ` Joakim Zhang
0 siblings, 0 replies; 21+ messages in thread
From: Joakim Zhang @ 2026-05-30 12:04 UTC (permalink / raw)
To: Krzysztof Kozlowski, mturquette@baylibre.com, sboyd@kernel.org,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
p.zabel@pengutronix.de, lgirdwood@gmail.com, broonie@kernel.org
Cc: cix-kernel-upstream, linux-clk@vger.kernel.org,
linux-sound@vger.kernel.org
Hi,
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Saturday, May 30, 2026 5:08 PM
> To: Joakim Zhang <joakim.zhang@cixtech.com>; mturquette@baylibre.com;
> sboyd@kernel.org; robh@kernel.org; krzk+dt@kernel.org;
> conor+dt@kernel.org; p.zabel@pengutronix.de; lgirdwood@gmail.com;
> broonie@kernel.org
> Cc: cix-kernel-upstream <cix-kernel-upstream@cixtech.com>; linux-
> clk@vger.kernel.org; linux-sound@vger.kernel.org
> Subject: Re: [PATCH v1 7/7] arm64: dts: cix: sky1: add audss device nodes
>
> EXTERNAL EMAIL
>
> On 30/05/2026 04:16, joakim.zhang@cixtech.com wrote:
> > From: Joakim Zhang <joakim.zhang@cixtech.com>
> >
> > Add audss support for cix sky1 platform, including clock, reset and
> > hda controllers.
> >
> > Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
> > ---
> > arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 34 ++++++++++++++
> > arch/arm64/boot/dts/cix/sky1.dtsi | 56 +++++++++++++++++++++++
> > 2 files changed, 90 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> > b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> > index e39c87774c12..1700ecbfa1ce 100644
> > --- a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> > +++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts
> > @@ -66,6 +66,20 @@ pins {
> > drive-strength = <8>;
> > };
> > };
> > +
> > + pinctrl_audss_hda: hda-cfg {
> > + pins {
> > + pinmux = <CIX_PAD_HDA_BITCLK_FUNC_HDA_BITCLK>,
> > + <CIX_PAD_HDA_RST_L_FUNC_HDA_RST_L>,
> > + <CIX_PAD_HDA_SDIN0_FUNC_HDA_SDIN0>,
> > + <CIX_PAD_HDA_SDOUT0_FUNC_HDA_SDOUT0>,
> > + <CIX_PAD_HDA_SYNC_FUNC_HDA_SYNC>,
> > + <CIX_PAD_HDA_SDIN1_FUNC_HDA_SDIN1>,
> > + <CIX_PAD_HDA_SDOUT1_FUNC_HDA_SDOUT1>;
> > + bias-pull-down;
> > + drive-strength = <20>;
> > + };
> > + };
> > };
> >
> > &iomuxc_s5 {
> > @@ -82,6 +96,26 @@ pins {
> > };
> > };
> >
> > +&audss_cru {
> > + status = "okay";
> > +};
> > +
> > +&audss_clk {
> > + status = "okay";
> > +};
> > +
> > +&audss_rst {
> > + status = "okay";
> > +};
> > +
> > +&audss_ipb_hda {
> > + model = "Radxa Orion O6 HDA";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_audss_hda>;
> > + memory-region = <&audio_alsa_hda>;
> > + status = "okay";
> > +};
> > +
> > &pcie_x8_rc {
> > status = "okay";
> > };
> > diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi
> > b/arch/arm64/boot/dts/cix/sky1.dtsi
> > index bb5cfb1f2113..fe096ab95f3b 100644
> > --- a/arch/arm64/boot/dts/cix/sky1.dtsi
> > +++ b/arch/arm64/boot/dts/cix/sky1.dtsi
> > @@ -6,6 +6,10 @@
> >
> > #include <dt-bindings/interrupt-controller/arm-gic.h>
> > #include <dt-bindings/clock/cix,sky1.h>
> > +#include <dt-bindings/clock/sky1-audss.h> #include
> > +<dt-bindings/reset/cix,sky1-system-control.h>
> > +#include <dt-bindings/reset/cix,sky1-s5-system-control.h>
> > +#include <dt-bindings/reset/sky1-reset-audss.h>
> > #include "sky1-power.h"
> >
> > / {
> > @@ -155,6 +159,18 @@ core11 {
> > };
> > };
> >
> > + reserved-memory {
> > + #address-cells = <2>;
> > + #size-cells = <2>;
> > + ranges;
> > +
> > + audio_alsa_hda: audio_alsa_hda@d0c00000 {
> > + compatible = "shared-dma-pool";
> > + reg = <0x0 0xd0c00000 0x0 0x200000>;
> > + no-map;
> > + };
> > + };
> > +
> > firmware {
> > ap_to_pm_scmi: scmi {
> > compatible = "arm,scmi"; @@ -488,6 +504,46 @@
> > mbox_pm2ap: mailbox@65a0080 {
> > cix,mbox-dir = "rx";
> > };
> >
> > + audss_ipb_hda: hda@70c0000 {
> > + compatible = "cix,sky1-ipbloq-hda";
> > + reg = <0x0 0x070c0000 0x0 0x10000>;
> > + interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>;
> > + clocks = <&audss_clk CLK_HDA_SYS>,
> > + <&audss_clk CLK_HDA_HDA>;
> > + clock-names = "ipg", "per";
> > + resets = <&audss_rst AUDSS_HDA_SW_RST_N>;
> > + status = "disabled";
> > + };
> > +
> > + audss_cru: system-controller@7110000 {
> > + compatible = "cix,sky1-audss-cru", "simple-mfd", "syscon";
> > + reg = <0x0 0x07110000 0x0 0x10000>;
> > + status = "disabled";
>
> What is missing on the board side? Why SoC component is disabled?
Indeed, there is absolutely no need to disable. Will updated.
Thanks,
Joakim
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller
2026-05-30 12:04 ` Joakim Zhang
@ 2026-05-30 12:20 ` Krzysztof Kozlowski
2026-05-30 13:51 ` Joakim Zhang
0 siblings, 1 reply; 21+ messages in thread
From: Krzysztof Kozlowski @ 2026-05-30 12:20 UTC (permalink / raw)
To: Joakim Zhang, mturquette@baylibre.com, sboyd@kernel.org,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
p.zabel@pengutronix.de, lgirdwood@gmail.com, broonie@kernel.org
Cc: cix-kernel-upstream, linux-clk@vger.kernel.org,
linux-sound@vger.kernel.org
On 30/05/2026 14:04, Joakim Zhang wrote:
>>
>>
>> I am not really reviewing this, since you never tested it and did not follow the
>> process, but to spare you one review cycle - no resources here, so this is NOT a
>> separate node. Please read writing bindings or
>> DTS101 slides.
>
> Sorry, that's the meaning of " so this is NOT a separate node ", could you please explain it more, so I can update later.
>
Does that mean you are not willing to read existing guides?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller
2026-05-30 12:20 ` Krzysztof Kozlowski
@ 2026-05-30 13:51 ` Joakim Zhang
0 siblings, 0 replies; 21+ messages in thread
From: Joakim Zhang @ 2026-05-30 13:51 UTC (permalink / raw)
To: Krzysztof Kozlowski, mturquette@baylibre.com, sboyd@kernel.org,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
p.zabel@pengutronix.de, lgirdwood@gmail.com, broonie@kernel.org
Cc: cix-kernel-upstream, linux-clk@vger.kernel.org,
linux-sound@vger.kernel.org
Hi,
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Saturday, May 30, 2026 8:20 PM
> To: Joakim Zhang <joakim.zhang@cixtech.com>; mturquette@baylibre.com;
> sboyd@kernel.org; robh@kernel.org; krzk+dt@kernel.org;
> conor+dt@kernel.org; p.zabel@pengutronix.de; lgirdwood@gmail.com;
> broonie@kernel.org
> Cc: cix-kernel-upstream <cix-kernel-upstream@cixtech.com>; linux-
> clk@vger.kernel.org; linux-sound@vger.kernel.org
> Subject: Re: [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss
> reset controller
>
> EXTERNAL EMAIL
>
> On 30/05/2026 14:04, Joakim Zhang wrote:
> >>
> >>
> >> I am not really reviewing this, since you never tested it and did not
> >> follow the process, but to spare you one review cycle - no resources
> >> here, so this is NOT a separate node. Please read writing bindings or
> >> DTS101 slides.
> >
> > Sorry, that's the meaning of " so this is NOT a separate node ", could you
> please explain it more, so I can update later.
> >
>
> Does that mean you are not willing to read existing guides?
I understand what you mean now. I saw this:
- DON'T create nodes just for the sake of instantiating drivers. Multi-function
devices only need child nodes when the child nodes have their own DT
resources. A single node can be multiple providers (e.g. clocks and resets).
According to this, reset node does not have resources, should not be a separate node.
Joakim
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 6/7] dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region
2026-05-30 2:16 ` [PATCH v1 6/7] dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region joakim.zhang
@ 2026-06-01 11:58 ` Mark Brown
2026-06-01 19:34 ` Rob Herring
1 sibling, 0 replies; 21+ messages in thread
From: Mark Brown @ 2026-06-01 11:58 UTC (permalink / raw)
To: joakim.zhang
Cc: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
cix-kernel-upstream, linux-clk, linux-sound
[-- Attachment #1: Type: text/plain, Size: 568 bytes --]
On Sat, May 30, 2026 at 10:16:41AM +0800, joakim.zhang@cixtech.com wrote:
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> Document the reserved memory region used for IPBLOQ HDA DMA buffers and
> require it in board DTS.
Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 3/7] clk: cix: add sky1 audss clock controller
2026-05-30 2:16 ` [PATCH v1 3/7] clk: cix: add sky1 " joakim.zhang
@ 2026-06-01 17:28 ` Brian Masney
0 siblings, 0 replies; 21+ messages in thread
From: Brian Masney @ 2026-06-01 17:28 UTC (permalink / raw)
To: joakim.zhang
Cc: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, lgirdwood,
broonie, cix-kernel-upstream, linux-clk, linux-sound
Hi Joakim,
On Sat, May 30, 2026 at 10:16:38AM +0800, joakim.zhang@cixtech.com wrote:
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> Add clock controller driver for the Cix Sky1 audio subsystem (AUDSS).
> The driver controls mux, divider and gate clocks in the audio CRU via
> the parent syscon regmap and registers clock outputs for audio IPs.
>
> Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
> ---
> drivers/clk/Kconfig | 1 +
> drivers/clk/Makefile | 1 +
> drivers/clk/cix/Kconfig | 17 +
> drivers/clk/cix/Makefile | 3 +
> drivers/clk/cix/clk-sky1-audss.c | 1123 ++++++++++++++++++++++++++++++
> 5 files changed, 1145 insertions(+)
> create mode 100644 drivers/clk/cix/Kconfig
> create mode 100644 drivers/clk/cix/Makefile
> create mode 100644 drivers/clk/cix/clk-sky1-audss.c
>
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index b2efbe9f6acb..ead41e45c0f6 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -503,6 +503,7 @@ source "drivers/clk/actions/Kconfig"
> source "drivers/clk/analogbits/Kconfig"
> source "drivers/clk/aspeed/Kconfig"
> source "drivers/clk/bcm/Kconfig"
> +source "drivers/clk/cix/Kconfig"
> source "drivers/clk/eswin/Kconfig"
> source "drivers/clk/hisilicon/Kconfig"
> source "drivers/clk/imgtec/Kconfig"
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index a3e2862ebd7e..9135ea6e5a8f 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -118,6 +118,7 @@ obj-$(CONFIG_ARCH_ARTPEC) += axis/
> obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
> obj-y += bcm/
> obj-$(CONFIG_ARCH_BERLIN) += berlin/
> +obj-y += cix/
> obj-$(CONFIG_ARCH_DAVINCI) += davinci/
> obj-$(CONFIG_COMMON_CLK_ESWIN) += eswin/
> obj-$(CONFIG_ARCH_HISI) += hisilicon/
> diff --git a/drivers/clk/cix/Kconfig b/drivers/clk/cix/Kconfig
> new file mode 100644
> index 000000000000..d248f109c051
> --- /dev/null
> +++ b/drivers/clk/cix/Kconfig
> @@ -0,0 +1,17 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Audio subsystem clock support for Cixtech SoC family
> +menu "Clock support for Cixtech audss"
> +
> +comment "Clock options for Cixtech audss:"
This comment is redundant with the menu name, and can be dropped.
> +
> +config CLK_SKY1_AUDSS
> + tristate "Cixtech Sky1 Audio Subsystem Clock Driver"
> + depends on ARCH_CIX || COMPILE_TEST
depends on MFD_SYSCON since syscon_node_to_regmap() is used below.
> + select REGMAP_MMIO
> + select RESET_CONTROLLER
> + help
> + Support for the Audio Subsystem clock controller present on
> + Cixtech Sky1 SoC. This driver provides mux, divider and gate
> + clocks for DSP, I2S, HDA and related blocks in the audio
> + subsystem. Say M or Y here if you want to build this driver.
> +endmenu
> diff --git a/drivers/clk/cix/Makefile b/drivers/clk/cix/Makefile
> new file mode 100644
> index 000000000000..bc612f1d08b2
> --- /dev/null
> +++ b/drivers/clk/cix/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_CLK_SKY1_AUDSS) += clk-sky1-audss.o
> diff --git a/drivers/clk/cix/clk-sky1-audss.c b/drivers/clk/cix/clk-sky1-audss.c
> new file mode 100644
> index 000000000000..ab6ec7338ebe
> --- /dev/null
> +++ b/drivers/clk/cix/clk-sky1-audss.c
> @@ -0,0 +1,1123 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright 2026 Cix Technology Group Co., Ltd.
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include <dt-bindings/clock/sky1-audss.h>
> +
> +#define INFO_HIFI0 0x00
> +#define INFO_CLK_GATE 0x10
> +#define INFO_CLK_DIV 0x14
> +#define INFO_CLK_MUX 0x18
> +#define INFO_MCLK 0x70
> +
> +#define SKY1_AUDSS_CLK_PARENTS_CNT 6
> +#define AUDSS_CLK_PARENTS_MAX SKY1_AUDSS_CLK_PARENTS_CNT
Can this second one be dropped?
> +
> +static u32 sky1_reg_save[][2] = {
> + { INFO_HIFI0, 0 },
> + { INFO_CLK_GATE, 0 },
> + { INFO_CLK_DIV, 0 },
> + { INFO_CLK_MUX, 0 },
> + { INFO_MCLK, 0 },
> +};
Should this be moved into struct sky1_audss_clks_priv?
> +
> +static const char *sky1_audss_clk_names[SKY1_AUDSS_CLK_PARENTS_CNT] = {
> + "audio_clk0", "audio_clk1", "audio_clk2",
> + "audio_clk3", "audio_clk4", "audio_clk5",
> +};
> +
> +static const u32 sky1_clk_rate_default[SKY1_AUDSS_CLK_PARENTS_CNT] = {
> + 294912000,
> + 344064000,
> + 270950400,
> + 316108800,
> + 800000000,
> + 48000000,
> +};
> +
> +static DEFINE_SPINLOCK(lock);
> +static struct clk_hw_onecell_data *clk_data;
Move both of these into struct sky1_audss_clks_priv.
> +
> +static const char * const dsp_clk_parent[] = {
> + "audio_clk4"
> +};
> +
> +static const char * const dsp_bclk_parent[] = {
> + "audio_clk4_div2"
> +};
> +
> +static const char * const dsp_pbclk_parent[] = {
> + "audio_clk4_div4"
> +};
> +
> +static const char * const sram_axi_parent[] = {
> + "audio_clk4_div2"
> +};
> +
> +static const char * const hda_sys_parent[] = {
> + "audio_clk4_div2"
> +};
> +
> +static const char * const hda_hda_parent[] = {
> + "audio_clk5"
> +};
> +
> +static const char * const dmac_axi_parent[] = {
> + "audio_clk4_div2"
> +};
> +
> +static const char * const wdg_apb_parent[] = {
> + "audio_clk5_div2"
> +};
> +
> +static const char * const wdg_wdg_parent[] = {
> + "audio_clk5_div2"
> +};
> +
> +static const char * const timer_apb_parent[] = {
> + "audio_clk4_div4"
> +};
> +
> +static const char * const timer_timer_parent[] = {
> + "audio_clk5_div2"
> +};
> +
> +static const char * const mailbox_apb_parent[] = {
> + "audio_clk4_div4"
> +};
> +
> +static const char * const i2s_apb_parent[] = {
> + "audio_clk4_div4"
> +};
> +
> +static const char * const i2s0_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +static const char * const i2s1_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +static const char * const i2s2_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +static const char * const i2s3_parents[] = {
> + "audio_clk0", "audio_clk1", "audio_clk2", "audio_clk3"
> +};
> +
> +static const char * const i2s4_parents[] = {
> + "audio_clk0", "audio_clk1", "audio_clk2", "audio_clk3"
> +};
> +
> +static const char * const i2s5_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +static const char * const i2s6_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +static const char * const i2s7_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +static const char * const i2s8_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +static const char * const i2s9_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +static const char * const mclk_parents[] = {
> + "audio_clk0", "audio_clk2"
> +};
> +
> +/*
> + * audss composite clock definition
> + */
> +struct muxdiv_cfg {
> + int offset;
> + u8 shift;
> + u8 width;
> + u8 flags;
> +};
> +
> +struct gate_cfg {
> + int offset;
> + u8 shift;
> + u8 flags;
> +};
> +
> +struct composite_clk_cfg {
> + u32 id;
> + const char *name;
> + const char * const *parent_names;
Can the name also be const char * const * like the parent_names?
> + int num_parents;
> + struct muxdiv_cfg *mux_cfg;
> + struct muxdiv_cfg *div_cfg;
> + struct gate_cfg *gate_cfg;
> + unsigned long flags;
> +};
> +
> +#define CFG(_id,\
> + _name,\
> + _parent_names,\
> + _mux_offset, _mux_shift, _mux_width, _mux_flags,\
> + _div_offset, _div_shift, _div_width, _div_flags,\
> + _gate_offset, _gate_shift, _gate_flags,\
> + _flags)\
> +{\
> + .id = _id,\
> + .name = _name,\
> + .parent_names = _parent_names,\
> + .num_parents = ARRAY_SIZE(_parent_names),\
> + .mux_cfg = &(struct muxdiv_cfg) { _mux_offset, _mux_shift, _mux_width, _mux_flags },\
> + .div_cfg = &(struct muxdiv_cfg) { _div_offset, _div_shift, _div_width, _div_flags },\
> + .gate_cfg = &(struct gate_cfg) { _gate_offset, _gate_shift, _gate_flags },\
> + .flags = _flags,\
> +}
> +
> +static const struct composite_clk_cfg sky1_audss_clks[] = {
> + /* dsp */
> + CFG(CLK_DSP_CLK,
> + "audss_dsp_clk",
> + dsp_clk_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_HIFI0, 0, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_DSP_BCLK,
> + "audss_dsp_bclk",
> + dsp_bclk_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + -1, 0, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_DSP_PBCLK,
> + "audss_dsp_pbclk",
> + dsp_pbclk_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + -1, 0, 0,
> + CLK_GET_RATE_NOCACHE),
> + /* sram */
> + CFG(CLK_SRAM_AXI,
> + "audss_sram_axi",
> + sram_axi_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 16, 0,
> + CLK_GET_RATE_NOCACHE),
> + /* hda */
> + CFG(CLK_HDA_SYS,
> + "audss_hda_sys",
> + hda_sys_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 14, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_HDA_HDA,
> + "audss_hda_hda",
> + hda_hda_parent,
> + -1, 0, 0, 0,
> + -1, 0, 0, 0,
> + INFO_CLK_GATE, 14, 0,
> + CLK_GET_RATE_NOCACHE),
> + /* dmac */
> + CFG(CLK_DMAC_AXI,
> + "audss_dmac_axi",
> + dmac_axi_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 15, 0,
> + CLK_GET_RATE_NOCACHE),
> + /* wdg */
> + CFG(CLK_WDG_APB,
> + "audss_wdg_apb",
> + wdg_apb_parent,
> + -1, 0, 0, 0,
> + -1, 0, 0, 0,
> + INFO_CLK_GATE, 10, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_WDG_WDG,
> + "audss_wdg_wdg",
> + wdg_wdg_parent,
> + -1, 0, 0, 0,
> + -1, 0, 0, 0,
> + INFO_CLK_GATE, 10, 0,
> + CLK_GET_RATE_NOCACHE),
> + /* timer */
> + CFG(CLK_TIMER_APB,
> + "audss_timer_apb",
> + timer_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 11, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_TIMER_TIMER,
> + "audss_timer_timer",
> + timer_timer_parent,
> + -1, 0, 0, 0,
> + -1, 0, 0, 0,
> + INFO_CLK_GATE, 11, 0,
> + CLK_GET_RATE_NOCACHE),
> + /* mailbox: mb0(ap->dsp), mb1(dsp->ap) */
> + CFG(CLK_MB_0_APB,
> + "audss_mb_0_apb",
> + mailbox_apb_parent,
> + -1, 0, 0, 0,
> + -1, 0, 0, 0,
> + INFO_CLK_GATE, 12, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_MB_1_APB,
> + "audss_mb_1_apb",
> + mailbox_apb_parent,
> + -1, 0, 0, 0,
> + -1, 0, 0, 0,
> + INFO_CLK_GATE, 13, 0,
> + CLK_GET_RATE_NOCACHE),
> + /* i2s */
> + CFG(CLK_I2S0_APB,
> + "audss_i2s0_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 0, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S1_APB,
> + "audss_i2s1_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 1, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S2_APB,
> + "audss_i2s2_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 2, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S3_APB,
> + "audss_i2s3_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 3, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S4_APB,
> + "audss_i2s4_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 4, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S5_APB,
> + "audss_i2s5_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 5, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S6_APB,
> + "audss_i2s6_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 6, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S7_APB,
> + "audss_i2s7_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 7, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S8_APB,
> + "audss_i2s8_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 8, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S9_APB,
> + "audss_i2s9_apb",
> + i2s_apb_parent,
> + -1, 0, 0, 0,
> + INFO_CLK_DIV, 0, 2, 0,
> + INFO_CLK_GATE, 9, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S0,
> + "audss_i2s0",
> + i2s0_parents,
> + INFO_CLK_MUX, 0, 2, 0,
> + INFO_CLK_DIV, 2, 2, 0,
> + INFO_CLK_GATE, 0, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S1,
> + "audss_i2s1",
> + i2s1_parents,
> + INFO_CLK_MUX, 2, 2, 0,
> + INFO_CLK_DIV, 4, 2, 0,
> + INFO_CLK_GATE, 1, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S2,
> + "audss_i2s2",
> + i2s2_parents,
> + INFO_CLK_MUX, 4, 2, 0,
> + INFO_CLK_DIV, 6, 2, 0,
> + INFO_CLK_GATE, 2, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S3,
> + "audss_i2s3",
> + i2s3_parents,
> + INFO_CLK_MUX, 6, 2, 0,
> + INFO_CLK_DIV, 8, 2, 0,
> + INFO_CLK_GATE, 3, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S4,
> + "audss_i2s4",
> + i2s4_parents,
> + INFO_CLK_MUX, 8, 2, 0,
> + INFO_CLK_DIV, 10, 2, 0,
> + INFO_CLK_GATE, 4, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S5,
> + "audss_i2s5",
> + i2s5_parents,
> + INFO_CLK_MUX, 10, 2, 0,
> + INFO_CLK_DIV, 12, 2, 0,
> + INFO_CLK_GATE, 5, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S6,
> + "audss_i2s6",
> + i2s6_parents,
> + INFO_CLK_MUX, 12, 2, 0,
> + INFO_CLK_DIV, 14, 2, 0,
> + INFO_CLK_GATE, 6, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S7,
> + "audss_i2s7",
> + i2s7_parents,
> + INFO_CLK_MUX, 14, 2, 0,
> + INFO_CLK_DIV, 16, 2, 0,
> + INFO_CLK_GATE, 7, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S8,
> + "audss_i2s8",
> + i2s8_parents,
> + INFO_CLK_MUX, 16, 2, 0,
> + INFO_CLK_DIV, 18, 2, 0,
> + INFO_CLK_GATE, 8, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_I2S9,
> + "audss_i2s9",
> + i2s9_parents,
> + INFO_CLK_MUX, 18, 2, 0,
> + INFO_CLK_DIV, 20, 2, 0,
> + INFO_CLK_GATE, 9, 0,
> + CLK_GET_RATE_NOCACHE),
> + /* mclk */
> + CFG(CLK_MCLK0,
> + "audss_mclk0",
> + mclk_parents,
> + INFO_MCLK, 5, 1, 0,
> + -1, 0, 0, 0,
> + INFO_MCLK, 0, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_MCLK1,
> + "audss_mclk1",
> + mclk_parents,
> + INFO_MCLK, 6, 1, 0,
> + -1, 0, 0, 0,
> + INFO_MCLK, 1, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_MCLK2,
> + "audss_mclk2",
> + mclk_parents,
> + INFO_MCLK, 7, 1, 0,
> + -1, 0, 0, 0,
> + INFO_MCLK, 2, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_MCLK3,
> + "audss_mclk3",
> + mclk_parents,
> + INFO_MCLK, 8, 1, 0,
> + -1, 0, 0, 0,
> + INFO_MCLK, 3, 0,
> + CLK_GET_RATE_NOCACHE),
> + CFG(CLK_MCLK4,
> + "audss_mclk4",
> + mclk_parents,
> + INFO_MCLK, 9, 1, 0,
> + -1, 0, 0, 0,
> + INFO_MCLK, 4, 0,
> + CLK_GET_RATE_NOCACHE),
Why is CLK_GET_RATE_NOCACHE enabled for all of these clocks?
> +};
> +
> +struct sky1_audss_clks_devtype_data {
> + u32 (*reg_save)[2];
> + size_t reg_save_size;
> + const char **clk_names;
const char * const *clk_names ?
> + size_t clk_num;
> + const u32 *clk_rate_default;
> + const struct composite_clk_cfg *clk_cfg;
> + size_t clk_cfg_size;
> +};
> +
> +struct sky1_audss_clks_priv {
> + struct device *dev;
> + struct regmap *regmap_cru;
> + struct clk *clks[AUDSS_CLK_PARENTS_MAX];
> + struct reset_control *rst_noc;
> + const struct sky1_audss_clks_devtype_data *devtype_data;
> +};
> +
> +/*
> + * clk_ops for audss clock mux/divicer/gate
divider
> + */
> +struct sky1_clk_divider {
> + struct clk_divider div;
> + struct regmap *regmap;
> + int offset;
> +};
> +
> +struct sky1_clk_gate {
> + struct clk_gate gate;
> + struct regmap *regmap;
> + int offset;
> +};
> +
> +struct sky1_clk_mux {
> + struct clk_mux mux;
> + struct regmap *regmap;
> + int offset;
> +};
> +
> +static inline struct sky1_clk_mux *to_sky1_clk_mux(struct clk_mux *mux)
> +{
> + return container_of(mux, struct sky1_clk_mux, mux);
> +}
> +
> +static u8 sky1_audss_clk_mux_get_parent(struct clk_hw *hw)
> +{
> + struct clk_mux *mux = to_clk_mux(hw);
> + struct sky1_clk_mux *sky1_mux = to_sky1_clk_mux(mux);
> + u32 val;
> +
> + regmap_read(sky1_mux->regmap, sky1_mux->offset, &val);
> + val = val >> mux->shift;
> + val &= mux->mask;
> +
> + return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
> +}
> +
> +static int sky1_audss_clk_mux_set_parent(struct clk_hw *hw, u8 index)
> +{
> + struct clk_mux *mux = to_clk_mux(hw);
> + struct sky1_clk_mux *sky1_mux = to_sky1_clk_mux(mux);
> + u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
Reverse Christmas tree order. Swap these two lines. The mux needs to
stay first due to dependency.
> + unsigned long flags = 0;
> + u32 reg;
> +
> + if (mux->lock)
> + spin_lock_irqsave(mux->lock, flags);
> + else
> + __acquire(mux->lock);
> +
> + if (mux->flags & CLK_MUX_HIWORD_MASK) {
> + reg = mux->mask << (mux->shift + 16);
> + } else {
> + regmap_read(sky1_mux->regmap, sky1_mux->offset, ®);
> + reg &= ~(mux->mask << mux->shift);
> + }
> + val = val << mux->shift;
> + reg |= val;
> + regmap_write(sky1_mux->regmap, sky1_mux->offset, reg);
> +
> + if (mux->lock)
> + spin_unlock_irqrestore(mux->lock, flags);
> + else
> + __release(mux->lock);
> +
> + return 0;
> +}
> +
> +static int sky1_audss_clk_mux_determine_rate(struct clk_hw *hw,
> + struct clk_rate_request *req)
> +{
> + struct clk_mux *mux = to_clk_mux(hw);
> +
> + return clk_mux_determine_rate_flags(hw, req, mux->flags);
> +}
> +
> +static const struct clk_ops sky1_audss_clk_mux_ops = {
> + .get_parent = sky1_audss_clk_mux_get_parent,
> + .set_parent = sky1_audss_clk_mux_set_parent,
> + .determine_rate = sky1_audss_clk_mux_determine_rate,
> +};
> +
> +static inline struct sky1_clk_divider *to_sky1_clk_divider(struct clk_divider *div)
> +{
> + return container_of(div, struct sky1_clk_divider, div);
> +}
> +
> +static unsigned long sky1_audss_clk_divider_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct clk_divider *divider = to_clk_divider(hw);
> + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider);
> + unsigned int val;
> +
> + regmap_read(sky1_div->regmap, sky1_div->offset, &val);
> + val = val >> divider->shift;
> + val &= clk_div_mask(divider->width);
> +
> + return divider_recalc_rate(hw, parent_rate, val, divider->table,
> + divider->flags, divider->width);
> +}
> +
> +static int sky1_audss_clk_divider_determine_rate(struct clk_hw *hw,
> + struct clk_rate_request *req)
> +{
> + struct clk_divider *divider = to_clk_divider(hw);
> + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider);
> +
> + /* if read only, just return current value */
> + if (divider->flags & CLK_DIVIDER_READ_ONLY) {
> + u32 val;
> +
> + regmap_read(sky1_div->regmap, sky1_div->offset, &val);
> + val = val >> divider->shift;
> + val &= clk_div_mask(divider->width);
> +
> + return divider_ro_determine_rate(hw, req, divider->table,
> + divider->width,
> + divider->flags, val);
> + }
> +
> + return divider_determine_rate(hw, req, divider->table, divider->width,
> + divider->flags);
> +}
> +
> +static int sky1_audss_clk_divider_set_rate(struct clk_hw *hw,
> + unsigned long rate,
> + unsigned long parent_rate)
> +{
> + struct clk_divider *divider = to_clk_divider(hw);
> + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider);
> + int value;
> + unsigned long flags = 0;
> + u32 val;
> +
> + value = divider_get_val(rate, parent_rate, divider->table,
> + divider->width, divider->flags);
> + if (value < 0)
> + return value;
> +
> + if (divider->lock)
> + spin_lock_irqsave(divider->lock, flags);
> + else
> + __acquire(divider->lock);
> +
> + if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
> + val = clk_div_mask(divider->width) << (divider->shift + 16);
> + } else {
> + regmap_read(sky1_div->regmap, sky1_div->offset, &val);
> + val &= ~(clk_div_mask(divider->width) << divider->shift);
> + }
> + val |= (u32)value << divider->shift;
> + regmap_write(sky1_div->regmap, sky1_div->offset, val);
> +
> + if (divider->lock)
> + spin_unlock_irqrestore(divider->lock, flags);
> + else
> + __release(divider->lock);
> +
> + return 0;
> +}
> +
> +static const struct clk_ops sky1_audss_clk_divider_ops = {
> + .recalc_rate = sky1_audss_clk_divider_recalc_rate,
> + .determine_rate = sky1_audss_clk_divider_determine_rate,
> + .set_rate = sky1_audss_clk_divider_set_rate,
> +};
> +
> +static inline struct sky1_clk_gate *to_sky1_clk_gate(struct clk_gate *gate)
> +{
> + return container_of(gate, struct sky1_clk_gate, gate);
> +}
> +
> +static void sky1_audss_clk_gate_endisable(struct clk_hw *hw, int enable)
> +{
> + struct clk_gate *gate = to_clk_gate(hw);
> + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate);
> + int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
> + unsigned long flags;
unsigned long flags = 0;
> + u32 reg;
> +
> + set ^= enable;
> +
> + if (gate->lock)
> + spin_lock_irqsave(gate->lock, flags);
> + else
> + __acquire(gate->lock);
> +
> + if (gate->flags & CLK_GATE_HIWORD_MASK) {
> + reg = BIT(gate->bit_idx + 16);
> + if (set)
> + reg |= BIT(gate->bit_idx);
> + } else {
> + regmap_read(sky1_gate->regmap, sky1_gate->offset, ®);
> +
> + if (set)
> + reg |= BIT(gate->bit_idx);
> + else
> + reg &= ~BIT(gate->bit_idx);
> + }
> +
> + regmap_write(sky1_gate->regmap, sky1_gate->offset, reg);
> +
> + if (gate->lock)
> + spin_unlock_irqrestore(gate->lock, flags);
> + else
> + __release(gate->lock);
> +}
> +
> +static int sky1_audss_clk_gate_enable(struct clk_hw *hw)
> +{
> + sky1_audss_clk_gate_endisable(hw, 1);
> +
> + return 0;
> +}
> +
> +static void sky1_audss_clk_gate_disable(struct clk_hw *hw)
> +{
> + sky1_audss_clk_gate_endisable(hw, 0);
> +}
> +
> +static int sky1_audss_clk_gate_is_enabled(struct clk_hw *hw)
> +{
> + u32 reg;
> + struct clk_gate *gate = to_clk_gate(hw);
> + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate);
> +
> + regmap_read(sky1_gate->regmap, sky1_gate->offset, ®);
> +
> + /* if a set bit disables this clk, flip it before masking */
> + if (gate->flags & CLK_GATE_SET_TO_DISABLE)
> + reg ^= BIT(gate->bit_idx);
> +
> + reg &= BIT(gate->bit_idx);
> +
> + return reg ? 1 : 0;
return !!reg;
> +}
> +
> +static const struct clk_ops sky1_audss_clk_gate_ops = {
> + .enable = sky1_audss_clk_gate_enable,
> + .disable = sky1_audss_clk_gate_disable,
> + .is_enabled = sky1_audss_clk_gate_is_enabled,
> +};
> +
> +static struct clk_hw *sky1_audss_clk_register(struct device *dev,
> + const char *name,
> + const char * const *parent_names,
> + int num_parents,
> + struct regmap *regmap,
> + struct muxdiv_cfg *mux_cfg,
> + struct muxdiv_cfg *div_cfg,
> + struct gate_cfg *gate_cfg,
> + unsigned long flags,
> + spinlock_t *lock)
> +{
> + const struct clk_ops *sky1_mux_ops = NULL;
> + const struct clk_ops *sky1_div_ops = NULL;
> + const struct clk_ops *sky1_gate_ops = NULL;
> + struct clk_hw *hw = ERR_PTR(-ENOMEM);
> + struct sky1_clk_divider *sky1_div = NULL;
> + struct sky1_clk_gate *sky1_gate = NULL;
> + struct sky1_clk_mux *sky1_mux = NULL;
> +
> + if (mux_cfg->offset >= 0) {
> + sky1_mux = devm_kzalloc(dev, sizeof(*sky1_mux), GFP_KERNEL);
> + if (!sky1_mux)
> + return ERR_PTR(-ENOMEM);
> +
> + sky1_mux->mux.reg = NULL;
> + sky1_mux->mux.shift = mux_cfg->shift;
> + sky1_mux->mux.mask = BIT(mux_cfg->width) - 1;
> + sky1_mux->mux.flags = mux_cfg->flags;
> + sky1_mux->mux.lock = lock;
> + sky1_mux_ops = &sky1_audss_clk_mux_ops;
> + sky1_mux->regmap = regmap;
> + sky1_mux->offset = mux_cfg->offset;
> + }
> +
> + if (div_cfg->offset >= 0) {
> + sky1_div = devm_kzalloc(dev, sizeof(*sky1_div), GFP_KERNEL);
> + if (!sky1_div)
> + return ERR_PTR(-ENOMEM);
> +
> + sky1_div->div.reg = NULL;
> + sky1_div->div.shift = div_cfg->shift;
> + sky1_div->div.width = div_cfg->width;
> + sky1_div->div.flags = div_cfg->flags | CLK_DIVIDER_POWER_OF_TWO;
> + sky1_div->div.lock = lock;
> + sky1_div_ops = &sky1_audss_clk_divider_ops;
> + sky1_div->regmap = regmap;
> + sky1_div->offset = div_cfg->offset;
> + }
> +
> + if (gate_cfg->offset >= 0) {
> + sky1_gate = devm_kzalloc(dev, sizeof(*sky1_gate), GFP_KERNEL);
> + if (!sky1_gate)
> + return ERR_PTR(-ENOMEM);
> +
> + sky1_gate->gate.reg = NULL;
> + sky1_gate->gate.bit_idx = gate_cfg->shift;
> + sky1_gate->gate.flags = gate_cfg->flags;
> + sky1_gate->gate.lock = lock;
> + sky1_gate_ops = &sky1_audss_clk_gate_ops;
> + sky1_gate->regmap = regmap;
> + sky1_gate->offset = gate_cfg->offset;
> + }
> +
> + hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
> + sky1_mux ? &sky1_mux->mux.hw : NULL, sky1_mux_ops,
> + sky1_div ? &sky1_div->div.hw : NULL, sky1_div_ops,
> + sky1_gate ? &sky1_gate->gate.hw : NULL, sky1_gate_ops,
> + flags);
> + if (IS_ERR(hw)) {
> + dev_err(dev, "register %s clock failed with err = %ld\n",
> + name, PTR_ERR(hw));
> + return ERR_CAST(hw);
return hw;
> + }
> +
> + return hw;
> +}
> +
> +static int sky1_audss_clks_get(struct sky1_audss_clks_priv *priv)
> +{
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + int i;
> +
> + for (i = 0; i < devtype_data->clk_num; i++) {
> + priv->clks[i] = devm_clk_get(priv->dev, devtype_data->clk_names[i]);
> + if (IS_ERR(priv->clks[i]))
> + return dev_err_probe(priv->dev, PTR_ERR(priv->clks[i]),
> + "failed to get clock %s", devtype_data->clk_names[i]);
> + }
> +
> + return 0;
> +}
> +
> +static int sky1_audss_clks_enable(struct sky1_audss_clks_priv *priv)
> +{
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + int i, err;
> +
> + for (i = 0; i < devtype_data->clk_num; i++) {
> + err = clk_prepare_enable(priv->clks[i]);
> + if (err) {
> + dev_err(priv->dev, "failed to enable clock %s\n",
> + devtype_data->clk_names[i]);
> + goto err_clks;
> + }
> + }
> +
> + return 0;
> +
> +err_clks:
> + while (--i >= 0)
> + clk_disable_unprepare(priv->clks[i]);
> +
> + return err;
> +}
> +
> +static void sky1_audss_clks_disable(struct sky1_audss_clks_priv *priv)
> +{
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + int i;
> +
> + for (i = 0; i < devtype_data->clk_num; i++)
> + clk_disable_unprepare(priv->clks[i]);
> +}
> +
> +static int sky1_audss_clks_set_rate(struct sky1_audss_clks_priv *priv)
> +{
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + int i, err;
> +
> + for (i = 0; i < devtype_data->clk_num; i++) {
> + err = clk_set_rate(priv->clks[i], devtype_data->clk_rate_default[i]);
> + if (err) {
> + dev_err(priv->dev, "failed to set clock rate %s\n",
> + devtype_data->clk_names[i]);
> + return err;
> + }
> + }
> +
> + return 0;
> +}
> +
> +/* register sky1 audio subsystem clocks */
> +static int sky1_audss_clk_probe(struct platform_device *pdev)
> +{
> + const struct sky1_audss_clks_devtype_data *devtype_data;
> + struct sky1_audss_clks_priv *priv;
> + struct device_node *parent_np;
> + struct device *dev = &pdev->dev;
> + struct reset_control *rst_noc;
> + struct clk_hw **clk_table;
> + struct regmap *regmap_cru;
> + int i, ret;
> +
> + parent_np = of_get_parent(pdev->dev.of_node);
> + regmap_cru = syscon_node_to_regmap(parent_np);
> + of_node_put(parent_np);
> + if (IS_ERR(regmap_cru))
> + return dev_err_probe(dev, PTR_ERR(regmap_cru),
> + "unable to get audss cru regmap");
> +
> + devtype_data = of_device_get_match_data(dev);
device_get_match_data() is more generic.
> + if (!devtype_data)
> + return -ENODEV;
> +
> + clk_data = devm_kzalloc(&pdev->dev,
> + struct_size(clk_data, hws, AUDSS_MAX_CLKS),
> + GFP_KERNEL);
> + if (!clk_data)
> + return -ENOMEM;
> +
> + clk_data->num = AUDSS_MAX_CLKS;
> + clk_table = clk_data->hws;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->dev = dev;
> + priv->regmap_cru = regmap_cru;
> + priv->devtype_data = devtype_data;
> +
> + ret = sky1_audss_clks_get(priv);
> + if (ret)
> + return ret;
> +
> + rst_noc = devm_reset_control_get(dev, NULL);
> + if (IS_ERR(rst_noc))
> + return dev_err_probe(dev, PTR_ERR(rst_noc),
> + "failed to get noc reset");
> + priv->rst_noc = rst_noc;
> +
> + platform_set_drvdata(pdev, priv);
> +
> + /*
> + * Enable runtime PM here to allow the clock core using runtime PM
> + * for the registered clocks.
> + */
> + pm_runtime_get_noresume(dev);
> + pm_runtime_set_active(dev);
> + pm_runtime_enable(dev);
> +
> + ret = sky1_audss_clks_enable(priv);
> + if (ret) {
> + dev_err(dev, "failed to enable clocks\n");
> + goto fail_clks_enable;
pm_runtime_get_noresume() is acquired above but not released below in
this case.
> + }
> +
> + ret = sky1_audss_clks_set_rate(priv);
> + if (ret) {
> + dev_err(dev, "failed to set clocks rate\n");
> + goto fail_clks_set;
> + }
> +
> + /* assert reset */
> + reset_control_assert(rst_noc);
> + usleep_range(1, 2);
> +
> + /* deassert reset */
> + reset_control_deassert(rst_noc);
> +
> + /* audio_clk4 clock fixed divider */
> + clk_table[CLK_AUD_CLK4_DIV2] =
> + devm_clk_hw_register_fixed_factor(dev,
> + "audio_clk4_div2",
> + "audio_clk4",
> + CLK_GET_RATE_NOCACHE,
> + 1, 2);
> + if (IS_ERR(clk_table[CLK_AUD_CLK4_DIV2])) {
> + ret = PTR_ERR(clk_table[CLK_AUD_CLK4_DIV2]);
> + dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK4_DIV2, ret);
> + goto fail_fixed_clk;
> + }
> +
> + clk_table[CLK_AUD_CLK4_DIV4] =
> + devm_clk_hw_register_fixed_factor(dev,
> + "audio_clk4_div4",
> + "audio_clk4",
> + CLK_GET_RATE_NOCACHE,
> + 1, 4);
> + if (IS_ERR(clk_table[CLK_AUD_CLK4_DIV4])) {
> + ret = PTR_ERR(clk_table[CLK_AUD_CLK4_DIV4]);
> + dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK4_DIV4, ret);
> + goto fail_fixed_clk;
> + }
> +
> + /* audio_clk5 clock fixed divider */
> + clk_table[CLK_AUD_CLK5_DIV2] =
> + devm_clk_hw_register_fixed_factor(dev,
> + "audio_clk5_div2",
> + "audio_clk5",
> + CLK_GET_RATE_NOCACHE,
> + 1, 2);
> + if (IS_ERR(clk_table[CLK_AUD_CLK5_DIV2])) {
> + ret = PTR_ERR(clk_table[CLK_AUD_CLK5_DIV2]);
> + dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK5_DIV2, ret);
> + goto fail_fixed_clk;
> + }
> +
> + for (i = 0; i < devtype_data->clk_cfg_size; i++) {
> + clk_table[devtype_data->clk_cfg[i].id] =
> + sky1_audss_clk_register(dev,
> + devtype_data->clk_cfg[i].name,
> + devtype_data->clk_cfg[i].parent_names,
> + devtype_data->clk_cfg[i].num_parents,
> + regmap_cru,
> + devtype_data->clk_cfg[i].mux_cfg,
> + devtype_data->clk_cfg[i].div_cfg,
> + devtype_data->clk_cfg[i].gate_cfg,
> + devtype_data->clk_cfg[i].flags,
> + &lock);
> + if (IS_ERR(clk_table[devtype_data->clk_cfg[i].id])) {
> + ret = PTR_ERR(clk_table[devtype_data->clk_cfg[i].id]);
> + dev_err(dev, "failed to register clock %d, ret:%d\n",
> + devtype_data->clk_cfg[i].id, ret);
> + goto fail_array_clk;
> + }
> + }
> +
> + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
> + if (ret) {
> + dev_err(dev, "failed to add clock provider: %d\n", ret);
> + goto fail_register;
> + }
> +
> + pm_runtime_put_sync(dev);
> +
> + return 0;
> +
> +fail_register:
> +fail_array_clk:
> + while (i--)
> + clk_hw_unregister_composite(clk_table[devtype_data->clk_cfg[i].id]);
> +fail_fixed_clk:
> +fail_clks_set:
> + pm_runtime_put_sync(dev);
> +fail_clks_enable:
> + pm_runtime_disable(dev);
> + return ret;
> +}
> +
> +static void sky1_audss_clk_remove(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev);
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + int i = 0;
> +
> + for (i = 0; i < devtype_data->clk_cfg_size; i++)
> + clk_hw_unregister_composite(clk_data->hws[devtype_data->clk_cfg[i].id]);
> +
> + if (!pm_runtime_status_suspended(dev))
> + pm_runtime_force_suspend(dev);
> +
> + pm_runtime_disable(dev);
> +}
> +
> +static int __maybe_unused sky1_audss_clk_runtime_suspend(struct device *dev)
> +{
> + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev);
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + int i;
> +
> + for (i = 0; i < devtype_data->reg_save_size; i++)
> + regmap_read(priv->regmap_cru,
> + devtype_data->reg_save[i][0], &devtype_data->reg_save[i][1]);
> +
> + sky1_audss_clks_disable(priv);
Where's the locking?
> +
> + return 0;
> +}
> +
> +static int __maybe_unused sky1_audss_clk_runtime_resume(struct device *dev)
> +{
> + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev);
> + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data;
> + int i, ret;
> +
> + ret = sky1_audss_clks_enable(priv);
> + if (ret) {
> + dev_err(dev, "failed to enable clocks\n");
> + return ret;
> + }
> +
> + reset_control_deassert(priv->rst_noc);
> +
> + for (i = 0; i < priv->devtype_data->reg_save_size; i++)
> + regmap_write(priv->regmap_cru,
> + devtype_data->reg_save[i][0], devtype_data->reg_save[i][1]);
Where's the locking?
Brian
> +
> + return 0;
> +}
> +
> +static const struct dev_pm_ops sky1_audss_clk_pm_ops = {
> + SET_RUNTIME_PM_OPS(sky1_audss_clk_runtime_suspend,
> + sky1_audss_clk_runtime_resume, NULL)
> + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> + pm_runtime_force_resume)
> +};
> +
> +static const struct sky1_audss_clks_devtype_data sky1_devtype_data = {
> + .reg_save = sky1_reg_save,
> + .reg_save_size = ARRAY_SIZE(sky1_reg_save),
> + .clk_names = sky1_audss_clk_names,
> + .clk_num = ARRAY_SIZE(sky1_audss_clk_names),
> + .clk_rate_default = sky1_clk_rate_default,
> + .clk_cfg = sky1_audss_clks,
> + .clk_cfg_size = ARRAY_SIZE(sky1_audss_clks),
> +};
> +
> +static const struct of_device_id sky1_audss_clk_of_match[] = {
> + { .compatible = "cix,sky1-audss-clock", .data = &sky1_devtype_data, },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, sky1_audss_clk_of_match);
> +
> +static struct platform_driver sky1_audss_clk_driver = {
> + .probe = sky1_audss_clk_probe,
> + .remove = sky1_audss_clk_remove,
> + .driver = {
> + .name = "sky1-audss-clk",
> + .suppress_bind_attrs = true,
> + .of_match_table = sky1_audss_clk_of_match,
> + .pm = &sky1_audss_clk_pm_ops,
> + },
> +};
> +module_platform_driver(sky1_audss_clk_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Joakim Zhang <joakim.zhang@cixtech.com>");
> +MODULE_DESCRIPTION("Cixtech Sky1 Audio Subsystem Clock Controller Driver");
> --
> 2.50.1
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 6/7] dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region
2026-05-30 2:16 ` [PATCH v1 6/7] dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region joakim.zhang
2026-06-01 11:58 ` Mark Brown
@ 2026-06-01 19:34 ` Rob Herring
1 sibling, 0 replies; 21+ messages in thread
From: Rob Herring @ 2026-06-01 19:34 UTC (permalink / raw)
To: joakim.zhang
Cc: mturquette, sboyd, krzk+dt, conor+dt, p.zabel, lgirdwood, broonie,
cix-kernel-upstream, linux-clk, linux-sound
On Fri, May 29, 2026 at 9:16 PM <joakim.zhang@cixtech.com> wrote:
>
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> Document the reserved memory region used for IPBLOQ HDA DMA buffers and
> require it in board DTS.
>
> Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
> ---
> .../devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml | 6 ++++++
> 1 file changed, 6 insertions(+)
Resend this to the DT list if you want it reviewed.
Rob
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-06-01 19:34 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-30 2:16 [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support joakim.zhang
2026-05-30 2:16 ` [PATCH v1 1/7] dt-bindings: soc: cix,sky1-audss-cru: add audss cru system controller joakim.zhang
2026-05-30 9:07 ` Krzysztof Kozlowski
2026-05-30 12:04 ` Joakim Zhang
2026-05-30 2:16 ` [PATCH v1 2/7] dt-bindings: clock: cix,sky1-audss-clock: add audss clock controller joakim.zhang
2026-05-30 2:16 ` [PATCH v1 3/7] clk: cix: add sky1 " joakim.zhang
2026-06-01 17:28 ` Brian Masney
2026-05-30 2:16 ` [PATCH v1 4/7] dt-bindings: reset: cix,sky1-audss-reset: add aduss reset controller joakim.zhang
2026-05-30 9:11 ` Krzysztof Kozlowski
2026-05-30 12:04 ` Joakim Zhang
2026-05-30 12:20 ` Krzysztof Kozlowski
2026-05-30 13:51 ` Joakim Zhang
2026-05-30 2:16 ` [PATCH v1 5/7] reset: cix: add sky1 audss " joakim.zhang
2026-05-30 2:16 ` [PATCH v1 6/7] dt-bindings: sound: cix,sky1-ipbloq-hda: add hda dma memory-region joakim.zhang
2026-06-01 11:58 ` Mark Brown
2026-06-01 19:34 ` Rob Herring
2026-05-30 2:16 ` [PATCH v1 7/7] arm64: dts: cix: sky1: add audss device nodes joakim.zhang
2026-05-30 9:07 ` Krzysztof Kozlowski
2026-05-30 12:04 ` Joakim Zhang
2026-05-30 9:10 ` [PATCH v1 0/7] Add Cix Sky1 AUDSS clock and reset support Krzysztof Kozlowski
2026-05-30 12:02 ` Joakim Zhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox