镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Pi 3: HDMI pixel clock stuck at firmware minimum after modeset on 6.18 — monitor reports "Mode Not Supported" #7564

Closed

Description

@nicoske

Describe the bug

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:

# grep -E "pllh_pix|fw-clk-pixel" /sys/kernel/debug/clk/clk_summary
 fw-clk-pixel      2  2  0  2400000000  ...  3f902000.hdmi  pixel
    pllh_pix       0  0  0    86400000  ...

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)
  • Firmware: raspberrypi/firmware @ 78e81e2c (24 Jul)
  • Compositor: sway 1.11 / wlroots 0.19 (DRM atomic)
  • Monitor: Samsung S24C650, EDID preferred DTD 1920x1080@60 (148.500 MHz)

Activity

  1. popcornmix commented on Aug 18, 2026

    @popcornmix
    Collaborator

    Can you describe how you reproduce this?

    1. Boot in 1080p60 mode
    2. [ do something that triggers unprepare/prepare ]
    3. See "Mode not supported"

    What are you doing for step 2?

  2. nicoske commented on Aug 18, 2026

    @nicoske
    Author

    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.

  3. popcornmix commented on Aug 19, 2026

    @popcornmix
    Collaborator

    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:

    pi@domb3plus:~ $ kmsprint 
    Connector 0 (35) HDMI-A-1 (connected)
      Encoder 0 (34) TMDS
        Crtc 3 (97) 1920x1080@60.00 148.500 1920/88/44/148/- 1080/4/5/36/- 60 (60.00) D 
          Plane 3 (86) fb-id: 671 (crtcs: 3) 0,0 1920x1080 -> 0,0 1920x1080 (XR24 AR24 AB24 XB24 RX24 RA24 BX24 BA24 RG16 BG16 AR15 XR15 RG24 BG24 YU16 YV16 YU24 YV24 YU12 YV12 NV12 NV21 NV16 NV61 RGB8 BGR8 XR12 AR12 XB12 AB12 BX12 BA12 RX12 RA12)
            FB 671 1920x1080 RG16
    pi@domb3plus:~ $ vcgencmd measure_clock pixel
    frequency(29)=148500000
     fw-clk-pixel                        2       2        0        148500000   0          0     50000      Y   3f902000.hdmi                   pixel                    
    

    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?

  4. nicoske commented on Aug 19, 2026

    @nicoske
    Author

    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:

    • 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.

  5. mairacanal commented on Aug 19, 2026

    @mairacanal
    Contributor

    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.

  6. popcornmix commented on Aug 20, 2026

    @popcornmix
    Collaborator

    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).

  7. nicoske commented on Aug 20, 2026

    @nicoske
    Author

    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:

    1. Boot with a monitor that actually goes to standby (Samsung S24C650 here), full KMS, screen showing a picture.
    2. Turn the output off: swaymsg "output * power off", or any DPMS off.
    3. Wait 25 to 40 minutes, long enough for the monitor to really sleep, not just blank.
    4. Turn the output back on: swaymsg "output * power on".
    5. 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.

  8. popcornmix commented on Aug 20, 2026

    @popcornmix
    Collaborator

    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.

  9. nicoske commented on Aug 21, 2026

    @nicoske
    Author

    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.

  10. popcornmix commented on Aug 21, 2026

    @popcornmix
    Collaborator

    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.

  11. popcornmix commented on Aug 24, 2026

    @popcornmix
    Collaborator

    Any update? I'd like to know what distribution you are running.

  12. nicoske commented on Aug 26, 2026

    @nicoske
    Author

    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.

  13. popcornmix commented on Aug 27, 2026

    @popcornmix
    Collaborator

    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.

  14. nicoske commented on Sep 4, 2026

    @nicoske
    Author

    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.

  15. popcornmix commented on Sep 4, 2026

    @popcornmix
    Collaborator

    Thanks - I can reproduce with force_turbo.

    pi@dompi3p:~ $ vcgencmd version
    Aug  7 2026 19:06:45 
    Copyright (c) 2012 Broadcom
    version 3fc16e3acefe335796a62e224bc7af85f28667fa (tainted) (release) (start)
    pi@dompi3p:~ $ uname -a
    Linux dompi3p 6.18.39+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.18.39-1+rpt1 (2026-07-29) aarch64 GNU/Linux
    pi@dompi3p:~ $ vcgencmd get_config force_turbo
    force_turbo=1
    pi@dompi3p:~ $ vcgencmd measure_clock pixel
    frequency(29)=86400000
    

    My Dell monitor is actually happy with this clock, displaying a correct looking image. It's only If I dig further:

    pi@dompi3p:~ $ kmstest --flip
    Connector 0/@35: HDMI-A-1
      Crtc 3/@97: 1920x1080@60.00 148.500 1920/88/44/148/- 1080/4/5/36/- 60 (60.00) D 
      Plane 3/@86: 0,0-1920x1080
        Fb 670 1920x1080-XR24
    press enter to exit
    Connector 0: fps 34.91, slowest 28.71 ms
    

    I see the fps is lower than expected. This should be enough to work out exactly what caused the change in behaviour.

  16. popcornmix commented on Sep 4, 2026

    @popcornmix
    Collaborator

    Can you test this test firmware and let me know if it solves your issue?

  17. nicoske commented on Sep 4, 2026

    @nicoske
    Author

    It works! Output back after 40 minutes of monitor sleep, 2 out of 2, measure_clock pixel 148500000.

  18. popcornmix commented on Sep 7, 2026

    @popcornmix
    Collaborator

    Thanks for report and testing. It's now merged internally and in rpi-update firmware.
    It will be be in subsequent apt firmwares.

  19. added a commit that references this issue on Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions