Skip to content

bcm2712: Use all 20 MIP1 outputs - #7729

Open
nbuchwitz wants to merge 617 commits into
raspberrypi:rpi-7.3.yfrom
nbuchwitz:devel/pcie-mip1-bump
Open

nbuchwitz wants to merge 617 commits into
raspberrypi:rpi-7.3.yfrom
nbuchwitz:devel/pcie-mip1-bump

Conversation

@nbuchwitz

Copy link
Copy Markdown
Contributor

I've been experimenting with more MSI vectors on MIP1, as our RevPi Connect 5 has 3x LAN7430s on pcie1. They don't fit into the 8 MIP1 outputs (each tries to claim 6 outputs), so our DT uses the rc MSI controller instead. Unfortunately it can't pin IRQs, which is not great in most industrial fieldbus setups.

The patches seem to work for my limited PCIe knowledge, but I'd really value @P33M's (and others) feedback on it. If this can work, I'd try to upstream the patches as usual.

@nbuchwitz nbuchwitz changed the title Devel/pcie mip1 bump bcm2712: Use all 20 MIP1 outputs Oct 31, 2026
@nbuchwitz
nbuchwitz force-pushed the devel/pcie-mip1-bump branch from 55e66be to b789b8b Compare October 31, 2026 21:28
pelwell and others added 28 commits November 2, 2026 14:03
The DHT11 datasheet is pretty cryptic, but it does suggest that after
each integer value (humidity and temperature) there are "decimal"
values. Validate these as integers in the range 0-9 and treat them as
tenths of a unit.

Link: raspberrypi#6220

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

The non-desktop property "Indicates the output should be ignored for
purposes of displaying a standard desktop environment or console."

That sounds like it should be true for all writeback and virtual
connectors as you shouldn't render a desktop to them, so set it
by default.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The limit of 32 planes per DRM device is dictated by the use
of planes_mask returning a u32.

Change to a u64 such that 64 planes can be supported by a device.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Some hardware will implement transpose as a rotation operation,
which when combined with X and Y reflect can result in a rotation,
but is a discrete operation in its own right.

Add an option for transpose only.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Some connectors, particularly writeback, can implement flip
or transpose operations as writing back to memory.

Add a connector rotation property to control this.

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

drm: Validate connector rotation has one bit set in the rotation property

Copy the same validation logic as from the plane rotation property.

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

drm/vc4: txp: add implementation of the missing connector reset custom function

In the previous commit, we added a rotation parameter to be used in the
connector, but because we are still using the default reset function
without implementing a custom reset function to properly initialize it,
the rotation variable remains NULL until it is initialized directly
in userspace.

To prevent this, we must implement a custom reset function that properly
initializes the rotation parameter.

Signed-off-by: Jeongjun Park <aha310510@gmail.com>
For devices where transfer lengths are not known upfront, there is a
danger when the destination is wider than the source that partial words
can be lost at the end of a transfer. Ideally the controller would be
able to flush the residue, but it can't - it's not even possible to tell
that there is any.

Instead, allow the client driver to avoid the problem by setting a
smaller width.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
SPI transfers are of defined length, unlike some UART traffic, so it is
safe to let the DMA controller choose a suitable memory width.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
Attempting to start a non-idle channel causes an error message to be
logged, and is inefficient. Test for emptiness of the desc_issued list
before doing so.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
The Raspberry Pi RP1 includes 2 M3 cores running firmware. This driver
adds a mailbox communication channel to them via a doorbell and some
shared memory.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
The RP1 firmware runs a simple communications channel over some shared
memory and a mailbox. This driver provides access to that channel.

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

firmware: rp1: Simplify rp1_firmware_get

Simplify the implementation of rp1_firmware_get, requiring its clients
to have a valid 'firmware' property. Also make it return NULL on error.

Link: raspberrypi#6593

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

firmware: rp1: Linger on firmware failure

To avoid pointless retries, let the probe function succeed if the
firmware interface is configured correctly but the firmware is
incompatible. The value of the private drvdata field holds the outcome.

Link: raspberrypi#6642

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

firmware: rp1: Rename to rp1-fw to avoid module name collision

There is already the driver in drivers/mfd/rp1.ko, so having
drivers/firmware/rp1.ko can cause issues when using modinfo
and similar, and we can get errors with "Module rp1 is already
loaded" when trying to load it.

Rename the module so that the name is unique.

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

mailbox: rp1: Don't claim channels in of_xlate

The of_xlate method saves the calculated event mask in the con_priv
field. It also rejects subsequent attempt to use that channel because
the mask is non-zero, which causes a repeated instantiation of a client
driver to fail.

The of_xlate method is not meant to be a point of resource acquisition.
Leave the con_priv initialisation, but drop the test that it was
previously zero.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
Provide remote access to the PIO hardware in RP1. There is a single
instance, with 4 state machines.

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

misc: rp1-pio: Support larger data transfers

Add a separate IOCTL for larger transfer with a 32-bit data_bytes
field.

See: raspberrypi/utils#107

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

misc: rp1-pio: More logical probe sequence

Sort the probe function initialisation into a more logical order.

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

misc: rp1-pio: Minor cosmetic tweaks

No functional change.

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

misc: rp1-pio: Add in-kernel DMA support

Add kernel-facing implementations of pio_sm_config_xfer and
pio_xm_xfer_data.

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

misc: rp1-pio: Handle probe errors

Ensure that rp1_pio_open fails if the device failed to probe.

Link: raspberrypi#6593

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

misc: rp1-pio: SM_CONFIG_XFER32 = larger DMA bufs

Add an ioctl type - SM_CONFIG_XFER32 - that takes uints for the buf_size
and buf_count values.

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

misc/rp1-pio: Fix copy/paste error in pio_rp1.h

As per the subject, there was a copy/paste error that caused
pio_sm_unclaim from a driver to result in a call to
pio_sm_claim. Fix it.

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

misc: rp1-pio: Fix parameter checks wihout client

Passing bad parameters to an API call without a pio pointer will cause
a NULL pointer exception when the persistent error is set. Guard
against that.

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

misc: rp1-pio: Convert floats to 24.8 fixed point

Floating point arithmetic is not supported in the kernel, so use fixed
point instead.

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

misc: rp1-pio: Error out on incompatible firmware

If the RP1 firmware has reported an error then return that from the PIO
probe function, otherwise defer the probing.

Link: raspberrypi#6642

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

misc: rp1-pio: Demote fw probe error to warning

Support for the RP1 firmware mailbox API is rolling out to Pi 5 EEPROM
images. For most users, the fact that the PIO is not available is no
cause for alarm. Change the message to a warning, so that it does not
appear with "quiet" in cmdline.txt.

Link: raspberrypi#6642

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

misc: rp1-pio: Don't just reuse the same DMA buf

A missing pointer increment meant that not only was the same buffer
being reused again and again, there was also no protection against
using it simultaneously for multiple transfers. Fix that basic bug, and
also move a similar increment to before the transfer is started, which
feels less racy.

See: raspberrypi#6919

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

misc: rp1-pio: Fix a config_xfer error path

If the DMA channel allocation fails, the relevant dma_configs entry
should be marked as no longer claimed, otherwise rp1_pio_sm_dma_free
will be called with an error number as a DMA channel pointer.

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

misc: rp1-pio: Request a DMA burst size of 8

Improve DMA performance by increasing the burst size to 8.

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

misc: rp1-pio: Get burst size from DMA capabilities

Although the PIO throughput benefits from larger burst sizes, only the
first two DMA channels support a burst size of 8 - the others are capped
at 4. To avoid misconfiguring the PIO hardware, retrieve the actual
max_burst value from the DMA channel's capabilities.

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

misc: rp1-pio: Defer for out-of-order probing

In the event that a client of the rp1-pio driver is probed before it,
return -EPROBE_DEFER from pio_open to allow it to be retried.
Otherwise, return an error code on error, not a NULL pointer, as that
is what clients are expecting.

See: raspberrypi#7211

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

misc: rp1-pio: Add narrowing casts

Avoid some compiler warnings by adding explicit narrowing casts.

See: raspberrypi#7309

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

misc: rp1-pio: Include maxburst in PIO_DMACTRL

The PIO DMA interface exposes empty/not empty signals as well as
the threshold signals required for bursts. If the FIFO is not ready
for a burst, a single beat burst can still be performed.

It is therefore safe to set the PIO FIFO thresholds to the burst size
used by the DMA controller.

See: https://forums.raspberrypi.com/viewtopic.php?t=398882

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

misc: rp1-pio: Ensure transfers are configured

Fail transfers if they haven't first been configured.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
Use the PIO hardware on RP1 to implement a PWM interface.

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

pwm: rp1: use pwmchip_get_drvdata() instead of container_of()

The PWM framework may not embed struct pwm_chip within the driver’s
private data. Using container_of() can result in accessing invalid
memory or NULL pointers, especially after recent kernel changes.

Switch to pwmchip_get_drvdata() to reliably access the driver data.
This resolves kernel warnings and probe failures seen after updating
from kernel 6.12.28 to 6.12.34 [1]

While at it remove the now obsolete `struct pwm_chip chip` member from
`struct pwm_pio_rp1`.

[1] raspberrypi#6971

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>

pwm: rp1: Silently correct illegal values

Remove the need for the user to know the limitations of this PWM
implementation by adjusting configuration requests to be the closest
acceptable value. Add a get_state method so that the actual values can
be queried.

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

pwm: rp1: Correct period off-by-1 error

Correct the set_period method to pass (period - 1), as required by the
PIO state machine.

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

pwm: pio-rp1: don't flag driver as using atomic ops

The functions are implemented over a RPC pipe, so may sleep.

Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
ws2812-pio-rp1 is a PIO-based driver for WS2812 LEDS. It creates a
character device in /dev, the default name of which is /dev/leds<n>,
where <n> is the instance number. The number of LEDS should be set
in the DT overlay, as should whether it is RGB or RGBW, and the default
brightness.

Write data to the /dev/* entry in a 4 bytes-per-pixel format in RGBW
order:

  RR GG BB WW RR GG BB WW ...

The white values are ignored unless the rgbw flag is set for the device.

To change the brightness, write a single byte to offset 0, 255 being
full brightness and 0 being off.

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

misc: ws2812-pio-rp1: Add pass-through mode

Pass-through mode disables all gamma and brightness processing, sending
the raw pixel data directly to the LEDs. It is enabled by setting the
brightness to zero, either in Device Tree or using the runtime method of
writing a single byte (in this case 0) to the device.

See: raspberrypi#7108

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
Using increased bit depth for no reason increases power
consumption, and differs from the behaviour prior to the
conversion to use the HDMI helper functions.

Initialise the state max_bpc and requested_max_bpc to the
minimum value supported. This only affects Raspberry Pi,
as the other users of the helpers (rockchip/inno_hdmi and
sunx4i) only support a bit depth of 8.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
DSI0 and DSI1 have different widths for the command FIFO (24bit
vs 32bit), but the driver was assuming the 32bit width of DSI1
in all cases.
DSI0 also wants the data packed as 24bit big endian, so the
formatting code needs updating.

Handle the difference via the variant structure.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
During normal operations, the cursor position update is done through an
asynchronous plane update, which on the vc4 driver basically just
modifies the right dlist word to move the plane to the new coordinates.

However, when we have the overscan margins setup, we fall back to a
regular commit when we are next to the edges. And since that commit
happens to be on a cursor plane, it's considered a legacy cursor update
by KMS.

The main difference it makes is that it won't wait for its completion
(ie, next vblank) before returning. This means if we have multiple
commits happening in rapid succession, we can have several of them
happening before the next vblank.

In parallel, our dlist allocation is tied to a CRTC state, and each time
we do a commit we end up with a new CRTC state, with the previous one
being freed. This means that we free our previous dlist entry (but don't
clear it though) every time a new one is being committed.

Now, if we were to have two commits happening before the next vblank, we
could end up freeing reusing the same dlist entries before the next
vblank.

Indeed, we would start from an initial state taking, for example, the
dlist entries 10 to 20, then start a commit taking the entries 20 to 30
and setting the dlist pointer to 20, and freeing the dlist entries 10 to
20. However, since we haven't reach vblank yet, the HVS is still using
the entries 10 to 20.

If we were to make a new commit now, chances are the allocator are going
to give the 10 to 20 entries back, and we would change their content to
match the new state. If vblank hasn't happened yet, we just corrupted
the active dlist entries.

A first attempt to solve this was made by creating an intermediate dlist
buffer to store the current (ie, as of the last commit) dlist content,
that we would update each time the HVS is done with a frame. However, if
the interrupt handler missed the vblank window, we would end up copying
our intermediate dlist to the hardware one during the composition,
essentially creating the same issue.

Since making sure that our interrupt handler runs within a fixed,
constrained, time window would require to make Linux a real-time kernel,
this seems a bit out of scope.

Instead, we can work around our original issue by keeping the dlist
slots allocation longer. That way, we won't reuse a dlist slot while
it's still in flight. In order to achieve this, instead of freeing the
dlist slot when its associated CRTC state is destroyed, we'll queue it
in a list.

A naive implementation would free the buffers in that queue when we get
our end of frame interrupt. However, there's still a race since, just
like in the shadow dlist case, we don't control when the handler for
that interrupt is going to run. Thus, we can end up with a commit adding
an old dlist allocation to our queue during the window between our
actual interrupt and when our handler will run. And since that buffer is
still being used for the composition of the current frame, we can't free
it right away, exposing us to the original bug.

Fortunately for us, the hardware provides a frame counter that is
increased each time the first line of a frame is being generated.
Associating the frame counter the image is supposed to go away to the
allocation, and then only deallocate buffers that have a counter below
or equal to the one we see when the deallocation code should prevent the
above race from occurring.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Users are reporting running out of DLIST memory. Add a
debugfs file to dump out all the allocations.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
We have a read-modify-write race when updating SCALER_DISPCTRL for
underrun and end-of-frame interrupts.
Ideally it would be fixed via a spinlock or similar, but that will
require a reasonable amount of study to ensure we don't get deadlocks.

The underrun reporting is only for debug, so disable it for now.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The dmabuf import already checks that the backing buffer is contiguous
and rejects it if it isn't. vc4 also requires that the buffer is
in the bottom 1GB of RAM, and this is all correctly defined via
dma-ranges.

However the kernel silently uses swiotlb to bounce dma buffers
around if they are in the wrong region. This relies on dma sync
functions to be called in order to copy the data to/from the
bounce buffer.

DRM is based on all memory allocations being coherent with the
GPU so that any updates to a framebuffer will be acted on without
the need for any additional update. This is fairly fundamentally
incompatible with needing to call dma_sync_ to handle the bounce
buffer copies, and therefore we have to detect and reject mappings
that use bounce buffers.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
DSI0 is misbehaving and needs to action things on vblank to
work around it.
Add a new hook to call across during vblank.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The initialisation sequence differs slightly from the documentation
in that the clocks are meant to be running before resets and
similar.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
vc4_dsi_bridge_disable wasn't resetting things during shutdown,
so add that in.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The block must be enabled for the FIFO resets to be actioned,
so ensure this is the case.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The pixel to byte FIFO appears to not always reset correctly,
which can lead to colour errors and/or horizontal shifts.
Reset on every vblank to work around the issue.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The TC358762 bridge and panel decodes the mode differently on
DSI0 to DSI1 for no obvious reason, and results in a shift off
the screen.
Whilst it would be possible to change the compatible used for
the panel, that then messes up Pi5.

As it appears to be restricted to vc4 DSI0, fix up the mode
in vc4_dsi.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Some DSI peripheral drivers wish to send commands in the
post_disable or panel unprepare callback. These are called
after the DSI host's disable call, but before the host's
post_disable if pre_enable_prev_first is set.

Don't reset the block until post_disable to allow these
commands to be sent.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The DSI block appears to be able to come up stuck in a condition where
it leaves the lanes in HS mode or just jabbering. This stops LP
transfers from completing as there is no LP time available. This is
signalled via the LP1 contention error.

Enabling video briefly clears that condition, so if we detect the
error condition, enable video mode and then retry.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Similar to the ch7006 and nouveau drivers, introduce a "tv_mode" module
parameter that allow setting the TV norm by specifying vc4.tv_norm= on
the kernel command line.

If that is not specified, try inferring one of the most popular norms
(PAL or NTSC) from the video mode specified on the command line. On
Raspberry Pis, this causes the most common cases of the sdtv_mode
setting in config.txt to be respected.

Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>

drm/vc4: Do not reset tv mode as this is already handled by framework

In vc4_vec_connector_reset, the tv mode is already reset to the
property default by drm_atomic_helper_connector_tv_reset, so there
is no need for a local fixup to potentially some other default.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
6by9 and others added 19 commits November 2, 2026 14:03
If the requested region matched the defined active area then
the driver switched to all-pixel mode. This left the possibility
that the activeare was incorrect and not reading out the area
expected.

Switch to always requesting window mode.

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

Several of the Sony Starvis 2 sensors are identical in the
majority of their programming, but differ largely only in the
size of pixel array and some timing parameters.

Parameterise those parameters in preparation for supporting other
variants.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
With some Starvis 2 sensors, the link frequency on 2 lanes is sufficient
to achieve a lower line time than the 4 lane divided by 2, effectively
that it hits the minimum that the pixel array can handle.
That can't easily be handled with the way the values are currently stored.

Storing the 2 lane hmax alongside the pixel array's minimum allows the
4 lane support to divide the value by 2, and then clip to the pixel
array value as a minimum.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
DT allows configuration of multiple link frequencies.
V4L2_CID_LINK_FREQ allows read write control.

Join these up so that link frequency can be configured at run time,
as long, as the sensor isn't streaming.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
As we have a way to confirm which Starvis2 module is connected, add
a generic compatible that will use all defined variants to attempt to
identify which module is connected.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
IMX662 is a 1080p Starvis 2 sensor that follows the same programming
pattern as IMX678, so add it to the newly parameterised common
driver.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The IMX675 is a 5MPix Starvis2 sensor that follows the same
programming pattern as IMX678 and IMX662, so add it into the
driver.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
IMX832 is replacing IMX662, and it follows the same pattern as all the
Starvis2 sensors.

Add the sensor specific configuration for it.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
IMX585 is an 8MPix Starvis 2 sensor, so add support for it.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
HCG (High Conversion Gain) adds additional gain within the sensor,
but also requires that the minimum analogue gain is 34 rather than
0 when in the default LCG mode.

Add a module parameter that is read during probe and at the start
of enable_streams, and adjust settings accordingly.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Whilst normally digital gain would be applied in the ISP, there
are some situations where it is an advantage to allow the use of
the on-sensor digital gain too. Allow it.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
The software reference for imx678 lists register SHR0 setting
the shutter sweep time with a valid range of 4 to (Number of
lines per frame - 1), and then gives the example of all-pixel
scan mode with VMAX=2250 and SHR0=2249 giving an integraion time
of "1H + Toffset" (further defining Toffset as 0).

The driver defining STARVIS2_EXPOSURE_MIN as 2 would therefore
be contradictory, and increasing the minimum exposure achievable.

Correct STARVIS2_EXPOSURE_MIN.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Disabling a channel will stall and timeout if it is currently
transferring to or from a slow peripheral with handshaking (which they
all have). When that happens, use the channels "abort" feature to
unblock the channel.

See: raspberrypi#7642

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
IMX585 requires bit 4 of the WINMODE register (0x3018) to be
set, whilst the bottom nibble selects between all-pixel and
window mode.

Switch to using cci_update_bits so that only the bottom nibble
is updated, thereby working on all supported Starvis2 sensors.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Commit 44d7fb8 ("media: pwm-ir-tx: Avoid direct access to
hrtimer clockbase") converted a loop conditional from
               now = timer->base->get_time();
       } while (hrtimer_get_expires_tv64(timer) < now);
to
       while (hrtimer_expires_remaining(timer) > 0);

hrtimer_expires_remaining returns (expires - now), so the
change has inverted the condition.

Convert back to follow the original pattern, but using the
proper API call.

Fixes: 44d7fb8 ("media: pwm-ir-tx: Avoid direct access to hrtimer clockbase")
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
When more than 8 bpc is requested and RGB only fits the TMDS limit at
8 bpc (e.g. 4k60 at 594MHz), YUV422 at 12 bpc fits at the same TMDS
rate. Previously RGB was tried at every bpc before YUV422, so 8 bpc RGB
was always chosen and the extra depth was lost.

Try RGB down to 10 bpc, then YUV422, and only then RGB at 8 bpc. This
keeps the existing preference for RGB at 10 bpc over YUV422 at 12 bpc.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
The driver already allows BCM2711's GPIOs 54-57 to be controlled, but an
interrupt for one of these will not be handled, likely causing an
interrupt storm. Extend the mask for bank 2 to include these higher
GPIOs.

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

On BCM2712 D0, a format with no alpha channel takes its alpha from the
plane alpha property (ALPHA_MASK_FIXED). With the default
"Pre-multiplied" blend mode the ALPHA_PREMULT flag was still set, so
the HVS treated the colour as already multiplied by the plane alpha and
added it unscaled on top of the planes below.

The KMS blend modes are all equivalent when there is no pixel alpha,
so only set ALPHA_PREMULT when the format has an alpha channel, as the
other generations already do.

Fixes: raspberrypi#7700
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
With the "None" pixel blend mode the HVS takes the plane alpha property
as a fixed alpha. For a format with an alpha channel ALPHA_MIX was also
set, multiplying the plane alpha in a second time, so a plane alpha of
0.5 blended at 0.25. Seen on both BCM2712 C1 and D0.

Don't set ALPHA_MIX when the blend mode is "None".

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
MIP1, the MSI controller behind pcie1 on BCM2712, only describes 8
outputs. I measured the wiring on a CM5 and found 20, routed to GIC
SPIs that are not contiguous.

Patch 1 documents multiple msi-ranges entries. Patch 2 fixes multi-MSI
blocks for non-power-of-two counts and is meant for stable. Patch 3
lets the driver take several ranges. Patch 4 adds the outputs and
depends on patch 3.

Tested on rpi-7.3.y on a Revolution Pi Connect 5 (CM5) with three
LAN7430 NICs behind a PCIe switch, 6 MSI-X vectors each. DPC on the
switch ports uses another 6 outputs. Vectors per NIC:

                  8 outputs         20 outputs
  --------------------------------------------
  without DPC     6, 2, INTx        6, 6, 6
  with DPC        2, INTx, INTx     6, 6, 2

Industrial Ethernet setups often pin each NIC's interrupts to its own
CPU. That only works on MIP1. The RC MSI target keeps everything on
CPU0. Two NVMe drives behind a switch or an FPGA design [1] hit the
same limit.

A test module requesting 3 MSI vectors per NIC gets aligned blocks with
the series. Without patch 2 the block is misaligned, its last vector
lands outside the described outputs and the device's own MSI never
arrives. The old single-range node still works.

[1] https://forums.raspberrypi.com/viewtopic.php?t=398134

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>

--- b4-submit-tracking ---
# This section is used internally by b4 prep for tracking purposes.
{
  "series": {
    "revision": 1,
    "change-id": "20261030-investigate-bcm2712-mip1-v2-4ff97c32b04a",
    "prefixes": [],
    "presubject": ""
  }
}
…msi-ranges

The MIP outputs are not wired to one contiguous block of GIC SPIs, so a
single msi-ranges entry cannot describe all of them. Define how several
entries map to the outputs, and limit the legacy brcm,msi-offset to a
single entry, the only case the driver has ever handled.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
…unts

Multi-message MSI needs a naturally aligned block of message data, but
ilog2() rounds the request size down. A request for three vectors
reserves two slots and maps the third onto the next slot, which may
already belong to another device.

Reserve exactly the requested number of slots at a start aligned to the
next power of two.

Fixes: 32c6c05 ("irqchip: Add Broadcom BCM2712 MSI-X interrupt controller")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
The MIP outputs are not wired to one contiguous block of GIC SPIs, so a
single msi-ranges entry can only describe part of a MIP. Accept one
entry per contiguous run, in output order, and look up the SPI for each
message.

brcm,msi-offset keeps its meaning for the existing single range and is
rejected when more than one range is given.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
MIP1 serves pcie1, the external PCIe x1 port on Pi 5 and CM5, but only
8 of its outputs are described. A single multi-queue device can use
most of them, and further devices get fewer vectors or none.

The remaining wiring was measured on a CM5 by raising each MIP output
and checking which SPI became pending. 20 outputs are wired, the others
showed no route. The wiring is assumed to be the same on all BCM2712
steppings but has only been verified on CM5.

  MIP output    GIC SPI
   0..1         196..197
   2..3         200..201
   4..5         206..207
   6            240
   7            246
   8..15        255..262
  16            275
  17            282
  18            263
  19            283

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
@nbuchwitz
nbuchwitz force-pushed the devel/pcie-mip1-bump branch from b789b8b to ba5b936 Compare November 2, 2026 15:34
@P33M

P33M commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

From the incomplete Broadcom documentation that I have, the MIP to SPI mappings look correct. There was a register bit on 2712C1 that the firmware always sets to enable this (expanded but discontiguous) mapping, I believe it's hardcoded to a 1 in 2712D0.

@nbuchwitz

Copy link
Copy Markdown
Contributor Author

Thanks! Has the firmware always set that bit on C1, or is there a minimum version?

@P33M

P33M commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

All rpi-eeprom releases supporting Pi 5 set this bit on C1.

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.