[PATCH] nvme: Fix missing inbound DMA offset calculation
Torsten Duwe
duwe at lst.de
Wed May 6 11:42:22 CEST 2026
On Wed, 6 May 2026 10:59:55 +0200
Neil Armstrong <neil.armstrong at linaro.org> wrote:
> On 5/6/26 09:52, Neil Armstrong wrote:
> > On 4/30/26 16:54, Torsten Duwe wrote:
[...]
> >> +/*
> >> + * This macro detects the correct inbound DMA offset in both cases:
> >> + * 1) the NVMe is mentioned in the device tree, along with its parent,
> >> + * and no intermediate PCIe bus node in between.
> >> + * 2) the NVMe was found dynamically by PCI enumeration which has created
> >> + * an intermediate PCIe bus node. That node will be skipped and the offset
> >> + * looked up in the grandparent.
> >> + */
> >> +#define DEV_ADDR(a) (dev_has_ofnode(dev->udev) ? \
> >> + dev_phys_to_bus(dev->udev, (a)) : \
> >> + dev_phys_to_bus(dev->udev->parent, (a)))
> >
> > This looks subspicious, what is the state of the rpi5 here ? with a DT node or without ?
> >
> > AFAIK NVMes are always dynamically detected, it seems the dma_offset is not correctly
> > copied to the nvme udev when created.
Yes, they are _usually_ detected via PCI enumeration, which dynamically
adds a bus node without a corresponding DT node. But it is not prohibited
to explicitly specify an NVMe disk in the device tree, I think. We've seen
this with the RP1 chip (patches yet to come). With and without.
>
> So to check could you try adding something like:
>
> ```
> diff --git a/dts/upstream/src/arm64/broadcom/bcm2712-rpi-5-b-base.dtsi b/dts/upstream/src/arm64/broadcom/bcm2712-rpi-5-b-base.dtsi
> index 04738bf281e..640c5987077 100644
> --- a/dts/upstream/src/arm64/broadcom/bcm2712-rpi-5-b-base.dtsi
> +++ b/dts/upstream/src/arm64/broadcom/bcm2712-rpi-5-b-base.dtsi
> @@ -247,6 +247,15 @@
>
> &pcie1 {
> status = "okay";
> +
> + pci at 0,0 {
> + reg = <0x0 0x0 0x0 0x0 0x0>;
> + ranges;
> + bus-range = <0 1>;
> + device_type = "pci";
> + #address-cells = <3>;
> + #size-cells = <2>;
> + };
> };
>
> &pcie2 {
> ```
We've had that in a previous version. The downside of this is that it
would have to be done for each platform and each potential m.2 socket.
> or:
>
> ```
> --- a/drivers/core/device.c
> +++ b/drivers/core/device.c
> @@ -459,7 +459,19 @@ static int device_get_dma_constraints(struct udevice *dev)
> u64 size = 0;
> int ret;
>
> - if (!CONFIG_IS_ENABLED(DM_DMA) || !parent || !dev_has_ofnode(parent))
> + if (!CONFIG_IS_ENABLED(DM_DMA) || !parent)
> + return 0;
> +
> + /* Look for the first node in the parent chain */
> + while (parent) {
> + if (dev_has_ofnode(parent))
> + break;
> +
> + parent = dev_get_parent(parent);
> + }
> +
> + /* No parents have a node, bail out */
> + if (!parent)
> return 0;
>
> /*
> ```
> Which will try to find the node higher in the parent chain.
Now this looks extremely tempting. It should solve the problem for NVMe
and probably a few other PCI(e) scenarios in the future.
I'll give it a spin...
Thanks,
Torsten
More information about the U-Boot
mailing list