clk: bcm: rpi: Restore the requested rate when preparing a clock - #7565
clk: bcm: rpi: Restore the requested rate when preparing a clock#7565mairacanal wants to merge 1 commit into
Conversation
Lowering the rate on unprepare writes to the firmware directly, so the rate the clock framework has cached keeps describing a state the hardware is no longer in. Nothing puts that rate back. A consumer that requests the same rate it had requested before the clock was unprepared is short-circuited by clk_core_set_rate_nolock(), which skips clocks that are already at the requested rate, so .set_rate is never reached. The clock is re-enabled at the rate unprepare left behind, and neither the consumer nor the framework has any indication that the request had no effect. Restore the rate the framework last resolved when preparing a clock, so that lowering the rate on unprepare stays invisible to consumers. Fixes: 0276d66 ("clk: bcm: rpi: Manage clock rate in prepare/unprepare callbacks") Signed-off-by: Maíra Canal <mcanal@igalia.com>
|
I do locally have an exactly equivalent change claude came up with. But I wasn't able to provoke the failure mode reported (I believe that pixel clock being marked critical avoided that code path). But I do agree this patch is wanted. |
I wasn't able to reproduce it as well, but from the user's report, I believe that this change makes sense. I'm planning on testing if we can remove some of these |
|
You may hit some of the known firmware issues when removing |
|
Tested the patch on the board from the issue, on top of rpi-6.18.y at 59abfb5. It doesn't help: first modeset still comes up at the firmware minimum, and after a DPMS off/on cycle I think the problem is these clocks are registered with |
Lowering the rate on unprepare writes to the firmware directly, so the rate the clock framework has cached keeps describing a state the hardware is no longer in.
Nothing puts that rate back. A consumer that requests the same rate it had requested before the clock was unprepared is short-circuited by clk_core_set_rate_nolock(), which skips clocks that are already at the requested rate, so .set_rate is never reached. The clock is re-enabled at the rate unprepare left behind, and neither the consumer nor the framework has any indication that the request had no effect.
Restore the rate the framework last resolved when preparing a clock, so that lowering the rate on unprepare stays invisible to consumers.