Commit 187b4ac7 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'arm-soc/for-5.1/drivers' of https://github.com/Broadcom/stblinux into arm/drivers

This pull request contains Broadcom ARM/ARM64/MIPS based SoCs changes
for 5.1, please pull the following:

- Stefan updates the BCM2835 SoC driver with downstream properties and
  uses that to implement a reboot notifier to tell the VC4 firmware when
  Linux on the ARM CPU is rebooting

- Eric adds a proper power domain driver for the BCM283x SoCs and
  updates a bunch of drivers to have a better and clearer Device Tree
  definition to support power domains/breaking up of functionality. This
  requires converting the existing watchdog driver into a MFD and then
  breaking up the functionality into separate drivers and finally
  updating the DTS files to leverage the power domains information.

- Wei provides a fix for making a symbol static

* tag 'arm-soc/for-5.1/drivers' of https://github.com/Broadcom/stblinux:
  ARM: bcm283x: Switch V3D over to using the PM driver instead of firmware.
  ARM: bcm283x: Extend the WDT DT node out to cover the whole PM block. (v4)
  soc: bcm: bcm2835-pm: Make local symbol static
  soc: bcm: Make PM driver default for BCM2835
  soc: bcm: bcm2835-pm: Add support for power domains under a new binding.
  bcm2835-pm: Move bcm2835-watchdog's DT probe to an MFD.
  dt-bindings: soc: Add a new binding for the BCM2835 PM node. (v4)
  firmware: raspberrypi: notify VC4 firmware of a reboot
  soc: bcm2835: sync firmware properties with downstream
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 405bcfff 50de6494
BCM2835 PM (Power domains, watchdog)
The PM block controls power domains and some reset lines, and includes
a watchdog timer. This binding supersedes the brcm,bcm2835-pm-wdt
binding which covered some of PM's register range and functionality.
Required properties:
- compatible: Should be "brcm,bcm2835-pm"
- reg: Specifies base physical address and size of the two
register ranges ("PM" and "ASYNC_BRIDGE" in that
order)
- clocks: a) v3d: The V3D clock from CPRMAN
b) peri_image: The PERI_IMAGE clock from CPRMAN
c) h264: The H264 clock from CPRMAN
d) isp: The ISP clock from CPRMAN
- #reset-cells: Should be 1. This property follows the reset controller
bindings[1].
- #power-domain-cells: Should be 1. This property follows the power domain
bindings[2].
Optional properties:
- timeout-sec: Contains the watchdog timeout in seconds
- system-power-controller: Whether the watchdog is controlling the
system power. This node follows the power controller bindings[3].
[1] Documentation/devicetree/bindings/reset/reset.txt
[2] Documentation/devicetree/bindings/power/power_domain.txt
[3] Documentation/devicetree/bindings/power/power-controller.txt
Example:
pm {
compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt";
#power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x7e100000 0x114>,
<0x7e00a000 0x24>;
clocks = <&clocks BCM2835_CLOCK_V3D>,
<&clocks BCM2835_CLOCK_PERI_IMAGE>,
<&clocks BCM2835_CLOCK_H264>,
<&clocks BCM2835_CLOCK_ISP>;
clock-names = "v3d", "peri_image", "h264", "isp";
system-power-controller;
};
......@@ -87,10 +87,6 @@ &usb {
power-domains = <&power RPI_POWER_DOMAIN_USB>;
};
&v3d {
power-domains = <&power RPI_POWER_DOMAIN_V3D>;
};
&hdmi {
power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
status = "okay";
......
......@@ -3,6 +3,7 @@
#include <dt-bindings/clock/bcm2835-aux.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/soc/bcm2835-pm.h>
/* firmware-provided startup stubs live here, where the secondary CPUs are
* spinning.
......@@ -120,9 +121,18 @@ intc: interrupt-controller@7e00b200 {
#interrupt-cells = <2>;
};
watchdog@7e100000 {
compatible = "brcm,bcm2835-pm-wdt";
reg = <0x7e100000 0x28>;
pm: watchdog@7e100000 {
compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt";
#power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x7e100000 0x114>,
<0x7e00a000 0x24>;
clocks = <&clocks BCM2835_CLOCK_V3D>,
<&clocks BCM2835_CLOCK_PERI_IMAGE>,
<&clocks BCM2835_CLOCK_H264>,
<&clocks BCM2835_CLOCK_ISP>;
clock-names = "v3d", "peri_image", "h264", "isp";
system-power-controller;
};
clocks: cprman@7e101000 {
......@@ -629,6 +639,7 @@ v3d: v3d@7ec00000 {
compatible = "brcm,bcm2835-v3d";
reg = <0x7ec00000 0x1000>;
interrupts = <1 10>;
power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
};
vc4: gpu {
......
......@@ -167,6 +167,7 @@ config ARCH_BCM2835
select BCM2835_TIMER
select PINCTRL
select PINCTRL_BCM2835
select MFD_CORE
help
This enables support for the Broadcom BCM2835 and BCM2836 SoCs.
This SoC is used in the Raspberry Pi and Roku 2 devices.
......
......@@ -238,6 +238,16 @@ static int rpi_firmware_probe(struct platform_device *pdev)
return 0;
}
static void rpi_firmware_shutdown(struct platform_device *pdev)
{
struct rpi_firmware *fw = platform_get_drvdata(pdev);
if (!fw)
return;
rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, NULL, 0);
}
static int rpi_firmware_remove(struct platform_device *pdev)
{
struct rpi_firmware *fw = platform_get_drvdata(pdev);
......@@ -278,6 +288,7 @@ static struct platform_driver rpi_firmware_driver = {
.of_match_table = rpi_firmware_of_match,
},
.probe = rpi_firmware_probe,
.shutdown = rpi_firmware_shutdown,
.remove = rpi_firmware_remove,
};
module_platform_driver(rpi_firmware_driver);
......
......@@ -10,6 +10,7 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
obj-$(CONFIG_MFD_ACT8945A) += act8945a.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o
obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o
cros_ec_core-objs := cros_ec.o
......
// SPDX-License-Identifier: GPL-2.0+
/*
* PM MFD driver for Broadcom BCM2835
*
* This driver binds to the PM block and creates the MFD device for
* the WDT and power drivers.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/mfd/bcm2835-pm.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/watchdog.h>
static const struct mfd_cell bcm2835_pm_devs[] = {
{ .name = "bcm2835-wdt" },
};
static const struct mfd_cell bcm2835_power_devs[] = {
{ .name = "bcm2835-power" },
};
static int bcm2835_pm_probe(struct platform_device *pdev)
{
struct resource *res;
struct device *dev = &pdev->dev;
struct bcm2835_pm *pm;
int ret;
pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL);
if (!pm)
return -ENOMEM;
platform_set_drvdata(pdev, pm);
pm->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pm->base = devm_ioremap_resource(dev, res);
if (IS_ERR(pm->base))
return PTR_ERR(pm->base);
ret = devm_mfd_add_devices(dev, -1,
bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs),
NULL, 0, NULL);
if (ret)
return ret;
/* We'll use the presence of the AXI ASB regs in the
* bcm2835-pm binding as the key for whether we can reference
* the full PM register range and support power domains.
*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res) {
pm->asb = devm_ioremap_resource(dev, res);
if (IS_ERR(pm->asb))
return PTR_ERR(pm->asb);
ret = devm_mfd_add_devices(dev, -1,
bcm2835_power_devs,
ARRAY_SIZE(bcm2835_power_devs),
NULL, 0, NULL);
if (ret)
return ret;
}
return 0;
}
static const struct of_device_id bcm2835_pm_of_match[] = {
{ .compatible = "brcm,bcm2835-pm-wdt", },
{ .compatible = "brcm,bcm2835-pm", },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match);
static struct platform_driver bcm2835_pm_driver = {
.probe = bcm2835_pm_probe,
.driver = {
.name = "bcm2835-pm",
.of_match_table = bcm2835_pm_of_match,
},
};
module_platform_driver(bcm2835_pm_driver);
MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD");
MODULE_LICENSE("GPL");
menu "Broadcom SoC drivers"
config BCM2835_POWER
bool "BCM2835 power domain driver"
depends on ARCH_BCM2835 || (COMPILE_TEST && OF)
default y if ARCH_BCM2835
select PM_GENERIC_DOMAINS if PM
select RESET_CONTROLLER
help
This enables support for the BCM2835 power domains and reset
controller. Any usage of power domains by the Raspberry Pi
firmware means that Linux usage of the same power domain
must be accessed using the RASPBERRYPI_POWER driver
config RASPBERRYPI_POWER
bool "Raspberry Pi power domain driver"
depends on ARCH_BCM2835 || (COMPILE_TEST && OF)
......
obj-$(CONFIG_BCM2835_POWER) += bcm2835-power.o
obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o
obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/
This diff is collapsed.
......@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/mfd/bcm2835-pm.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/watchdog.h>
......@@ -47,6 +48,8 @@ struct bcm2835_wdt {
spinlock_t lock;
};
static struct bcm2835_wdt *bcm2835_power_off_wdt;
static unsigned int heartbeat;
static bool nowayout = WATCHDOG_NOWAYOUT;
......@@ -148,10 +151,7 @@ static struct watchdog_device bcm2835_wdt_wdd = {
*/
static void bcm2835_power_off(void)
{
struct device_node *np =
of_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm-wdt");
struct platform_device *pdev = of_find_device_by_node(np);
struct bcm2835_wdt *wdt = platform_get_drvdata(pdev);
struct bcm2835_wdt *wdt = bcm2835_power_off_wdt;
u32 val;
/*
......@@ -169,7 +169,7 @@ static void bcm2835_power_off(void)
static int bcm2835_wdt_probe(struct platform_device *pdev)
{
struct resource *res;
struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent);
struct device *dev = &pdev->dev;
struct bcm2835_wdt *wdt;
int err;
......@@ -181,10 +181,7 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
wdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
wdt->base = pm->base;
watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt);
watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
......@@ -211,8 +208,10 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
return err;
}
if (pm_power_off == NULL)
if (pm_power_off == NULL) {
pm_power_off = bcm2835_power_off;
bcm2835_power_off_wdt = wdt;
}
dev_info(dev, "Broadcom BCM2835 watchdog timer");
return 0;
......@@ -226,18 +225,11 @@ static int bcm2835_wdt_remove(struct platform_device *pdev)
return 0;
}
static const struct of_device_id bcm2835_wdt_of_match[] = {
{ .compatible = "brcm,bcm2835-pm-wdt", },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_wdt_of_match);
static struct platform_driver bcm2835_wdt_driver = {
.probe = bcm2835_wdt_probe,
.remove = bcm2835_wdt_remove,
.driver = {
.name = "bcm2835-wdt",
.of_match_table = bcm2835_wdt_of_match,
},
};
module_platform_driver(bcm2835_wdt_driver);
......
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
#ifndef _DT_BINDINGS_ARM_BCM2835_PM_H
#define _DT_BINDINGS_ARM_BCM2835_PM_H
#define BCM2835_POWER_DOMAIN_GRAFX 0
#define BCM2835_POWER_DOMAIN_GRAFX_V3D 1
#define BCM2835_POWER_DOMAIN_IMAGE 2
#define BCM2835_POWER_DOMAIN_IMAGE_PERI 3
#define BCM2835_POWER_DOMAIN_IMAGE_ISP 4
#define BCM2835_POWER_DOMAIN_IMAGE_H264 5
#define BCM2835_POWER_DOMAIN_USB 6
#define BCM2835_POWER_DOMAIN_DSI0 7
#define BCM2835_POWER_DOMAIN_DSI1 8
#define BCM2835_POWER_DOMAIN_CAM0 9
#define BCM2835_POWER_DOMAIN_CAM1 10
#define BCM2835_POWER_DOMAIN_CCP2TX 11
#define BCM2835_POWER_DOMAIN_HDMI 12
#define BCM2835_POWER_DOMAIN_COUNT 13
#define BCM2835_RESET_V3D 0
#define BCM2835_RESET_ISP 1
#define BCM2835_RESET_H264 2
#define BCM2835_RESET_COUNT 3
#endif /* _DT_BINDINGS_ARM_BCM2835_PM_H */
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef BCM2835_MFD_PM_H
#define BCM2835_MFD_PM_H
#include <linux/regmap.h>
struct bcm2835_pm {
struct device *dev;
void __iomem *base;
void __iomem *asb;
};
#endif /* BCM2835_MFD_PM_H */
......@@ -73,6 +73,8 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021,
RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030,
RPI_FIRMWARE_GET_THROTTLED = 0x00030046,
RPI_FIRMWARE_GET_CLOCK_MEASURED = 0x00030047,
RPI_FIRMWARE_NOTIFY_REBOOT = 0x00030048,
RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001,
RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002,
RPI_FIRMWARE_SET_VOLTAGE = 0x00038003,
......@@ -86,6 +88,8 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043,
RPI_FIRMWARE_GET_PERIPH_REG = 0x00030045,
RPI_FIRMWARE_SET_PERIPH_REG = 0x00038045,
RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049,
RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050,
/* Dispmanx TAGS */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment