[PATCH v2] drm/vc4: hdmi: Fix HSM clock too low on Pi4

Maxime Ripard maxime at cerno.tech
Fri Oct 28 11:29:33 UTC 2022


Hi Javier,

On Thu, Oct 27, 2022 at 05:25:49PM +0200, Javier Martinez Canillas wrote:
> On 10/21/22 15:13, maxime at cerno.tech wrote:
> > Commit ae71ab585c81 ("drm/vc4: hdmi: Enforce the minimum rate at
> > runtime_resume") reintroduced the call to clk_set_min_rate in an attempt
> > to fix the boot without a monitor connected on the RaspberryPi3.
> > 
> > However, that introduced a regression breaking the display output
> > entirely (black screen but no vblank timeout) on the Pi4.
> > 
> > This is due to the fact that we now have in a typical modeset at boot,
> > in vc4_hdmi_encoder_pre_crtc_configure(), we have a first call to
> > clk_set_min_rate() asking for the minimum rate of the HSM clock for our
> > given resolution, and then a call to pm_runtime_resume_and_get(). We
> > will thus execute vc4_hdmi_runtime_resume() which, since the commit
> > mentioned above, will call clk_set_min_rate() a second time with the
> > absolute minimum rate we want to enforce on the HSM clock.
> > 
> > We're thus effectively erasing the minimum mandated by the mode we're
> > trying to set. The fact that only the Pi4 is affected is due to the fact
> > that it uses a different clock driver that tries to minimize the HSM
> > clock at all time. It will thus lower the HSM clock rate to 120MHz on
> > the second clk_set_min_rate() call.
> > 
> > The Pi3 doesn't use the same driver and will not change the frequency on
> > the second clk_set_min_rate() call since it's still within the new
> > boundaries and it doesn't have the code to minimize the clock rate as
> > needed. So even though the boundaries are still off, the clock rate is
> > still the right one for our given mode, so everything works.
> > 
> > There is a lot of moving parts, so I couldn't find any obvious
> > solution:
> > 
> >   - Reverting the original is not an option, as that would break the Pi3
> >     again.
> > 
> >   - We can't move the clk_set_min_rate() call in _pre_crtc_configure()
> >     since because, on the Pi3, the HSM clock has the CLK_SET_RATE_GATE
> >     flag which prevents the clock rate from being changed after it's
> >     been enabled. Our calls to clk_set_min_rate() can change it, so they
> >     need to be done before clk_prepare_enable().
> > 
> >   - We can't remove the call to clk_prepare_enable() from the
> >     runtime_resume hook to put it into _pre_crtc_configure() either,
> >     since we need that clock to be enabled to access the registers, and
> >     we can't count on the fact that the display will be active in all
> >     situations (doing any CEC operation, or listing the modes while
> >     inactive are valid for example()).
> > 
> >   - We can't drop the call to clk_set_min_rate() in
> >     _pre_crtc_configure() since we would need to still enforce the
> >     minimum rate for a given resolution, and runtime_resume doesn't have
> >     access to the current mode, if there's any.
> > 
> >   - We can't copy the TMDS character rate into vc4_hdmi and reuse it
> >     since, because it's part of the KMS atomic state, it needs to be
> >     protected by a mutex. Unfortunately, some functions (CEC operations,
> >     mostly) can be reentrant (through the CEC framework) and still need
> >     a pm_runtime_get.
> > 
> > However, we can work around this issue by leveraging the fact that the
> > clk_set_min_rate() calls set boundaries for its given struct clk, and
> > that each different clk_get() call will return a different instance of
> > struct clk. The clock framework will then aggregate the boundaries for
> > each struct clk instances linked to a given clock, plus its hardware
> > boundaries, and will use that.
> > 
> > We can thus get an extra HSM clock user for runtime_pm use only, and use
> > our different clock instances depending on the context: runtime_pm will
> > use its own to set the absolute minimum clock setup so that we never
> > lock the CPU waiting for a register access, and the modeset part will
> > set its requirement for the current resolution. And we let the CCF do
> > the coordination.
> > 
> > It's not an ideal solution, but it's fairly unintrusive and doesn't
> > really change any part of the logic so it looks like a rather safe fix.
> > 
> 
> What a great commit message. I learned a couple of things from it :)
> 
> [...]
> 
> Maybe adding some comments here explaining why two instances of the
> same clock are getting by the driver? It's very clear after reading
> your commit message, but it may not be for someone looking the code.

Yeah, possibly. I have every intention on switching to the same clock
driver for the Pi 0-3 and Pi4 (patches have been sent already), and
reverting that commit and a few others in a few releases.

I've already tested that everything works with the firmware clocks + the
reverts, so it's just a matter of letting enough time for everybody to
catch up. So that patch is just transitory and is just meant to fix the
code right now.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20221028/ea54c8d5/attachment.sig>


More information about the dri-devel mailing list