Repository navigation
ov5693 on IPU6 (Surface Pro 8): 2x-binned 1296x972 readout returns zero-byte buffers with csi2 Transfer FIFO overflow, full 2592x1944 readout works #2234
Description
Summary
On a Surface Pro 8 (TGL, IPU6, ov5693 front sensor), the sensor's 2x-binned
1296x972 readout produces zero-byte buffers and a burst of
csi2-4: Transfer FIFO overflow, while the full 2592x1944 readout works
perfectly on the same boot, same session. The binned mode is the one every
default application asks for (GNOME Snapshot, Firefox/Chromium getUserMedia and
most WebRTC pages open at 640x480 or 720p), so the camera looks completely dead
to a user while a full-resolution cam capture reports everything is fine.
Filing this separately from the CSI2 clock-lane work in #2171, because it is a
distinct fault that survives that fix.
Environment
- Surface Pro 8, Zorin OS 18.1
- Kernel
6.19.8-surface-3(linux-surface, carries0013-cameras.patch) intel_ipu6/intel_ipu6_isys, CSI2 port 4- libcamera 0.7.1 (simple pipeline + software ISP), pipewire 1.0.5
- Sensor
ov5693, Bayer BGGR10
Confirmation for #2171 (clock lane), not a new finding
The MIPI_CTRL00 (register 0x4800) write from #2171 is required on this
hardware and it works. Without it, every capture at every size ended in
stream stop time out with zero bytes: the sensor streams internally but the
CSI2 D-PHY clock lane never starts, so the receiver sees nothing. With it, the
full-resolution readout delivers real frames reliably. That patch is not mine
and this is only a hardware confirmation on a Surface Pro 8, offered because the
PR needs testers.
The actual report: per-mode failure
With the clock-lane fix applied and the driver otherwise stock, capture size
decides everything (cam -c 2 --capture=3, one run per row):
| Requested | Sensor readout | Result |
|---|---|---|
| 2592x1944 | full | real frames |
| 1920x1080 | full, cropped | real frames |
| 1280x720 | 2x-binned 1296x972 | zero-byte buffers |
| 640x480 | 2x-binned 1296x972 | zero-byte buffers |
The failing rows log csi2-4: Transfer FIFO overflow in dmesg. The passing
rows do not depend on luck: full-resolution capture was repeated many times over
several hours without a single short buffer.
Read the sensor readout, not the requested size. Both failing rows negotiate the
same binned 1296x972 readout, and both fail; both passing rows read out the full
array. So this is a property of the binned mode, not of any particular output
resolution.
Workaround used here (a workaround, not a fix)
Two hunks in drivers/media/i2c/ov5693.c, both required together:
ov5693_set_fmt(): clamphratioandvratioto1, 1instead of1, 2,
so only the full-sensor readout can ever be selected.ov5693_enum_frame_size(): reject atfse->index > 0instead of> 1, so
the binned size is no longer advertised.
The second one is easy to miss and matters: if set_fmt refuses a size that
enum_frame_size still advertises, the driver lies to userspace and libcamera
negotiates a mode it can never get back.
With both applied, every requested size produces frames and the applications
work. The cost is real and users will notice it: the sensor now always reads out
the full array, so a small requested size arrives as a narrow, zoomed-in field
of view, plus the CPU cost of handling full-resolution frames for a 640x480
stream. That is why this is posted as a bug report rather than a patch.
What the real fix probably is
The binned readout changes the CSI2 line length and timing while the D-PHY link
configuration stays as computed for the full readout, which fits a receiver-side
FIFO overflow rather than a sensor-side fault. The fix is presumably the CSI2
D-PHY link timing (or the link frequency / lane rate derived for the binned
mode), after which both hunks above can be dropped.
Happy to run any test build or register dump on this hardware.
Activity
luqqas96 commentedon Aug 21, 2026
Second device with this, and one data point that complicates the picture usefully.
Surface Pro 7+, Fedora 44, kernel
6.19.8-3.surface.fc43, IPU68086:9a19, frontov5693, libcamera 0.7.1. Same fault, same shape as yours: anything that negotiates the2x-binned 1296x972 readout comes back with empty buffers, while the full 2592x1944 readout
delivers frames in the same session. And the same practical consequence — every application
asks for 640x480 or 720p, so the camera looks dead while
camat full resolution sayseverything is fine.
Different kernel message. Where you get
csi2-4: Transfer FIFO overflow, this machinelogs
intel_ipu6_isys.isys: csi2-4 error: Frame sync erroron the failing captures. Twodifferent receiver-side complaints for the same binned readout is probably worth noting for
whoever chases the root cause.
Also worth ruling out: it is not the libcamera software-ISP bug. Reproduces identically
with
LIBCAMERA_SOFTISP_MODE=cpuand=gpu.The complication
A Surface Pro 7+ in #1702 / #2201 reports the binned mode working: 1296x972 SBGGR10,
300/300 frames, ~28.7 fps, no timeout. Same model, same sensor, opposite result.
Frame sync errorThe most visible difference between the working setup and mine is not the machine — it is
when
0x4800gets written. The driver patch rewrites it on every stream-on; myuserspace service writes it once at boot. Selecting the binned mode reprograms the sensor,
so a register written once may simply not survive the mode switch.
That is a hypothesis, not a result. I can test it cheaply — this machine can write any
sensor register over I2C from userspace, no rebuild or module signing needed — and I will
post what I get. If it holds, the binned mode may not be broken at all on some of these
devices, and the driver-side fix here would be masking a write-ordering problem rather than
a hardware limit. Worth knowing before the
hratio/vratioclamp lands, since that clampcosts every user the full-resolution readout plus a software downscale.
For reference, that cost is real: forcing the native mode on this machine runs ~12-15% of
one core out of eight during capture, plus GPU load for the EGL debayer.
On your two-hunk workaround: I reached the same conclusion one layer up, in libcamera's
simple pipeline, filtering the broken binning modes out of the sensor's mode list. Your
second hunk is the one that matters and it is easy to miss — I hit exactly that failure. If
set_fmtrefuses a size thatenum_frame_sizestill advertises, libcamera negotiates amode it can never get back and the failure moves rather than disappearing.
If the fix does belong in the driver, I would rather have it there than in libcamera: a
local libcamera build is what is currently keeping this machine on a version-locked package
with no security updates.
rarestache commentedon Oct 7, 2026
Another Surface Pro 8 data point, and it bears on the write-timing hypothesis in the comment above: with
0x4800written by the driver on every stream-on, the binned mode still fails here.Setup: Surface Pro 8 (TGL IPU6
8086:9a19,ov5693atINT33BE, csi2-4), Fedora 43,6.19.8-3.surface.fc43, libcamera 0.5.2 (Fedora package, simple pipeline + soft ISP), PipeWire 1.4.11. Capture viapipewiresrc.ov5693.korebuilt out of tree from v6.19.8ov5693.c(the onlyov5693.cchange in0013-cameras.patchis theOVTI5693HID, irrelevant forINT33BE), plus acci_write(0x4800, 0x24)immediately before theOV5693_SW_STREAM_REGwrite inov5693_enable_streaming(), i.e. on every stream-on, as in the v2 upstream patch.stream stop time out, 0 frames0x4800 = 0x24at each stream-oncsi2-4 error: Frame sync error(~134 suppressed per 5 s)0x4800 = 0x24at each stream-on0x24+ both hunks from this issue (hratio = vratio = 1,enum_frame_sizerejectsindex > 0)So on this machine the binned failure is not a write-once artifact: the register is rewritten at every stream-on and the binned readout still breaks, with
Frame sync error(as on @luqqas96's Pro 7+) rather thanTransfer FIFO overflow.Not tested:
0x20or0x2dwith the binned mode. I only tried0x24.