Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drm/vc4: Initialization hangs when HDMI display is *not* connected #4457

Closed
kFYatek opened this issue Jul 16, 2021 · 21 comments · Fixed by #4547
Closed

drm/vc4: Initialization hangs when HDMI display is *not* connected #4457

kFYatek opened this issue Jul 16, 2021 · 21 comments · Fixed by #4547

Comments

@kFYatek
Copy link

kFYatek commented Jul 16, 2021

I was working on #4406, and after rebasing the changes onto the current rpi-5.10.y head (e6410af), I found that my Pi3 freezes when trying to initialize the vc4 module. This is not related to my changes, as it happens on e6410af without any changes as well.

After some investigation, I found that everything worked fine after connecting an HDMI display. I was then also able to successfully switch to composite output afterwards through xrandr.

This seems to be somehow related to the 94bc403 commit - the best fix I could find is:

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 5401b6a6f440..768c26b08c15 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -2316,14 +2316,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
                        vc4_hdmi->disable_4kp60 = true;
        }
 
-       /*
-        * We need to have the device powered up at this point to call
-        * our reset hook and for the CEC init.
-        */
-       ret = vc4_hdmi_runtime_resume(dev);
-       if (ret)
-               goto err_put_ddc;
-
        pm_runtime_get_noresume(dev);
        pm_runtime_set_active(dev);
        pm_runtime_enable(dev);

although I don't dare proposing that as a permanent fix, because a) it does not seem to make any sense, b) the Pi still freezes after hot-plugging the HDMI display after having booted without one.

Please excuse me for taking the liberty to tag @mripard in advance - you're the author of that commit, maybe you'll make some sense of it.

Please also note that I did not test any of that behavior on Pi4 (yet).

@mripard
Copy link
Contributor

mripard commented Jul 16, 2021

Indeed, @HiassofT reported it on slack earlier this week too, and I'm currently looking into it.

I'm not sure why you're saying that this part doesn't make sense though?

So far I haven't been able to find what's going on exactly, but it seems to be related to the configuration options on the board. The one used by LibreElec are broken just like yours, but mine aren't for the exact same kernel, board and boot method. Could you share yours?

@kFYatek
Copy link
Author

kFYatek commented Jul 16, 2021

I'm not sure why you're saying that this part doesn't make sense though?

Well, there's a reason (clearly stated in the comment) why you added this call that I removed in my quickfix. And while I don't know much about those power management APIs, as far as I understand, that pm_runtime_put_sync() near the end of the function is supposed to indirectly call vc4_hdmi_runtime_suspend() if the port is not used, effectively forming a clk_prepare_enable() ... clk_disable_unprepare() block as it is supposed to be used. By removing the vc4_hdmi_runtime_resume(), it looks that I'm removing the initial clk_prepare_enable().

However, like I said, I don't know much about the kernel's PM API, so I might be missing something or maybe my analysis is completely wrong.

Could you share yours?

I suppose you mean config.txt? Here you go. It's mostly just defaults, taken from a default Raspberry Pi OS installation from around May 2021, just with the Full KMS driver enabled. All the DTB and DTBO files are taken from the freshly compiled kernel.

BTW, I used firmware revision dc6dc9bc6692d808fcce5ace9d6209d33d5afbac from rpi-update, which seems to be the latest there at the moment. The problem also occurred with the original kernel that goes along with that firmware version.

@mripard
Copy link
Contributor

mripard commented Jul 16, 2021

My bad, I thought you were saying the part you removed didn't make any sense, not that removing it didn't :)

I just found out what made it work in my config.txt, it's hdmi_force_hotplug=1, and neither you nor LibreElec are using it, so it seems consistent. Could you try adding it and see if it fixes it on your side too?

@kFYatek
Copy link
Author

kFYatek commented Jul 16, 2021

Well... yes and no. When I enable hdmi_force_hotplug, the board does not freeze and I can SSH to it, but there is absolutely no video on the composite output (neither during the initial firmware phase nor when X is supposed to start - X does not start at all in fact), and not even on HDMI if I hotplug it later.

I looked into dmesg and there are some nasty things there in that scenario.

@mripard
Copy link
Contributor

mripard commented Jul 16, 2021

I've had it occur a couple of times, but it does look like there's some initialisation or resources taken in the firmware that isn't picked up on, and / or leaves the firmware in a weird state.

@popcornmix, @6by9 do you know what could cause this?

@mripard
Copy link
Contributor

mripard commented Jul 16, 2021

I tested whether it would be the video= parameter set by the firmware on the kernel command line that would cause it, but running without hdmi_force_hotplug but with disable_fw_kms_setup doesn't change anything, so it does look like we fail to enable some resource in the kernel and were relying on it to be enabled by the firmware.

@popcornmix
Copy link
Collaborator

@mripard can you clarify exactly what isn't working for you?

I was interpreting this thread as some firmware setup of hdmi is required by kms driver which makes booting with hdmi uplugged (so firmware doesn't do it's setup) and then plugging in hdmi (or using something like video=HDMI-A-1:1920x1200M@60e) would fail.

But I'm not seeing that. e.g. with:

disable_fw_kms_setup=1
hdmi_force_hotplug=0

and
video=HDMI-A-1:1920x1200M@60e

and booting with no hdmi connected has no errors in dmesg, and subsequently plugging in hdmi produces expected output.

@HiassofT
Copy link
Contributor

@popcornmix the minimal setup to reproduce the issue here is stock cmdline.txt and config.txt only containing the single line

dtoverlay=vc4-kms-v3d

Booting RPi3B+ with no HDMI connected hangs.

serial console output with current rpi-update kernel/fw: http://ix.io/3tRY

adding disable_fw_kms_setup=1 to config.txt and video=HDMI-A-1:1920x1200M@60eto cmdline.txt doesn't help either http://ix.io/3tS2

Only adding hdmi_force_hotplug=1 lets the RPi3B+ boot without HDMI connected (even with disable_fw_kms_setup=1 and no video= in cmdline.txt).

RPi4 doesn't suffer from that, it boots just fine without any HDMI connected.

@popcornmix
Copy link
Collaborator

popcornmix commented Aug 19, 2021

@mripard I've added some logging and we hang in vc4_hdmi_reset which is where the first writes to any hvs/hdmi
hardware occur. I believe this is because clocks are not running. Most likely this one:

bcm2708: HDMI SM = 0.000 MHz

Note: if we boot without hdmi connected, on a Pi0-3, the firmware will configure VEC (composite) output.
It won't touch the HDMI block. It won't enable clocks needed by it (it will configure the VEC clock to 108MHz).

hdmi_force_hotplug=1 switches this around and VEC won't be configured, but HDMI will be.

Pi4 swaps the default and configures hdmi output unless enable_tvout=1 is set.

So the real issue is kms driver needs to setup whatever clocks are required before accessing registers.
Let me see if enabling HDMI SM clock on firmware is sufficient to get past that point, or if more is needed.

@sans-c
Copy link

sans-c commented Aug 20, 2021

Not sure if this is helpful or even related but blacklisting the snd module did the job for me as a workaround. For unrelated reasons I was suspecting something sound related after my headless raspberry pi stopped booting after an update and only went through when a monitor was attached.

@popcornmix
Copy link
Collaborator

popcornmix commented Aug 23, 2021

@mripard confirmed. Writing:

0x7e10108C  CM_HSMDIV  0x5a001000
0x7e101088   CM_HSMCTL 0x5a000011

(sets HDMI SM clock to run off OSC) and Pi3 now boots.

I think the bug in kms driver is simple. vc4_hdmi_reset is being called without the magic PM enable that makes sure hdmi state machine clock is running.

@mripard
Copy link
Contributor

mripard commented Aug 23, 2021

Thanks for looking into this. Which block are those registers in?

We are already running vc4_hdmi_reset with runtime_pm enabled:

Maybe we'd need a delay for the clock to settle?

@popcornmix
Copy link
Collaborator

CM_HSMDIV / CM_HSMCTL should be set by a call to:

clk_set_rate(vc4_hdmi->hsm_clock, 163682864);

(or any non-zero value). I suspect maybe the clock is enabled, but never set to a non-zero value?

@popcornmix
Copy link
Collaborator

Just confirmed that adding that line to start of vc4_hdmi_reset does allow pi3 to boot without hdmi connected.
(Obviously that's not the best place for it).

@popcornmix
Copy link
Collaborator

Fix should be in latest rpi-update kernel.

@lategoodbye
Copy link
Contributor

Thanks for fixing this.

For a upstream solution, i would expect the fix more in clk-bcm2835. But not sure this is possible.

@mripard
Copy link
Contributor

mripard commented Aug 30, 2021

I tried to do that, but the driver seems to make a point of undershooting every clock frequency that it needs to set, so I was a bit afraid of the side effects. Do you recall why you did so?

@lategoodbye
Copy link
Contributor

Most of the clock driver has been done by Stephen (different person) and Emma. Unfortunately the documentation of SoC clocks is not public available. So i'm not able to answer your question.

@mripard
Copy link
Contributor

mripard commented Sep 28, 2021

I ended up reworking the clock driver as part of this series:
https://lore.kernel.org/linux-arm-kernel/[email protected]/

@lss4
Copy link

lss4 commented Dec 5, 2021

Deleting the old comment as I found it was not entirely correct.

As of fresh Arch Linux ARM AArch64 on RPi 3B (5.15.5 kernel):

  1. If booted with a HDMI monitor connected, the moment you detach the monitor, the system dies, with i2c-bcm2835 3f805000.i2c: i2c transfer timed out errors in dmesg.
  2. Without hdmi_force_hotplug=1, the RPi 3B can boot without a monitor (headless). However, there would be no output if you attach the HDMI monitor later on, and the aforementioned i2c transfer timed out error will not appear.
  3. With hdmi_force_hotplug=1, while the RPi 3B can boot without a monitor, the i2c transfer timed out error will keep flooding in the dmesg but the system will not die. When you attach a HDMI monitor later on, there will be output and you'll see these error messages, but as soon as you detach the monitor, the system dies, exactly as in situation b).

b) the Pi still freezes after hot-plugging the HDMI display after having booted without one.

So hdmi_force_hotplug=1 doesn't really fix the issue at all. It only allows you to connect a HDMI monitor later on, and once you connected a monitor, you cannot disconnect it without causing the system to hang (requiring a manual power cycle).

@mripard
Copy link
Contributor

mripard commented Dec 8, 2021

That doesn't look like the original issue, can you open a new one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants