[PATCH 3/3] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO

Daniele Briguglio posted 3 patches 3 weeks ago
There is a newer version of this series
[PATCH 3/3] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
Posted by Daniele Briguglio 3 weeks ago
The I2S MCLK outputs on RK3588 are gated by bits in the SYS_GRF
register SOC_CON6 (offset 0x318). These gates control whether the
internal CRU MCLK signals reach the external IO pins connected to
audio codecs.

The kernel should explicitly manage these gates so that audio
functionality does not depend on bootloader register state. This is
analogous to what was done for RK3576 SAI MCLK outputs [1].

Register the SYS_GRF as an auxiliary GRF with grf_type_sys in the
early clock init, and add GATE_GRF entries for all four I2S MCLK
output gates:

  - I2S0_8CH_MCLKOUT_TO_IO (bit 0)
  - I2S1_8CH_MCLKOUT_TO_IO (bit 1)
  - I2S2_2CH_MCLKOUT_TO_IO (bit 2)
  - I2S3_2CH_MCLKOUT_TO_IO (bit 7)

Board DTS files that need MCLK on an IO pin can reference these
clocks, e.g.:

    clocks = <&cru I2S0_8CH_MCLKOUT_TO_IO>;

Tested on the Youyeetoo YY3588 (RK3588) with an ES8388 codec on I2S0.

[1] https://lore.kernel.org/r/20250305-rk3576-sai-v1-2-64e6cf863e9a@collabora.com/

Signed-off-by: Daniele Briguglio <hello@superkali.me>
---
 drivers/clk/rockchip/clk-rk3588.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
index 1694223f4f84..0e550642c655 100644
--- a/drivers/clk/rockchip/clk-rk3588.c
+++ b/drivers/clk/rockchip/clk-rk3588.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
@@ -892,6 +893,8 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
 			RK3588_CLKGATE_CON(8), 0, GFLAGS),
 	MUX(I2S2_2CH_MCLKOUT, "i2s2_2ch_mclkout", i2s2_2ch_mclkout_p, CLK_SET_RATE_PARENT,
 			RK3588_CLKSEL_CON(30), 2, 1, MFLAGS),
+	GATE_GRF(I2S2_2CH_MCLKOUT_TO_IO, "i2s2_2ch_mclkout_to_io", "i2s2_2ch_mclkout",
+			0, 0x0318, 2, GFLAGS, grf_type_sys),
 
 	COMPOSITE(CLK_I2S3_2CH_SRC, "clk_i2s3_2ch_src", gpll_aupll_p, 0,
 			RK3588_CLKSEL_CON(30), 8, 1, MFLAGS, 3, 5, DFLAGS,
@@ -907,6 +910,8 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
 			RK3588_CLKGATE_CON(8), 4, GFLAGS),
 	MUX(I2S3_2CH_MCLKOUT, "i2s3_2ch_mclkout", i2s3_2ch_mclkout_p, CLK_SET_RATE_PARENT,
 			RK3588_CLKSEL_CON(32), 2, 1, MFLAGS),
+	GATE_GRF(I2S3_2CH_MCLKOUT_TO_IO, "i2s3_2ch_mclkout_to_io", "i2s3_2ch_mclkout",
+			0, 0x0318, 7, GFLAGS, grf_type_sys),
 	GATE(PCLK_ACDCDIG, "pclk_acdcdig", "pclk_audio_root", 0,
 			RK3588_CLKGATE_CON(7), 11, GFLAGS),
 	GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio_root", 0,
@@ -935,6 +940,8 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
 			RK3588_CLKGATE_CON(7), 10, GFLAGS),
 	MUX(I2S0_8CH_MCLKOUT, "i2s0_8ch_mclkout", i2s0_8ch_mclkout_p, CLK_SET_RATE_PARENT,
 			RK3588_CLKSEL_CON(28), 2, 2, MFLAGS),
+	GATE_GRF(I2S0_8CH_MCLKOUT_TO_IO, "i2s0_8ch_mclkout_to_io", "i2s0_8ch_mclkout",
+			0, 0x0318, 0, GFLAGS, grf_type_sys),
 
 	GATE(HCLK_PDM1, "hclk_pdm1", "hclk_audio_root", 0,
 			RK3588_CLKGATE_CON(9), 6, GFLAGS),
@@ -2220,6 +2227,8 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
 			RK3588_PMU_CLKGATE_CON(2), 13, GFLAGS),
 	MUX(I2S1_8CH_MCLKOUT, "i2s1_8ch_mclkout", i2s1_8ch_mclkout_p, CLK_SET_RATE_PARENT,
 			RK3588_PMU_CLKSEL_CON(9), 2, 2, MFLAGS),
+	GATE_GRF(I2S1_8CH_MCLKOUT_TO_IO, "i2s1_8ch_mclkout_to_io", "i2s1_8ch_mclkout",
+			0, 0x0318, 1, GFLAGS, grf_type_sys),
 	GATE(PCLK_PMU1, "pclk_pmu1", "pclk_pmu0_root", CLK_IS_CRITICAL,
 			RK3588_PMU_CLKGATE_CON(1), 0, GFLAGS),
 	GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "clk_pmu0", CLK_IGNORE_UNUSED,
@@ -2439,6 +2448,8 @@ static struct rockchip_clk_branch rk3588_clk_branches[] = {
 static void __init rk3588_clk_early_init(struct device_node *np)
 {
 	struct rockchip_clk_provider *ctx;
+	struct rockchip_aux_grf *sys_grf_e;
+	struct regmap *sys_grf;
 	unsigned long clk_nr_clks, max_clk_id1, max_clk_id2;
 	void __iomem *reg_base;
 
@@ -2479,6 +2490,17 @@ static void __init rk3588_clk_early_init(struct device_node *np)
 			&rk3588_cpub1clk_data, rk3588_cpub1clk_rates,
 			ARRAY_SIZE(rk3588_cpub1clk_rates));
 
+	/* Register SYS_GRF for I2S MCLK output to IO gate clocks */
+	sys_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3588-sys-grf");
+	if (!IS_ERR(sys_grf)) {
+		sys_grf_e = kzalloc_obj(*sys_grf_e);
+		if (sys_grf_e) {
+			sys_grf_e->grf = sys_grf;
+			sys_grf_e->type = grf_type_sys;
+			hash_add(ctx->aux_grf_table, &sys_grf_e->node, grf_type_sys);
+		}
+	}
+
 	rockchip_clk_register_branches(ctx, rk3588_early_clk_branches,
 				       ARRAY_SIZE(rk3588_early_clk_branches));
 

-- 
2.53.0
Re: [PATCH 3/3] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
Posted by kernel test robot 2 weeks, 4 days ago
Hi Daniele,

kernel test robot noticed the following build errors:

[auto build test ERROR on b84a0ebe421ca56995ff78b66307667b62b3a900]

url:    https://github.com/intel-lab-lkp/linux/commits/Daniele-Briguglio/dt-bindings-clock-rockchip-rk3588-cru-add-I2S-MCLK-output-to-IO-clock-IDs/20260316-222240
base:   b84a0ebe421ca56995ff78b66307667b62b3a900
patch link:    https://lore.kernel.org/r/20260316-rk3588-mclk-gate-grf-v1-3-66fb9a246718%40superkali.me
patch subject: [PATCH 3/3] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
config: arm-allyesconfig (https://download.01.org/0day-ci/archive/20260319/202603191419.MH6EuPga-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260319/202603191419.MH6EuPga-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603191419.MH6EuPga-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/clk/rockchip/clk-rk3588.c: In function 'rk3588_clk_early_init':
>> drivers/clk/rockchip/clk-rk3588.c:2496:29: error: implicit declaration of function 'kzalloc_obj' [-Wimplicit-function-declaration]
    2496 |                 sys_grf_e = kzalloc_obj(*sys_grf_e);
         |                             ^~~~~~~~~~~
>> drivers/clk/rockchip/clk-rk3588.c:2496:27: error: assignment to 'struct rockchip_aux_grf *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    2496 |                 sys_grf_e = kzalloc_obj(*sys_grf_e);
         |                           ^


vim +/kzalloc_obj +2496 drivers/clk/rockchip/clk-rk3588.c

  2447	
  2448	static void __init rk3588_clk_early_init(struct device_node *np)
  2449	{
  2450		struct rockchip_clk_provider *ctx;
  2451		struct rockchip_aux_grf *sys_grf_e;
  2452		struct regmap *sys_grf;
  2453		unsigned long clk_nr_clks, max_clk_id1, max_clk_id2;
  2454		void __iomem *reg_base;
  2455	
  2456		max_clk_id1 = rockchip_clk_find_max_clk_id(rk3588_clk_branches,
  2457						ARRAY_SIZE(rk3588_clk_branches));
  2458		max_clk_id2 = rockchip_clk_find_max_clk_id(rk3588_early_clk_branches,
  2459						ARRAY_SIZE(rk3588_early_clk_branches));
  2460		clk_nr_clks = max(max_clk_id1, max_clk_id2) + 1;
  2461	
  2462		reg_base = of_iomap(np, 0);
  2463		if (!reg_base) {
  2464			pr_err("%s: could not map cru region\n", __func__);
  2465			return;
  2466		}
  2467	
  2468		ctx = rockchip_clk_init_early(np, reg_base, clk_nr_clks);
  2469		if (IS_ERR(ctx)) {
  2470			pr_err("%s: rockchip clk init failed\n", __func__);
  2471			iounmap(reg_base);
  2472			return;
  2473		}
  2474		early_ctx = ctx;
  2475	
  2476		rockchip_clk_register_plls(ctx, rk3588_pll_clks,
  2477					   ARRAY_SIZE(rk3588_pll_clks),
  2478					   RK3588_GRF_SOC_STATUS0);
  2479	
  2480		rockchip_clk_register_armclk(ctx, ARMCLK_L, "armclk_l",
  2481				mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p),
  2482				&rk3588_cpulclk_data, rk3588_cpulclk_rates,
  2483				ARRAY_SIZE(rk3588_cpulclk_rates));
  2484		rockchip_clk_register_armclk(ctx, ARMCLK_B01, "armclk_b01",
  2485				mux_armclkb01_p, ARRAY_SIZE(mux_armclkb01_p),
  2486				&rk3588_cpub0clk_data, rk3588_cpub0clk_rates,
  2487				ARRAY_SIZE(rk3588_cpub0clk_rates));
  2488		rockchip_clk_register_armclk(ctx, ARMCLK_B23, "armclk_b23",
  2489				mux_armclkb23_p, ARRAY_SIZE(mux_armclkb23_p),
  2490				&rk3588_cpub1clk_data, rk3588_cpub1clk_rates,
  2491				ARRAY_SIZE(rk3588_cpub1clk_rates));
  2492	
  2493		/* Register SYS_GRF for I2S MCLK output to IO gate clocks */
  2494		sys_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3588-sys-grf");
  2495		if (!IS_ERR(sys_grf)) {
> 2496			sys_grf_e = kzalloc_obj(*sys_grf_e);
  2497			if (sys_grf_e) {
  2498				sys_grf_e->grf = sys_grf;
  2499				sys_grf_e->type = grf_type_sys;
  2500				hash_add(ctx->aux_grf_table, &sys_grf_e->node, grf_type_sys);
  2501			}
  2502		}
  2503	
  2504		rockchip_clk_register_branches(ctx, rk3588_early_clk_branches,
  2505					       ARRAY_SIZE(rk3588_early_clk_branches));
  2506	
  2507		rockchip_clk_of_add_provider(np, ctx);
  2508	}
  2509	CLK_OF_DECLARE_DRIVER(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_early_init);
  2510	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki