Hi Torsten,

On 2026-09-25T10:54:32, Torsten Duwe <[email protected]> wrote:
> mfd: add support for RPi5 RP1 chip MFD
>
> MFD base driver for the RP1 chip, similar to Linux'
> drivers/misc/rp1/rp1_pci.c
>
> Signed-off-by: Torsten Duwe <[email protected]>
> Co-authored-by: Oleksii Moisieiev <[email protected]>
>
> configs/rpi_arm64_defconfig   |   1 +
>  drivers/mfd/Kconfig           |  10 ++
>  drivers/mfd/Makefile          |   1 +
>  drivers/mfd/rp1.c             | 127 ++++++++++++++++++++++
>  include/dt-bindings/mfd/rp1.h | 239 
> ++++++++++++++++++++++++++++++++++++++++++
>  include/pci_ids.h             |   3 +
>  6 files changed, 381 insertions(+)

> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> @@ -2,3 +2,13 @@ config MFD_ATMEL_SMC
> +config MFD_RP1
> +     tristate "RP1 MFD driver"
> +     depends on PCI
> +     help
> +       Support for the RP1 peripheral chip.
> +
> +       This driver provides support for the Raspberry Pi RP1 peripheral chip.
> +       It is responsible for enabling the Device Tree node once the PCIe 
> endpoint
> +       has been configureds.

Please use 'bool' rather than 'tristate' - U-Boot does not build
loadable modules, and the surrounding entries are all bool. Also
'configureds' should be 'configured'.

> diff --git a/drivers/mfd/rp1.c b/drivers/mfd/rp1.c
> @@ -0,0 +1,127 @@
> +#define RP1_B0_CHIP_ID 0x10001927
> +#define RP1_C0_CHIP_ID 0x20001927
> +
> +#define RP1_PLATFORM_ASIC BIT(1)
> +#define RP1_PLATFORM_FPGA BIT(0)
> +
> +#define RP1_DRIVER_NAME "rp1"
> +
> +#define PCI_DEVICE_REV_RP1_C0 2

RP1_B0_CHIP_ID, RP1_PLATFORM_ASIC and PCI_DEVICE_REV_RP1_C0 are all
unused - please drop them, or actually use them (e.g. accept the B0
variant, or check the revision).

> diff --git a/drivers/mfd/rp1.c b/drivers/mfd/rp1.c
> @@ -0,0 +1,127 @@
> +static u32 rp1_reg_read(struct rp1_dev *rp1, unsigned int base_addr, u32 
> offset)
> +{
> +     resource_size_t phys = rp1_io_to_phys(rp1, base_addr);
> +     void __iomem *regblock = ioremap(phys, 0x1000);
> +     u32 value = readl(regblock + offset);
> +
> +     iounmap(regblock);
> +     return value;
> +}

Please map the BAR once in probe (store the virtual address in struct
rp1_dev) and just do readl() here. ioremap()/iounmap() around every
register access is unnecessary, and there is no check that ioremap()
succeeded before the readl().

> diff --git a/drivers/mfd/rp1.c b/drivers/mfd/rp1.c
> @@ -0,0 +1,127 @@
> +static int rp1_get_bar_region(struct udevice *dev, phys_addr_t *bar_start)
> +{
> +     *bar_start = (phys_addr_t)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_1, 0, 0,
> +                     PCI_REGION_TYPE, PCI_REGION_MEM);
> +     return 0;
> +}

This wrapper adds nothing and always returns 0 without checking
whether dm_pci_map_bar() succeeded. Either fold it into rp1_probe()
and check the result, or make it return an actual error when the map
fails.

> diff --git a/drivers/mfd/rp1.c b/drivers/mfd/rp1.c
> @@ -0,0 +1,127 @@
> +     /*
> +      * HACK: Set bar address in the correct order.
> +      * Required for correct U-Boot operation.
> +      */
> +     dm_pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0);
> +     dm_pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0x40000);

A driver shouldn't need to poke BARs by hand - the PCI core is meant
to assign them. Please explain in the comment (and in the commit
message) why auto-assignment does the wrong thing here, and whether
the underlying issue in the PCI core / RC driver can be fixed instead
of open-coding it. 'HACK' with no reference to the root cause makes it
hard for something to understand / fix this later.

> diff --git a/drivers/mfd/rp1.c b/drivers/mfd/rp1.c
> @@ -0,0 +1,127 @@
> +static int rp1_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
> +                             uint offset, ulong *valuep, enum pci_size_t 
> size)
> +{
> +     /*
> +      * Leaving this call because pci subsystem calls for read_config
> +      * and produces error then this callback is not set.
> +      * Just return 0 here.s
> +      */
> +     *valuep = 0;
> +     return 0;
> +}

A leaf UCLASS_PCI_GENERIC device shouldn't need dm_pci_ops at all -
those are for PCI controllers. If the core is complaining, that looks
like a real bug in the PCI uclass rather than something to paper over
with a stub that silently returns 0 for every config read. Please
investigate and fix the root cause. Also: typo 'here.s', and 'then'
should be 'when'.

> diff --git a/drivers/mfd/rp1.c b/drivers/mfd/rp1.c
> @@ -0,0 +1,127 @@
> +static int rp1_bind(struct udevice *dev)
> +{
> +     device_set_name(dev, RP1_DRIVER_NAME);
> +     return 0;
> +}

Is renaming the device really needed? The bound name normally comes
from the driver / DT node, and having every RP1 instance use the fixed
string 'rp1' will collide if more than one is ever probed. If this is
only cosmetic, please drop the bind hook.

> diff --git a/include/dt-bindings/mfd/rp1.h b/include/dt-bindings/mfd/rp1.h
> @@ -0,0 +1,239 @@
> +/*
> + * This header provides constants for the PY MFD.
> + *
> + * Copyright (c) 2024 EPAM Systems
> + *
> + * Derived from linux rp1.h.
> + */

How about 'RP1 MFD' instead of 'PY MFD' ?

> diff --git a/include/pci_ids.h b/include/pci_ids.h
> @@ -2555,6 +2555,9 @@
> +#define PCI_VENDOR_ID_RPI            0x1de4
> +#define PCI_DEVICE_ID_RPI_RP1_C0             0x0001

The extra tab on PCI_DEVICE_ID_RPI_RP1_C0 misaligns it with the
surrounding block - please drop it.

Tested-by: Simon Glass <[email protected]>  # rpi5

Regards,
Simon

Reply via email to