All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Álvaro Fernández Rojas" <noltari@gmail.com>
To: hauke@hauke-m.de, zajec5@gmail.com, tsbogend@alpha.franken.de,
	robh+dt@kernel.org, f.fainelli@gmail.com, jonas.gorski@gmail.com,
	bcm-kernel-feedback-list@broadcom.com,
	linux-mips@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Cc: "Álvaro Fernández Rojas" <noltari@gmail.com>
Subject: [PATCH v2 2/6] soc: bcm: add BCM63xx power domain driver
Date: Wed, 10 Jun 2020 18:32:57 +0200	[thread overview]
Message-ID: <20200610163301.461160-3-noltari@gmail.com> (raw)
In-Reply-To: <20200610163301.461160-1-noltari@gmail.com>

BCM6318, BCM6328, BCM6362 and BCM63268 SoCs have a power domain controller
to enable/disable certain components in order to save power.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v2: Introduce bcm63xx folder in drivers/soc/bcm and update MAINTAINERS.

 MAINTAINERS                             |   1 +
 drivers/soc/bcm/Kconfig                 |  10 +
 drivers/soc/bcm/Makefile                |   1 +
 drivers/soc/bcm/bcm63xx/Kconfig         |  12 +
 drivers/soc/bcm/bcm63xx/Makefile        |   2 +
 drivers/soc/bcm/bcm63xx/bcm63xx-power.c | 374 ++++++++++++++++++++++++
 6 files changed, 400 insertions(+)
 create mode 100644 drivers/soc/bcm/bcm63xx/Kconfig
 create mode 100644 drivers/soc/bcm/bcm63xx/Makefile
 create mode 100644 drivers/soc/bcm/bcm63xx/bcm63xx-power.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 77a3fa5e3edd..e9ba7b955d5f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3442,6 +3442,7 @@ F:	arch/mips/bmips/*
 F:	arch/mips/boot/dts/brcm/bcm*.dts*
 F:	arch/mips/include/asm/mach-bmips/*
 F:	arch/mips/kernel/*bmips*
+F:	drivers/soc/bcm/bcm63xx
 F:	drivers/irqchip/irq-bcm63*
 F:	drivers/irqchip/irq-bcm7*
 F:	drivers/irqchip/irq-brcmstb*
diff --git a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig
index 648e32693b7e..24f92a6e882a 100644
--- a/drivers/soc/bcm/Kconfig
+++ b/drivers/soc/bcm/Kconfig
@@ -22,6 +22,15 @@ config RASPBERRYPI_POWER
 	  This enables support for the RPi power domains which can be enabled
 	  or disabled via the RPi firmware.
 
+config SOC_BCM63XX
+	bool "Broadcom 63xx SoC drivers"
+	depends on BMIPS_GENERIC || COMPILE_TEST
+	help
+	  Enables drivers for the Broadcom 63xx series of chips.
+	  Drivers can be enabled individually within this menu.
+
+	  If unsure, say N.
+
 config SOC_BRCMSTB
 	bool "Broadcom STB SoC drivers"
 	depends on ARM || ARM64 || BMIPS_GENERIC || COMPILE_TEST
@@ -33,6 +42,7 @@ config SOC_BRCMSTB
 
 	  If unsure, say N.
 
+source "drivers/soc/bcm/bcm63xx/Kconfig"
 source "drivers/soc/bcm/brcmstb/Kconfig"
 
 endmenu
diff --git a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile
index d92268a829a9..7bc90e0bd773 100644
--- a/drivers/soc/bcm/Makefile
+++ b/drivers/soc/bcm/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_BCM2835_POWER)	+= bcm2835-power.o
 obj-$(CONFIG_RASPBERRYPI_POWER)	+= raspberrypi-power.o
+obj-$(CONFIG_SOC_BCM63XX)	+= bcm63xx/
 obj-$(CONFIG_SOC_BRCMSTB)	+= brcmstb/
diff --git a/drivers/soc/bcm/bcm63xx/Kconfig b/drivers/soc/bcm/bcm63xx/Kconfig
new file mode 100644
index 000000000000..16f648a6c70a
--- /dev/null
+++ b/drivers/soc/bcm/bcm63xx/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+if SOC_BCM63XX
+
+config BCM63XX_POWER
+	bool "BCM63xx power domain driver"
+	depends on BMIPS_GENERIC || (COMPILE_TEST && OF)
+	select PM_GENERIC_DOMAINS if PM
+	help
+	  This enables support for the BCM63xx power domains controller on
+	  BCM6318, BCM6328, BCM6362 and BCM63268 SoCs.
+
+endif # SOC_BCM63XX
diff --git a/drivers/soc/bcm/bcm63xx/Makefile b/drivers/soc/bcm/bcm63xx/Makefile
new file mode 100644
index 000000000000..0710d5e018cc
--- /dev/null
+++ b/drivers/soc/bcm/bcm63xx/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_BCM63XX_POWER) += bcm63xx-power.o
diff --git a/drivers/soc/bcm/bcm63xx/bcm63xx-power.c b/drivers/soc/bcm/bcm63xx/bcm63xx-power.c
new file mode 100644
index 000000000000..b6e51b721f09
--- /dev/null
+++ b/drivers/soc/bcm/bcm63xx/bcm63xx-power.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * BCM63xx Power Domain Controller Driver
+ *
+ * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+struct bcm63xx_power_dev {
+	struct generic_pm_domain genpd;
+	struct bcm63xx_power *power;
+	uint32_t mask;
+};
+
+struct bcm63xx_power {
+	void __iomem *base;
+	spinlock_t lock;
+	struct bcm63xx_power_dev *dev;
+	struct genpd_onecell_data genpd_data;
+	struct generic_pm_domain **genpd;
+};
+
+struct bcm63xx_power_data {
+	const char * const name;
+	uint8_t bit;
+	unsigned int flags;
+};
+
+static int bcm63xx_power_get_state(struct bcm63xx_power_dev *pmd, bool *is_on)
+{
+	struct bcm63xx_power *power = pmd->power;
+
+	if (!pmd->mask) {
+		*is_on = false;
+		return -EINVAL;
+	}
+
+	*is_on = !(__raw_readl(power->base) & pmd->mask);
+
+	return 0;
+}
+
+static int bcm63xx_power_set_state(struct bcm63xx_power_dev *pmd, bool on)
+{
+	struct bcm63xx_power *power = pmd->power;
+	unsigned long flags;
+	uint32_t val;
+
+	if (!pmd->mask)
+		return -EINVAL;
+
+	spin_lock_irqsave(&power->lock, flags);
+	val = __raw_readl(power->base);
+	if (on)
+		val &= ~pmd->mask;
+	else
+		val |= pmd->mask;
+	__raw_writel(val, power->base);
+	spin_unlock_irqrestore(&power->lock, flags);
+
+	return 0;
+}
+
+static int bcm63xx_power_on(struct generic_pm_domain *genpd)
+{
+	struct bcm63xx_power_dev *pmd = container_of(genpd,
+		struct bcm63xx_power_dev, genpd);
+
+	return bcm63xx_power_set_state(pmd, true);
+}
+
+static int bcm63xx_power_off(struct generic_pm_domain *genpd)
+{
+	struct bcm63xx_power_dev *pmd = container_of(genpd,
+		struct bcm63xx_power_dev, genpd);
+
+	return bcm63xx_power_set_state(pmd, false);
+}
+
+static int bcm63xx_power_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct resource *res;
+	const struct bcm63xx_power_data *entry, *table;
+	struct bcm63xx_power *power;
+	unsigned int ndom;
+	uint8_t max_bit = 0;
+	int ret;
+
+	power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL);
+	if (!power)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	power->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(power->base))
+		return PTR_ERR(power->base);
+
+	table = of_device_get_match_data(dev);
+	if (!table)
+		return -EINVAL;
+
+	power->genpd_data.num_domains = 0;
+	ndom = 0;
+	for (entry = table; entry->name; entry++) {
+		max_bit = max(max_bit, entry->bit);
+		ndom++;
+	}
+
+	if (!ndom)
+		return -ENODEV;
+
+	power->genpd_data.num_domains = max_bit + 1;
+
+	power->dev = devm_kcalloc(dev, power->genpd_data.num_domains,
+				  sizeof(struct bcm63xx_power_dev),
+				  GFP_KERNEL);
+	if (!power->dev)
+		return -ENOMEM;
+
+	power->genpd = devm_kcalloc(dev, power->genpd_data.num_domains,
+				    sizeof(struct generic_pm_domain *),
+				    GFP_KERNEL);
+	if (!power->genpd)
+		return -ENOMEM;
+
+	power->genpd_data.domains = power->genpd;
+
+	ndom = 0;
+	for (entry = table; entry->name; entry++) {
+		struct bcm63xx_power_dev *pmd = &power->dev[ndom];
+		bool is_on;
+
+		pmd->power = power;
+		pmd->mask = BIT(entry->bit);
+		pmd->genpd.name = entry->name;
+		pmd->genpd.flags = entry->flags;
+
+		ret = bcm63xx_power_get_state(pmd, &is_on);
+		if (ret)
+			dev_warn(dev, "unable to get current state for %s\n",
+				 pmd->genpd.name);
+
+		pmd->genpd.power_on = bcm63xx_power_on;
+		pmd->genpd.power_off = bcm63xx_power_off;
+
+		pm_genpd_init(&pmd->genpd, NULL, !is_on);
+		power->genpd[entry->bit] = &pmd->genpd;
+
+		ndom++;
+	}
+
+	spin_lock_init(&power->lock);
+
+	ret = of_genpd_add_provider_onecell(np, &power->genpd_data);
+	if (ret) {
+		dev_err(dev, "failed to register genpd driver: %d\n", ret);
+		return ret;
+	}
+
+	dev_info(dev, "registered %u power domains\n", ndom);
+
+	return 0;
+}
+
+static const struct bcm63xx_power_data bcm6318_power_domains[] = {
+	{
+		.name = "pcie",
+		.bit = 0,
+	}, {
+		.name = "usb",
+		.bit = 1,
+	}, {
+		.name = "ephy0",
+		.bit = 2,
+	}, {
+		.name = "ephy1",
+		.bit = 3,
+	}, {
+		.name = "ephy2",
+		.bit = 4,
+	}, {
+		.name = "ephy3",
+		.bit = 5,
+	}, {
+		.name = "ldo2p5",
+		.bit = 6,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "ldo2p9",
+		.bit = 7,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "sw1p0",
+		.bit = 8,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "pad",
+		.bit = 9,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		/* sentinel */
+	},
+};
+
+static const struct bcm63xx_power_data bcm6328_power_domains[] = {
+	{
+		.name = "adsl2-mips",
+		.bit = 0,
+	}, {
+		.name = "adsl2-phy",
+		.bit = 1,
+	}, {
+		.name = "adsl2-afe",
+		.bit = 2,
+	}, {
+		.name = "sar",
+		.bit = 3,
+	}, {
+		.name = "pcm",
+		.bit = 4,
+	}, {
+		.name = "usbd",
+		.bit = 5,
+	}, {
+		.name = "usbh",
+		.bit = 6,
+	}, {
+		.name = "pcie",
+		.bit = 7,
+	}, {
+		.name = "robosw",
+		.bit = 8,
+	}, {
+		.name = "ephy",
+		.bit = 9,
+	}, {
+		/* sentinel */
+	},
+};
+
+static const struct bcm63xx_power_data bcm6362_power_domains[] = {
+	{
+		.name = "sar",
+		.bit = 0,
+	}, {
+		.name = "ipsec",
+		.bit = 1,
+	}, {
+		.name = "mips",
+		.bit = 2,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "dect",
+		.bit = 3,
+	}, {
+		.name = "usbh",
+		.bit = 4,
+	}, {
+		.name = "usbd",
+		.bit = 5,
+	}, {
+		.name = "robosw",
+		.bit = 6,
+	}, {
+		.name = "pcm",
+		.bit = 7,
+	}, {
+		.name = "periph",
+		.bit = 8,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "adsl-phy",
+		.bit = 9,
+	}, {
+		.name = "gmii-pads",
+		.bit = 10,
+	}, {
+		.name = "fap",
+		.bit = 11,
+	}, {
+		.name = "pcie",
+		.bit = 12,
+	}, {
+		.name = "wlan-pads",
+		.bit = 13,
+	}, {
+		/* sentinel */
+	},
+};
+
+static const struct bcm63xx_power_data bcm63268_power_domains[] = {
+	{
+		.name = "sar",
+		.bit = 0,
+	}, {
+		.name = "ipsec",
+		.bit = 1,
+	}, {
+		.name = "mips",
+		.bit = 2,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "dect",
+		.bit = 3,
+	}, {
+		.name = "usbh",
+		.bit = 4,
+	}, {
+		.name = "usbd",
+		.bit = 5,
+	}, {
+		.name = "robosw",
+		.bit = 6,
+	}, {
+		.name = "pcm",
+		.bit = 7,
+	}, {
+		.name = "periph",
+		.bit = 8,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "vdsl-phy",
+		.bit = 9,
+	}, {
+		.name = "vdsl-mips",
+		.bit = 10,
+	}, {
+		.name = "fap",
+		.bit = 11,
+	}, {
+		.name = "pcie",
+		.bit = 12,
+	}, {
+		.name = "wlan-pads",
+		.bit = 13,
+	}, {
+		/* sentinel */
+	},
+};
+
+static const struct of_device_id bcm63xx_power_of_match[] = {
+	{
+		.compatible = "brcm,bcm6318-power-controller",
+		.data = &bcm6318_power_domains,
+	}, {
+		.compatible = "brcm,bcm6328-power-controller",
+		.data = &bcm6328_power_domains,
+	}, {
+		.compatible = "brcm,bcm6362-power-controller",
+		.data = &bcm6362_power_domains,
+	}, {
+		.compatible = "brcm,bcm63268-power-controller",
+		.data = &bcm63268_power_domains,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver bcm63xx_power_driver = {
+	.driver = {
+		.name = "bcm63xx-power-controller",
+		.of_match_table = bcm63xx_power_of_match,
+	},
+	.probe  = bcm63xx_power_probe,
+};
+builtin_platform_driver(bcm63xx_power_driver);
-- 
2.26.2


WARNING: multiple messages have this Message-ID (diff)
From: "Álvaro Fernández Rojas" <noltari@gmail.com>
To: hauke@hauke-m.de, zajec5@gmail.com, tsbogend@alpha.franken.de,
	robh+dt@kernel.org, f.fainelli@gmail.com, jonas.gorski@gmail.com,
	bcm-kernel-feedback-list@broadcom.com,
	linux-mips@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Cc: "Álvaro Fernández Rojas" <noltari@gmail.com>
Subject: [PATCH v2 2/6] soc: bcm: add BCM63xx power domain driver
Date: Wed, 10 Jun 2020 18:32:57 +0200	[thread overview]
Message-ID: <20200610163301.461160-3-noltari@gmail.com> (raw)
In-Reply-To: <20200610163301.461160-1-noltari@gmail.com>

BCM6318, BCM6328, BCM6362 and BCM63268 SoCs have a power domain controller
to enable/disable certain components in order to save power.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v2: Introduce bcm63xx folder in drivers/soc/bcm and update MAINTAINERS.

 MAINTAINERS                             |   1 +
 drivers/soc/bcm/Kconfig                 |  10 +
 drivers/soc/bcm/Makefile                |   1 +
 drivers/soc/bcm/bcm63xx/Kconfig         |  12 +
 drivers/soc/bcm/bcm63xx/Makefile        |   2 +
 drivers/soc/bcm/bcm63xx/bcm63xx-power.c | 374 ++++++++++++++++++++++++
 6 files changed, 400 insertions(+)
 create mode 100644 drivers/soc/bcm/bcm63xx/Kconfig
 create mode 100644 drivers/soc/bcm/bcm63xx/Makefile
 create mode 100644 drivers/soc/bcm/bcm63xx/bcm63xx-power.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 77a3fa5e3edd..e9ba7b955d5f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3442,6 +3442,7 @@ F:	arch/mips/bmips/*
 F:	arch/mips/boot/dts/brcm/bcm*.dts*
 F:	arch/mips/include/asm/mach-bmips/*
 F:	arch/mips/kernel/*bmips*
+F:	drivers/soc/bcm/bcm63xx
 F:	drivers/irqchip/irq-bcm63*
 F:	drivers/irqchip/irq-bcm7*
 F:	drivers/irqchip/irq-brcmstb*
diff --git a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig
index 648e32693b7e..24f92a6e882a 100644
--- a/drivers/soc/bcm/Kconfig
+++ b/drivers/soc/bcm/Kconfig
@@ -22,6 +22,15 @@ config RASPBERRYPI_POWER
 	  This enables support for the RPi power domains which can be enabled
 	  or disabled via the RPi firmware.
 
+config SOC_BCM63XX
+	bool "Broadcom 63xx SoC drivers"
+	depends on BMIPS_GENERIC || COMPILE_TEST
+	help
+	  Enables drivers for the Broadcom 63xx series of chips.
+	  Drivers can be enabled individually within this menu.
+
+	  If unsure, say N.
+
 config SOC_BRCMSTB
 	bool "Broadcom STB SoC drivers"
 	depends on ARM || ARM64 || BMIPS_GENERIC || COMPILE_TEST
@@ -33,6 +42,7 @@ config SOC_BRCMSTB
 
 	  If unsure, say N.
 
+source "drivers/soc/bcm/bcm63xx/Kconfig"
 source "drivers/soc/bcm/brcmstb/Kconfig"
 
 endmenu
diff --git a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile
index d92268a829a9..7bc90e0bd773 100644
--- a/drivers/soc/bcm/Makefile
+++ b/drivers/soc/bcm/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_BCM2835_POWER)	+= bcm2835-power.o
 obj-$(CONFIG_RASPBERRYPI_POWER)	+= raspberrypi-power.o
+obj-$(CONFIG_SOC_BCM63XX)	+= bcm63xx/
 obj-$(CONFIG_SOC_BRCMSTB)	+= brcmstb/
diff --git a/drivers/soc/bcm/bcm63xx/Kconfig b/drivers/soc/bcm/bcm63xx/Kconfig
new file mode 100644
index 000000000000..16f648a6c70a
--- /dev/null
+++ b/drivers/soc/bcm/bcm63xx/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+if SOC_BCM63XX
+
+config BCM63XX_POWER
+	bool "BCM63xx power domain driver"
+	depends on BMIPS_GENERIC || (COMPILE_TEST && OF)
+	select PM_GENERIC_DOMAINS if PM
+	help
+	  This enables support for the BCM63xx power domains controller on
+	  BCM6318, BCM6328, BCM6362 and BCM63268 SoCs.
+
+endif # SOC_BCM63XX
diff --git a/drivers/soc/bcm/bcm63xx/Makefile b/drivers/soc/bcm/bcm63xx/Makefile
new file mode 100644
index 000000000000..0710d5e018cc
--- /dev/null
+++ b/drivers/soc/bcm/bcm63xx/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_BCM63XX_POWER) += bcm63xx-power.o
diff --git a/drivers/soc/bcm/bcm63xx/bcm63xx-power.c b/drivers/soc/bcm/bcm63xx/bcm63xx-power.c
new file mode 100644
index 000000000000..b6e51b721f09
--- /dev/null
+++ b/drivers/soc/bcm/bcm63xx/bcm63xx-power.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * BCM63xx Power Domain Controller Driver
+ *
+ * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+struct bcm63xx_power_dev {
+	struct generic_pm_domain genpd;
+	struct bcm63xx_power *power;
+	uint32_t mask;
+};
+
+struct bcm63xx_power {
+	void __iomem *base;
+	spinlock_t lock;
+	struct bcm63xx_power_dev *dev;
+	struct genpd_onecell_data genpd_data;
+	struct generic_pm_domain **genpd;
+};
+
+struct bcm63xx_power_data {
+	const char * const name;
+	uint8_t bit;
+	unsigned int flags;
+};
+
+static int bcm63xx_power_get_state(struct bcm63xx_power_dev *pmd, bool *is_on)
+{
+	struct bcm63xx_power *power = pmd->power;
+
+	if (!pmd->mask) {
+		*is_on = false;
+		return -EINVAL;
+	}
+
+	*is_on = !(__raw_readl(power->base) & pmd->mask);
+
+	return 0;
+}
+
+static int bcm63xx_power_set_state(struct bcm63xx_power_dev *pmd, bool on)
+{
+	struct bcm63xx_power *power = pmd->power;
+	unsigned long flags;
+	uint32_t val;
+
+	if (!pmd->mask)
+		return -EINVAL;
+
+	spin_lock_irqsave(&power->lock, flags);
+	val = __raw_readl(power->base);
+	if (on)
+		val &= ~pmd->mask;
+	else
+		val |= pmd->mask;
+	__raw_writel(val, power->base);
+	spin_unlock_irqrestore(&power->lock, flags);
+
+	return 0;
+}
+
+static int bcm63xx_power_on(struct generic_pm_domain *genpd)
+{
+	struct bcm63xx_power_dev *pmd = container_of(genpd,
+		struct bcm63xx_power_dev, genpd);
+
+	return bcm63xx_power_set_state(pmd, true);
+}
+
+static int bcm63xx_power_off(struct generic_pm_domain *genpd)
+{
+	struct bcm63xx_power_dev *pmd = container_of(genpd,
+		struct bcm63xx_power_dev, genpd);
+
+	return bcm63xx_power_set_state(pmd, false);
+}
+
+static int bcm63xx_power_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct resource *res;
+	const struct bcm63xx_power_data *entry, *table;
+	struct bcm63xx_power *power;
+	unsigned int ndom;
+	uint8_t max_bit = 0;
+	int ret;
+
+	power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL);
+	if (!power)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	power->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(power->base))
+		return PTR_ERR(power->base);
+
+	table = of_device_get_match_data(dev);
+	if (!table)
+		return -EINVAL;
+
+	power->genpd_data.num_domains = 0;
+	ndom = 0;
+	for (entry = table; entry->name; entry++) {
+		max_bit = max(max_bit, entry->bit);
+		ndom++;
+	}
+
+	if (!ndom)
+		return -ENODEV;
+
+	power->genpd_data.num_domains = max_bit + 1;
+
+	power->dev = devm_kcalloc(dev, power->genpd_data.num_domains,
+				  sizeof(struct bcm63xx_power_dev),
+				  GFP_KERNEL);
+	if (!power->dev)
+		return -ENOMEM;
+
+	power->genpd = devm_kcalloc(dev, power->genpd_data.num_domains,
+				    sizeof(struct generic_pm_domain *),
+				    GFP_KERNEL);
+	if (!power->genpd)
+		return -ENOMEM;
+
+	power->genpd_data.domains = power->genpd;
+
+	ndom = 0;
+	for (entry = table; entry->name; entry++) {
+		struct bcm63xx_power_dev *pmd = &power->dev[ndom];
+		bool is_on;
+
+		pmd->power = power;
+		pmd->mask = BIT(entry->bit);
+		pmd->genpd.name = entry->name;
+		pmd->genpd.flags = entry->flags;
+
+		ret = bcm63xx_power_get_state(pmd, &is_on);
+		if (ret)
+			dev_warn(dev, "unable to get current state for %s\n",
+				 pmd->genpd.name);
+
+		pmd->genpd.power_on = bcm63xx_power_on;
+		pmd->genpd.power_off = bcm63xx_power_off;
+
+		pm_genpd_init(&pmd->genpd, NULL, !is_on);
+		power->genpd[entry->bit] = &pmd->genpd;
+
+		ndom++;
+	}
+
+	spin_lock_init(&power->lock);
+
+	ret = of_genpd_add_provider_onecell(np, &power->genpd_data);
+	if (ret) {
+		dev_err(dev, "failed to register genpd driver: %d\n", ret);
+		return ret;
+	}
+
+	dev_info(dev, "registered %u power domains\n", ndom);
+
+	return 0;
+}
+
+static const struct bcm63xx_power_data bcm6318_power_domains[] = {
+	{
+		.name = "pcie",
+		.bit = 0,
+	}, {
+		.name = "usb",
+		.bit = 1,
+	}, {
+		.name = "ephy0",
+		.bit = 2,
+	}, {
+		.name = "ephy1",
+		.bit = 3,
+	}, {
+		.name = "ephy2",
+		.bit = 4,
+	}, {
+		.name = "ephy3",
+		.bit = 5,
+	}, {
+		.name = "ldo2p5",
+		.bit = 6,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "ldo2p9",
+		.bit = 7,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "sw1p0",
+		.bit = 8,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "pad",
+		.bit = 9,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		/* sentinel */
+	},
+};
+
+static const struct bcm63xx_power_data bcm6328_power_domains[] = {
+	{
+		.name = "adsl2-mips",
+		.bit = 0,
+	}, {
+		.name = "adsl2-phy",
+		.bit = 1,
+	}, {
+		.name = "adsl2-afe",
+		.bit = 2,
+	}, {
+		.name = "sar",
+		.bit = 3,
+	}, {
+		.name = "pcm",
+		.bit = 4,
+	}, {
+		.name = "usbd",
+		.bit = 5,
+	}, {
+		.name = "usbh",
+		.bit = 6,
+	}, {
+		.name = "pcie",
+		.bit = 7,
+	}, {
+		.name = "robosw",
+		.bit = 8,
+	}, {
+		.name = "ephy",
+		.bit = 9,
+	}, {
+		/* sentinel */
+	},
+};
+
+static const struct bcm63xx_power_data bcm6362_power_domains[] = {
+	{
+		.name = "sar",
+		.bit = 0,
+	}, {
+		.name = "ipsec",
+		.bit = 1,
+	}, {
+		.name = "mips",
+		.bit = 2,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "dect",
+		.bit = 3,
+	}, {
+		.name = "usbh",
+		.bit = 4,
+	}, {
+		.name = "usbd",
+		.bit = 5,
+	}, {
+		.name = "robosw",
+		.bit = 6,
+	}, {
+		.name = "pcm",
+		.bit = 7,
+	}, {
+		.name = "periph",
+		.bit = 8,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "adsl-phy",
+		.bit = 9,
+	}, {
+		.name = "gmii-pads",
+		.bit = 10,
+	}, {
+		.name = "fap",
+		.bit = 11,
+	}, {
+		.name = "pcie",
+		.bit = 12,
+	}, {
+		.name = "wlan-pads",
+		.bit = 13,
+	}, {
+		/* sentinel */
+	},
+};
+
+static const struct bcm63xx_power_data bcm63268_power_domains[] = {
+	{
+		.name = "sar",
+		.bit = 0,
+	}, {
+		.name = "ipsec",
+		.bit = 1,
+	}, {
+		.name = "mips",
+		.bit = 2,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "dect",
+		.bit = 3,
+	}, {
+		.name = "usbh",
+		.bit = 4,
+	}, {
+		.name = "usbd",
+		.bit = 5,
+	}, {
+		.name = "robosw",
+		.bit = 6,
+	}, {
+		.name = "pcm",
+		.bit = 7,
+	}, {
+		.name = "periph",
+		.bit = 8,
+		.flags = GENPD_FLAG_ALWAYS_ON,
+	}, {
+		.name = "vdsl-phy",
+		.bit = 9,
+	}, {
+		.name = "vdsl-mips",
+		.bit = 10,
+	}, {
+		.name = "fap",
+		.bit = 11,
+	}, {
+		.name = "pcie",
+		.bit = 12,
+	}, {
+		.name = "wlan-pads",
+		.bit = 13,
+	}, {
+		/* sentinel */
+	},
+};
+
+static const struct of_device_id bcm63xx_power_of_match[] = {
+	{
+		.compatible = "brcm,bcm6318-power-controller",
+		.data = &bcm6318_power_domains,
+	}, {
+		.compatible = "brcm,bcm6328-power-controller",
+		.data = &bcm6328_power_domains,
+	}, {
+		.compatible = "brcm,bcm6362-power-controller",
+		.data = &bcm6362_power_domains,
+	}, {
+		.compatible = "brcm,bcm63268-power-controller",
+		.data = &bcm63268_power_domains,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver bcm63xx_power_driver = {
+	.driver = {
+		.name = "bcm63xx-power-controller",
+		.of_match_table = bcm63xx_power_of_match,
+	},
+	.probe  = bcm63xx_power_probe,
+};
+builtin_platform_driver(bcm63xx_power_driver);
-- 
2.26.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2020-06-10 16:33 UTC|newest]

Thread overview: 116+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-09 10:52 [PATCH 0/4] bmips: add BCM63xx power domain controller Álvaro Fernández Rojas
2020-06-09 10:52 ` Álvaro Fernández Rojas
2020-06-09 10:52 ` [PATCH 1/4] dt-bindings: soc: brcm: add BCM63xx power domain binding Álvaro Fernández Rojas
2020-06-09 10:52   ` Álvaro Fernández Rojas
2020-06-10  1:15   ` Florian Fainelli
2020-06-10  1:15     ` Florian Fainelli
2020-06-10  6:03     ` Álvaro Fernández Rojas
2020-06-10  6:03       ` Álvaro Fernández Rojas
2020-06-09 10:52 ` [PATCH 2/4] soc: bcm: add BCM63xx power domain driver Álvaro Fernández Rojas
2020-06-09 10:52   ` Álvaro Fernández Rojas
2020-06-10  2:19   ` Florian Fainelli
2020-06-10  2:19     ` Florian Fainelli
2020-06-09 10:52 ` [PATCH 3/4] mips: bmips: dts: add BCM6328 power domain support Álvaro Fernández Rojas
2020-06-09 10:52   ` Álvaro Fernández Rojas
2020-06-10  1:12   ` Florian Fainelli
2020-06-10  1:12     ` Florian Fainelli
2020-06-09 10:52 ` [PATCH 4/4] mips: bmips: dts: add BCM6362 " Álvaro Fernández Rojas
2020-06-09 10:52   ` Álvaro Fernández Rojas
2020-06-10  2:21   ` Florian Fainelli
2020-06-10  2:21     ` Florian Fainelli
2020-06-10  2:27   ` Florian Fainelli
2020-06-10  2:27     ` Florian Fainelli
2020-06-10 16:32 ` [PATCH v2 0/6] bmips: add BCM63xx power domain controller Álvaro Fernández Rojas
2020-06-10 16:32   ` Álvaro Fernández Rojas
2020-06-10 16:32   ` [PATCH v2 1/6] dt-bindings: soc: brcm: add BCM63xx power domain binding Álvaro Fernández Rojas
2020-06-10 16:32     ` Álvaro Fernández Rojas
2020-06-10 16:44     ` Florian Fainelli
2020-06-10 16:44       ` Florian Fainelli
2020-06-10 16:32   ` Álvaro Fernández Rojas [this message]
2020-06-10 16:32     ` [PATCH v2 2/6] soc: bcm: add BCM63xx power domain driver Álvaro Fernández Rojas
2020-06-10 16:49     ` Florian Fainelli
2020-06-10 16:49       ` Florian Fainelli
2020-06-10 16:32   ` [PATCH v2 3/6] mips: bmips: dts: add BCM6328 power domain support Álvaro Fernández Rojas
2020-06-10 16:32     ` Álvaro Fernández Rojas
2020-06-10 16:32   ` [PATCH v2 4/6] mips: bmips: dts: add BCM6362 " Álvaro Fernández Rojas
2020-06-10 16:32     ` Álvaro Fernández Rojas
2020-06-10 16:33   ` [PATCH v2 5/6] mips: bmips: dts: add BCM63268 " Álvaro Fernández Rojas
2020-06-10 16:33     ` Álvaro Fernández Rojas
2020-06-10 16:33   ` [PATCH v2 6/6] mips: bmips: add BCM6318 power domain definitions Álvaro Fernández Rojas
2020-06-10 16:33     ` Álvaro Fernández Rojas
2020-06-10 16:49   ` [PATCH v2 0/6] bmips: add BCM63xx power domain controller Florian Fainelli
2020-06-10 16:49     ` Florian Fainelli
2020-06-10 17:16   ` [PATCH v3 0/9] " Álvaro Fernández Rojas
2020-06-10 17:16     ` Álvaro Fernández Rojas
2020-06-10 17:16     ` [PATCH v3 1/9] dt-bindings: soc: brcm: add BCM63xx power domain binding Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-12 21:55       ` Rob Herring
2020-06-12 21:55         ` Rob Herring
2020-06-12 21:56       ` Rob Herring
2020-06-12 21:56         ` Rob Herring
2020-06-10 17:16     ` [PATCH v3 2/9] mips: bmips: dts: add BCM6328 power domain definitions Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-10 17:16     ` [PATCH v3 3/9] mips: bmips: dts: add BCM6362 " Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-10 17:16     ` [PATCH v3 4/9] mips: bmips: dts: add BCM63268 " Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-10 17:16     ` [PATCH v3 5/9] mips: bmips: add BCM6318 " Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-10 17:16     ` [PATCH v3 6/9] soc: bcm: add BCM63xx power domain driver Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-10 17:16     ` [PATCH v3 7/9] mips: bmips: dts: add BCM6328 power domain support Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-10 17:16     ` [PATCH v3 8/9] mips: bmips: dts: add BCM6362 " Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-10 17:16     ` [PATCH v3 9/9] mips: bmips: dts: add BCM63268 " Álvaro Fernández Rojas
2020-06-10 17:16       ` Álvaro Fernández Rojas
2020-06-13  8:21     ` [PATCH v4 0/9] bmips: add BCM63xx power domain controller Álvaro Fernández Rojas
2020-06-13  8:21       ` Álvaro Fernández Rojas
2020-06-13  8:21       ` [PATCH v4 1/9] dt-bindings: soc: brcm: add BCM63xx power domain binding Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-07-09 22:59         ` Rob Herring
2020-07-09 22:59           ` Rob Herring
2020-06-13  8:21       ` [PATCH v4 2/9] mips: bmips: add BCM6328 power domain definitions Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-06-14  4:45         ` Florian Fainelli
2020-06-14  4:45           ` Florian Fainelli
2020-07-09 23:00         ` Rob Herring
2020-07-09 23:00           ` Rob Herring
2020-06-13  8:21       ` [PATCH v4 3/9] mips: bmips: add BCM6362 " Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-06-14  4:46         ` Florian Fainelli
2020-06-14  4:46           ` Florian Fainelli
2020-07-09 23:00         ` Rob Herring
2020-07-09 23:00           ` Rob Herring
2020-06-13  8:21       ` [PATCH v4 4/9] mips: bmips: add BCM63268 " Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-06-14  4:46         ` Florian Fainelli
2020-06-14  4:46           ` Florian Fainelli
2020-07-09 23:01         ` Rob Herring
2020-07-09 23:01           ` Rob Herring
2020-06-13  8:21       ` [PATCH v4 5/9] mips: bmips: add BCM6318 " Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-06-14  4:46         ` Florian Fainelli
2020-06-14  4:46           ` Florian Fainelli
2020-07-09 23:01         ` Rob Herring
2020-07-09 23:01           ` Rob Herring
2020-06-13  8:21       ` [PATCH v4 6/9] soc: bcm: add BCM63xx power domain driver Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-06-14  4:48         ` Florian Fainelli
2020-06-14  4:48           ` Florian Fainelli
2020-06-13  8:21       ` [PATCH v4 7/9] mips: bmips: dts: add BCM6328 power domain support Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-07-23  9:10         ` Thomas Bogendoerfer
2020-07-23  9:10           ` Thomas Bogendoerfer
2020-06-13  8:21       ` [PATCH v4 8/9] mips: bmips: dts: add BCM6362 " Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-07-23  9:10         ` Thomas Bogendoerfer
2020-07-23  9:10           ` Thomas Bogendoerfer
2020-06-13  8:21       ` [PATCH v4 9/9] mips: bmips: dts: add BCM63268 " Álvaro Fernández Rojas
2020-06-13  8:21         ` Álvaro Fernández Rojas
2020-06-14  4:48         ` Florian Fainelli
2020-06-14  4:48           ` Florian Fainelli
2020-07-23  9:10         ` Thomas Bogendoerfer
2020-07-23  9:10           ` Thomas Bogendoerfer
2020-07-24 22:15       ` [PATCH v4 0/9] bmips: add BCM63xx power domain controller Florian Fainelli
2020-07-24 22:15         ` Florian Fainelli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200610163301.461160-3-noltari@gmail.com \
    --to=noltari@gmail.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=devicetree@vger.kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=hauke@hauke-m.de \
    --cc=jonas.gorski@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=tsbogend@alpha.franken.de \
    --cc=zajec5@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.