Skip to content

Conversation

kbingham
Copy link
Contributor

Some redesign of the imx283 mode configuration that allows us to add modes and configurations more easily. Ultimately - I hope to progress this sometime to support free arbitrary cropping on the sensor side with the driver handling all the alignment and restrictions correctly - but that will take some more time still yet.

Crucially in this series is some changes to the handling of the user clamp area which contains the VOB but isn't actually part of the sensor vertical position coordinates. Previously - this means that a 16 line offset has been occuring in the output image.

Another artifact is that the sensor introduces an extra line at the top of the image which we believe is to support or prevent bayer reordering on vflip. But the additional line produces an undesirable artifact in the output. This series uses the ability to adjust the clamp area/VOB to extend over the additional line (and one more to maintain bayer order) to remove the artifact. To prevent this causing the image to be offset - an extra two lines are requested on top of the mode first.

Finally - three clear new modes are added

  • native array - outputs the full 5592x3710 pixel count - which is interesting as you see the bayer reorder occur - and the various HOB/VOB areas.
  • a 'full active' pixels mode produces all output from the sensor /excluding/ the HOB/VOB - but this includes the additional line artifact.
  • The 'effective array' is the datasheet pixel area that includes a 12 pixel margin on all sides to allow for color processing to occur in the ISP scalers without issues at the edges.

I'd still like to get the binning and timing values out of the crop mode structure - but that will take some more work - and we don't yet have an api to control binning / skipping which makes it difficult to convey in the scanout mode structures.

popcornmix and others added 30 commits September 25, 2025 15:49
See: https://forum.libreelec.tv/thread/24783-tv-avr-turns-back-on-right-after-turning-them-off

While the kernel provides a :D flag for assuming device is connected,
it doesn't stop this function from being called and generating a cec_phys_addr_invalidate
message when hotplug is deasserted.

That message provokes a flurry of CEC messages which for many users results in the TV
switching back on again and it's very hard to get it to stay switched off.

It seems to only occur with an AVR and TV connected but has been observed across a
number of manufacturers.

The issue started with raspberrypi#4371
and this provides an optional way of getting back the old behaviour

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
The intention of the vc4.force_hotplug setting is to
ignore hotplug completely.

It can be used when a display toggles hotplug when
switching AV inputs, going into standby or changing a
KVM switch, and some side effect of that is unwanted.

It turns out while vc4.force_hotplug currently makes
hotplug always read as asserted, that isn't enough to
stop drm doing lots of stuff, including re-reading
the edid.

An example of what drm does with a hotplug deasert/assert
and vc4.force_hotplug=1 currently is:

https://paste.debian.net/hidden/dc07434b/

That is unwanted. Lets ignore the hotplug interrupt
completely so drm is blissfully unaware of the hotplug change.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
There appears to be a requirement for some devices
(I'm testing with a 8K VRROOM 40Gbps HDMI switch)
for a measable delay between removing the hdmi phy output from
the old mode, to enabling the hdmi phy output for the new mode.

Without the delay, a mode switch has a small change of getting a permanent
'no signal', which requires a subsequent mode switch or a unplug/replug
to redetect.

Switching between 4kp24/25/30 modes fails about 5% of time in my testing.

Add a delay to make it impossible to switch faster than this.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
The body of this function was missing so we don't reset the phy
when disabling it.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
The current reset code doesn't actually stop the hdmi output.
That makes it difficult for displays to handle a mode set.

Powering down the PLL does actually remove the hdmi signal
and makes mode sets more reliable

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
There are no MEDIA_BUS_FMT_* defines for GRB or BRG, and adding
them is a pain.

Add a DT override to allow setting the order.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
Seeing as the HVS can be configured with regard the scaling filter,
and DRM now supports selecting scaling filters at a per CRTC or
per plane level, we can implement it.

Default remains as the Mitchell/Netravali filter, but nearest
neighbour is now also implemented.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The documentation says that the TPZ filter can not upscale,
and requesting a scaling factor > 1:1 will output the original
image in the top left, and repeat the right/bottom most pixels
thereafter.
That fits perfectly with upscaling a 1x1 image which is done
a fair amount by some compositors to give solid colour, and it
saves a large amount of LBM (TPZ is based on src size, whilst
PPF is based on dest size).

Select TPZ filter for images with source rectangle <=1.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The register to enable/disable background fill was being set
from atomic flush, however that will be applied immediately and
can be a while before the vblank. If it was required for the
current frame but not for the next one, that can result in
corruption for part of the current frame.

Store the state in vc4_hvs, and update it on vblank.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The HVS can accept an arbitrary number of planes, provided
that the overall pixel read load is within limits, and
the display list can fit into the dlist memory.

Now that DRM will support 64 planes per device, increase
the number of overlay planes from 16 to 48 so that the
dlist complexity can be increased (eg 4x4 video wall on
each of 3 displays).

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Instead of having 48 generic overlay planes, assign 32 to the
writeback connector so that there is no ambiguity in wlroots
when trying to find a plane for composition using the writeback
connector vs display.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The transposer/writeback connector should be running with a
lower priority, so shouldn't be factored into the load
calculations.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
As the writeback connector doesn't have the same realtime
constraints of a live display, drop the panic priority for it.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The txp block can implement transpose as it writes out the image
data, so expose that through the new connector rotation property.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

drm: vc4: txp: Do not allow 24bpp formats when transposing

The hardware doesn't support transposing to 24bpp (RGB888/BGR888)
formats. There's no way to advertise this through DRM, so block
it from atomic_check instead.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Currently, booting with no hdmi connected has:
pi@pi4:~ $ vcgencmd measure_clock hdmi pixel
frequency(9)=120010256
frequency(29)=74988280

After connecting hdmi we get:
pi@pi4:~ $ vcgencmd measure_clock hdmi pixel
frequency(9)=300005856
frequency(29)=149989744

and that persists after disconnecting hdmi

I can measure this on a power supply as 10mA@5.2V (52mW).

We should always remove clk_set_min_rate requests
when we no longer need them.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
Whilst BCM2712 does fix using odd horizontal timings, it doesn't
work with interlaced modes.

Drop the workaround for interlaced modes and revert to the same
behaviour as BCM2711.

raspberrypi#6281

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
This is a squash of all firmware-kms related patches from previous
branches, up to and including
"drm/vc4: Set the possible crtcs mask correctly for planes with FKMS"
plus a couple of minor fixups for the 5.9 branch.
Please refer to earlier branches for full history.

This patch includes work by Eric Anholt, James Hughes, Phil Elwell,
Dave Stevenson, Dom Cobley, and Jonathon Bell.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

drm/vc4: Fixup firmware-kms after "drm/atomic: Pass the full state to CRTC atomic enable/disable"

Prototype for those calls changed, so amend fkms (which isn't
upstream) to match.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

drm/vc4: Fixup fkms for API change

Atomic flush and check changed API, so fix up the downstream-only
FKMS driver.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

drm/vc4: Make normalize_zpos conditional on using fkms

Eric's view was that there was no point in having zpos
support on vc4 as all the planes had the same functionality.

Can be later squashed into (and fixes):
drm/vc4: Add firmware-kms mode

Signed-off-by: Dom Cobley <popcornmix@gmail.com>

drm/vc4: FKMS: Change of Broadcast RGB mode needs a mode change

The Broadcast RGB (aka HDMI limited/full range) property is only
notified to the firmware on mode change, so this needs to be
signalled when set.

raspberrypi/firmware#1580

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

vc4/drv: Only notify firmware of display done with kms

fkms driver still wants firmware display to be active

Signed-off-by: Dom Cobley <popcornmix@gmail.com>

ydrm/vc4: fkms: Fix margin calculations for the right/bottom edges

The calculations clipped the right/bottom edge of the clipped
range based on the left/top margins.

raspberrypi#4447

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

drm/vc4: fkms: Use new devm_rpi_firmware_get api

drm/kms: Add allow_fb_modifiers

Signed-off-by: Dom Cobley <popcornmix@gmail.com>

drm/vc4: Add async update support for cursor planes

Now that cursors are implemented as regular planes, all cursor
movements result in atomic updates. As the firmware-kms driver
doesn't support asynchronous updates, these are synchronous, which
limits the update rate to the screen refresh rate. Xorg seems unaware
of this (or at least of the effect of this), because if the mouse is
configured with a higher update rate than the screen then continuous
mouse movement results in an increasing backlog of mouse events -
cue extreme lag.

Add minimal support for asynchronous updates - limited to cursor
planes - to eliminate the lag.

See: raspberrypi#4971
     raspberrypi#4988

Signed-off-by: Phil Elwell <phil@raspberrypi.com>

drivers/gpu/drm/vc4: Add missing 32-bit RGB formats

The missing 32-bit per pixel ABGR and various "RGB with an X value"
formats are added. Change sent by Dave Stevenson.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>

drm: vc4: Fixup duplicated macro definition in vc4_firmware_kms

Both vc4_drv.h and vc4_firmware_kms.c had definitions for
to_vc4_crtc.

Rename the fkms one to make it unique, and drop the magic
define vc4_crtc vc4_kms_crtc
define to_vc4_crtc to_vc4_kms_crtc
that renamed half the variable and function names in a slightly
unexpected way.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

drm/vc4: Fix FKMS for when the YUV chroma planes are different buffers

The code was assuming that it was a single buffer with offsets,
when kmstest uses separate buffers and 0 offsets for each plane.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

drm/vc4: fkms: Rename plane related functions

The name collide with the Full KMS functions that are going to be made
public.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>

drm/vc4_fkms: Fix up interrupt handler for both 2835/2711 and 2712

2712 has switched from using the SMI peripheral to another interrupt
source for the vsync interrupt, so handle both sources cleanly.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

drm/vc4: fkms: No SMI abuse needed on BCM2712

Since we don't use the (absent) SMI block to create interrupts on
BCM2712, there's no need to map any registers.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
Testing whether the VideoCore generation we want to mock is vc5 or vc4
worked so far, but will be difficult to extend to support BCM2712 (VC6).

Convert to a switch.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
The DRM device pointer and the DRM encoder pointer are redundant, since
the latter is attached to the former and we can just follow the
drm_encoder->dev pointer.

Let's remove the drm_device pointer argument.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Some tests will need to retrieve the output that was just allocated by
vc4_mock_atomic_add_output().

Instead of making them look them up in the DRM device, we can simply
make vc4_mock_atomic_add_output() return an error pointer that holds the
allocated output instead of the error code.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
The BCM2712 has a simpler pipeline that can only output to a writeback
connector and two HDMI controllers.

Let's allow our kunit tests to create a mock of that pipeline.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
The BCM2712 has a simpler pipeline than the BCM2711, and thus the muxing
requirements are different. Create some tests to make sure we get proper
muxing decisions.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
The current mock planes were just using the regular drm_plane_state,
while the driver expect struct vc4_plane_state that subclasses
drm_plane_state.

Hook the proper implementations of reset, duplicate_state, destroy and
atomic_check to create vc4_plane_state.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Some tests will need to find a plane to run a test on for a given CRTC.
Let's create a small helper to do that.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
We'll start to add some tests for the plane state logic, so let's create
a helper to add a plane to an existing atomic state.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
We'll start testing our planes code in situations where we will use more
than XRGB8888, so let's add a few common pixel formats.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
The BCM2712 comes with a different LBM size computation than the
previous generations, so let's add the few examples provided as kunit
tests to make sure we always satisfy those requirements.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
The tests on vc4 (BCM2835-7) were checking for DSI1 muxing being
to restricted channel 2, and therefore muxing with TXP was impossible.

As we no longer have that restriction, update the capabilities
defined for DSI1, move the tests that used to be impossible to the
valid list, and extend for additional combinations that are now
possible.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Following the example of [1], move the state allocation out of the init
function to make it thread safe.

[1] commit 7e0351a ("drm/vc4: tests: Stop allocating the state in
test init")

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
6by9 and others added 22 commits September 25, 2025 16:08
There was lots of register definition information dumped from
the some source into the driver but unused. Remove it, and
format the remaining lines according to the Linux kernel coding
style.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The D-PHY on RP1 support lane polarity swapping, and there
is a standard device tree mechanism for configuring this,
so tie the two together.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The PL011 driver in this downstream kernel tree supports an extra
compatible string - arm,pl011-axi - for use by RP1. This registers as a
platform driver, not an AMBA driver, and has the advantage of responding
to dynamic Device Tree changes such as loading one of the "uart<n>"
overlays.

Change all of the downstream Raspberry Pi dts files to use the new
compatible string. At the same time, remove the override of the periphid
as the upstream code now has the correct value.

See: raspberrypi#7019

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
The target crop rectangle is initialized with the crop of the default
sensor mode. This is incorrect when a different sensor mode gets
selected. Fix that by updating the crop rectangle when changing the
sensor mode.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
The exposure control on the imx283 is handled through the SHR register.
This value is calculated based upon the hmax and vmax registers as a
property of the total line and frame length.

Ensure that the SHR is updated whenever the blankings update and adjust
the frame intervals to ensure the correct exposure is configured on the
sensor.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
When the code requested by imx283_set_pad_format() is not supported, a
kernel exception occurs due to dereferencing the mode variable which is
null. Fix that by correcting the code to a valid value before getting
the mode table.

While at it, remove the cases for the other unsupported codes in
get_mode_table.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Move the struct imx283_mode further down in the compilation unit so that
it can make reference of the scan out mode structures which are
presently defined after.

No functional change intended in this commit.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Move the common data structures to a new scanout table and allow v4l2
output modes to reference their scanout.

This removes duplication from the mode definitions.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The horizontal optical black values are not used as we do not enable
HOB output - and instead directly use HTRIMMING to request the desired
horizontal cropping position.

Remove the unused reference to simplify.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The Vertical Optical Black region is a property of the selected scan mode.

Move the storage of this property to the scan mode table so it does
not get duplicated when adding new output modes.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The vertical cropping parameters are specific to the readout mode
selected and do not need to be duplicated on v4l2 mode choices.

Move them to the imx283_scanout definitions. This also fixes the 10bit
mode which had not yet defined the veff correctly and worked by chance.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Provide a common reference for the recommended recording area to use in
each of the binning modes.

No functional change intended in this commit.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Adapt the Horiztonal configuration into its own scope to improve
readability of these two associated register configurations.

No functional change intended in this commit.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reduce the scope of the 5 registers used for vertical positioning to
make it easier to maintain and calculate the exact vertical
configuration.

No functional changes intended in this patch, which simplifies
later development.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Refactor the v_pos to separate out the vflip handling from the top
coordinate.

No functional change is intended in this commit.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The vertical handling cuts unused lines to restrict the output to the
desired height.

It can be valid to set y_outsize larger than the veff to include optical
black regions in the visible image.

Ensure that the cut is clamped to the veff to prevent underflow.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The user clamp region is included in the pixel native area coordinates
but is not included in the sensor vertical coordinates when configuring
the VWINPOS.

Remove the 16 line offset from the top position to account for this
and in the event that a crop position requested vertical optical
black, reduce the OB_SIZE_V register which causes those lines to be
output in the main image data type instead.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The IMX283 introduces an extra line on the all-pixel scan out modes to
prevent bayer re-ordering on flip handling.

This is undesireable as it introduces the line in all crop
configurations.

The OB_SIZE_V register determines how many lines from the output will be
directed into the custom data type for optical black region.

To overcome the extra line which is forcefully added, utilise the
vertical optical black region to redirect the extra line. An additional
line also needs to be redirected to once again retain the bayer order.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The size should represent the amount of lines to cut vertically
and exclude from the pixel array for the image data.

Keeping this at the expected value causes corruption on the last
line. Reduce by increasing the defined size of the image by
a single line to ensure that the data is valid for the final
output.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Provide a mode that outputs all pixels from the full native array.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Add a mode to support output of the full illuminated area of the pixel
array. When not flipped this mode includes a top black line which is
added by the sensor to prevent bayer reording when flipping.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Provide a mode that includes all effective pixels which includes a 12
pixel margin for colour processing on all edges.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
@kbingham
Copy link
Contributor Author

I haven't posted these upstream yet - sharing here to get them tested by known IMX283 users on RPi ... but no specific desire to merge this into the RPi tree until reviewed upstream. But they could be if testers find the series beneficial.

@will127534
Copy link

will127534 commented Sep 27, 2025

SRGGB12_CSI2P,5592x3710 mode doesn't seems right, but all other modes are working fine:
5592x3710:
IMX283_5592_3710

5496x3672:
IMX283_5496_3672

@will127534
Copy link

will127534 commented Sep 27, 2025

Ah it looks like SRGGB10_CSI2P,5472x3648/0 this mode isn't working also, there is no error message but the frame is empty.

@will127534
Copy link

Here are the jpeg images for all the modes
=========12-bit Mode ============
5592x3710_12:
5592x3710_12
5496x3694_12:
5496x3694_12
5496x3672_12:
5496x3672_12
5472x3648_12:
5472x3648_12
2736x1824_12:
2736x1824_12
1824x1216_12:
1824x1216_12

=========10-bit Mode ============
5472x3648_10:
5472x3648_10

@kbingham
Copy link
Contributor Author

Thank you - I hadn't noticed 10 bit was broken - but thanks to your test I can see the bug. I'll fix that.

@kbingham
Copy link
Contributor Author

kbingham commented Sep 27, 2025

5592x3710_12:
5592x3710_12

I think this is almost expected behaviour - I was expecting 'pink' because the bayer order ends up being mis-interpreted/mis-aligned - though I don't know why it goes quite so psychedelic through the ISP ...
But it's also a bit too specialised a mode to actually advertise anyway I think - so I'll just drop this one.

The 10 bit mode failed to specify the vertical and horizontal binning
ratio and therefore creates an invalid configuration.

Provide the values.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
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.