Skip to content

Commit

Permalink
arm: rpi: Add function to trigger VL805's firmware load
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nicolas Saenz Julienne authored and mbgg committed Jul 10, 2020
1 parent 440bca8 commit d774da0
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
13 changes: 13 additions & 0 deletions arch/arm/mach-bcm283x/include/mach/mbox.h
Expand Up @@ -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.
*
Expand Down
7 changes: 7 additions & 0 deletions arch/arm/mach-bcm283x/include/mach/msg.h
Expand Up @@ -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
46 changes: 46 additions & 0 deletions arch/arm/mach-bcm283x/msg.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

0 comments on commit d774da0

Please sign in to comment.