2020-05-07 14:11:53 +00:00
|
|
|
From 8b708cd3b79419b69a530ce1e5f081ee549cb27c Mon Sep 17 00:00:00 2001
|
2020-04-23 20:47:21 +00:00
|
|
|
From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
|
|
|
Date: Tue, 10 Mar 2020 13:52:40 +0100
|
|
|
|
Subject: [PATCH] firmware: raspberrypi: Introduce vl805 init routine
|
|
|
|
|
|
|
|
On the Raspberry Pi 4, after a PCI reset, VL805's firmware may either be
|
|
|
|
loaded directly from an EEPROM or, if not present, by the SoC's
|
|
|
|
VideCore. The function informs VideCore that VL805 was just reset, or
|
|
|
|
requests for a probe defer.
|
|
|
|
|
|
|
|
Based on Tim Gover's downstream implementation.
|
|
|
|
|
|
|
|
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
|
|
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
|
|
|
---
|
|
|
|
drivers/firmware/raspberrypi.c | 38 ++++++++++++++++++++++
|
|
|
|
include/soc/bcm2835/raspberrypi-firmware.h | 7 ++++
|
|
|
|
2 files changed, 45 insertions(+)
|
|
|
|
|
|
|
|
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
|
|
|
|
index da26a584dca0..cbb495aff6a0 100644
|
|
|
|
--- a/drivers/firmware/raspberrypi.c
|
|
|
|
+++ b/drivers/firmware/raspberrypi.c
|
|
|
|
@@ -12,6 +12,7 @@
|
|
|
|
#include <linux/of_platform.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
+#include <linux/pci.h>
|
|
|
|
#include <soc/bcm2835/raspberrypi-firmware.h>
|
2020-04-27 02:15:20 +00:00
|
|
|
|
2020-04-23 20:47:21 +00:00
|
|
|
#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf))
|
|
|
|
@@ -286,6 +287,43 @@ struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rpi_firmware_get);
|
2020-04-27 02:15:20 +00:00
|
|
|
|
2020-04-23 20:47:21 +00:00
|
|
|
+/*
|
|
|
|
+ * On the Raspberry Pi 4, after a PCI reset, VL805's firmware may either be
|
|
|
|
+ * loaded directly from an EEPROM or, if not present, by the SoC's VideCore.
|
|
|
|
+ * Inform VideCore that VL805 was just reset, or defer xhci's probe if not yet
|
|
|
|
+ * joinable trough the mailbox interface.
|
|
|
|
+ */
|
|
|
|
+int rpi_firmware_init_vl805(struct pci_dev *pdev)
|
|
|
|
+{
|
|
|
|
+ struct device_node *fw_np;
|
|
|
|
+ struct rpi_firmware *fw;
|
|
|
|
+ u32 dev_addr;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ fw_np = of_find_compatible_node(NULL, NULL,
|
|
|
|
+ "raspberrypi,bcm2835-firmware");
|
|
|
|
+ if (!fw_np)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ fw = rpi_firmware_get(fw_np);
|
|
|
|
+ of_node_put(fw_np);
|
|
|
|
+ if (!fw)
|
|
|
|
+ return -EPROBE_DEFER;
|
|
|
|
+
|
|
|
|
+ dev_addr = pdev->bus->number << 20 | PCI_SLOT(pdev->devfn) << 15 |
|
|
|
|
+ PCI_FUNC(pdev->devfn) << 12;
|
|
|
|
+
|
|
|
|
+ ret = rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_XHCI_RESET,
|
|
|
|
+ &dev_addr, sizeof(dev_addr));
|
|
|
|
+ if (ret)
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+ dev_dbg(&pdev->dev, "loaded Raspberry Pi's VL805 firmware\n");
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL_GPL(rpi_firmware_init_vl805);
|
|
|
|
+
|
|
|
|
static const struct of_device_id rpi_firmware_of_match[] = {
|
|
|
|
{ .compatible = "raspberrypi,bcm2835-firmware", },
|
|
|
|
{},
|
|
|
|
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
|
|
|
|
index cc9cdbc66403..3025aca3c358 100644
|
|
|
|
--- a/include/soc/bcm2835/raspberrypi-firmware.h
|
|
|
|
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
|
|
|
|
@@ -10,6 +10,7 @@
|
|
|
|
#include <linux/of_device.h>
|
2020-04-27 02:15:20 +00:00
|
|
|
|
2020-04-23 20:47:21 +00:00
|
|
|
struct rpi_firmware;
|
|
|
|
+struct pci_dev;
|
2020-04-27 02:15:20 +00:00
|
|
|
|
2020-04-23 20:47:21 +00:00
|
|
|
enum rpi_firmware_property_status {
|
|
|
|
RPI_FIRMWARE_STATUS_REQUEST = 0,
|
|
|
|
@@ -141,6 +142,7 @@ int rpi_firmware_property(struct rpi_firmware *fw,
|
|
|
|
int rpi_firmware_property_list(struct rpi_firmware *fw,
|
|
|
|
void *data, size_t tag_size);
|
|
|
|
struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node);
|
|
|
|
+int rpi_firmware_init_vl805(struct pci_dev *pdev);
|
|
|
|
#else
|
|
|
|
static inline int rpi_firmware_property(struct rpi_firmware *fw, u32 tag,
|
|
|
|
void *data, size_t len)
|
|
|
|
@@ -158,6 +160,11 @@ static inline struct rpi_firmware *rpi_firmware_get(struct device_node *firmware
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+static inline int rpi_firmware_init_vl805(struct pci_dev *pdev)
|
|
|
|
+{
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
#endif
|
2020-04-27 02:15:20 +00:00
|
|
|
|
2020-04-23 20:47:21 +00:00
|
|
|
#endif /* __SOC_RASPBERRY_FIRMWARE_H__ */
|
|
|
|
--
|
2020-04-27 02:15:20 +00:00
|
|
|
2.26.2
|
2020-04-23 20:47:21 +00:00
|
|
|
|