Re: [RFC] clk: meson: t7: Intermittent boot instability and memory corruption on VIM4

From: Lucas Tanure

Date: Wed Aug 26 2026 - 16:05:03 EST


On 26/08/2026 18:17, Brian Masney wrote:
Hi Lucas,

On Wed, Aug 26, 2026 at 05:42:01PM +0100, Lucas Tanure wrote:
With Brian's patches, VIM4 does not turn off 4 clocks:

t7_sys_sd_emmc_b
t7_sys_sd_emmc_c
sd_emmc_b
sd_emmc_c

This is expected since I'm trying to run from an SD card. However, even with
these four clocks kept enabled, the board still hangs.

Complete list with all clocks being disabled after Brians patches:
[ 1.002247] clk: Disabled unused clock: t7_sys_pwm_ao_gh
[ 1.002898] clk: Disabled unused clock: t7_sys_pwm_ao_ef
[ 1.003560] clk: Disabled unused clock: t7_sys_pwm_ao_cd
[ 1.004220] clk: Disabled unused clock: t7_sys_pwm_ao_ab
[ 1.004972] clk: Disabled unused clock: t7_sys_pwm_ef
[ 1.005509] clk: Disabled unused clock: t7_sys_pwm_cd
[ 1.006211] clk: Disabled unused clock: t7_sys_pwm_ab
[ 1.006766] clk: Disabled unused clock: t7_sys_ts_hevc
[ 1.007434] clk: Disabled unused clock: t7_sys_ts_vpu
[ 1.008033] clk: Disabled unused clock: t7_sys_ts_nna
[ 1.008741] clk: Disabled unused clock: t7_sys_ts_gpu
[ 1.009294] clk: Disabled unused clock: t7_sys_sar_adc
[ 1.009929] clk: Disabled unused clock: t7_sys_vpu_intr
[ 1.010609] clk: Disabled unused clock: t7_sys_dspb
[ 1.011186] clk: Disabled unused clock: t7_sys_dspa
[ 1.011792] clk: Disabled unused clock: t7_sys_a73pclk_apb
[ 1.012554] clk: Disabled unused clock: t7_sys_pclk_sys_apb
[ 1.013213] clk: Disabled unused clock: t7_sys_rsa
[ 1.013811] clk: Disabled unused clock: t7_sys_mipi_isp_pclk
[ 1.014529] clk: Disabled unused clock: t7_sys_mmc_apb
[ 1.015107] clk: Disabled unused clock: t7_sys_hdmirx_pclk
[ 1.015819] clk: Disabled unused clock: t7_sys_i2c_s_a
[ 1.016429] clk: Disabled unused clock: t7_sys_hdmitx_apb
[ 1.017109] clk: Disabled unused clock: t7_sys_i2c_m_f
[ 1.017740] clk: Disabled unused clock: t7_sys_i2c_m_e
[ 1.018379] clk: Disabled unused clock: t7_sys_i2c_m_d
[ 1.019018] clk: Disabled unused clock: t7_sys_i2c_m_c
[ 1.019657] clk: Disabled unused clock: t7_sys_i2c_m_b
[ 1.020296] clk: Disabled unused clock: t7_sys_i2c_m_a
[ 1.020940] clk: Disabled unused clock: t7_sys_i2c_ao_b
[ 1.021585] clk: Disabled unused clock: t7_sys_i2c_ao_a
[ 1.022236] clk: Disabled unused clock: t7_sys_pcie_phy
[ 1.022885] clk: Disabled unused clock: t7_sys_usb
[ 1.023482] clk: Disabled unused clock: t7_sys_pcie
[ 1.024088] clk: Disabled unused clock: t7_sys_spicc1
[ 1.024723] clk: Disabled unused clock: t7_sys_spicc0
[ 1.025345] clk: Disabled unused clock: t7_sys_g2d
[ 1.025940] clk: Disabled unused clock: t7_sys_spicc5
[ 1.026569] clk: Disabled unused clock: t7_sys_ts_a53
[ 1.027197] clk: Disabled unused clock: t7_sys_ts_a73
[ 1.027825] clk: Disabled unused clock: t7_sys_spicc4
[ 1.028454] clk: Disabled unused clock: t7_sys_spicc3
[ 1.029085] clk: Disabled unused clock: t7_sys_spicc2
[ 1.029710] clk: Disabled unused clock: t7_sys_aififo
[ 1.030339] clk: Disabled unused clock: t7_sys_uart_f
[ 1.030967] clk: Disabled unused clock: t7_sys_uart_e
[ 1.031595] clk: Disabled unused clock: t7_sys_uart_d
[ 1.032224] clk: Disabled unused clock: t7_sys_uart_c
[ 1.032857] clk: Disabled unused clock: t7_sys_uart_b
[ 1.033482] clk: Disabled unused clock: t7_sys_eth
[ 1.034077] clk: Disabled unused clock: t7_sys_audio
[ 1.034694] clk: Disabled unused clock: t7_sys_ir_ctrl
[ 1.035333] clk: Disabled unused clock: t7_sys_msr_clk
[ 1.035972] clk: Disabled unused clock: t7_sys_spifc
[ 1.036596] clk: Disabled unused clock: t7_sys_acodec
[ 1.037218] clk: Disabled unused clock: t7_sys_smartcard
[ 1.037880] clk: Disabled unused clock: t7_sys_am2axi2
[ 1.038518] clk: Disabled unused clock: t7_sys_am2axi1
[ 1.039157] clk: Disabled unused clock: t7_sys_am2axi0
[ 1.039796] clk: Disabled unused clock: t7_sys_ampipe_eth
[ 1.040468] clk: Disabled unused clock: t7_sys_ampipe_nand
[ 1.041155] clk: Disabled unused clock: t7_sys_deswarp
[ 1.041790] clk: Disabled unused clock: t7_sys_gdc
[ 1.042385] clk: Disabled unused clock: t7_sys_cec
[ 1.042981] clk: Disabled unused clock: t7_sys_aucpu
[ 1.043600] clk: Disabled unused clock: t7_sys_aocpu
[ 1.044217] clk: Disabled unused clock: t7_sys_mali
[ 1.044830] clk: Disabled unused clock: t7_sys_ethphy
[ 1.045451] clk: Disabled unused clock: t7_sys_mipi_dsi_b
[ 1.046123] clk: Disabled unused clock: t7_sys_mipi_dsi_a
[ 1.046795] clk: Disabled unused clock: t7_sys_dos
[ 1.047390] clk: Disabled unused clock: t7_sys_ddr
[ 1.047991] clk: Disabled unused clock: pwm_ao_g
[ 1.048565] clk: Disabled unused clock: pwm_ao_f
[ 1.049135] clk: Disabled unused clock: pwm_ao_e
[ 1.049709] clk: Disabled unused clock: pwm_ao_d
[ 1.050283] clk: Disabled unused clock: pwm_ao_b
[ 1.050857] clk: Disabled unused clock: pwm_ao_a
[ 1.051454] clk: Disabled unused clock: rtc_dualdiv
[ 1.052038] clk: Disabled unused clock: rtc_duandiv_in

Also with the patches the disable happens 0.5 second later, from 0.5 seconds
after the boot to 1 second after the boot.

I am still investigating what is missing a consumer or what should be
labeled critical.

I've seen cases where a clock is modeled in Linux, but isn't actually
used by Linux, so it gets caught in the disable unused clocks sweep.

Does the board immediately crash after the disable unused clock sweep?
yes> If so, you could add a log statement, then 1 second sleep in
clk_disable_unused_subtree() and wait for the board to crash.
good idea , thanks

If you can't get timely help from the vendor, then you can add
CLK_IGNORE_UNUSED to all of those clocks, and slowly start taking them
off in batches and wait for the crash.
That's what I've been doing for the past few weeks, but I'm probably hunting down a set of clock issues, as support for this board is still in its early stages. It's a combination of clocks, which makes it way more time-consuming.

I went with a more localized approach:

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 2b6fae54702a..3358f4dc871f 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1489,14 +1489,95 @@ static void clk_unprepare_unused_subtree(struct clk_core *core,
else if (core->ops->unprepare)
core->ops->unprepare(core->hw);
trace_clk_unprepare_complete(core);
+ pr_info("clk: V Unprepared unused clock: %s\n", core->name);
}
}

+static const char * const disable_clocks[] = {
+ "t7_sys_pwm_ao_gh",
+ "t7_sys_pwm_ao_ef",
+ "t7_sys_pwm_ef",
+ "t7_sys_pwm_cd",
+ "t7_sys_pwm_ab",
+ "t7_sys_ts_hevc",
+ "t7_sys_ts_vpu",
+ "t7_sys_ts_nna",
+ "t7_sys_ts_gpu",
+ "t7_sys_sar_adc",
+ "t7_sys_vpu_intr",
+ "t7_sys_dspb",
+ "t7_sys_dspa",
+ "t7_sys_a73pclk_apb",
+ "t7_sys_pclk_sys_apb",
+ "t7_sys_rsa",
+ "t7_sys_mipi_isp_pclk",
+ "t7_sys_mmc_apb",
+ "t7_sys_hdmirx_pclk",
+ "t7_sys_i2c_s_a",
+ "t7_sys_hdmitx_apb",
+ "t7_sys_i2c_m_f",
+ "t7_sys_i2c_m_e",
+ "t7_sys_i2c_m_d",
+ "t7_sys_i2c_m_c",
+ "t7_sys_i2c_m_b",
+ "t7_sys_i2c_m_a",
+ "t7_sys_i2c_ao_b",
+ "t7_sys_i2c_ao_a",
+ "t7_sys_pcie_phy",
+ "t7_sys_usb",
+ "t7_sys_pcie",
+ "t7_sys_spicc1",
+ "t7_sys_spicc0",
+ "t7_sys_g2d",
+ "t7_sys_spicc5",
+ "t7_sys_ts_a53",
+ "t7_sys_ts_a73",
+ "t7_sys_spicc4",
+ "t7_sys_spicc3",
+ "t7_sys_spicc2",
+ "t7_sys_aififo",
+ "t7_sys_uart_f",
+ "t7_sys_uart_e",
+ "t7_sys_uart_d",
+ "t7_sys_uart_c",
+ "t7_sys_uart_b",
+ "t7_sys_eth",
+ "t7_sys_audio",
+ "t7_sys_ir_ctrl",
+ "t7_sys_msr_clk",
+ "t7_sys_spifc",
+ "t7_sys_acodec",
+ "t7_sys_smartcard",
+ "t7_sys_am2axi2",
+ "t7_sys_am2axi1",
+ "t7_sys_am2axi0",
+ "t7_sys_ampipe_eth",
+ "t7_sys_ampipe_nand",
+ "t7_sys_deswarp",
+ "t7_sys_gdc",
+ "t7_sys_cec",
+ "t7_sys_aucpu",
+ "t7_sys_aocpu",
+ "t7_sys_mali",
+ "t7_sys_ethphy",
+ "t7_sys_mipi_dsi_b",
+ "t7_sys_mipi_dsi_a",
+ "t7_sys_dos",
+ "t7_sys_ddr",
+ "pwm_ao_g",
+ "pwm_ao_e",
+ "pwm_ao_a",
+ "rtc_dualdiv",
+ "rtc_duandiv_in",
+};
+
+
static void clk_disable_unused_subtree(struct clk_core *core,
struct device *dev)
{
struct clk_core *child;
unsigned long flags;
+ int i;

lockdep_assert_held(&prepare_lock);

@@ -1517,6 +1598,11 @@ static void clk_disable_unused_subtree(struct clk_core *core,
if (core->flags & CLK_IGNORE_UNUSED)
goto unlock_out;

+ for (i = 0; i < ARRAY_SIZE(disable_clocks); i++) {
+ if (strcmp(core->name, disable_clocks[i]) == 0)
+ goto unlock_out;
+ }
+
/*
* some gate clocks have special needs during the disable-unused
* sequence. call .disable_unused if available, otherwise fall
@@ -1529,6 +1615,7 @@ static void clk_disable_unused_subtree(struct clk_core *core,
else if (core->ops->disable)
core->ops->disable(core->hw);
trace_clk_disable_complete(core);
+ pr_info("clk: V Disabled unused clock: %s\n", core->name);
}

This makes it easier to let the sweep disable clocks for testing.


Brian

Thanks
Lucas