raspberrypi.c (fbbc5ff3f7f9f4cad562e530ae2cf5d8964fe6d3) raspberrypi.c (4a60f58ee00266ebee652e991954e48d060ea950)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Defines interfaces for interacting wtih the Raspberry Pi firmware's
4 * property channel.
5 *
6 * Copyright © 2015 Broadcom
7 */
8
9#include <linux/dma-mapping.h>
10#include <linux/mailbox_client.h>
11#include <linux/module.h>
12#include <linux/of_platform.h>
13#include <linux/platform_device.h>
14#include <linux/slab.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Defines interfaces for interacting wtih the Raspberry Pi firmware's
4 * property channel.
5 *
6 * Copyright © 2015 Broadcom
7 */
8
9#include <linux/dma-mapping.h>
10#include <linux/mailbox_client.h>
11#include <linux/module.h>
12#include <linux/of_platform.h>
13#include <linux/platform_device.h>
14#include <linux/slab.h>
15#include <linux/pci.h>
16#include <linux/delay.h>
17#include <soc/bcm2835/raspberrypi-firmware.h>
18
19#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf))
20#define MBOX_CHAN(msg) ((msg) & 0xf)
21#define MBOX_DATA28(msg) ((msg) & ~0xf)
22#define MBOX_CHAN_PROPERTY 8
23
15#include <soc/bcm2835/raspberrypi-firmware.h>
16
17#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf))
18#define MBOX_CHAN(msg) ((msg) & 0xf)
19#define MBOX_DATA28(msg) ((msg) & ~0xf)
20#define MBOX_CHAN_PROPERTY 8
21
24#define VL805_PCI_CONFIG_VERSION_OFFSET 0x50
25
26static struct platform_device *rpi_hwmon;
27static struct platform_device *rpi_clk;
28
29struct rpi_firmware {
30 struct mbox_client cl;
31 struct mbox_chan *chan; /* The property channel. */
32 struct completion c;
33 u32 enabled;

--- 147 unchanged lines hidden (view full) ---

181static void
182rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
183{
184 u32 packet;
185 int ret = rpi_firmware_property(fw,
186 RPI_FIRMWARE_GET_FIRMWARE_REVISION,
187 &packet, sizeof(packet));
188
22static struct platform_device *rpi_hwmon;
23static struct platform_device *rpi_clk;
24
25struct rpi_firmware {
26 struct mbox_client cl;
27 struct mbox_chan *chan; /* The property channel. */
28 struct completion c;
29 u32 enabled;

--- 147 unchanged lines hidden (view full) ---

177static void
178rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
179{
180 u32 packet;
181 int ret = rpi_firmware_property(fw,
182 RPI_FIRMWARE_GET_FIRMWARE_REVISION,
183 &packet, sizeof(packet));
184
189 if (ret == 0) {
190 struct tm tm;
185 if (ret)
186 return;
191
187
192 time64_to_tm(packet, 0, &tm);
193
194 dev_info(fw->cl.dev,
195 "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n",
196 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
197 tm.tm_hour, tm.tm_min);
198 }
188 dev_info(fw->cl.dev, "Attached to firmware from %ptT\n", &packet);
199}
200
201static void
202rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw)
203{
204 u32 packet;
205 int ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED,
206 &packet, sizeof(packet));

--- 78 unchanged lines hidden (view full) ---

285
286 if (!pdev)
287 return NULL;
288
289 return platform_get_drvdata(pdev);
290}
291EXPORT_SYMBOL_GPL(rpi_firmware_get);
292
189}
190
191static void
192rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw)
193{
194 u32 packet;
195 int ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED,
196 &packet, sizeof(packet));

--- 78 unchanged lines hidden (view full) ---

275
276 if (!pdev)
277 return NULL;
278
279 return platform_get_drvdata(pdev);
280}
281EXPORT_SYMBOL_GPL(rpi_firmware_get);
282
293/*
294 * The Raspberry Pi 4 gets its USB functionality from VL805, a PCIe chip that
295 * implements xHCI. After a PCI reset, VL805's firmware may either be loaded
296 * directly from an EEPROM or, if not present, by the SoC's co-processor,
297 * VideoCore. RPi4's VideoCore OS contains both the non public firmware load
298 * logic and the VL805 firmware blob. This function triggers the aforementioned
299 * process.
300 */
301int rpi_firmware_init_vl805(struct pci_dev *pdev)
302{
303 struct device_node *fw_np;
304 struct rpi_firmware *fw;
305 u32 dev_addr, version;
306 int ret;
307
308 fw_np = of_find_compatible_node(NULL, NULL,
309 "raspberrypi,bcm2835-firmware");
310 if (!fw_np)
311 return 0;
312
313 fw = rpi_firmware_get(fw_np);
314 of_node_put(fw_np);
315 if (!fw)
316 return -ENODEV;
317
318 /*
319 * Make sure we don't trigger a firmware load unnecessarily.
320 *
321 * If something went wrong with PCI, this whole exercise would be
322 * futile as VideoCore expects from us a configured PCI bus. Just take
323 * the faulty version (likely ~0) and let xHCI's registration fail
324 * further down the line.
325 */
326 pci_read_config_dword(pdev, VL805_PCI_CONFIG_VERSION_OFFSET, &version);
327 if (version)
328 goto exit;
329
330 dev_addr = pdev->bus->number << 20 | PCI_SLOT(pdev->devfn) << 15 |
331 PCI_FUNC(pdev->devfn) << 12;
332
333 ret = rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_XHCI_RESET,
334 &dev_addr, sizeof(dev_addr));
335 if (ret)
336 return ret;
337
338 /* Wait for vl805 to startup */
339 usleep_range(200, 1000);
340
341 pci_read_config_dword(pdev, VL805_PCI_CONFIG_VERSION_OFFSET,
342 &version);
343exit:
344 pci_info(pdev, "VL805 firmware version %08x\n", version);
345
346 return 0;
347}
348EXPORT_SYMBOL_GPL(rpi_firmware_init_vl805);
349
350static const struct of_device_id rpi_firmware_of_match[] = {
351 { .compatible = "raspberrypi,bcm2835-firmware", },
352 {},
353};
354MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
355
356static struct platform_driver rpi_firmware_driver = {
357 .driver = {

--- 12 unchanged lines hidden ---
283static const struct of_device_id rpi_firmware_of_match[] = {
284 { .compatible = "raspberrypi,bcm2835-firmware", },
285 {},
286};
287MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
288
289static struct platform_driver rpi_firmware_driver = {
290 .driver = {

--- 12 unchanged lines hidden ---