arm: rpi: Add function to trigger VL805's firmware load
authorNicolas Saenz Julienne <nsaenzjulienne@suse.de>
Mon, 29 Jun 2020 16:37:22 +0000 (18:37 +0200)
committerMatthias Brugger <mbrugger@suse.com>
Fri, 10 Jul 2020 09:49:28 +0000 (11:49 +0200)
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>
Signed-off-by: Matthias Brugger <mbrugger@suse.com>
arch/arm/mach-bcm283x/include/mach/mbox.h
arch/arm/mach-bcm283x/include/mach/msg.h
arch/arm/mach-bcm283x/msg.c

index 60e226ce1dd396040c11d2ec20b58676d1018a79..2ae2d3d97c36e3e2a4967e988ba807283c2be12c 100644 (file)
@@ -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.
  *
index 4afb08631bbd9a772406a050a88f6344b80093f8..e45c1bf010f189ed54257501eac2293eacad6c5f 100644 (file)
@@ -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
index 94b75283f8e2311e4d2b54199722b57ba5b48709..347aece3cd8d996827f8527cc98ad6aa5ab7467c 100644 (file)
@@ -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;
+}
+