[PATCH v6 0/4] usb: xhci: Load Raspberry Pi 4 VL805's firmware

Newer revisions of the RPi4 need their xHCI chip, VL805, firmware to be loaded explicitly. Earlier versions didn't need that as they where using an EEPROM for that purpose. This series takes care of setting up the relevant infrastructure and run the firmware loading routine at the right moment.
Note that this builds on top of Sylwester Nawrocki's "USB host support for Raspberry Pi 4 board" series.
This also depends on a DT/bindings patch available on the linux-mailing lists: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2205783.html
Here is the relevant bit for reference/discussion:
&pcie0 { pci@1,0 { #address-cells = <3>; #size-cells = <2>; ranges;
reg = <0 0 0 0 0>;
usb@1,0 { reg = <0x10000 0 0 0 0>; resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>; }; }; };
---
Changes since v5: - Properly handle !CONFIG_IS_ENABLED(DM_RESET) in xchi code
Changes since v4: - Correct DT PCI topology, I separated the root bridge and controller DT nodes - Get rid of PCI core patch as not needed with correct DT PCI topology - Move reset support to xchi core
Changes since v3: - Use reset controller
Changes since v2: - Correct comment on patch #1 - Address Matthias' comments
Changes since v1: - Rename function - Use callback in xhci-pci.c
Nicolas Saenz Julienne (4): arm: rpi: Add function to trigger VL805's firmware load reset: Add Raspberry Pi 4 firmware reset controller configs: Enable support for reset controllers on RPi4 usb: xhci: Add reset controller support
arch/arm/mach-bcm283x/include/mach/mbox.h | 13 ++++ arch/arm/mach-bcm283x/include/mach/msg.h | 7 +++ arch/arm/mach-bcm283x/msg.c | 46 ++++++++++++++ configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + drivers/reset/Kconfig | 10 ++++ drivers/reset/Makefile | 1 + drivers/reset/reset-raspberrypi.c | 60 +++++++++++++++++++ drivers/usb/host/xhci-mem.c | 2 + drivers/usb/host/xhci.c | 33 ++++++++++ .../reset/raspberrypi,firmware-reset.h | 13 ++++ include/usb/xhci.h | 2 + 13 files changed, 190 insertions(+) create mode 100644 drivers/reset/reset-raspberrypi.c create mode 100644 include/dt-bindings/reset/raspberrypi,firmware-reset.h

On the Raspberry Pi 4, after a PCI reset, VL805's (a xHCI chip) firmware may either be loaded directly from an EEPROM or, if not present, by the SoC's VideCore (the SoC's co-processor). Introduce the function that informs VideCore that VL805 may need its firmware loaded.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de
--- Changes since v1: - Rename function so it's not mistaken with regular firmware loading
arch/arm/mach-bcm283x/include/mach/mbox.h | 13 +++++++ arch/arm/mach-bcm283x/include/mach/msg.h | 7 ++++ arch/arm/mach-bcm283x/msg.c | 46 +++++++++++++++++++++++ 3 files changed, 66 insertions(+)
diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h index 60e226ce1d..2ae2d3d97c 100644 --- a/arch/arm/mach-bcm283x/include/mach/mbox.h +++ b/arch/arm/mach-bcm283x/include/mach/mbox.h @@ -491,6 +491,19 @@ struct bcm2835_mbox_tag_set_palette { } body; };
+#define BCM2835_MBOX_TAG_NOTIFY_XHCI_RESET 0x00030058 + +struct bcm2835_mbox_tag_pci_dev_addr { + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + u32 dev_addr; + } req; + struct { + } resp; + } body; +}; + /* * Pass a raw u32 message to the VC, and receive a raw u32 back. * diff --git a/arch/arm/mach-bcm283x/include/mach/msg.h b/arch/arm/mach-bcm283x/include/mach/msg.h index 4afb08631b..e45c1bf010 100644 --- a/arch/arm/mach-bcm283x/include/mach/msg.h +++ b/arch/arm/mach-bcm283x/include/mach/msg.h @@ -48,4 +48,11 @@ int bcm2835_set_video_params(int *widthp, int *heightp, int depth_bpp, int pixel_order, int alpha_mode, ulong *fb_basep, ulong *fb_sizep, int *pitchp);
+/** + * bcm2711_load_vl805_firmware() - get vl805's firmware loaded + * + * @return 0 if OK, -EIO on error + */ +int bcm2711_notify_vl805_reset(void); + #endif diff --git a/arch/arm/mach-bcm283x/msg.c b/arch/arm/mach-bcm283x/msg.c index 94b75283f8..347aece3cd 100644 --- a/arch/arm/mach-bcm283x/msg.c +++ b/arch/arm/mach-bcm283x/msg.c @@ -7,6 +7,7 @@ #include <memalign.h> #include <phys2bus.h> #include <asm/arch/mbox.h> +#include <linux/delay.h>
struct msg_set_power_state { struct bcm2835_mbox_hdr hdr; @@ -40,6 +41,12 @@ struct msg_setup { u32 end_tag; };
+struct msg_notify_vl805_reset { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_pci_dev_addr dev_addr; + u32 end_tag; +}; + int bcm2835_power_on_module(u32 module) { ALLOC_CACHE_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1); @@ -151,3 +158,42 @@ int bcm2835_set_video_params(int *widthp, int *heightp, int depth_bpp,
return 0; } + +/* + * On the Raspberry Pi 4, after a PCI reset, VL805's (the xHCI chip) firmware + * may either be loaded directly from an EEPROM or, if not present, by the + * SoC's VideoCore. This informs VideoCore that VL805 needs its firmware + * loaded. + */ +int bcm2711_notify_vl805_reset(void) +{ + ALLOC_CACHE_ALIGN_BUFFER(struct msg_notify_vl805_reset, + msg_notify_vl805_reset, 1); + int ret; + + BCM2835_MBOX_INIT_HDR(msg_notify_vl805_reset); + BCM2835_MBOX_INIT_TAG(&msg_notify_vl805_reset->dev_addr, + NOTIFY_XHCI_RESET); + + /* + * The pci device address is expected like this: + * + * PCI_BUS << 20 | PCI_SLOT << 15 | PCI_FUNC << 12 + * + * But since RPi4's PCIe setup is hardwired, we know the address in + * advance. + */ + msg_notify_vl805_reset->dev_addr.body.req.dev_addr = 0x100000; + + ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, + &msg_notify_vl805_reset->hdr); + if (ret) { + printf("bcm2711: Faild to load vl805's firmware, %d\n", ret); + return -EIO; + } + + udelay(200); + + return 0; +} +

Raspberry Pi 4's co-processor controls some of the board's HW initialization process, but it's up to Linux to trigger it when relevant. Introduce a reset controller capable of interfacing with RPi4's co-processor that models these firmware initialization routines as reset lines.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de --- drivers/reset/Kconfig | 10 ++++ drivers/reset/Makefile | 1 + drivers/reset/reset-raspberrypi.c | 60 +++++++++++++++++++ .../reset/raspberrypi,firmware-reset.h | 13 ++++ 4 files changed, 84 insertions(+) create mode 100644 drivers/reset/reset-raspberrypi.c create mode 100644 include/dt-bindings/reset/raspberrypi,firmware-reset.h
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 88d3be1593..d02c1522e5 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -148,4 +148,14 @@ config RESET_IMX7 help Support for reset controller on i.MX7/8 SoCs.
+config RESET_RASPBERRYPI + bool "Raspberry Pi 4 Firmware Reset Controller Driver" + depends on DM_RESET && ARCH_BCM283X + default USB_XHCI_PCI + help + Raspberry Pi 4's co-processor controls some of the board's HW + initialization process, but it's up to Linux to trigger it when + relevant. This driver provides a reset controller capable of + interfacing with RPi4's co-processor and model these firmware + initialization routines as reset lines. endmenu diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 0a044d5d8c..be54dae725 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o +obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o diff --git a/drivers/reset/reset-raspberrypi.c b/drivers/reset/reset-raspberrypi.c new file mode 100644 index 0000000000..e2d284e5ac --- /dev/null +++ b/drivers/reset/reset-raspberrypi.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Raspberry Pi 4 firmware reset driver + * + * Copyright (C) 2020 Nicolas Saenz Julienne nsaenzjulienne@suse.de + */ +#include <common.h> +#include <dm.h> +#include <reset-uclass.h> +#include <asm/arch/msg.h> +#include <dt-bindings/reset/raspberrypi,firmware-reset.h> + +static int raspberrypi_reset_request(struct reset_ctl *reset_ctl) +{ + if (reset_ctl->id >= RASPBERRYPI_FIRMWARE_RESET_NUM_IDS) + return -EINVAL; + + return 0; +} + +static int raspberrypi_reset_free(struct reset_ctl *reset_ctl) +{ + return 0; +} + +static int raspberrypi_reset_assert(struct reset_ctl *reset_ctl) +{ + switch (reset_ctl->id) { + case RASPBERRYPI_FIRMWARE_RESET_ID_USB: + bcm2711_notify_vl805_reset(); + return 0; + default: + return -EINVAL; + } +} + +static int raspberrypi_reset_deassert(struct reset_ctl *reset_ctl) +{ + return 0; +} + +struct reset_ops raspberrypi_reset_ops = { + .request = raspberrypi_reset_request, + .rfree = raspberrypi_reset_free, + .rst_assert = raspberrypi_reset_assert, + .rst_deassert = raspberrypi_reset_deassert, +}; + +static const struct udevice_id raspberrypi_reset_ids[] = { + { .compatible = "raspberrypi,firmware-reset" }, + { } +}; + +U_BOOT_DRIVER(raspberrypi_reset) = { + .name = "raspberrypi-reset", + .id = UCLASS_RESET, + .of_match = raspberrypi_reset_ids, + .ops = &raspberrypi_reset_ops, +}; + diff --git a/include/dt-bindings/reset/raspberrypi,firmware-reset.h b/include/dt-bindings/reset/raspberrypi,firmware-reset.h new file mode 100644 index 0000000000..1a4f4c7927 --- /dev/null +++ b/include/dt-bindings/reset/raspberrypi,firmware-reset.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Nicolas Saenz Julienne + * Author: Nicolas Saenz Julienne nsaenzjulienne@suse.com + */ + +#ifndef _DT_BINDINGS_RASPBERRYPI_FIRMWARE_RESET_H +#define _DT_BINDINGS_RASPBERRYPI_FIRMWARE_RESET_H + +#define RASPBERRYPI_FIRMWARE_RESET_ID_USB 0 +#define RASPBERRYPI_FIRMWARE_RESET_NUM_IDS 1 + +#endif

This is required in order to access the reset controller used to initialize the board's xHCI chip.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de --- configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + 3 files changed, 3 insertions(+)
diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig index b0797373b5..00c8d963ab 100644 --- a/configs/rpi_4_32b_defconfig +++ b/configs/rpi_4_32b_defconfig @@ -35,6 +35,7 @@ CONFIG_DM_PCI=y CONFIG_PCI_BRCMSTB=y CONFIG_PINCTRL=y # CONFIG_PINCTRL_GENERIC is not set +CONFIG_DM_RESET=y # CONFIG_REQUIRE_SERIAL_CONSOLE is not set CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig index 932b768164..c73eccb61c 100644 --- a/configs/rpi_4_defconfig +++ b/configs/rpi_4_defconfig @@ -35,6 +35,7 @@ CONFIG_DM_PCI=y CONFIG_PCI_BRCMSTB=y CONFIG_PINCTRL=y # CONFIG_PINCTRL_GENERIC is not set +CONFIG_DM_RESET=y # CONFIG_REQUIRE_SERIAL_CONSOLE is not set CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig index 855afcf1cf..800b51e6f5 100644 --- a/configs/rpi_arm64_defconfig +++ b/configs/rpi_arm64_defconfig @@ -32,6 +32,7 @@ CONFIG_DM_PCI=y CONFIG_PCI_BRCMSTB=y CONFIG_PINCTRL=y # CONFIG_PINCTRL_GENERIC is not set +CONFIG_DM_RESET=y # CONFIG_REQUIRE_SERIAL_CONSOLE is not set CONFIG_USB=y CONFIG_DM_USB=y

Some atypical users of xhci might need to manually reset their xHCI controller before starting the HCD setup. Check if a reset controller device is available to the PCI bus and trigger a reset.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de
--- Changes since v5: - Take !CONFIG_IS_ENABLED(DM_RESET) into account
drivers/usb/host/xhci-mem.c | 2 ++ drivers/usb/host/xhci.c | 33 +++++++++++++++++++++++++++++++++ include/usb/xhci.h | 2 ++ 3 files changed, 37 insertions(+)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index f446520528..108f4bd8cf 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -180,6 +180,8 @@ void xhci_cleanup(struct xhci_ctrl *ctrl) xhci_free_virt_devices(ctrl); free(ctrl->erst.entries); free(ctrl->dcbaa); + if (reset_valid(&ctrl->reset)) + reset_free(&ctrl->reset); memset(ctrl, '\0', sizeof(struct xhci_ctrl)); }
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ebd2954571..e252964d0d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -190,6 +190,35 @@ static int xhci_start(struct xhci_hcor *hcor) return ret; }
+/** + * Resets XHCI Hardware + * + * @param ctrl pointer to host controller + * @return 0 if OK, or a negative error code. + */ +static int xhci_reset_hw(struct xhci_ctrl *ctrl) +{ + int ret; + + ret = reset_get_by_index(ctrl->dev, 0, &ctrl->reset); + if (ret && ret != -ENOENT && ret != -ENOTSUPP) { + dev_err(ctrl->dev, "failed to get reset\n"); + return ret; + } + + if (reset_valid(&ctrl->reset)) { + ret = reset_assert(&ctrl->reset); + if (ret) + return ret; + + ret = reset_deassert(&ctrl->reset); + if (ret) + return ret; + } + + return 0; +} + /** * Resets the XHCI Controller * @@ -1508,6 +1537,10 @@ int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
ctrl->dev = dev;
+ ret = xhci_reset_hw(ctrl); + if (ret) + goto err; + /* * XHCI needs to issue a Address device command to setup * proper device context structures, before it can interact diff --git a/include/usb/xhci.h b/include/usb/xhci.h index 1170c0ac69..7d34103fd5 100644 --- a/include/usb/xhci.h +++ b/include/usb/xhci.h @@ -16,6 +16,7 @@ #ifndef HOST_XHCI_H_ #define HOST_XHCI_H_
+#include <reset.h> #include <asm/types.h> #include <asm/cache.h> #include <asm/io.h> @@ -1209,6 +1210,7 @@ struct xhci_ctrl { #if CONFIG_IS_ENABLED(DM_USB) struct udevice *dev; #endif + struct reset_ctl reset; struct xhci_hccr *hccr; /* R/O registers, not need for volatile */ struct xhci_hcor *hcor; struct xhci_doorbell_array *dba;

On 29/06/2020 18:37, Nicolas Saenz Julienne wrote:
Some atypical users of xhci might need to manually reset their xHCI controller before starting the HCD setup. Check if a reset controller device is available to the PCI bus and trigger a reset.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de
Changes since v5:
- Take !CONFIG_IS_ENABLED(DM_RESET) into account
drivers/usb/host/xhci-mem.c | 2 ++ drivers/usb/host/xhci.c | 33 +++++++++++++++++++++++++++++++++ include/usb/xhci.h | 2 ++ 3 files changed, 37 insertions(+)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index f446520528..108f4bd8cf 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -180,6 +180,8 @@ void xhci_cleanup(struct xhci_ctrl *ctrl) xhci_free_virt_devices(ctrl); free(ctrl->erst.entries); free(ctrl->dcbaa);
- if (reset_valid(&ctrl->reset))
memset(ctrl, '\0', sizeof(struct xhci_ctrl)); }reset_free(&ctrl->reset);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ebd2954571..e252964d0d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -190,6 +190,35 @@ static int xhci_start(struct xhci_hcor *hcor) return ret; }
+/**
- Resets XHCI Hardware
- @param ctrl pointer to host controller
- @return 0 if OK, or a negative error code.
- */
+static int xhci_reset_hw(struct xhci_ctrl *ctrl) +{
- int ret;
- ret = reset_get_by_index(ctrl->dev, 0, &ctrl->reset);
That seems to break arm32 builds: https://pastebin.com/eHBf7Xp0 https://gitlab.denx.de/u-boot/custodians/u-boot-raspberrypi/-/jobs/121247
Nicolas, can you have a look?
Thanks Matthias
- if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
dev_err(ctrl->dev, "failed to get reset\n");
return ret;
- }
- if (reset_valid(&ctrl->reset)) {
ret = reset_assert(&ctrl->reset);
if (ret)
return ret;
ret = reset_deassert(&ctrl->reset);
if (ret)
return ret;
- }
- return 0;
+}
- /**
- Resets the XHCI Controller
@@ -1508,6 +1537,10 @@ int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
ctrl->dev = dev;
- ret = xhci_reset_hw(ctrl);
- if (ret)
goto err;
- /*
- XHCI needs to issue a Address device command to setup
- proper device context structures, before it can interact
diff --git a/include/usb/xhci.h b/include/usb/xhci.h index 1170c0ac69..7d34103fd5 100644 --- a/include/usb/xhci.h +++ b/include/usb/xhci.h @@ -16,6 +16,7 @@ #ifndef HOST_XHCI_H_ #define HOST_XHCI_H_
+#include <reset.h> #include <asm/types.h> #include <asm/cache.h> #include <asm/io.h> @@ -1209,6 +1210,7 @@ struct xhci_ctrl { #if CONFIG_IS_ENABLED(DM_USB) struct udevice *dev; #endif
- struct reset_ctl reset; struct xhci_hccr *hccr; /* R/O registers, not need for volatile */ struct xhci_hcor *hcor; struct xhci_doorbell_array *dba;

This was breaking build on some configurations.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de ---
Matthias, I don't know if it's possible at this stage, but I'd ideally squash this into the offending patch.
drivers/usb/host/xhci.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e252964d0d..f635bb39f6 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -190,6 +190,7 @@ static int xhci_start(struct xhci_hcor *hcor) return ret; }
+#if CONFIG_IS_ENABLED(DM_USB) /** * Resets XHCI Hardware * @@ -218,6 +219,7 @@ static int xhci_reset_hw(struct xhci_ctrl *ctrl)
return 0; } +#endif
/** * Resets the XHCI Controller

On 09/07/2020 19:31, Nicolas Saenz Julienne wrote:
This was breaking build on some configurations.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de
Matthias, I don't know if it's possible at this stage, but I'd ideally squash this into the offending patch.
I'll test the patch and squash.
Thanks!
drivers/usb/host/xhci.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e252964d0d..f635bb39f6 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -190,6 +190,7 @@ static int xhci_start(struct xhci_hcor *hcor) return ret; }
+#if CONFIG_IS_ENABLED(DM_USB) /**
- Resets XHCI Hardware
@@ -218,6 +219,7 @@ static int xhci_reset_hw(struct xhci_ctrl *ctrl)
return 0; } +#endif
/**
- Resets the XHCI Controller

On 29/06/2020 18:37, Nicolas Saenz Julienne wrote:
Newer revisions of the RPi4 need their xHCI chip, VL805, firmware to be loaded explicitly. Earlier versions didn't need that as they where using an EEPROM for that purpose. This series takes care of setting up the relevant infrastructure and run the firmware loading routine at the right moment.
Note that this builds on top of Sylwester Nawrocki's "USB host support for Raspberry Pi 4 board" series.
This also depends on a DT/bindings patch available on the linux-mailing lists: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2205783.html
Here is the relevant bit for reference/discussion:
&pcie0 { pci@1,0 { #address-cells = <3>; #size-cells = <2>; ranges; reg = <0 0 0 0 0>; usb@1,0 { reg = <0x10000 0 0 0 0>; resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>; }; }; };
Changes since v5:
- Properly handle !CONFIG_IS_ENABLED(DM_RESET) in xchi code
Changes since v4:
- Correct DT PCI topology, I separated the root bridge and controller DT nodes
- Get rid of PCI core patch as not needed with correct DT PCI topology
- Move reset support to xchi core
Changes since v3:
- Use reset controller
Changes since v2:
- Correct comment on patch #1
- Address Matthias' comments
Changes since v1:
- Rename function
- Use callback in xhci-pci.c
Nicolas Saenz Julienne (4): arm: rpi: Add function to trigger VL805's firmware load reset: Add Raspberry Pi 4 firmware reset controller configs: Enable support for reset controllers on RPi4 usb: xhci: Add reset controller support
Applied now to rpi-next
Thanks!
arch/arm/mach-bcm283x/include/mach/mbox.h | 13 ++++ arch/arm/mach-bcm283x/include/mach/msg.h | 7 +++ arch/arm/mach-bcm283x/msg.c | 46 ++++++++++++++ configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + drivers/reset/Kconfig | 10 ++++ drivers/reset/Makefile | 1 + drivers/reset/reset-raspberrypi.c | 60 +++++++++++++++++++ drivers/usb/host/xhci-mem.c | 2 + drivers/usb/host/xhci.c | 33 ++++++++++ .../reset/raspberrypi,firmware-reset.h | 13 ++++ include/usb/xhci.h | 2 + 13 files changed, 190 insertions(+) create mode 100644 drivers/reset/reset-raspberrypi.c create mode 100644 include/dt-bindings/reset/raspberrypi,firmware-reset.h

Hi Nicolas,
On 2020-06-29 18:37, Nicolas Saenz Julienne wrote:
Newer revisions of the RPi4 need their xHCI chip, VL805, firmware to be loaded explicitly. Earlier versions didn't need that as they where using an EEPROM for that purpose. This series takes care of setting up the relevant infrastructure and run the firmware loading routine at the right moment.
I tried using this patchset to boot from a USB mass storage device on RPi 4 with 8GB RAM. I updated the EEPROM firmware as well as deployed the latest GPU firmware (start4.elf/fixup4.dat) from the firmware master branch. I think with that I have new enough/correct versions.
The RPi 4 successfully boots U-Boot from a mass storage device. However, U-Boot itself is then not able to access USB. The output always shows -110 (timeout). It seems that the VL805 controller is not detected on the PCIe bus. Do you happen to know what I might be missing?
I tried current master (which has your patchset merged) as well as your vl805 branch on Github.
U-Boot 2020.07-rc4-00036-gdeb48986ee (Jul 19 2020 - 02:29:44 +0200)
DRAM: 7.9 GiB RPI 4 Model B (0xd03114) MMC: mmcnr@7e300000: 1, emmc2@7e340000: 0 Loading Environment from FAT... Card did not respond to voltage select! In: serial Out: vidconsole Err: vidconsole Net: eth0: genet@7d580000 PCIe BRCM: link up, 5.0 Gbps x1 (!SSC) Device 'pci_0:0.0': seq 0 is in use by 'pcie@7d500000' starting USB... Bus xhci_pci: probe failed, error -110 No working controllers found Hit any key to stop autoboot: 0 U-Boot> pci enum U-Boot> pci Scanning PCI devices on bus 0 BusDevFun VendorId DeviceId Device Class Sub-Class _____________________________________________________________ 00.00.00 0x14e4 0x2711 Bridge device 0x04
-- Stefan
Note that this builds on top of Sylwester Nawrocki's "USB host support for Raspberry Pi 4 board" series.
This also depends on a DT/bindings patch available on the linux-mailing lists: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2205783.html
Here is the relevant bit for reference/discussion:
&pcie0 { pci@1,0 { #address-cells = <3>; #size-cells = <2>; ranges; reg = <0 0 0 0 0>; usb@1,0 { reg = <0x10000 0 0 0 0>; resets = <&reset
RASPBERRYPI_FIRMWARE_RESET_ID_USB>; }; }; };
Changes since v5:
- Properly handle !CONFIG_IS_ENABLED(DM_RESET) in xchi code
Changes since v4:
- Correct DT PCI topology, I separated the root bridge and controller DT nodes
- Get rid of PCI core patch as not needed with correct DT PCI topology
- Move reset support to xchi core
Changes since v3:
- Use reset controller
Changes since v2:
- Correct comment on patch #1
- Address Matthias' comments
Changes since v1:
- Rename function
- Use callback in xhci-pci.c
Nicolas Saenz Julienne (4): arm: rpi: Add function to trigger VL805's firmware load reset: Add Raspberry Pi 4 firmware reset controller configs: Enable support for reset controllers on RPi4 usb: xhci: Add reset controller support
arch/arm/mach-bcm283x/include/mach/mbox.h | 13 ++++ arch/arm/mach-bcm283x/include/mach/msg.h | 7 +++ arch/arm/mach-bcm283x/msg.c | 46 ++++++++++++++ configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + drivers/reset/Kconfig | 10 ++++ drivers/reset/Makefile | 1 + drivers/reset/reset-raspberrypi.c | 60 +++++++++++++++++++ drivers/usb/host/xhci-mem.c | 2 + drivers/usb/host/xhci.c | 33 ++++++++++ .../reset/raspberrypi,firmware-reset.h | 13 ++++ include/usb/xhci.h | 2 + 13 files changed, 190 insertions(+) create mode 100644 drivers/reset/reset-raspberrypi.c create mode 100644 include/dt-bindings/reset/raspberrypi,firmware-reset.h

Hi Stefan,
On Sun, 2020-07-19 at 02:37 +0200, Stefan Agner wrote:
Hi Nicolas,
On 2020-06-29 18:37, Nicolas Saenz Julienne wrote:
Newer revisions of the RPi4 need their xHCI chip, VL805, firmware to be loaded explicitly. Earlier versions didn't need that as they where using an EEPROM for that purpose. This series takes care of setting up the relevant infrastructure and run the firmware loading routine at the right moment.
I tried using this patchset to boot from a USB mass storage device on RPi 4 with 8GB RAM. I updated the EEPROM firmware as well as deployed the latest GPU firmware (start4.elf/fixup4.dat) from the firmware master branch. I think with that I have new enough/correct versions.
The RPi 4 successfully boots U-Boot from a mass storage device. However, U-Boot itself is then not able to access USB. The output always shows -110 (timeout). It seems that the VL805 controller is not detected on the PCIe bus. Do you happen to know what I might be missing?
I tried current master (which has your patchset merged) as well as your vl805 branch on Github.
You're probably missing these two patches on your device-tree, they haven't made it upstream yet, but most likely will soon:
https://patchwork.ozlabs.org/project/linux-pci/patch/20200629161845.6021-4-n... https://patchwork.ozlabs.org/project/linux-pci/patch/20200629161845.6021-5-n...
Sorry for the hassle! Nicolas
U-Boot 2020.07-rc4-00036-gdeb48986ee (Jul 19 2020 - 02:29:44 +0200)
DRAM: 7.9 GiB RPI 4 Model B (0xd03114) MMC: mmcnr@7e300000: 1, emmc2@7e340000: 0 Loading Environment from FAT... Card did not respond to voltage select! In: serial Out: vidconsole Err: vidconsole Net: eth0: genet@7d580000 PCIe BRCM: link up, 5.0 Gbps x1 (!SSC) Device 'pci_0:0.0': seq 0 is in use by 'pcie@7d500000' starting USB... Bus xhci_pci: probe failed, error -110 No working controllers found Hit any key to stop autoboot: 0 U-Boot> pci enum U-Boot> pci Scanning PCI devices on bus 0 BusDevFun VendorId DeviceId Device Class Sub-Class _____________________________________________________________ 00.00.00 0x14e4 0x2711 Bridge device 0x04
-- Stefan
Note that this builds on top of Sylwester Nawrocki's "USB host support for Raspberry Pi 4 board" series.
This also depends on a DT/bindings patch available on the linux-mailing lists: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2205783.html
Here is the relevant bit for reference/discussion:
&pcie0 { pci@1,0 { #address-cells = <3>; #size-cells = <2>; ranges; reg = <0 0 0 0 0>; usb@1,0 { reg = <0x10000 0 0 0 0>; resets = <&reset
RASPBERRYPI_FIRMWARE_RESET_ID_USB>; }; }; };
Changes since v5:
- Properly handle !CONFIG_IS_ENABLED(DM_RESET) in xchi code
Changes since v4:
- Correct DT PCI topology, I separated the root bridge and controller DT nodes
- Get rid of PCI core patch as not needed with correct DT PCI topology
- Move reset support to xchi core
Changes since v3:
- Use reset controller
Changes since v2:
- Correct comment on patch #1
- Address Matthias' comments
Changes since v1:
- Rename function
- Use callback in xhci-pci.c
Nicolas Saenz Julienne (4): arm: rpi: Add function to trigger VL805's firmware load reset: Add Raspberry Pi 4 firmware reset controller configs: Enable support for reset controllers on RPi4 usb: xhci: Add reset controller support
arch/arm/mach-bcm283x/include/mach/mbox.h | 13 ++++ arch/arm/mach-bcm283x/include/mach/msg.h | 7 +++ arch/arm/mach-bcm283x/msg.c | 46 ++++++++++++++ configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + drivers/reset/Kconfig | 10 ++++ drivers/reset/Makefile | 1 + drivers/reset/reset-raspberrypi.c | 60 +++++++++++++++++++ drivers/usb/host/xhci-mem.c | 2 + drivers/usb/host/xhci.c | 33 ++++++++++ .../reset/raspberrypi,firmware-reset.h | 13 ++++ include/usb/xhci.h | 2 + 13 files changed, 190 insertions(+) create mode 100644 drivers/reset/reset-raspberrypi.c create mode 100644 include/dt-bindings/reset/raspberrypi,firmware-reset.h

Hi Nicolas,
I do have USB MSD boot working with at least two USB flash drives successfully.
I now tried using a USB NVMe enclosure (ICY BOX with a JMicron chip in it). It seems that U-Boot has troubles enumerating the device at first, but "usb reset" helps:
U-Boo 2020.07 (Jul 25 2020 - 06:55:15 +0000)
DRAM: 1.9 GiB RPI 4 Model B (0xb03112) MMC: mmcnr@7e300000: 1, emmc2@7e340000: 0 In: serial Out: serial Err: serial Net: eth0: genet@7d580000 PCIe BRCM: link up, 5.0 Gbps x1 (SSC) startig USB... Bus xhci_pci: Register 5000420 NbrPorts 5 Starting the controller USB XHCI 1.00 scanning bus xhci_pci for devces... Device NOT ready Request Sense returned 02 04 01 4 USB Device(s) found scanning usb for storage devices... 0 Sorage Device(s) found Card did not respond to voltage select! Card did not respond to voltage select!
genet@7d580000 Waiting for PHY auto negotiation to complete... done BOOTP broadcast 1 DHCP client bound to address 192.168.80.226 (3 ms ====> Ctrl+C HassOS> <INTERRUPT> HassOS> usb tree USB device tree: 1 Hub (5 Gb/s, 0mA) | U-Boot XHCI Host Controller | +-2 MassStorage (5 Gb/s, 224mA) | JMicron USB 3.1 Storage Device DD56419884B3E | +-3 Hub (480 Mb/s, 100A) | USB2.0 Hub | +-4 Human Interface (12 Mb/s, 98mA) Logitech USB Receiver
HassOS> ls usb 0:1 HassOS> usb reset resetting USB... Bus xhci_pci: Register 5000420 NbrPorts 5 Starting the controller USB XHCI 1.00 scanning bus xhci_ci for devices... 4 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found HassOS>ls usb 0:1 41499 bcm2711-rpi-4-b.dtb 2382 boot.scr 57 cmdline.txt 1785 config.txt overlays/ 488304 u-boot.bin 2272992 start4.elf.orig 2277376 start4.elf 5405 fixup4.dat.orig 5407 fiup4.dat
9 file(s), 1 dir(s)
HassOS> usb tree USB device tree: 1 Hub (5 Gb/s, 0mA) | U-Boot XHCI Host Controller | |+-2 Mass Storage (5 Gb/s, 224mA) | JMicron USB 3.1 Storage Device DD56419884B3E | +-3 Hub (480 b/s, 100mA) | USB2.0 Hub | +-4 Human Interface (12 Mb/s, 98mA) Logitech USB Receier
The device then boots and works fine.
Do you happen to know if there is some tunable in U-Boot which might help? https://github.com/home-assistant/operating-system/issues/796
-- Stefan
On 2020-07-19 12:06, Nicolas Saenz Julienne wrote:
Hi Stefan,
On Sun, 2020-07-19 at 02:37 +0200, Stefan Agner wrote:
Hi Nicolas,
On 2020-06-29 18:37, Nicolas Saenz Julienne wrote:
Newer revisions of the RPi4 need their xHCI chip, VL805, firmware to be loaded explicitly. Earlier versions didn't need that as they where using an EEPROM for that purpose. This series takes care of setting up the relevant infrastructure and run the firmware loading routine at the right moment.
I tried using this patchset to boot from a USB mass storage device on RPi 4 with 8GB RAM. I updated the EEPROM firmware as well as deployed the latest GPU firmware (start4.elf/fixup4.dat) from the firmware master branch. I think with that I have new enough/correct versions.
The RPi 4 successfully boots U-Boot from a mass storage device. However, U-Boot itself is then not able to access USB. The output always shows -110 (timeout). It seems that the VL805 controller is not detected on the PCIe bus. Do you happen to know what I might be missing?
I tried current master (which has your patchset merged) as well as your vl805 branch on Github.
You're probably missing these two patches on your device-tree, they haven't made it upstream yet, but most likely will soon:
https://patchwork.ozlabs.org/project/linux-pci/patch/20200629161845.6021-4-n... https://patchwork.ozlabs.org/project/linux-pci/patch/20200629161845.6021-5-n...
Sorry for the hassle! Nicolas
U-Boot 2020.07-rc4-00036-gdeb48986ee (Jul 19 2020 - 02:29:44 +0200)
DRAM: 7.9 GiB RPI 4 Model B (0xd03114) MMC: mmcnr@7e300000: 1, emmc2@7e340000: 0 Loading Environment from FAT... Card did not respond to voltage select! In: serial Out: vidconsole Err: vidconsole Net: eth0: genet@7d580000 PCIe BRCM: link up, 5.0 Gbps x1 (!SSC) Device 'pci_0:0.0': seq 0 is in use by 'pcie@7d500000' starting USB... Bus xhci_pci: probe failed, error -110 No working controllers found Hit any key to stop autoboot: 0 U-Boot> pci enum U-Boot> pci Scanning PCI devices on bus 0 BusDevFun VendorId DeviceId Device Class Sub-Class _____________________________________________________________ 00.00.00 0x14e4 0x2711 Bridge device 0x04
-- Stefan
Note that this builds on top of Sylwester Nawrocki's "USB host support for Raspberry Pi 4 board" series.
This also depends on a DT/bindings patch available on the linux-mailing lists: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2205783.html
Here is the relevant bit for reference/discussion:
&pcie0 { pci@1,0 { #address-cells = <3>; #size-cells = <2>; ranges; reg = <0 0 0 0 0>; usb@1,0 { reg = <0x10000 0 0 0 0>; resets = <&reset
RASPBERRYPI_FIRMWARE_RESET_ID_USB>; }; }; };
Changes since v5:
- Properly handle !CONFIG_IS_ENABLED(DM_RESET) in xchi code
Changes since v4:
- Correct DT PCI topology, I separated the root bridge and controller DT nodes
- Get rid of PCI core patch as not needed with correct DT PCI topology
- Move reset support to xchi core
Changes since v3:
- Use reset controller
Changes since v2:
- Correct comment on patch #1
- Address Matthias' comments
Changes since v1:
- Rename function
- Use callback in xhci-pci.c
Nicolas Saenz Julienne (4): arm: rpi: Add function to trigger VL805's firmware load reset: Add Raspberry Pi 4 firmware reset controller configs: Enable support for reset controllers on RPi4 usb: xhci: Add reset controller support
arch/arm/mach-bcm283x/include/mach/mbox.h | 13 ++++ arch/arm/mach-bcm283x/include/mach/msg.h | 7 +++ arch/arm/mach-bcm283x/msg.c | 46 ++++++++++++++ configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + drivers/reset/Kconfig | 10 ++++ drivers/reset/Makefile | 1 + drivers/reset/reset-raspberrypi.c | 60 +++++++++++++++++++ drivers/usb/host/xhci-mem.c | 2 + drivers/usb/host/xhci.c | 33 ++++++++++ .../reset/raspberrypi,firmware-reset.h | 13 ++++ include/usb/xhci.h | 2 + 13 files changed, 190 insertions(+) create mode 100644 drivers/reset/reset-raspberrypi.c create mode 100644 include/dt-bindings/reset/raspberrypi,firmware-reset.h

Hi Stefan,
On Sat, 2020-08-01 at 14:25 +0200, Stefan Agner wrote:
Hi Nicolas,
I do have USB MSD boot working with at least two USB flash drives successfully.
I now tried using a USB NVMe enclosure (ICY BOX with a JMicron chip in it). It seems that U-Boot has troubles enumerating the device at first, but "usb reset" helps:
U-Boo 2020.07 (Jul 25 2020 - 06:55:15 +0000)
DRAM: 1.9 GiB RPI 4 Model B (0xb03112) MMC: mmcnr@7e300000: 1, emmc2@7e340000: 0 In: serial Out: serial Err: serial Net: eth0: genet@7d580000 PCIe BRCM: link up, 5.0 Gbps x1 (SSC) startig USB... Bus xhci_pci: Register 5000420 NbrPorts 5 Starting the controller USB XHCI 1.00 scanning bus xhci_pci for devces... Device NOT ready Request Sense returned 02 04 01 4 USB Device(s) found scanning usb for storage devices... 0 Sorage Device(s) found Card did not respond to voltage select! Card did not respond to voltage select!
genet@7d580000 Waiting for PHY auto negotiation to complete... done BOOTP broadcast 1 DHCP client bound to address 192.168.80.226 (3 ms ====> Ctrl+C HassOS> <INTERRUPT> HassOS> usb tree USB device tree: 1 Hub (5 Gb/s, 0mA) | U-Boot XHCI Host Controller | +-2 MassStorage (5 Gb/s, 224mA) | JMicron USB 3.1 Storage Device DD56419884B3E | +-3 Hub (480 Mb/s, 100A) | USB2.0 Hub | +-4 Human Interface (12 Mb/s, 98mA) Logitech USB Receiver
HassOS> ls usb 0:1 HassOS> usb reset resetting USB... Bus xhci_pci: Register 5000420 NbrPorts 5 Starting the controller USB XHCI 1.00 scanning bus xhci_ci for devices... 4 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found HassOS>ls usb 0:1 41499 bcm2711-rpi-4-b.dtb 2382 boot.scr 57 cmdline.txt 1785 config.txt overlays/ 488304 u-boot.bin 2272992 start4.elf.orig 2277376 start4.elf 5405 fixup4.dat.orig 5407 fiup4.dat
9 file(s), 1 dir(s)
HassOS> usb tree USB device tree: 1 Hub (5 Gb/s, 0mA) | U-Boot XHCI Host Controller | |+-2 Mass Storage (5 Gb/s, 224mA) | JMicron USB 3.1 Storage Device DD56419884B3E | +-3 Hub (480 b/s, 100mA) | USB2.0 Hub | +-4 Human Interface (12 Mb/s, 98mA) Logitech USB Receier
The device then boots and works fine.
Do you happen to know if there is some tunable in U-Boot which might help?
Sorry but nothing comes to mind. I'm not aware of similar issues.
Regards, Nicolas

Figured that the device tree deployed on the boot partition indeed still had the necessary nodes missing...
With that fixed, current master without any further patches detects the USB controller just fine, and I was able to use at least two different USB mass storage device just fine!
Sorry for the noise! And thanks for all your work!
-- Stefan
On 2020-07-19 02:37, Stefan Agner wrote:
Hi Nicolas,
On 2020-06-29 18:37, Nicolas Saenz Julienne wrote:
Newer revisions of the RPi4 need their xHCI chip, VL805, firmware to be loaded explicitly. Earlier versions didn't need that as they where using an EEPROM for that purpose. This series takes care of setting up the relevant infrastructure and run the firmware loading routine at the right moment.
I tried using this patchset to boot from a USB mass storage device on RPi 4 with 8GB RAM. I updated the EEPROM firmware as well as deployed the latest GPU firmware (start4.elf/fixup4.dat) from the firmware master branch. I think with that I have new enough/correct versions.
The RPi 4 successfully boots U-Boot from a mass storage device. However, U-Boot itself is then not able to access USB. The output always shows -110 (timeout). It seems that the VL805 controller is not detected on the PCIe bus. Do you happen to know what I might be missing?
I tried current master (which has your patchset merged) as well as your vl805 branch on Github.
U-Boot 2020.07-rc4-00036-gdeb48986ee (Jul 19 2020 - 02:29:44 +0200)
DRAM: 7.9 GiB RPI 4 Model B (0xd03114) MMC: mmcnr@7e300000: 1, emmc2@7e340000: 0 Loading Environment from FAT... Card did not respond to voltage select! In: serial Out: vidconsole Err: vidconsole Net: eth0: genet@7d580000 PCIe BRCM: link up, 5.0 Gbps x1 (!SSC) Device 'pci_0:0.0': seq 0 is in use by 'pcie@7d500000' starting USB... Bus xhci_pci: probe failed, error -110 No working controllers found Hit any key to stop autoboot: 0 U-Boot> pci enum U-Boot> pci Scanning PCI devices on bus 0 BusDevFun VendorId DeviceId Device Class Sub-Class _____________________________________________________________ 00.00.00 0x14e4 0x2711 Bridge device 0x04
-- Stefan
Note that this builds on top of Sylwester Nawrocki's "USB host support for Raspberry Pi 4 board" series.
This also depends on a DT/bindings patch available on the linux-mailing lists: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2205783.html
Here is the relevant bit for reference/discussion:
&pcie0 { pci@1,0 { #address-cells = <3>; #size-cells = <2>; ranges; reg = <0 0 0 0 0>; usb@1,0 { reg = <0x10000 0 0 0 0>; resets = <&reset
RASPBERRYPI_FIRMWARE_RESET_ID_USB>; }; }; };
Changes since v5:
- Properly handle !CONFIG_IS_ENABLED(DM_RESET) in xchi code
Changes since v4:
- Correct DT PCI topology, I separated the root bridge and controller DT nodes
- Get rid of PCI core patch as not needed with correct DT PCI topology
- Move reset support to xchi core
Changes since v3:
- Use reset controller
Changes since v2:
- Correct comment on patch #1
- Address Matthias' comments
Changes since v1:
- Rename function
- Use callback in xhci-pci.c
Nicolas Saenz Julienne (4): arm: rpi: Add function to trigger VL805's firmware load reset: Add Raspberry Pi 4 firmware reset controller configs: Enable support for reset controllers on RPi4 usb: xhci: Add reset controller support
arch/arm/mach-bcm283x/include/mach/mbox.h | 13 ++++ arch/arm/mach-bcm283x/include/mach/msg.h | 7 +++ arch/arm/mach-bcm283x/msg.c | 46 ++++++++++++++ configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + drivers/reset/Kconfig | 10 ++++ drivers/reset/Makefile | 1 + drivers/reset/reset-raspberrypi.c | 60 +++++++++++++++++++ drivers/usb/host/xhci-mem.c | 2 + drivers/usb/host/xhci.c | 33 ++++++++++ .../reset/raspberrypi,firmware-reset.h | 13 ++++ include/usb/xhci.h | 2 + 13 files changed, 190 insertions(+) create mode 100644 drivers/reset/reset-raspberrypi.c create mode 100644 include/dt-bindings/reset/raspberrypi,firmware-reset.h
participants (3)
-
Matthias Brugger
-
Nicolas Saenz Julienne
-
Stefan Agner