* [PATCH v3 01/10] dt-bindings: clock: rk3576: add IOC gated clocks
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 02/10] clk: rockchip: introduce auxiliary GRFs Nicolas Frattaroli
` (9 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, Krzysztof Kozlowski, kernel, Luca Ceresoli,
linux-clk, linux-arm-kernel
Certain clocks on the RK3576 are additionally essentially "gated" behind
some bit toggles in the IOC GRF range. Downstream ungates these by
adding a separate clock driver that maps over the GRF range and leaks
their implementation of this into the DT.
Instead, define some new clock IDs for these, so that consumers of these
types of clocks can properly articulate which clock they're using, so
that we can then add them to the clock driver for SoCs that need them.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
include/dt-bindings/clock/rockchip,rk3576-cru.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/dt-bindings/clock/rockchip,rk3576-cru.h b/include/dt-bindings/clock/rockchip,rk3576-cru.h
index f576e61bec7041455e10ac18c92f3b33ec0760e3..ded5ce42e62a7f4bc8058fd71b5e9e1d4580f49c 100644
--- a/include/dt-bindings/clock/rockchip,rk3576-cru.h
+++ b/include/dt-bindings/clock/rockchip,rk3576-cru.h
@@ -594,4 +594,14 @@
#define SCMI_ARMCLK_B 11
#define SCMI_CLK_GPU 456
+/* IOC-controlled output clocks */
+#define CLK_SAI0_MCLKOUT_TO_IO 571
+#define CLK_SAI1_MCLKOUT_TO_IO 572
+#define CLK_SAI2_MCLKOUT_TO_IO 573
+#define CLK_SAI3_MCLKOUT_TO_IO 574
+#define CLK_SAI4_MCLKOUT_TO_IO 575
+#define CLK_SAI4_MCLKOUT_TO_IO 575
+#define CLK_FSPI0_TO_IO 576
+#define CLK_FSPI1_TO_IO 577
+
#endif
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 02/10] clk: rockchip: introduce auxiliary GRFs
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 01/10] dt-bindings: clock: rk3576: add IOC gated clocks Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 03/10] clk: rockchip: introduce GRF gates Nicolas Frattaroli
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
The MUXGRF clock branch type depends on having access to some sort of
GRF as a regmap to be registered. So far, we could easily get away with
only ever having one GRF stowed away in the context.
However, newer Rockchip SoCs, such as the RK3576, have several GRFs
which are relevant for clock purposes. It already depends on the pmu0
GRF for MUXGRF reasons, but could get away with not refactoring this
because it didn't need the sysgrf at all, so could overwrite the pointer
in the clock provider to the pmu0 grf regmap handle.
In preparation for needing to finally access more than one GRF per SoC,
let's untangle this. Introduce an auxiliary GRF hashmap, and a GRF type
enum. The hasmap is keyed by the enum, and clock branches now have a
struct member to store the value of that enum, which defaults to the
system GRF.
The SoC-specific _clk_init function can then insert pointers to GRF
regmaps into the hashmap based on the grf type.
During clock branch registration, we then pick the right GRF for each
branch from the hashmap if something other than the sys GRF is
requested.
The reason for doing it with this grf type indirection in the clock
branches is so that we don't need to define the MUXGRF branches in a
separate step, just to have a direct pointer to a regmap available
already.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/clk/rockchip/clk-rk3288.c | 2 +-
drivers/clk/rockchip/clk-rk3328.c | 6 +++---
drivers/clk/rockchip/clk-rk3568.c | 2 +-
drivers/clk/rockchip/clk-rk3576.c | 32 ++++++++++++++++++++++----------
drivers/clk/rockchip/clk-rv1126.c | 2 +-
drivers/clk/rockchip/clk.c | 17 ++++++++++++++++-
drivers/clk/rockchip/clk.h | 29 ++++++++++++++++++++++++++++-
7 files changed, 72 insertions(+), 18 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 90d329216064a5a31cefab723c86088fcb620ea2..0a1e017df7c661e4eb73b236b7a9dadde4ac0ff7 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -418,7 +418,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
RK3288_CLKGATE_CON(3), 11, GFLAGS),
MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, CLK_SET_RATE_PARENT,
- RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS),
+ RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS, grf_type_sys),
GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
RK3288_CLKGATE_CON(9), 0, GFLAGS),
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index cf60fcf2fa5cde4ef97a05852f071763a4ccee40..cd5f65b6cdf55074c753f1dee96972c2a589c260 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -677,9 +677,9 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
RK3328_CLKSEL_CON(27), 15, 1, MFLAGS, 8, 5, DFLAGS,
RK3328_CLKGATE_CON(3), 5, GFLAGS),
MUXGRF(SCLK_MAC2IO, "clk_mac2io", mux_mac2io_src_p, CLK_SET_RATE_NO_REPARENT,
- RK3328_GRF_MAC_CON1, 10, 1, MFLAGS),
+ RK3328_GRF_MAC_CON1, 10, 1, MFLAGS, grf_type_sys),
MUXGRF(SCLK_MAC2IO_EXT, "clk_mac2io_ext", mux_mac2io_ext_p, CLK_SET_RATE_NO_REPARENT,
- RK3328_GRF_SOC_CON4, 14, 1, MFLAGS),
+ RK3328_GRF_SOC_CON4, 14, 1, MFLAGS, grf_type_sys),
COMPOSITE(SCLK_MAC2PHY_SRC, "clk_mac2phy_src", mux_2plls_p, 0,
RK3328_CLKSEL_CON(26), 7, 1, MFLAGS, 0, 5, DFLAGS,
@@ -692,7 +692,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
RK3328_CLKSEL_CON(26), 8, 2, DFLAGS,
RK3328_CLKGATE_CON(9), 2, GFLAGS),
MUXGRF(SCLK_MAC2PHY, "clk_mac2phy", mux_mac2phy_src_p, CLK_SET_RATE_NO_REPARENT,
- RK3328_GRF_MAC_CON2, 10, 1, MFLAGS),
+ RK3328_GRF_MAC_CON2, 10, 1, MFLAGS, grf_type_sys),
FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
index ed2fb08bd39de81de2127b70ddb184cf66afa3bb..d48ab9d6c064632498a1f7eaff22952e8e62b642 100644
--- a/drivers/clk/rockchip/clk-rk3568.c
+++ b/drivers/clk/rockchip/clk-rk3568.c
@@ -591,7 +591,7 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
RK3568_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS,
RK3568_CLKGATE_CON(4), 0, GFLAGS),
MUXGRF(CLK_DDR1X, "clk_ddr1x", clk_ddr1x_p, CLK_SET_RATE_PARENT,
- RK3568_CLKSEL_CON(9), 15, 1, MFLAGS),
+ RK3568_CLKSEL_CON(9), 15, 1, MFLAGS, grf_type_sys),
COMPOSITE_NOMUX(CLK_MSCH, "clk_msch", "clk_ddr1x", CLK_IGNORE_UNUSED,
RK3568_CLKSEL_CON(10), 0, 2, DFLAGS,
diff --git a/drivers/clk/rockchip/clk-rk3576.c b/drivers/clk/rockchip/clk-rk3576.c
index be703f250197af2097fa591837de03accb8c51da..7a23683e18ff0d813e7b7fdc339b9539fa27bc66 100644
--- a/drivers/clk/rockchip/clk-rk3576.c
+++ b/drivers/clk/rockchip/clk-rk3576.c
@@ -1678,13 +1678,13 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = {
/* phy ref */
MUXGRF(CLK_PHY_REF_SRC, "clk_phy_ref_src", clk_phy_ref_src_p, 0,
- RK3576_PMU0_GRF_OSC_CON6, 4, 1, MFLAGS),
+ RK3576_PMU0_GRF_OSC_CON6, 4, 1, MFLAGS, grf_type_pmu0),
MUXGRF(CLK_USBPHY_REF_SRC, "clk_usbphy_ref_src", clk_usbphy_ref_src_p, 0,
- RK3576_PMU0_GRF_OSC_CON6, 2, 1, MFLAGS),
+ RK3576_PMU0_GRF_OSC_CON6, 2, 1, MFLAGS, grf_type_pmu0),
MUXGRF(CLK_CPLL_REF_SRC, "clk_cpll_ref_src", clk_cpll_ref_src_p, 0,
- RK3576_PMU0_GRF_OSC_CON6, 1, 1, MFLAGS),
+ RK3576_PMU0_GRF_OSC_CON6, 1, 1, MFLAGS, grf_type_pmu0),
MUXGRF(CLK_AUPLL_REF_SRC, "clk_aupll_ref_src", clk_aupll_ref_src_p, 0,
- RK3576_PMU0_GRF_OSC_CON6, 0, 1, MFLAGS),
+ RK3576_PMU0_GRF_OSC_CON6, 0, 1, MFLAGS, grf_type_pmu0),
/* secure ns */
COMPOSITE_NODIV(ACLK_SECURE_NS, "aclk_secure_ns", mux_350m_175m_116m_24m_p, CLK_IS_CRITICAL,
@@ -1727,13 +1727,14 @@ static void __init rk3576_clk_init(struct device_node *np)
struct rockchip_clk_provider *ctx;
unsigned long clk_nr_clks;
void __iomem *reg_base;
- struct regmap *grf;
+ struct rockchip_aux_grf *pmu0_grf_e;
+ struct regmap *pmu0_grf;
clk_nr_clks = rockchip_clk_find_max_clk_id(rk3576_clk_branches,
ARRAY_SIZE(rk3576_clk_branches)) + 1;
- grf = syscon_regmap_lookup_by_compatible("rockchip,rk3576-pmu0-grf");
- if (IS_ERR(grf)) {
+ pmu0_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3576-pmu0-grf");
+ if (IS_ERR(pmu0_grf)) {
pr_err("%s: could not get PMU0 GRF syscon\n", __func__);
return;
}
@@ -1747,11 +1748,16 @@ static void __init rk3576_clk_init(struct device_node *np)
ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
if (IS_ERR(ctx)) {
pr_err("%s: rockchip clk init failed\n", __func__);
- iounmap(reg_base);
- return;
+ goto err_unmap;
}
- ctx->grf = grf;
+ pmu0_grf_e = kzalloc(sizeof(*pmu0_grf_e), GFP_KERNEL);
+ if (!pmu0_grf_e)
+ goto err_unmap;
+
+ pmu0_grf_e->grf = pmu0_grf;
+ pmu0_grf_e->type = grf_type_pmu0;
+ hash_add(ctx->aux_grf_table, &pmu0_grf_e->node, grf_type_pmu0);
rockchip_clk_register_plls(ctx, rk3576_pll_clks,
ARRAY_SIZE(rk3576_pll_clks),
@@ -1774,6 +1780,12 @@ static void __init rk3576_clk_init(struct device_node *np)
rockchip_register_restart_notifier(ctx, RK3576_GLB_SRST_FST, NULL);
rockchip_clk_of_add_provider(np, ctx);
+
+ return;
+
+err_unmap:
+ iounmap(reg_base);
+ return;
}
CLK_OF_DECLARE(rk3576_cru, "rockchip,rk3576-cru", rk3576_clk_init);
diff --git a/drivers/clk/rockchip/clk-rv1126.c b/drivers/clk/rockchip/clk-rv1126.c
index fc19c5522490592b449580ea3c286f6d1f5b32cc..15e7bfe84506c30edb25909aae42aa25697649c6 100644
--- a/drivers/clk/rockchip/clk-rv1126.c
+++ b/drivers/clk/rockchip/clk-rv1126.c
@@ -857,7 +857,7 @@ static struct rockchip_clk_branch rv1126_clk_branches[] __initdata = {
RV1126_GMAC_CON, 5, 1, MFLAGS),
MUXGRF(CLK_GMAC_SRC, "clk_gmac_src", mux_clk_gmac_src_p, CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT,
- RV1126_GRF_IOFUNC_CON1, 12, 1, MFLAGS),
+ RV1126_GRF_IOFUNC_CON1, 12, 1, MFLAGS, grf_type_sys),
GATE(CLK_GMAC_REF, "clk_gmac_ref", "clk_gmac_src", 0,
RV1126_CLKGATE_CON(20), 7, GFLAGS),
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index cbf93ea119a9e25c037607ded1f6f358918e8656..0f029106d8aaa24ced78b2ef29726aa561ef6f0d 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -382,6 +382,8 @@ static struct rockchip_clk_provider *rockchip_clk_init_base(
ctx->cru_node = np;
spin_lock_init(&ctx->lock);
+ hash_init(ctx->aux_grf_table);
+
ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
"rockchip,grf");
@@ -496,6 +498,8 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
struct rockchip_clk_branch *list,
unsigned int nr_clk)
{
+ struct regmap *grf = ctx->grf;
+ struct rockchip_aux_grf *agrf;
struct clk *clk;
unsigned int idx;
unsigned long flags;
@@ -504,6 +508,17 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
flags = list->flags;
clk = NULL;
+ /* for GRF-dependent branches, choose the right grf first */
+ if (list->branch_type == branch_muxgrf &&
+ list->grf_type != grf_type_sys) {
+ hash_for_each_possible(ctx->aux_grf_table, agrf, node, list->grf_type) {
+ if (agrf->type == list->grf_type) {
+ grf = agrf->grf;
+ break;
+ }
+ }
+ }
+
/* catch simple muxes */
switch (list->branch_type) {
case branch_mux:
@@ -526,7 +541,7 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
case branch_muxgrf:
clk = rockchip_clk_register_muxgrf(list->name,
list->parent_names, list->num_parents,
- flags, ctx->grf, list->muxdiv_offset,
+ flags, grf, list->muxdiv_offset,
list->mux_shift, list->mux_width,
list->mux_flags);
break;
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index df2b2d706450f38dfe2b3c7762763c5e832b9892..c136ac54e6213490a995fff553730fa63694dd8f 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <linux/clk-provider.h>
+#include <linux/hashtable.h>
struct clk;
@@ -440,12 +441,35 @@ enum rockchip_pll_type {
.k = _k, \
}
+enum rockchip_grf_type {
+ grf_type_sys = 0,
+ grf_type_pmu0,
+ grf_type_pmu1,
+ grf_type_ioc,
+};
+
+/* ceil(sqrt(enums in rockchip_grf_type - 1)) */
+#define GRF_HASH_ORDER 2
+
+/**
+ * struct rockchip_aux_grf - entry for the aux_grf_table hashtable
+ * @grf: pointer to the grf this entry references
+ * @type: what type of GRF this is
+ * @node: hlist node
+ */
+struct rockchip_aux_grf {
+ struct regmap *grf;
+ enum rockchip_grf_type type;
+ struct hlist_node node;
+};
+
/**
* struct rockchip_clk_provider - information about clock provider
* @reg_base: virtual address for the register base.
* @clk_data: holds clock related data like clk* and number of clocks.
* @cru_node: device-node of the clock-provider
* @grf: regmap of the general-register-files syscon
+ * @aux_grf_table: hashtable of auxiliary GRF regmaps, indexed by grf_type
* @lock: maintains exclusion between callbacks for a given clock-provider.
*/
struct rockchip_clk_provider {
@@ -453,6 +477,7 @@ struct rockchip_clk_provider {
struct clk_onecell_data clk_data;
struct device_node *cru_node;
struct regmap *grf;
+ DECLARE_HASHTABLE(aux_grf_table, GRF_HASH_ORDER);
spinlock_t lock;
};
@@ -660,6 +685,7 @@ struct rockchip_clk_branch {
u8 gate_shift;
u8 gate_flags;
unsigned int linked_clk_id;
+ enum rockchip_grf_type grf_type;
struct rockchip_clk_branch *child;
};
@@ -900,7 +926,7 @@ struct rockchip_clk_branch {
.mux_table = mt, \
}
-#define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \
+#define MUXGRF(_id, cname, pnames, f, o, s, w, mf, gt) \
{ \
.id = _id, \
.branch_type = branch_muxgrf, \
@@ -913,6 +939,7 @@ struct rockchip_clk_branch {
.mux_width = w, \
.mux_flags = mf, \
.gate_offset = -1, \
+ .grf_type = gt, \
}
#define DIV(_id, cname, pname, f, o, s, w, df) \
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 03/10] clk: rockchip: introduce GRF gates
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 01/10] dt-bindings: clock: rk3576: add IOC gated clocks Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 02/10] clk: rockchip: introduce auxiliary GRFs Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 04/10] clk: rockchip: add GATE_GRFs for SAI MCLKOUT to rk3576 Nicolas Frattaroli
` (7 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
Some rockchip SoCs, namely the RK3576, have bits in a General Register
File (GRF) that act just like clock gates. The downstream vendor kernel
simply maps over the already mapped GRF range with a generic clock gate
driver. This solution isn't suitable for upstream, as a memory range
will be in use by multiple drivers at the same time, and it leaks
implementation details into the device tree.
Instead, implement this with a new clock branch type in the Rockchip
clock driver: GRF gates. Somewhat akin to MUXGRF, this clock branch
depends on the type of GRF, but functions like a gate instead.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/clk/rockchip/Makefile | 1 +
drivers/clk/rockchip/clk.c | 9 +++-
drivers/clk/rockchip/clk.h | 20 ++++++++
drivers/clk/rockchip/gate-grf.c | 105 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 134 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index e8ece20aebfdeffbdc5bfffd2c6f35f2cfcf74f6..f0e0b2c6e876a84610fb3ecf33cc1935b10058d9 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -14,6 +14,7 @@ clk-rockchip-y += clk-mmc-phase.o
clk-rockchip-y += clk-muxgrf.o
clk-rockchip-y += clk-ddr.o
clk-rockchip-y += gate-link.o
+clk-rockchip-y += gate-grf.o
clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
obj-$(CONFIG_CLK_PX30) += clk-px30.o
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 0f029106d8aaa24ced78b2ef29726aa561ef6f0d..34d96aa7cd51b8bde380b4a81ce07ffdf24b8593 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -509,7 +509,7 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
clk = NULL;
/* for GRF-dependent branches, choose the right grf first */
- if (list->branch_type == branch_muxgrf &&
+ if ((list->branch_type == branch_muxgrf || list->branch_type == branch_grf_gate) &&
list->grf_type != grf_type_sys) {
hash_for_each_possible(ctx->aux_grf_table, agrf, node, list->grf_type) {
if (agrf->type == list->grf_type) {
@@ -588,6 +588,13 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
ctx->reg_base + list->gate_offset,
list->gate_shift, list->gate_flags, &ctx->lock);
break;
+ case branch_grf_gate:
+ flags |= CLK_SET_RATE_PARENT;
+ clk = rockchip_clk_register_gate_grf(list->name,
+ list->parent_names[0], flags, grf,
+ list->gate_offset, list->gate_shift,
+ list->gate_flags);
+ break;
case branch_composite:
clk = rockchip_clk_register_branch(list->name,
list->parent_names, list->num_parents,
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index c136ac54e6213490a995fff553730fa63694dd8f..ebaed429a30dc2c41c866f973f8cf78b32136311 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -647,6 +647,11 @@ struct clk *rockchip_clk_register_muxgrf(const char *name,
int flags, struct regmap *grf, int reg,
int shift, int width, int mux_flags);
+struct clk *rockchip_clk_register_gate_grf(const char *name,
+ const char *parent_name, unsigned long flags,
+ struct regmap *regmap, unsigned int reg,
+ unsigned int shift, u8 gate_flags);
+
#define PNAME(x) static const char *const x[] __initconst
enum rockchip_clk_branch_type {
@@ -656,6 +661,7 @@ enum rockchip_clk_branch_type {
branch_divider,
branch_fraction_divider,
branch_gate,
+ branch_grf_gate,
branch_linked_gate,
branch_mmc,
branch_inverter,
@@ -985,6 +991,20 @@ struct rockchip_clk_branch {
.gate_flags = gf, \
}
+#define GATE_GRF(_id, cname, pname, f, o, b, gf, gt) \
+ { \
+ .id = _id, \
+ .branch_type = branch_grf_gate, \
+ .name = cname, \
+ .parent_names = (const char *[]){ pname }, \
+ .num_parents = 1, \
+ .flags = f, \
+ .gate_offset = o, \
+ .gate_shift = b, \
+ .gate_flags = gf, \
+ .grf_type = gt, \
+ }
+
#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \
{ \
.id = _id, \
diff --git a/drivers/clk/rockchip/gate-grf.c b/drivers/clk/rockchip/gate-grf.c
new file mode 100644
index 0000000000000000000000000000000000000000..8122f471f39134a7298be8daf0718cfa4f8852a7
--- /dev/null
+++ b/drivers/clk/rockchip/gate-grf.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Collabora Ltd.
+ * Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
+ *
+ * Certain clocks on Rockchip are "gated" behind an additional register bit
+ * write in a GRF register, such as the SAI MCLKs on RK3576. This code
+ * implements a clock driver for these types of gates, based on regmaps.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include "clk.h"
+
+struct rockchip_gate_grf {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ unsigned int reg;
+ unsigned int shift;
+ u8 flags;
+};
+
+#define to_gate_grf(_hw) container_of(_hw, struct rockchip_gate_grf, hw)
+
+static int rockchip_gate_grf_enable(struct clk_hw *hw)
+{
+ struct rockchip_gate_grf *gate = to_gate_grf(hw);
+ u32 val = !(gate->flags & CLK_GATE_SET_TO_DISABLE) ? BIT(gate->shift) : 0;
+ u32 hiword = ((gate->flags & CLK_GATE_HIWORD_MASK) ? 1 : 0) << (gate->shift + 16);
+ int ret;
+
+ ret = regmap_update_bits(gate->regmap, gate->reg,
+ hiword | BIT(gate->shift), hiword | val);
+
+ return ret;
+}
+
+static void rockchip_gate_grf_disable(struct clk_hw *hw)
+{
+ struct rockchip_gate_grf *gate = to_gate_grf(hw);
+ u32 val = !(gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : BIT(gate->shift);
+ u32 hiword = ((gate->flags & CLK_GATE_HIWORD_MASK) ? 1 : 0) << (gate->shift + 16);
+
+ regmap_update_bits(gate->regmap, gate->reg,
+ hiword | BIT(gate->shift), hiword | val);
+}
+
+static int rockchip_gate_grf_is_enabled(struct clk_hw *hw)
+{
+ struct rockchip_gate_grf *gate = to_gate_grf(hw);
+ bool invert = !!(gate->flags & CLK_GATE_SET_TO_DISABLE);
+ int ret;
+
+ ret = regmap_test_bits(gate->regmap, gate->reg, BIT(gate->shift));
+ if (ret < 0)
+ ret = 0;
+
+ return invert ? 1 - ret : ret;
+
+}
+
+static const struct clk_ops rockchip_gate_grf_ops = {
+ .enable = rockchip_gate_grf_enable,
+ .disable = rockchip_gate_grf_disable,
+ .is_enabled = rockchip_gate_grf_is_enabled,
+};
+
+struct clk *rockchip_clk_register_gate_grf(const char *name,
+ const char *parent_name, unsigned long flags,
+ struct regmap *regmap, unsigned int reg, unsigned int shift,
+ u8 gate_flags)
+{
+ struct rockchip_gate_grf *gate;
+ struct clk_init_data init;
+ struct clk *clk;
+
+ if (IS_ERR(regmap)) {
+ pr_err("%s: regmap not available\n", __func__);
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = flags;
+ init.num_parents = parent_name ? 1 : 0;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.ops = &rockchip_gate_grf_ops;
+
+ gate->hw.init = &init;
+ gate->regmap = regmap;
+ gate->reg = reg;
+ gate->shift = shift;
+ gate->flags = gate_flags;
+
+ clk = clk_register(NULL, &gate->hw);
+ if (IS_ERR(clk))
+ kfree(gate);
+
+ return clk;
+}
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 04/10] clk: rockchip: add GATE_GRFs for SAI MCLKOUT to rk3576
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
` (2 preceding siblings ...)
2025-05-02 11:03 ` [PATCH v3 03/10] clk: rockchip: introduce GRF gates Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 05/10] arm64: dts: rockchip: Add RK3576 SAI nodes Nicolas Frattaroli
` (6 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
The Rockchip RK3576 gates the SAI MCLKOUT clocks behind some IOC GRF
writes.
Add these clock branches, and add the IOC GRF to the auxiliary GRF
hashtable.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/clk/rockchip/clk-rk3576.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/clk/rockchip/clk-rk3576.c b/drivers/clk/rockchip/clk-rk3576.c
index 7a23683e18ff0d813e7b7fdc339b9539fa27bc66..1e269490ac7f6b56ed4e53a711c7d4d922b6e149 100644
--- a/drivers/clk/rockchip/clk-rk3576.c
+++ b/drivers/clk/rockchip/clk-rk3576.c
@@ -15,6 +15,7 @@
#define RK3576_GRF_SOC_STATUS0 0x600
#define RK3576_PMU0_GRF_OSC_CON6 0x18
+#define RK3576_VCCIO_IOC_MISC_CON0 0x6400
enum rk3576_plls {
bpll, lpll, vpll, aupll, cpll, gpll, ppll,
@@ -1481,6 +1482,14 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = {
RK3576_CLKGATE_CON(10), 0, GFLAGS),
GATE(CLK_SAI0_MCLKOUT, "clk_sai0_mclkout", "mclk_sai0_8ch", 0,
RK3576_CLKGATE_CON(10), 1, GFLAGS),
+ GATE_GRF(CLK_SAI0_MCLKOUT_TO_IO, "mclk_sai0_to_io", "clk_sai0_mclkout",
+ 0, RK3576_VCCIO_IOC_MISC_CON0, 0, GFLAGS, grf_type_ioc),
+ GATE_GRF(CLK_SAI1_MCLKOUT_TO_IO, "mclk_sai1_to_io", "clk_sai1_mclkout",
+ 0, RK3576_VCCIO_IOC_MISC_CON0, 1, GFLAGS, grf_type_ioc),
+ GATE_GRF(CLK_SAI2_MCLKOUT_TO_IO, "mclk_sai2_to_io", "clk_sai2_mclkout",
+ 0, RK3576_VCCIO_IOC_MISC_CON0, 2, GFLAGS, grf_type_ioc),
+ GATE_GRF(CLK_SAI3_MCLKOUT_TO_IO, "mclk_sai3_to_io", "clk_sai3_mclkout",
+ 0, RK3576_VCCIO_IOC_MISC_CON0, 3, GFLAGS, grf_type_ioc),
/* sdgmac */
COMPOSITE_NODIV(HCLK_SDGMAC_ROOT, "hclk_sdgmac_root", mux_200m_100m_50m_24m_p, 0,
@@ -1727,7 +1736,9 @@ static void __init rk3576_clk_init(struct device_node *np)
struct rockchip_clk_provider *ctx;
unsigned long clk_nr_clks;
void __iomem *reg_base;
+ struct rockchip_aux_grf *ioc_grf_e;
struct rockchip_aux_grf *pmu0_grf_e;
+ struct regmap *ioc_grf;
struct regmap *pmu0_grf;
clk_nr_clks = rockchip_clk_find_max_clk_id(rk3576_clk_branches,
@@ -1739,6 +1750,12 @@ static void __init rk3576_clk_init(struct device_node *np)
return;
}
+ ioc_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3576-ioc-grf");
+ if (IS_ERR(ioc_grf)) {
+ pr_err("%s: could not get IOC GRF syscon\n", __func__);
+ return;
+ }
+
reg_base = of_iomap(np, 0);
if (!reg_base) {
pr_err("%s: could not map cru region\n", __func__);
@@ -1759,6 +1776,14 @@ static void __init rk3576_clk_init(struct device_node *np)
pmu0_grf_e->type = grf_type_pmu0;
hash_add(ctx->aux_grf_table, &pmu0_grf_e->node, grf_type_pmu0);
+ ioc_grf_e = kzalloc(sizeof(*ioc_grf_e), GFP_KERNEL);
+ if (!ioc_grf_e)
+ goto err_free_pmu0;
+
+ ioc_grf_e->grf = ioc_grf;
+ ioc_grf_e->type = grf_type_ioc;
+ hash_add(ctx->aux_grf_table, &ioc_grf_e->node, grf_type_ioc);
+
rockchip_clk_register_plls(ctx, rk3576_pll_clks,
ARRAY_SIZE(rk3576_pll_clks),
RK3576_GRF_SOC_STATUS0);
@@ -1783,6 +1808,8 @@ static void __init rk3576_clk_init(struct device_node *np)
return;
+err_free_pmu0:
+ kfree(pmu0_grf_e);
err_unmap:
iounmap(reg_base);
return;
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 05/10] arm64: dts: rockchip: Add RK3576 SAI nodes
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
` (3 preceding siblings ...)
2025-05-02 11:03 ` [PATCH v3 04/10] clk: rockchip: add GATE_GRFs for SAI MCLKOUT to rk3576 Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 06/10] arm64: dts: rockchip: Add RK3576 HDMI audio Nicolas Frattaroli
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
The RK3576 SoC has 10 SAI controllers in total. Five of them are in the
video output power domains, and are used for digital audio output along
with the video signal of those, e.g. HDMI audio.
The other five, SAI0 through SAI4, are exposed externally. SAI0 and SAI1
are capable of 8-channel audio, whereas SAI2, SAI3 and SAI4 are limited
to two channels. These five are in the audio power domain.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
arch/arm64/boot/dts/rockchip/rk3576.dtsi | 200 +++++++++++++++++++++++++++++++
1 file changed, 200 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index ddc92ccc530d6757660971f0a609b5127784bb04..7bb906c3cb4e80691abf39d0e57888f79370bc75 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1010,6 +1010,41 @@ vop_mmu: iommu@27d07e00 {
status = "disabled";
};
+ sai5: sai@27d40000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x27d40000 0x0 0x1000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI5_8CH>, <&cru HCLK_SAI5_8CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac2 3>;
+ dma-names = "rx";
+ power-domains = <&power RK3576_PD_VO0>;
+ resets = <&cru SRST_M_SAI5_8CH>, <&cru SRST_H_SAI5_8CH>;
+ reset-names = "m", "h";
+ rockchip,sai-rx-route = <0 1 2 3>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI5";
+ status = "disabled";
+ };
+
+ sai6: sai@27d50000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x27d50000 0x0 0x1000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI6_8CH>, <&cru HCLK_SAI6_8CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac2 4>, <&dmac2 5>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3576_PD_VO0>;
+ resets = <&cru SRST_M_SAI6_8CH>, <&cru SRST_H_SAI6_8CH>;
+ reset-names = "m", "h";
+ rockchip,sai-rx-route = <0 1 2 3>;
+ rockchip,sai-tx-route = <0 1 2 3>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI6";
+ status = "disabled";
+ };
+
hdmi: hdmi@27da0000 {
compatible = "rockchip,rk3576-dw-hdmi-qp";
reg = <0x0 0x27da0000 0x0 0x20000>;
@@ -1050,6 +1085,57 @@ hdmi_out: port@1 {
};
};
+ sai7: sai@27ed0000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x27ed0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI7_8CH>, <&cru HCLK_SAI7_8CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac2 19>;
+ dma-names = "tx";
+ power-domains = <&power RK3576_PD_VO1>;
+ resets = <&cru SRST_M_SAI7_8CH>, <&cru SRST_H_SAI7_8CH>;
+ reset-names = "m", "h";
+ rockchip,sai-tx-route = <0 1 2 3>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI7";
+ status = "disabled";
+ };
+
+ sai8: sai@27ee0000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x27ee0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI8_8CH>, <&cru HCLK_SAI8_8CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac1 7>;
+ dma-names = "tx";
+ power-domains = <&power RK3576_PD_VO1>;
+ resets = <&cru SRST_M_SAI8_8CH>, <&cru SRST_H_SAI8_8CH>;
+ reset-names = "m", "h";
+ rockchip,sai-tx-route = <0 1 2 3>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI8";
+ status = "disabled";
+ };
+
+ sai9: sai@27ef0000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x27ef0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI9_8CH>, <&cru HCLK_SAI9_8CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac0 26>;
+ dma-names = "tx";
+ power-domains = <&power RK3576_PD_VO1>;
+ resets = <&cru SRST_M_SAI9_8CH>, <&cru SRST_H_SAI9_8CH>;
+ reset-names = "m", "h";
+ rockchip,sai-tx-route = <0 1 2 3>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI9";
+ status = "disabled";
+ };
+
qos_hdcp1: qos@27f02000 {
compatible = "rockchip,rk3576-qos", "syscon";
reg = <0x0 0x27f02000 0x0 0x20>;
@@ -1596,6 +1682,120 @@ log_leakage: log-leakage@22 {
};
};
+ sai0: sai@2a600000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x2a600000 0x0 0x1000>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI0_8CH>, <&cru HCLK_SAI0_8CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac0 0>, <&dmac0 1>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3576_PD_AUDIO>;
+ resets = <&cru SRST_M_SAI0_8CH>, <&cru SRST_H_SAI0_8CH>;
+ reset-names = "m", "h";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sai0m0_lrck
+ &sai0m0_sclk
+ &sai0m0_sdi0
+ &sai0m0_sdi1
+ &sai0m0_sdi2
+ &sai0m0_sdi3
+ &sai0m0_sdo0
+ &sai0m0_sdo1
+ &sai0m0_sdo2
+ &sai0m0_sdo3>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI0";
+ status = "disabled";
+ };
+
+ sai1: sai@2a610000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x2a610000 0x0 0x1000>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI1_8CH>, <&cru HCLK_SAI1_8CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac0 2>, <&dmac0 3>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3576_PD_AUDIO>;
+ resets = <&cru SRST_M_SAI1_8CH>, <&cru SRST_H_SAI1_8CH>;
+ reset-names = "m", "h";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sai1m0_lrck
+ &sai1m0_sclk
+ &sai1m0_sdi0
+ &sai1m0_sdo0
+ &sai1m0_sdo1
+ &sai1m0_sdo2
+ &sai1m0_sdo3>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI1";
+ status = "disabled";
+ };
+
+ sai2: sai@2a620000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x2a620000 0x0 0x1000>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI2_2CH>, <&cru HCLK_SAI2_2CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac1 0>, <&dmac1 1>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3576_PD_AUDIO>;
+ resets = <&cru SRST_M_SAI2_2CH>, <&cru SRST_H_SAI2_2CH>;
+ reset-names = "m", "h";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sai2m0_lrck
+ &sai2m0_sclk
+ &sai2m0_sdi
+ &sai2m0_sdo>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI2";
+ status = "disabled";
+ };
+
+ sai3: sai@2a630000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x2a630000 0x0 0x1000>;
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI3_2CH>, <&cru HCLK_SAI3_2CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac1 2>, <&dmac1 3>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3576_PD_AUDIO>;
+ resets = <&cru SRST_M_SAI3_2CH>, <&cru SRST_H_SAI3_2CH>;
+ reset-names = "m", "h";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sai3m0_lrck
+ &sai3m0_sclk
+ &sai3m0_sdi
+ &sai3m0_sdo>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI3";
+ status = "disabled";
+ };
+
+ sai4: sai@2a640000 {
+ compatible = "rockchip,rk3576-sai";
+ reg = <0x0 0x2a640000 0x0 0x1000>;
+ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_SAI4_2CH>, <&cru HCLK_SAI4_2CH>;
+ clock-names = "mclk", "hclk";
+ dmas = <&dmac2 0>, <&dmac2 1>;
+ dma-names = "tx", "rx";
+ power-domains = <&power RK3576_PD_AUDIO>;
+ resets = <&cru SRST_M_SAI4_2CH>, <&cru SRST_H_SAI4_2CH>;
+ reset-names = "m", "h";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sai4m0_lrck
+ &sai4m0_sclk
+ &sai4m0_sdi
+ &sai4m0_sdo>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SAI4";
+ status = "disabled";
+ };
+
gic: interrupt-controller@2a701000 {
compatible = "arm,gic-400";
reg = <0x0 0x2a701000 0 0x10000>,
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 06/10] arm64: dts: rockchip: Add RK3576 HDMI audio
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
` (4 preceding siblings ...)
2025-05-02 11:03 ` [PATCH v3 05/10] arm64: dts: rockchip: Add RK3576 SAI nodes Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 07/10] arm64: dts: rockchip: Add analog audio on RK3576 Sige5 Nicolas Frattaroli
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
The RK3576 SoC now has upstream support for HDMI.
Add an HDMI audio node, which uses SAI6 as its audio controller
according to downstream.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
arch/arm64/boot/dts/rockchip/rk3576.dtsi | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 7bb906c3cb4e80691abf39d0e57888f79370bc75..cb53561f55f3dfb913f40eaab7b0c8e090d23c31 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -413,6 +413,22 @@ scmi_clk: protocol@14 {
};
};
+ hdmi_sound: hdmi-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "HDMI";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ status = "disabled";
+
+ simple-audio-card,codec {
+ sound-dai = <&hdmi>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai6>;
+ };
+ };
+
pmu_a53: pmu-a53 {
compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
@@ -1069,6 +1085,7 @@ hdmi: hdmi@27da0000 {
reset-names = "ref", "hdp";
rockchip,grf = <&ioc_grf>;
rockchip,vo-grf = <&vo0_grf>;
+ #sound-dai-cells = <0>;
status = "disabled";
ports {
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 07/10] arm64: dts: rockchip: Add analog audio on RK3576 Sige5
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
` (5 preceding siblings ...)
2025-05-02 11:03 ` [PATCH v3 06/10] arm64: dts: rockchip: Add RK3576 HDMI audio Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 08/10] arm64: dts: rockchip: Enable HDMI audio on Sige5 Nicolas Frattaroli
` (3 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
The ArmSoM Sige5 board features an Everest ES8388 codec to provide
analog stereo audio output, as well as analog audio input. The codec
hangs off the i2c2 bus and responds to address 0x10. It is connected to
the SAI1 audio controller of the RK3576, with one SDO (output) lane and
one SDI (input) lane.
The codec has two sets of outputs. One set, LOUT1/ROUT1, is connected
through a set of 22uF non-polarised coupling capacitors to a 3-position
connector that appears to be a clone of the JST BM03B-SURS-TF header,
and is capable of mating with a JST 03SUR-32S (or JST 03SUR-36L if you
prefer lemon-lime) or compatible clone connector. The right headphone
output is the one closest to the Type-C DC input connector, the left
headphone output is the one in the middle, and the third position, the
one closest to the USB3 Type-A host connector, is puzzingly labelled as
"HP_GND" in the schematic but is in fact connected to the codecs RIN1
input through a 1uF non-plarised coupling capacitor.
LOUT2 and ROUT2 are routed to 1mm test pads T36 and T37 respectively.
These are located on the bottom of the board, and do not go through any
coupling capacitor. For use as line out, the ES8388 datasheet recommends
adding 1uF coupling capacitor if one wishes to use it as a line-level
output.
There is also a pair of inputs for a stereo microphone, going from two
1mm testpads T34 and T35, which are decoupled with a 100pF capacitor and
pulled to 3.3v and ground respectively. These inputs then go through 1uF
capacitors each and end up in the LINPUT2 and RINPUT2 pins of the
ES8388 codec.
The codec's power inputs are routed to receive 3.3V for both its analog
and digital inputs, though from different supplies.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
.../boot/dts/rockchip/rk3576-armsom-sige5.dts | 56 ++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts b/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
index 570252c4c0bfe56a3c269e47d81fca7676e61787..2c991ad974a95fe1995a8d15eaba3e7b07d4dfb6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
@@ -56,6 +56,34 @@ red_led: red-led {
};
};
+ es8388_sound: es8388-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,name = "On-board Analog ES8388";
+ simple-audio-card,widgets = "Microphone", "Headphone Mic",
+ "Microphone", "Mic Pads",
+ "Headphone", "Headphone",
+ "Line Out", "Line Out";
+ simple-audio-card,routing = "Headphone", "LOUT1",
+ "Headphone", "ROUT1",
+ "Line Out", "LOUT2",
+ "Line Out", "ROUT2",
+ "RINPUT1", "Headphone Mic",
+ "LINPUT2", "Mic Pads",
+ "RINPUT2", "Mic Pads";
+ simple-audio-card,pin-switches = "Headphone", "Line Out";
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai1>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&es8388>;
+ system-clock-frequency = <12288000>;
+ };
+ };
+
vcc_12v0_dcin: regulator-vcc-12v0-dcin {
compatible = "regulator-fixed";
regulator-name = "vcc_12v0_dcin";
@@ -624,6 +652,25 @@ hym8563: rtc@51 {
};
};
+&i2c3 {
+ status = "okay";
+
+ es8388: audio-codec@10 {
+ compatible = "everest,es8388", "everest,es8328";
+ reg = <0x10>;
+ clocks = <&cru CLK_SAI1_MCLKOUT_TO_IO>;
+ AVDD-supply = <&vcca_3v3_s0>;
+ DVDD-supply = <&vcc_3v3_s0>;
+ HPVDD-supply = <&vcca_3v3_s0>;
+ PVDD-supply = <&vcc_3v3_s0>;
+ assigned-clocks = <&cru CLK_SAI1_MCLKOUT_TO_IO>;
+ assigned-clock-rates = <12288000>;
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sai1m0_mclk>;
+ };
+};
+
&mdio0 {
rgmii_phy0: phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
@@ -680,6 +727,15 @@ pcie_reset: pcie-reset {
};
};
+&sai1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sai1m0_lrck
+ &sai1m0_sclk
+ &sai1m0_sdi0
+ &sai1m0_sdo0>;
+ status = "okay";
+};
+
&sdhci {
bus-width = <8>;
full-pwr-cycle-in-suspend;
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 08/10] arm64: dts: rockchip: Enable HDMI audio on Sige5
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
` (6 preceding siblings ...)
2025-05-02 11:03 ` [PATCH v3 07/10] arm64: dts: rockchip: Add analog audio on RK3576 Sige5 Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 09/10] arm64: defconfig: Enable Rockchip SAI Nicolas Frattaroli
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
With the hdmi_sound node added to the base RK3576 SoC tree, we can now
enable it on the Sige5 SBC.
Do this, and also enable the corresponding SAI6 audio controller node.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts b/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
index 2c991ad974a95fe1995a8d15eaba3e7b07d4dfb6..b09e789c75c47fec7cf7e9810ab0dcca32d9404a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
@@ -275,6 +275,10 @@ hdmi_out_con: endpoint {
};
};
+&hdmi_sound {
+ status = "okay";
+};
+
&hdptxphy {
status = "okay";
};
@@ -736,6 +740,10 @@ &sai1m0_sdi0
status = "okay";
};
+&sai6 {
+ status = "okay";
+};
+
&sdhci {
bus-width = <8>;
full-pwr-cycle-in-suspend;
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 09/10] arm64: defconfig: Enable Rockchip SAI
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
` (7 preceding siblings ...)
2025-05-02 11:03 ` [PATCH v3 08/10] arm64: dts: rockchip: Enable HDMI audio on Sige5 Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-02 11:03 ` [PATCH v3 10/10] arm64: defconfig: enable ES8328 and ES8328_I2C Nicolas Frattaroli
2025-05-05 20:51 ` (subset) [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Heiko Stuebner
10 siblings, 0 replies; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
The RK3576 uses Rockchip SAI for audio output.
Enable it in the defconfig.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 1b8e4abf5fbd8556c6e0c329cdff86512991b2e5..22cf6fb2774aef18c54c2435e4b3ff1b94c1a6b1 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1009,6 +1009,7 @@ CONFIG_SND_SOC_SC7280=m
CONFIG_SND_SOC_X1E80100=m
CONFIG_SND_SOC_ROCKCHIP=m
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=m
+CONFIG_SND_SOC_ROCKCHIP_SAI=m
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
CONFIG_SND_SOC_ROCKCHIP_RT5645=m
CONFIG_SND_SOC_RK3399_GRU_SOUND=m
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 10/10] arm64: defconfig: enable ES8328 and ES8328_I2C
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
` (8 preceding siblings ...)
2025-05-02 11:03 ` [PATCH v3 09/10] arm64: defconfig: Enable Rockchip SAI Nicolas Frattaroli
@ 2025-05-02 11:03 ` Nicolas Frattaroli
2025-05-05 15:53 ` Krzysztof Kozlowski
2025-05-05 20:51 ` (subset) [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Heiko Stuebner
10 siblings, 1 reply; 13+ messages in thread
From: Nicolas Frattaroli @ 2025-05-02 11:03 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Heiko Stuebner, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Philipp Zabel, Catalin Marinas,
Will Deacon, Sugar Zhang
Cc: devicetree, Sebastian Reichel, linux-sound, linux-kernel,
linux-rockchip, kernel, Luca Ceresoli, linux-clk,
linux-arm-kernel
The ArmSoM Sige5 board, which is supported in mainline, uses the ES8328
audio driver for audio output on its ES8388 codec controlled through I2C.
Enable them as a module.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
arch/arm64/configs/defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 22cf6fb2774aef18c54c2435e4b3ff1b94c1a6b1..c5a3d35e6196029560da4f39a5298c532756a670 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1048,6 +1048,8 @@ CONFIG_SND_SOC_DA7213=m
CONFIG_SND_SOC_ES7134=m
CONFIG_SND_SOC_ES7241=m
CONFIG_SND_SOC_ES8316=m
+CONFIG_SND_SOC_ES8328=m
+CONFIG_SND_SOC_ES8328_I2C=m
CONFIG_SND_SOC_GTM601=m
CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
--
2.49.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 10/10] arm64: defconfig: enable ES8328 and ES8328_I2C
2025-05-02 11:03 ` [PATCH v3 10/10] arm64: defconfig: enable ES8328 and ES8328_I2C Nicolas Frattaroli
@ 2025-05-05 15:53 ` Krzysztof Kozlowski
0 siblings, 0 replies; 13+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-05 15:53 UTC (permalink / raw)
To: Nicolas Frattaroli, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Liam Girdwood,
Mark Brown, Jaroslav Kysela, Takashi Iwai, Philipp Zabel,
Catalin Marinas, Will Deacon, Sugar Zhang
Cc: Luca Ceresoli, Sebastian Reichel, kernel, linux-clk, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, linux-sound
On 02/05/2025 13:03, Nicolas Frattaroli wrote:
> The ArmSoM Sige5 board, which is supported in mainline, uses the ES8328
> audio driver for audio output on its ES8388 codec controlled through I2C.
>
> Enable them as a module.
Squash these patches. It is one defconfig update, not one commit per one
symbol.
Best regards,
Krzysztof
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: (subset) [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support
2025-05-02 11:03 [PATCH v3 00/10] Add RK3576 SAI Audio Controller Support Nicolas Frattaroli
` (9 preceding siblings ...)
2025-05-02 11:03 ` [PATCH v3 10/10] arm64: defconfig: enable ES8328 and ES8328_I2C Nicolas Frattaroli
@ 2025-05-05 20:51 ` Heiko Stuebner
10 siblings, 0 replies; 13+ messages in thread
From: Heiko Stuebner @ 2025-05-05 20:51 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
Takashi Iwai, Philipp Zabel, Catalin Marinas, Will Deacon,
Sugar Zhang, Nicolas Frattaroli
Cc: Heiko Stuebner, Luca Ceresoli, Sebastian Reichel, kernel,
linux-clk, devicetree, linux-arm-kernel, linux-rockchip,
linux-kernel, linux-sound, Krzysztof Kozlowski
On Fri, 02 May 2025 13:03:06 +0200, Nicolas Frattaroli wrote:
> This series adds support for Rockchip's Serial Audio Interface (SAI)
> controller, found on SoCs such as the RK3576. The SAI is a flexible
> controller IP that allows both transmitting and receiving digital audio
> in the I2S, TDM and PCM formats. Instances of this controller are used
> both for externally exposed audio interfaces, as well as for audio on
> video interfaces such as HDMI.
>
> [...]
Applied, thanks!
[01/10] dt-bindings: clock: rk3576: add IOC gated clocks
commit: 4210f21c004a18aad11c55bdaf552e649a4fd286
[02/10] clk: rockchip: introduce auxiliary GRFs
commit: 70a114daf2077472e58b3cac23ba8998e35352f4
[03/10] clk: rockchip: introduce GRF gates
commit: e277168cabe9fd99e647f5dad0bc846d5d6b0093
[04/10] clk: rockchip: add GATE_GRFs for SAI MCLKOUT to rk3576
commit: 9199ec29f0977efee223791c9ee3eb402d23f8ba
Best regards,
--
Heiko Stuebner <heiko@sntech.de>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 13+ messages in thread