You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Pi 3: HDMI pixel clock stuck at firmware minimum after modeset on 6.18 — monitor reports "Mode Not Supported" #7564
On a Pi 3 Model B+ running a 6.18 kernel with a KMS/atomic compositor (wlroots/sway), the HDMI output is rejected by the monitor ("Mode Not Supported" on a Samsung S24C650). The EDID is read correctly and 1920x1080@60 (148.5 MHz) is selected as preferred mode, but the pixel PLL never leaves the firmware minimum rate:
The effective 86.4 MHz pixel clock on 1080p timings yields a ~35 Hz vertical rate, which the monitor rejects. Userspace mode switches (e.g. to 1280x720@60) return success but the clocks never change. No errors in dmesg; the DRM atomic state believes the mode was applied.
Analysis
Commit 0276d66 ("clk: bcm: rpi: Manage clock rate in prepare/unprepare callbacks") sets a firmware clock to its minimum rate on unprepare, and only restores a rate in prepare for clocks flagged maximize (currently v3d). However vc4_hdmi requests the TMDS/pixel rate before enabling the clock (drivers/gpu/drm/vc4/vc4_hdmi.c, vc4_hdmi_encoder_pre_crtc_configure(): clk_set_rate(pixel_clock, ...) followed by clk_prepare_enable(pixel_clock)). After any disable→enable cycle the requested rate is lost and the pixel clock stays at the firmware minimum (86.4 MHz — matching the measurement above).
BCM2711 is unaffected because the HDMI PHY generates TMDS from its internal PLL; BCM2835-37 uses the firmware-managed PLLH path, so all Pi 0-3 on 6.18 with full KMS should be affected. The commit is also present in rpi-6.19.y (350d775).
Workaround (verified)
Reverting 0276d66 on top of 8307cc8 restores correct output — verified on the same hardware/monitor: pllh_pix then locks at 148500000 and the monitor syncs at native 1920x1080@60.
System
Raspberry Pi 3 Model B+ Rev 1.3
Kernel: 6.18.39-v8, built from rpi-6.18.y @ 8307cc8 (vc4 full KMS, dtoverlay=vc4-kms-v3d,cma-256)
The output is already wrong at the first modeset after boot, on each boot. To make sure the compositor was not to blame, I disabled it and let the box boot to fbcon only: pllh_pix already reads 86400000 with the connector enabled. Starting the compositor afterwards, DPMS off/on or mode switches never move the clock. Nothing is forced in config.txt either, the kernel picks the EDID preferred 1080p60 itself.
Possibly relevant: vc4 is a module here, as on RPi OS, so clk: Disabling unused clocks at ~1.7s runs before vc4 binds at ~8.3s, and fw-clk-pixel gets unprepared, therefore set to the 86.4 MHz minimum, before the first modeset ever happens.
There are two clock drivers on raspberry pi:
clk-raspberrypi - this uses the firmware clock driver, which handles things like shared PLLs, dvfs etc
clk-bcm2835 - a legacy driver that is almost unused
the pixel clock is configured though clk-raspberrypi which reports the fw-clk-pixel line.
pllh_pix is reported by the legacy driver that doesn't own the pixel clock - I would ignore that completely.
But I (and presumably every other Pi3 user) am not seeing this issue.
I see:
and my display is happy.
I need to know how to reproduce this.
First question - can you take a freshly installed RPiOS trixie lite image and boot. Does this fail to display an image for you? If that works does it fail after running an apt upgrade?
So I redid the comparison with vcgencmd only. Same board, same firmware (8e367370, 23 Jul), the only thing that changes is the kernel:
stock rpi-6.18.y at 8307cc8: vcgencmd measure_clock pixel gives me 0, and the monitor complains about an out of range signal ("Mode Not Supported" on its OSD, so it does receive something).
exact same tree with just 0276d66 reverted: measure_clock pixel gives 148500000 like yours, and the display syncs at 1080p60.
Out of curiosity, which kernel is your Pi3 on? As far as I can tell 0276d66 is only in rpi-6.18.y and rpi-6.19.y, so a trixie image still on 6.12 wouldn't show anything.
I'd genuinely like to run the fresh trixie test but the board sits in a remote location, I'll do it as soon as I can get my hands on it. In the meantime, the differences from a stock setup I can think of: it boots through u-boot (kernel=u-boot.bin) and vc4 is built as a module. Otherwise plain vc4-kms-v3d.
I haven't been able to reproduce your issue locally. However, after reading your bug report and inspecting the code, I believe that you have a point when you say that the rate is not being properly restored. In this sense, I prepared a fix for this issue in the MR #7565.
If possible, give it a try and let me know if it fixed your issue.
I think the problem is these clocks are registered with CLK_GET_RATE_NOCACHE: clk_hw_get_rate() in prepare does a live GET_CLOCK_RATE query instead of returning what the consumer asked for. On my firmware that query returns a bogus 2400000000 for pixel (checked with vcmailbox, it reports that whatever the real rate is), so prepare restores garbage. Even with a sane reading it would restore the minimum unprepare just wrote. Maybe the driver should remember the last rate requested through .set_rate and restore that in prepare?
Assuming the arm has called SET_CLOCK_RATE at least once, GET_CLOCK_RATE should always report the value the arm last gave it. I don't know if u-boot may have sent any clock requests.
But really we need to reproduce this locally or we are just guessing. The test of whether you can reproduce this with a clean trixie install would be very helpful. And if it doesn't reproduce, at what stage does it reproduce (e.g. when you add u-boot into the equation).
I still couldn't run the fresh trixie test, the board is remote and nobody can swap the SD card for now. But I found how to reproduce the problem on demand, and it turned out to follow the firmware, not the kernel.
Here is the recipe, it takes about 40 minutes:
Boot with a monitor that actually goes to standby (Samsung S24C650 here), full KMS, screen showing a picture.
Turn the output off: swaymsg "output * power off", or any DPMS off.
Wait 25 to 40 minutes, long enough for the monitor to really sleep, not just blank.
Turn the output back on: swaymsg "output * power on".
Read vcgencmd measure_clock pixel.
You get 0 and no picture, while dmesg shows one flip_done timed out and DRM reports the connector connected and enabled at 1080p60. GET_CLOCK_STATE(pixel) says on, GET_CLOCK_RATE_MEASURED says 0, PLLH reads 148.5 MHz. Short off/on cycles never trigger it, the monitor really has to sleep first. Since the board is remote, a colleague stood in front of the monitor during one wake to confirm: monitor searching for its source while DRM believes everything is fine. measure_clock pixel matched the screen in both directions, so I used it as the proxy everywhere else.
This is what our signage player does every day, screens off at night and on in the morning, which is how I ran into it.
Then I swapped only bootcode.bin/start.elf/fixup.dat, same board, same monitor, same protocol:
eb3ee430 (Feb): wake OK, 148500000, both on 6.12.87 and 6.18.39
78e81e2c (24 Jul): broken on both kernels, 0
3d301dd9 (10 Aug): runtime wake still broken, but cold boot with the sleeping monitor works and a reboot recovers, which neither older one does
Our fleet ran eb3ee430 for months with daily screen off schedules and never saw it, it started with 78e81e2c. When nothing wakes the output, the monitor eventually sleeps deeper, HPD drops and only replugging recovers, which is why this looked like random permanent failures at first.
Tell me if you'd rather have this on the firmware repo.
The git hashes you are reporting are from the firmware repo, which includes both kernel and firmware updates.
Can you identify the most recent update that works? If we can narrow this down to a single hash that is first bad build, we can narrow things down.
I took the time to test every build. Most recent one that works is 0e05e1776 (8 May), first bad one is 495ed912a (21 May).
About the bundle: I don't use the kernel from that repo, I build my own and it stayed the same for every run (6.18.39). I only swapped bootcode.bin, start.elf and fixup.dat. Each build got two sleep/wake cycles, 40 minutes asleep, same board, same monitor, reading measure_clock pixel after the wake:
832291b92 (11 Feb): 148500000, 148500000
1d725033e (8 May): 148500000, 148500000
0e05e1776 (8 May): 148500000, 148500000
495ed912a (21 May): 0, 0
980e91e3a (19 Jun): 0, 0
ea3bc5a63 (1 Jul): 0, 0
8402891f3 (23 Jul): 0, 0
The kernel bumps in between (8fce67a9e, c3948a182, 41f480827) left those blobs byte identical, so the change came with 495ed912a. Its title has nothing to do with display, so it might be something else in the same build.
On the bad ones, if the monitor is already deeply asleep when the Pi boots, the screen stays dark after boot too, not only on wake. On 980e91e3a even a reboot didn't help, on the others it did.
I can also try on a stock Raspberry Pi OS install, but not before next week.
Its title has nothing to do with display, so it might be something else in the same build.
"firmware clock rework" will be the relevant change. It was intended to be a "no behaviour change", but did include a couple of "simplify code as this can never happen" based on requests that would make no sense to kernel to do.
My suspicion is u-boot is doing something we didn't expect. We don't really support u-boot, but try to avoid breaking things where possible.
Can you explain exactly what your install is? Was it RPiOS trixie with u-boot added? Or some other distribution that uses u-boot directly? If you can point me at an image that may fail for me, I can investigate.
It is a custom buildroot image. The firmware loads u-boot 2025.10 (upstream rpi_arm64 defconfig), which loads a self built 6.18.39 from rpi-6.18.y, full KMS.
To confirm the u-boot theory I can boot the same kernel directly from the firmware without u-boot on the same board and run the same sleep/wake test. I can also run the test on a stock Raspberry Pi OS install. I will report the results.
I finally had time to test on a stock trixie image, and to reproduce the problem. Same Pi 3B+ and monitor, no u-boot, kernel and firmware from the archive (6.18.39+rpt-rpi-v8, raspi-firmware 1.20260521). There are actually two different things going on.
1st one, pixel clock at the firmware minimum: force_turbo=1 triggers it. Stock kernel, measure_clock pixel after boot gives 148500000 without the line and 86400000 with it, and the monitor says "Mode Not Supported". With 0276d66 reverted I get 148500000 again, force_turbo=1 still there.
2nd one, no output after the monitor slept 40 minutes: the stock kernel wakes fine, 2 out of 2. The same tree at 8307cc8 with only 0276d66 reverted, loaded by the firmware through tryboot.txt, fails 2 out of 2: measure_clock pixel reads 0, dmesg has Timeout waiting for VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE and flip_done timed out. That is what I saw on 6.12.87 in August as well, which does not have the commit.
So as far as I can tell, firmware 495ed912a and later need 0276d66, and 0276d66 breaks force_turbo=1 on Pi 3.
Side note: GET_CLOCK_RATE on the pixel clock reads 2400000000 on this stock install too, so that value is not coming from u-boot.
About the files to boot: I don't think you need anything from me any more. A trixie image with force_turbo=1 shows the 1st one. For the 2nd one, any kernel without 0276d66 on firmware 1.20260521 should do it, for example the 6.12 packages still in the archive, with a monitor that really goes to sleep.
Activity
popcornmix commentedon Aug 18, 2026
Can you describe how you reproduce this?
What are you doing for step 2?
nicoske commentedon Aug 18, 2026
The output is already wrong at the first modeset after boot, on each boot. To make sure the compositor was not to blame, I disabled it and let the box boot to fbcon only:
pllh_pixalready reads 86400000 with the connector enabled. Starting the compositor afterwards, DPMS off/on or mode switches never move the clock. Nothing is forced in config.txt either, the kernel picks the EDID preferred 1080p60 itself.Possibly relevant: vc4 is a module here, as on RPi OS, so
clk: Disabling unused clocksat ~1.7s runs before vc4 binds at ~8.3s, andfw-clk-pixelgets unprepared, therefore set to the 86.4 MHz minimum, before the first modeset ever happens.popcornmix commentedon Aug 19, 2026
There are two clock drivers on raspberry pi:
clk-raspberrypi - this uses the firmware clock driver, which handles things like shared PLLs, dvfs etc
clk-bcm2835 - a legacy driver that is almost unused
the pixel clock is configured though clk-raspberrypi which reports the fw-clk-pixel line.
pllh_pix is reported by the legacy driver that doesn't own the pixel clock - I would ignore that completely.
But I (and presumably every other Pi3 user) am not seeing this issue.
I see:
and my display is happy.
I need to know how to reproduce this.
First question - can you take a freshly installed RPiOS trixie lite image and boot. Does this fail to display an image for you? If that works does it fail after running an apt upgrade?
nicoske commentedon Aug 19, 2026
Fair enough about pllh_pix.
So I redid the comparison with vcgencmd only. Same board, same firmware (8e367370, 23 Jul), the only thing that changes is the kernel:
vcgencmd measure_clock pixelgives me 0, and the monitor complains about an out of range signal ("Mode Not Supported" on its OSD, so it does receive something).measure_clock pixelgives 148500000 like yours, and the display syncs at 1080p60.Out of curiosity, which kernel is your Pi3 on? As far as I can tell 0276d66 is only in rpi-6.18.y and rpi-6.19.y, so a trixie image still on 6.12 wouldn't show anything.
I'd genuinely like to run the fresh trixie test but the board sits in a remote location, I'll do it as soon as I can get my hands on it. In the meantime, the differences from a stock setup I can think of: it boots through u-boot (kernel=u-boot.bin) and vc4 is built as a module. Otherwise plain vc4-kms-v3d.
mairacanal commentedon Aug 19, 2026
I haven't been able to reproduce your issue locally. However, after reading your bug report and inspecting the code, I believe that you have a point when you say that the rate is not being properly restored. In this sense, I prepared a fix for this issue in the MR #7565.
If possible, give it a try and let me know if it fixed your issue.
popcornmix commentedon Aug 20, 2026
Assuming the arm has called SET_CLOCK_RATE at least once, GET_CLOCK_RATE should always report the value the arm last gave it. I don't know if u-boot may have sent any clock requests.
But really we need to reproduce this locally or we are just guessing. The test of whether you can reproduce this with a clean trixie install would be very helpful. And if it doesn't reproduce, at what stage does it reproduce (e.g. when you add u-boot into the equation).
nicoske commentedon Aug 20, 2026
I still couldn't run the fresh trixie test, the board is remote and nobody can swap the SD card for now. But I found how to reproduce the problem on demand, and it turned out to follow the firmware, not the kernel.
Here is the recipe, it takes about 40 minutes:
swaymsg "output * power off", or any DPMS off.swaymsg "output * power on".vcgencmd measure_clock pixel.You get 0 and no picture, while dmesg shows one
flip_done timed outand DRM reports the connector connected and enabled at 1080p60. GET_CLOCK_STATE(pixel) says on, GET_CLOCK_RATE_MEASURED says 0, PLLH reads 148.5 MHz. Short off/on cycles never trigger it, the monitor really has to sleep first. Since the board is remote, a colleague stood in front of the monitor during one wake to confirm: monitor searching for its source while DRM believes everything is fine.measure_clock pixelmatched the screen in both directions, so I used it as the proxy everywhere else.This is what our signage player does every day, screens off at night and on in the morning, which is how I ran into it.
Then I swapped only bootcode.bin/start.elf/fixup.dat, same board, same monitor, same protocol:
Our fleet ran eb3ee430 for months with daily screen off schedules and never saw it, it started with 78e81e2c. When nothing wakes the output, the monitor eventually sleeps deeper, HPD drops and only replugging recovers, which is why this looked like random permanent failures at first.
Tell me if you'd rather have this on the firmware repo.
popcornmix commentedon Aug 20, 2026
The git hashes you are reporting are from the firmware repo, which includes both kernel and firmware updates.
Can you identify the most recent update that works? If we can narrow this down to a single hash that is first bad build, we can narrow things down.
nicoske commentedon Aug 21, 2026
I took the time to test every build. Most recent one that works is 0e05e1776 (8 May), first bad one is 495ed912a (21 May).
About the bundle: I don't use the kernel from that repo, I build my own and it stayed the same for every run (6.18.39). I only swapped bootcode.bin, start.elf and fixup.dat. Each build got two sleep/wake cycles, 40 minutes asleep, same board, same monitor, reading
measure_clock pixelafter the wake:The kernel bumps in between (8fce67a9e, c3948a182, 41f480827) left those blobs byte identical, so the change came with 495ed912a. Its title has nothing to do with display, so it might be something else in the same build.
On the bad ones, if the monitor is already deeply asleep when the Pi boots, the screen stays dark after boot too, not only on wake. On 980e91e3a even a reboot didn't help, on the others it did.
I can also try on a stock Raspberry Pi OS install, but not before next week.
popcornmix commentedon Aug 21, 2026
"firmware clock rework" will be the relevant change. It was intended to be a "no behaviour change", but did include a couple of "simplify code as this can never happen" based on requests that would make no sense to kernel to do.
My suspicion is u-boot is doing something we didn't expect. We don't really support u-boot, but try to avoid breaking things where possible.
Can you explain exactly what your install is? Was it RPiOS trixie with u-boot added? Or some other distribution that uses u-boot directly? If you can point me at an image that may fail for me, I can investigate.
popcornmix commentedon Aug 24, 2026
Any update? I'd like to know what distribution you are running.
nicoske commentedon Aug 26, 2026
It is a custom buildroot image. The firmware loads u-boot 2025.10 (upstream rpi_arm64 defconfig), which loads a self built 6.18.39 from rpi-6.18.y, full KMS.
To confirm the u-boot theory I can boot the same kernel directly from the firmware without u-boot on the same board and run the same sleep/wake test. I can also run the test on a stock Raspberry Pi OS install. I will report the results.
popcornmix commentedon Aug 27, 2026
If you provide files needed to boot that shows the works/not works behaviour with old/new firmware I can probably identify exactly where it fails.
nicoske commentedon Sep 4, 2026
I finally had time to test on a stock trixie image, and to reproduce the problem. Same Pi 3B+ and monitor, no u-boot, kernel and firmware from the archive (6.18.39+rpt-rpi-v8, raspi-firmware 1.20260521). There are actually two different things going on.
1st one, pixel clock at the firmware minimum:
force_turbo=1triggers it. Stock kernel,measure_clock pixelafter boot gives 148500000 without the line and 86400000 with it, and the monitor says "Mode Not Supported". With 0276d66 reverted I get 148500000 again,force_turbo=1still there.2nd one, no output after the monitor slept 40 minutes: the stock kernel wakes fine, 2 out of 2. The same tree at 8307cc8 with only 0276d66 reverted, loaded by the firmware through tryboot.txt, fails 2 out of 2:
measure_clock pixelreads 0, dmesg hasTimeout waiting for VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVEandflip_done timed out. That is what I saw on 6.12.87 in August as well, which does not have the commit.So as far as I can tell, firmware 495ed912a and later need 0276d66, and 0276d66 breaks
force_turbo=1on Pi 3.Side note:
GET_CLOCK_RATEon the pixel clock reads 2400000000 on this stock install too, so that value is not coming from u-boot.About the files to boot: I don't think you need anything from me any more. A trixie image with
force_turbo=1shows the 1st one. For the 2nd one, any kernel without 0276d66 on firmware 1.20260521 should do it, for example the 6.12 packages still in the archive, with a monitor that really goes to sleep.popcornmix commentedon Sep 4, 2026
Thanks - I can reproduce with force_turbo.
My Dell monitor is actually happy with this clock, displaying a correct looking image. It's only If I dig further:
I see the fps is lower than expected. This should be enough to work out exactly what caused the change in behaviour.
popcornmix commentedon Sep 4, 2026
Can you test this test firmware and let me know if it solves your issue?
nicoske commentedon Sep 4, 2026
It works! Output back after 40 minutes of monitor sleep, 2 out of 2,
measure_clock pixel148500000.firmware: arm_loader: Reapply call to get_turbo_clocks when querying …
firmware: arm_loader: Reapply call to get_turbo_clocks when querying …
popcornmix commentedon Sep 7, 2026
Thanks for report and testing. It's now merged internally and in rpi-update firmware.
It will be be in subsequent apt firmwares.
pieeprom-2026-09-10: 2712: Move rpi-fw-crypto functions to secure RAM…
Updates on Sept 10, 2026 20:29