Skip to content

patches/6.19: cameras: fix ov8865 stale mode when sensor is held powered (rear camera green screen) - #2169

Open
toor11 wants to merge 1 commit into
linux-surface:masterfrom
toor11:fix/ov8865-stale-mode-6.19
Open

patches/6.19: cameras: fix ov8865 stale mode when sensor is held powered (rear camera green screen)#2169
toor11 wants to merge 1 commit into
linux-surface:masterfrom
toor11:fix/ov8865-stale-mode-6.19

Conversation

@toor11

@toor11 toor11 commented Jun 9, 2026

Copy link
Copy Markdown

Problem

The IPU3 rear camera (ov8865) on Surface Book 2 — and likely other ov8865 devices — shows a frozen green/black frame in camera apps: the stream stalls after a single frame with ipu3-cio2 reporting frame sync error and payload length is X, received Y mismatches.

Root cause

ov8865 writes its sensor registers only in the runtime-PM resume handler; set_fmt() merely stores the requested mode. On IPU3 platforms, ipu_bridge gives the dw9719 VCM a DL_FLAG_PM_RUNTIME device link to the sensor, so a userspace process holding the VCM subdev open (wireplumber does, on any stock desktop) pins the sensor runtime-active. After that, format changes never reach the hardware: the sensor keeps streaming the mode programmed at the last resume while CIO2 expects the newly negotiated one.

Proof by inversion on SB2: with binned mode pinned, a full-res request fails with payload length is 10340352, received 2585088 — exactly one 1632x1224 binned frame where a 3264x2448 frame was expected. Stop wireplumber (sensor suspends/resumes again) and both modes stream 10/10 clean — so this is not a tuning-file issue (#2166) and not a sensor register table issue.

Fix

Two patches appended to patches/6.19/0013-cameras.patch:

  1. media: i2c: ov8865: Program the mode on stream start if needed — track the mode actually programmed into the hardware, invalidate on power-off, and reprogram at s_stream(1) when it differs from the negotiated mode (re-applying control values).
  2. media: i2c: ov8865: Drop PM runtime reference if stream start fails — pre-existing PM ref leak on the same error path.

Validation (SB2, 6.19.8-arch1-3-surface, wireplumber running = stock conditions)

  • Binned 1632x1224 raw capture: 10/10 frames at first try after boot (always 1/10 before)
  • Full-res and repeated binned↔full-res alternation without suspending: all 10/10, zero payload errors
  • libcamera cam -c1 --capture=40: 40/40 frames @ ~30 fps, no stall (previously froze on frame 1 — the green still)
  • checkpatch --strict clean; builds without warnings

Being submitted to linux-media for upstream inclusion as well; will link the lore thread here once posted. Related: the rear-camera reports in #2123 (separate from the VCM fix there) and #2166.

@toor11

toor11 commented Jun 9, 2026

Copy link
Copy Markdown
Author

Upstream submission is on the list now: https://lore.kernel.org/linux-media/20260609232255.13559-1-eng.juri@gmail.com/ (may take a few minutes to appear in the lore index).

@ma-schmitz

Copy link
Copy Markdown

Confirmed on Surface Pro 6 (IPU3, ov8865 rear + dw9719 VCM), kernel 6.19.8-surface-3.

This only became visible here after #2123 was applied. Before that the VCM never bound, so the DL_FLAG_PM_RUNTIME device link you describe did not exist and the rear camera was simply dead rather than stuck. With the VCM bound, the rear camera delivered exactly one frame and then stalled, with

ipu3-cio2 0000:00:14.3: payload length is 2585088, received 2588672

on every capture attempt. 2585088 = 2112 bytes/line x 1224 lines, i.e. the 1632x1224 binned mode — consistent with your "hardware left programmed for a previous mode" analysis.

The delivered buffers were entirely zero (Y=0, U=0, V=0). That is what renders as the solid green frame reported in #2166 — an empty buffer, not a colour or tuning problem.

One data point that differs from your Surface Book 2 findings: stopping wireplumber did not help here. With wireplumber stopped and the sensor confirmed runtime-suspended beforehand (/sys/bus/i2c/devices/i2c-INT347A:00/power/runtime_status), the payload mismatch stayed byte-for-byte identical and the stream still stalled after a single frame. So on this device the stale mode does not appear to be caused solely by a userspace process pinning the sensor runtime-active — your patch was needed, the workaround alone was not sufficient.

Results with both patches applied, rear camera pointed at a window:

  • 300 frames captured at 30 fps, no stall
  • zero payload length messages since boot (was one per frame before)
  • mean frame luminance stable, stdev 2.5 over frames 30-299; the only outliers are 3 frames in the first half second, which is stream startup

Happy to run further tests on this device if useful.

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 this pull request may close these issues.

2 participants