All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] i.MX6 PU power domain support
@ 2014-02-11 13:27 ` Philipp Zabel
  0 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Philipp Zabel

The i.MX6Q can gate off the CPU and PU (GPU/VPU) power domains using the
Power Gating Controller (PGC) in the GPC register space. The CPU power
domain is already handled by wait state code, but the PU power domain can
be controlled using the generic power domain framework and power off the PU
supply regulator if all devices in the power domain are (runtime) suspended.

This patchset adds a GPC platform device initialized at subsys_initcall time
(after anatop regulators) that binds to the gpc device tree node and sets up
the PU power domain:

	gpc: gpc@020dc000 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "fsl,imx6q-gpc";
		reg = <0x020dc000 0x4000>;
		interrupts = <0 89 0x04 0 90 0x04>;
		pu-supply = <&reg_pu>;

		pd_pu: power-domain@020dc260 {
			compatible = "fsl,power-domain";
			reg = <0x020dc260 0x10>;
		};
	};

It registers a platform bus notifier so that it can add GPU and VPU devices
to the power domain when they are bound. If finds devices to be added to the
power domain by scanning the device tree for nodes that contain a
	power-domain = <&pd_pu>;
property.

For i.MX6QDL there is only one power domain, but on i.MX6SL I suspect the
DISP power domain could be handled using the same mechanism.

regards
Philipp

Philipp Zabel (4):
  ARM: imx6: gpc: Add PU power domain for GPU/VPU
  ARM: imx6: gpc: Add pm clock support to PU power domain
  ARM: dts: imx6qdl: Allow disabling the PU regulator, add a enable ramp
    delay
  ARM: dts: imx6qdl: Add PU power-domain information to gpc node

 arch/arm/boot/dts/imx6qdl.dtsi |  11 +-
 arch/arm/mach-imx/Kconfig      |   2 +
 arch/arm/mach-imx/gpc.c        | 243 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 255 insertions(+), 1 deletion(-)

-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC PATCH 0/4] i.MX6 PU power domain support
@ 2014-02-11 13:27 ` Philipp Zabel
  0 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

The i.MX6Q can gate off the CPU and PU (GPU/VPU) power domains using the
Power Gating Controller (PGC) in the GPC register space. The CPU power
domain is already handled by wait state code, but the PU power domain can
be controlled using the generic power domain framework and power off the PU
supply regulator if all devices in the power domain are (runtime) suspended.

This patchset adds a GPC platform device initialized at subsys_initcall time
(after anatop regulators) that binds to the gpc device tree node and sets up
the PU power domain:

	gpc: gpc at 020dc000 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "fsl,imx6q-gpc";
		reg = <0x020dc000 0x4000>;
		interrupts = <0 89 0x04 0 90 0x04>;
		pu-supply = <&reg_pu>;

		pd_pu: power-domain at 020dc260 {
			compatible = "fsl,power-domain";
			reg = <0x020dc260 0x10>;
		};
	};

It registers a platform bus notifier so that it can add GPU and VPU devices
to the power domain when they are bound. If finds devices to be added to the
power domain by scanning the device tree for nodes that contain a
	power-domain = <&pd_pu>;
property.

For i.MX6QDL there is only one power domain, but on i.MX6SL I suspect the
DISP power domain could be handled using the same mechanism.

regards
Philipp

Philipp Zabel (4):
  ARM: imx6: gpc: Add PU power domain for GPU/VPU
  ARM: imx6: gpc: Add pm clock support to PU power domain
  ARM: dts: imx6qdl: Allow disabling the PU regulator, add a enable ramp
    delay
  ARM: dts: imx6qdl: Add PU power-domain information to gpc node

 arch/arm/boot/dts/imx6qdl.dtsi |  11 +-
 arch/arm/mach-imx/Kconfig      |   2 +
 arch/arm/mach-imx/gpc.c        | 243 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 255 insertions(+), 1 deletion(-)

-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC PATCH 1/4] ARM: imx6: gpc: Add PU power domain for GPU/VPU
  2014-02-11 13:27 ` Philipp Zabel
@ 2014-02-11 13:27     ` Philipp Zabel
  -1 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Philipp Zabel

When generic pm domain support is enabled, the PGC can be used
to completely gate power to the PU power domain containing GPU3D,
GPU2D, and VPU cores.
This code triggers the PGC powerdown sequence to disable the GPU/VPU
isolation cells and gate power and then disables the PU regulator.
To reenable, the reverse powerup sequence is triggered after the PU
regulaotor is enabled again.

Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 arch/arm/mach-imx/Kconfig |   2 +
 arch/arm/mach-imx/gpc.c   | 169 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 171 insertions(+)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 33567aa..3c58f2e 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -808,6 +808,7 @@ config SOC_IMX6Q
 	select PL310_ERRATA_727915 if CACHE_PL310
 	select PL310_ERRATA_769419 if CACHE_PL310
 	select PM_OPP if PM
+	select PM_GENERIC_DOMAINS if PM
 
 	help
 	  This enables support for Freescale i.MX6 Quad processor.
@@ -827,6 +828,7 @@ config SOC_IMX6SL
 	select PL310_ERRATA_588369 if CACHE_PL310
 	select PL310_ERRATA_727915 if CACHE_PL310
 	select PL310_ERRATA_769419 if CACHE_PL310
+	select PM_GENERIC_DOMAINS if PM
 
 	help
 	  This enables support for Freescale i.MX6 SoloLite processor.
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 586e017..c3ec2c5 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -10,19 +10,32 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regulator/consumer.h>
 #include <linux/irqchip/arm-gic.h>
 #include "common.h"
+#include "hardware.h"
 
+#define GPC_CNTR		0x000
 #define GPC_IMR1		0x008
+#define GPC_PGC_GPU_PDN		0x260
+#define GPC_PGC_GPU_PUPSCR	0x264
+#define GPC_PGC_GPU_PDNSCR	0x268
 #define GPC_PGC_CPU_PDN		0x2a0
 
 #define IMR_NUM			4
 
+#define GPU_VPU_PUP_REQ		BIT(1)
+#define GPU_VPU_PDN_REQ		BIT(0)
+
 static void __iomem *gpc_base;
 static u32 gpc_wake_irqs[IMR_NUM];
 static u32 gpc_saved_imrs[IMR_NUM];
@@ -138,3 +151,159 @@ void __init imx_gpc_init(void)
 	gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
 	gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
 }
+
+static struct regulator *pu_reg;
+
+static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
+{
+	u32 val;
+	int iso, iso2sw;
+
+	/* GPU3D, GPU2D, and VPU clocks should be disabled here */
+
+	/* Read ISO and ISO2SW power down delays */
+	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR);
+	iso = val & 0x3f;
+	iso2sw = (val >> 8) & 0x3f;
+
+	/* Gate off PU domain when GPU/VPU when powered down */
+	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
+
+	/* Request GPC to power down GPU/VPU */
+	val = readl_relaxed(gpc_base + GPC_CNTR);
+	val |= GPU_VPU_PDN_REQ;
+	writel_relaxed(val, gpc_base + GPC_CNTR);
+
+	/* Wait ISO + ISO2SW IPG clock cycles */
+	ndelay((iso + iso2sw) * 1000 / 66);
+
+	regulator_disable(pu_reg);
+
+	return 0;
+}
+
+static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
+{
+	int ret;
+	u32 val;
+	int sw, sw2iso;
+
+	ret = regulator_enable(pu_reg);
+	if (ret) {
+		pr_err("%s: failed to enable regulator: %d\n", __func__, ret);
+		return ret;
+	}
+
+	/* Gate off PU domain when GPU/VPU when powered down */
+	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
+
+	/* Read ISO and ISO2SW power down delays */
+	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR);
+	sw = val & 0x3f;
+	sw2iso = (val >> 8) & 0x3f;
+
+	/* Request GPC to power up GPU/VPU */
+	val = readl_relaxed(gpc_base + GPC_CNTR);
+	val |= GPU_VPU_PUP_REQ;
+	writel_relaxed(val, gpc_base + GPC_CNTR);
+
+	/* Wait ISO + ISO2SW IPG clock cycles */
+	ndelay((sw + sw2iso) * 1000 / 66);
+
+	return 0;
+}
+
+static struct generic_pm_domain imx6q_pu_domain = {
+	.name = "PU",
+	.power_off = imx6q_pm_pu_power_off,
+	.power_on = imx6q_pm_pu_power_on,
+};
+
+static int imx6q_pm_notifier_call(struct notifier_block *nb,
+				  unsigned long event, void *data)
+{
+	struct generic_pm_domain *genpd;
+	struct device *dev = data;
+	struct device_node *np;
+	int ret;
+
+	switch (event) {
+	case BUS_NOTIFY_BIND_DRIVER:
+		np = of_parse_phandle(dev->of_node, "power-domain", 0);
+		if (!np)
+			return NOTIFY_DONE;
+
+		ret = pm_genpd_of_add_device(np, dev);
+		if (ret)
+			dev_err(dev, "failed to add to power domain: %d\n",
+				ret);
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		genpd = dev_to_genpd(dev);
+		if (IS_ERR(genpd))
+			return NOTIFY_DONE;
+		ret = pm_genpd_remove_device(genpd, dev);
+		if (ret)
+			dev_err(dev, "failed to remove from power domain: %d\n",
+				ret);
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block imx6q_platform_nb = {
+	.notifier_call = imx6q_pm_notifier_call,
+};
+
+static int imx_gpc_probe(struct platform_device *pdev)
+{
+	struct device_node *np;
+	int ret;
+
+	np = of_get_child_by_name(pdev->dev.of_node, "power-domain");
+	if (!np) {
+		dev_err(&pdev->dev, "missing power-domain node\n");
+		return -EINVAL;
+	}
+
+	pu_reg = devm_regulator_get(&pdev->dev, "pu");
+	if (IS_ERR(pu_reg)) {
+		ret = PTR_ERR(pu_reg);
+		dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret);
+		return ret;
+	}
+
+	/* The regulator is initially enabled */
+	ret = regulator_enable(pu_reg);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to enable pu regulator: %d\n", ret);
+		return ret;
+	}
+
+	imx6q_pu_domain.of_node = np;
+	pm_genpd_init(&imx6q_pu_domain, NULL, false);
+	bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);
+
+	return 0;
+}
+
+static struct of_device_id imx_gpc_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-gpc" },
+	{ }
+};
+
+static struct platform_driver imx_gpc_driver = {
+	.driver = {
+		.name = "imx-gpc",
+		.owner = THIS_MODULE,
+		.of_match_table = imx_gpc_dt_ids,
+	},
+	.probe = imx_gpc_probe,
+};
+
+static int __init imx_pgc_init(void)
+{
+	return platform_driver_register(&imx_gpc_driver);
+}
+subsys_initcall(imx_pgc_init);
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [RFC PATCH 1/4] ARM: imx6: gpc: Add PU power domain for GPU/VPU
@ 2014-02-11 13:27     ` Philipp Zabel
  0 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

When generic pm domain support is enabled, the PGC can be used
to completely gate power to the PU power domain containing GPU3D,
GPU2D, and VPU cores.
This code triggers the PGC powerdown sequence to disable the GPU/VPU
isolation cells and gate power and then disables the PU regulator.
To reenable, the reverse powerup sequence is triggered after the PU
regulaotor is enabled again.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 arch/arm/mach-imx/Kconfig |   2 +
 arch/arm/mach-imx/gpc.c   | 169 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 171 insertions(+)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 33567aa..3c58f2e 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -808,6 +808,7 @@ config SOC_IMX6Q
 	select PL310_ERRATA_727915 if CACHE_PL310
 	select PL310_ERRATA_769419 if CACHE_PL310
 	select PM_OPP if PM
+	select PM_GENERIC_DOMAINS if PM
 
 	help
 	  This enables support for Freescale i.MX6 Quad processor.
@@ -827,6 +828,7 @@ config SOC_IMX6SL
 	select PL310_ERRATA_588369 if CACHE_PL310
 	select PL310_ERRATA_727915 if CACHE_PL310
 	select PL310_ERRATA_769419 if CACHE_PL310
+	select PM_GENERIC_DOMAINS if PM
 
 	help
 	  This enables support for Freescale i.MX6 SoloLite processor.
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 586e017..c3ec2c5 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -10,19 +10,32 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regulator/consumer.h>
 #include <linux/irqchip/arm-gic.h>
 #include "common.h"
+#include "hardware.h"
 
+#define GPC_CNTR		0x000
 #define GPC_IMR1		0x008
+#define GPC_PGC_GPU_PDN		0x260
+#define GPC_PGC_GPU_PUPSCR	0x264
+#define GPC_PGC_GPU_PDNSCR	0x268
 #define GPC_PGC_CPU_PDN		0x2a0
 
 #define IMR_NUM			4
 
+#define GPU_VPU_PUP_REQ		BIT(1)
+#define GPU_VPU_PDN_REQ		BIT(0)
+
 static void __iomem *gpc_base;
 static u32 gpc_wake_irqs[IMR_NUM];
 static u32 gpc_saved_imrs[IMR_NUM];
@@ -138,3 +151,159 @@ void __init imx_gpc_init(void)
 	gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
 	gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
 }
+
+static struct regulator *pu_reg;
+
+static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
+{
+	u32 val;
+	int iso, iso2sw;
+
+	/* GPU3D, GPU2D, and VPU clocks should be disabled here */
+
+	/* Read ISO and ISO2SW power down delays */
+	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR);
+	iso = val & 0x3f;
+	iso2sw = (val >> 8) & 0x3f;
+
+	/* Gate off PU domain when GPU/VPU when powered down */
+	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
+
+	/* Request GPC to power down GPU/VPU */
+	val = readl_relaxed(gpc_base + GPC_CNTR);
+	val |= GPU_VPU_PDN_REQ;
+	writel_relaxed(val, gpc_base + GPC_CNTR);
+
+	/* Wait ISO + ISO2SW IPG clock cycles */
+	ndelay((iso + iso2sw) * 1000 / 66);
+
+	regulator_disable(pu_reg);
+
+	return 0;
+}
+
+static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
+{
+	int ret;
+	u32 val;
+	int sw, sw2iso;
+
+	ret = regulator_enable(pu_reg);
+	if (ret) {
+		pr_err("%s: failed to enable regulator: %d\n", __func__, ret);
+		return ret;
+	}
+
+	/* Gate off PU domain when GPU/VPU when powered down */
+	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
+
+	/* Read ISO and ISO2SW power down delays */
+	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR);
+	sw = val & 0x3f;
+	sw2iso = (val >> 8) & 0x3f;
+
+	/* Request GPC to power up GPU/VPU */
+	val = readl_relaxed(gpc_base + GPC_CNTR);
+	val |= GPU_VPU_PUP_REQ;
+	writel_relaxed(val, gpc_base + GPC_CNTR);
+
+	/* Wait ISO + ISO2SW IPG clock cycles */
+	ndelay((sw + sw2iso) * 1000 / 66);
+
+	return 0;
+}
+
+static struct generic_pm_domain imx6q_pu_domain = {
+	.name = "PU",
+	.power_off = imx6q_pm_pu_power_off,
+	.power_on = imx6q_pm_pu_power_on,
+};
+
+static int imx6q_pm_notifier_call(struct notifier_block *nb,
+				  unsigned long event, void *data)
+{
+	struct generic_pm_domain *genpd;
+	struct device *dev = data;
+	struct device_node *np;
+	int ret;
+
+	switch (event) {
+	case BUS_NOTIFY_BIND_DRIVER:
+		np = of_parse_phandle(dev->of_node, "power-domain", 0);
+		if (!np)
+			return NOTIFY_DONE;
+
+		ret = pm_genpd_of_add_device(np, dev);
+		if (ret)
+			dev_err(dev, "failed to add to power domain: %d\n",
+				ret);
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		genpd = dev_to_genpd(dev);
+		if (IS_ERR(genpd))
+			return NOTIFY_DONE;
+		ret = pm_genpd_remove_device(genpd, dev);
+		if (ret)
+			dev_err(dev, "failed to remove from power domain: %d\n",
+				ret);
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block imx6q_platform_nb = {
+	.notifier_call = imx6q_pm_notifier_call,
+};
+
+static int imx_gpc_probe(struct platform_device *pdev)
+{
+	struct device_node *np;
+	int ret;
+
+	np = of_get_child_by_name(pdev->dev.of_node, "power-domain");
+	if (!np) {
+		dev_err(&pdev->dev, "missing power-domain node\n");
+		return -EINVAL;
+	}
+
+	pu_reg = devm_regulator_get(&pdev->dev, "pu");
+	if (IS_ERR(pu_reg)) {
+		ret = PTR_ERR(pu_reg);
+		dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret);
+		return ret;
+	}
+
+	/* The regulator is initially enabled */
+	ret = regulator_enable(pu_reg);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to enable pu regulator: %d\n", ret);
+		return ret;
+	}
+
+	imx6q_pu_domain.of_node = np;
+	pm_genpd_init(&imx6q_pu_domain, NULL, false);
+	bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);
+
+	return 0;
+}
+
+static struct of_device_id imx_gpc_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-gpc" },
+	{ }
+};
+
+static struct platform_driver imx_gpc_driver = {
+	.driver = {
+		.name = "imx-gpc",
+		.owner = THIS_MODULE,
+		.of_match_table = imx_gpc_dt_ids,
+	},
+	.probe = imx_gpc_probe,
+};
+
+static int __init imx_pgc_init(void)
+{
+	return platform_driver_register(&imx_gpc_driver);
+}
+subsys_initcall(imx_pgc_init);
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [RFC PATCH 2/4] ARM: imx6: gpc: Add pm clock support to PU power domain
  2014-02-11 13:27 ` Philipp Zabel
@ 2014-02-11 13:27     ` Philipp Zabel
  -1 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Philipp Zabel

Drivers still handle clocks themselves, we only enable pm clocks of the
GPU and VPU devices in the PU power domain temporarily during powerup
so that the reset machinery can work.

Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 arch/arm/mach-imx/gpc.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index c3ec2c5..e3f4492 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -18,6 +18,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
+#include <linux/pm_clock.h>
 #include <linux/pm_domain.h>
 #include <linux/regulator/consumer.h>
 #include <linux/irqchip/arm-gic.h>
@@ -184,6 +185,7 @@ static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
 
 static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
 {
+	struct pm_domain_data *pdd;
 	int ret;
 	u32 val;
 	int sw, sw2iso;
@@ -194,6 +196,10 @@ static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
 		return ret;
 	}
 
+	/* Enable PM clocks for all devices in the PU domain */
+	list_for_each_entry(pdd, &genpd->dev_list, list_node)
+		pm_clk_resume(pdd->dev);
+
 	/* Gate off PU domain when GPU/VPU when powered down */
 	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
 
@@ -210,6 +216,10 @@ static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
 	/* Wait ISO + ISO2SW IPG clock cycles */
 	ndelay((sw + sw2iso) * 1000 / 66);
 
+	/* Disable PM clocks for all devices in the PU domain */
+	list_for_each_entry(pdd, &genpd->dev_list, list_node)
+		pm_clk_suspend(pdd->dev);
+
 	return 0;
 }
 
@@ -219,6 +229,68 @@ static struct generic_pm_domain imx6q_pu_domain = {
 	.power_on = imx6q_pm_pu_power_on,
 };
 
+int imx6q_pm_clk_add(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	const char *con_id;
+	struct clk *clk;
+	int i = 0;
+
+	/* Add and prepare named clocks */
+	while (!of_property_read_string_index(np, "clock-names", i, &con_id)) {
+		pm_clk_add(dev, con_id);
+		clk = of_clk_get(np, i);
+		if (!IS_ERR(clk)) {
+			clk_prepare(clk);
+			clk_put(clk);
+		}
+		i++;
+	}
+
+	/* If no named clocks are given, add and prepare unnamed clock */
+	if (i == 1 && of_find_property(dev->of_node, "clocks", NULL)) {
+		pm_clk_add(dev, NULL);
+		clk = of_clk_get(np, 0);
+		if (!IS_ERR(clk)) {
+			clk_prepare(clk);
+			clk_put(clk);
+		}
+	}
+
+	return 0;
+}
+
+int imx6q_pm_clk_remove(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	const char *con_id;
+	struct clk *clk;
+	int i = 0;
+
+	/* Remove and unprepare named clocks */
+	while (!of_property_read_string_index(np, "clock-names", i, &con_id)) {
+		pm_clk_remove(dev, con_id);
+		clk = of_clk_get(np, i);
+		if (!IS_ERR(clk)) {
+			clk_unprepare(clk);
+			clk_put(clk);
+		}
+		i++;
+	}
+
+	/* If no named clocks are given, remove and unprepare unnamed clock */
+	if (i == 1 && of_find_property(dev->of_node, "clocks", NULL)) {
+		pm_clk_remove(dev, NULL);
+		clk = of_clk_get(np, 0);
+		if (!IS_ERR(clk)) {
+			clk_unprepare(clk);
+			clk_put(clk);
+		}
+	}
+
+	return 0;
+}
+
 static int imx6q_pm_notifier_call(struct notifier_block *nb,
 				  unsigned long event, void *data)
 {
@@ -237,6 +309,7 @@ static int imx6q_pm_notifier_call(struct notifier_block *nb,
 		if (ret)
 			dev_err(dev, "failed to add to power domain: %d\n",
 				ret);
+		imx6q_pm_clk_add(dev);
 		break;
 	case BUS_NOTIFY_UNBOUND_DRIVER:
 		genpd = dev_to_genpd(dev);
@@ -246,6 +319,7 @@ static int imx6q_pm_notifier_call(struct notifier_block *nb,
 		if (ret)
 			dev_err(dev, "failed to remove from power domain: %d\n",
 				ret);
+		imx6q_pm_clk_remove(dev);
 		break;
 	}
 
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [RFC PATCH 2/4] ARM: imx6: gpc: Add pm clock support to PU power domain
@ 2014-02-11 13:27     ` Philipp Zabel
  0 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

Drivers still handle clocks themselves, we only enable pm clocks of the
GPU and VPU devices in the PU power domain temporarily during powerup
so that the reset machinery can work.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 arch/arm/mach-imx/gpc.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index c3ec2c5..e3f4492 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -18,6 +18,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
+#include <linux/pm_clock.h>
 #include <linux/pm_domain.h>
 #include <linux/regulator/consumer.h>
 #include <linux/irqchip/arm-gic.h>
@@ -184,6 +185,7 @@ static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
 
 static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
 {
+	struct pm_domain_data *pdd;
 	int ret;
 	u32 val;
 	int sw, sw2iso;
@@ -194,6 +196,10 @@ static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
 		return ret;
 	}
 
+	/* Enable PM clocks for all devices in the PU domain */
+	list_for_each_entry(pdd, &genpd->dev_list, list_node)
+		pm_clk_resume(pdd->dev);
+
 	/* Gate off PU domain when GPU/VPU when powered down */
 	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
 
@@ -210,6 +216,10 @@ static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
 	/* Wait ISO + ISO2SW IPG clock cycles */
 	ndelay((sw + sw2iso) * 1000 / 66);
 
+	/* Disable PM clocks for all devices in the PU domain */
+	list_for_each_entry(pdd, &genpd->dev_list, list_node)
+		pm_clk_suspend(pdd->dev);
+
 	return 0;
 }
 
@@ -219,6 +229,68 @@ static struct generic_pm_domain imx6q_pu_domain = {
 	.power_on = imx6q_pm_pu_power_on,
 };
 
+int imx6q_pm_clk_add(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	const char *con_id;
+	struct clk *clk;
+	int i = 0;
+
+	/* Add and prepare named clocks */
+	while (!of_property_read_string_index(np, "clock-names", i, &con_id)) {
+		pm_clk_add(dev, con_id);
+		clk = of_clk_get(np, i);
+		if (!IS_ERR(clk)) {
+			clk_prepare(clk);
+			clk_put(clk);
+		}
+		i++;
+	}
+
+	/* If no named clocks are given, add and prepare unnamed clock */
+	if (i == 1 && of_find_property(dev->of_node, "clocks", NULL)) {
+		pm_clk_add(dev, NULL);
+		clk = of_clk_get(np, 0);
+		if (!IS_ERR(clk)) {
+			clk_prepare(clk);
+			clk_put(clk);
+		}
+	}
+
+	return 0;
+}
+
+int imx6q_pm_clk_remove(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	const char *con_id;
+	struct clk *clk;
+	int i = 0;
+
+	/* Remove and unprepare named clocks */
+	while (!of_property_read_string_index(np, "clock-names", i, &con_id)) {
+		pm_clk_remove(dev, con_id);
+		clk = of_clk_get(np, i);
+		if (!IS_ERR(clk)) {
+			clk_unprepare(clk);
+			clk_put(clk);
+		}
+		i++;
+	}
+
+	/* If no named clocks are given, remove and unprepare unnamed clock */
+	if (i == 1 && of_find_property(dev->of_node, "clocks", NULL)) {
+		pm_clk_remove(dev, NULL);
+		clk = of_clk_get(np, 0);
+		if (!IS_ERR(clk)) {
+			clk_unprepare(clk);
+			clk_put(clk);
+		}
+	}
+
+	return 0;
+}
+
 static int imx6q_pm_notifier_call(struct notifier_block *nb,
 				  unsigned long event, void *data)
 {
@@ -237,6 +309,7 @@ static int imx6q_pm_notifier_call(struct notifier_block *nb,
 		if (ret)
 			dev_err(dev, "failed to add to power domain: %d\n",
 				ret);
+		imx6q_pm_clk_add(dev);
 		break;
 	case BUS_NOTIFY_UNBOUND_DRIVER:
 		genpd = dev_to_genpd(dev);
@@ -246,6 +319,7 @@ static int imx6q_pm_notifier_call(struct notifier_block *nb,
 		if (ret)
 			dev_err(dev, "failed to remove from power domain: %d\n",
 				ret);
+		imx6q_pm_clk_remove(dev);
 		break;
 	}
 
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [RFC PATCH 3/4] ARM: dts: imx6qdl: Allow disabling the PU regulator, add a enable ramp delay
  2014-02-11 13:27 ` Philipp Zabel
@ 2014-02-11 13:27     ` Philipp Zabel
  -1 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Philipp Zabel

The PU regulator is enabled during boot, but not necessarily always-on.
It can be disabled by the generic pm domain framework when the PU power
domain is shut down. The ramp delay of 150 us might be a bit conservative,
the value is taken from the Freescale kernel.

Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index fb28b2e..253d82c 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -515,7 +515,8 @@
 					regulator-name = "vddpu";
 					regulator-min-microvolt = <725000>;
 					regulator-max-microvolt = <1450000>;
-					regulator-always-on;
+					regulator-enable-ramp-delay = <150>;
+					regulator-boot-on;
 					anatop-reg-offset = <0x140>;
 					anatop-vol-bit-shift = <9>;
 					anatop-vol-bit-width = <5>;
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [RFC PATCH 3/4] ARM: dts: imx6qdl: Allow disabling the PU regulator, add a enable ramp delay
@ 2014-02-11 13:27     ` Philipp Zabel
  0 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

The PU regulator is enabled during boot, but not necessarily always-on.
It can be disabled by the generic pm domain framework when the PU power
domain is shut down. The ramp delay of 150 us might be a bit conservative,
the value is taken from the Freescale kernel.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index fb28b2e..253d82c 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -515,7 +515,8 @@
 					regulator-name = "vddpu";
 					regulator-min-microvolt = <725000>;
 					regulator-max-microvolt = <1450000>;
-					regulator-always-on;
+					regulator-enable-ramp-delay = <150>;
+					regulator-boot-on;
 					anatop-reg-offset = <0x140>;
 					anatop-vol-bit-shift = <9>;
 					anatop-vol-bit-width = <5>;
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node
  2014-02-11 13:27 ` Philipp Zabel
@ 2014-02-11 13:27     ` Philipp Zabel
  -1 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Philipp Zabel

The PGC that is part of GPC controls isolation and power sequencing of the
PU power domain. The power domain will be handled by the generic pm domain
framework and needs a phandle to the PU regulator to turn off power when
the domain is disabled.

Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 253d82c..595750d 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -598,9 +598,17 @@
 			};
 
 			gpc: gpc@020dc000 {
+				#address-cells = <1>;
+				#size-cells = <1>;
 				compatible = "fsl,imx6q-gpc";
 				reg = <0x020dc000 0x4000>;
 				interrupts = <0 89 0x04 0 90 0x04>;
+				pu-supply = <&reg_pu>;
+
+				pd_pu: power-domain@020dc260 {
+					compatible = "fsl,power-domain";
+					reg = <0x020dc260 0x10>;
+				};
 			};
 
 			gpr: iomuxc-gpr@020e0000 {
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node
@ 2014-02-11 13:27     ` Philipp Zabel
  0 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-11 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

The PGC that is part of GPC controls isolation and power sequencing of the
PU power domain. The power domain will be handled by the generic pm domain
framework and needs a phandle to the PU regulator to turn off power when
the domain is disabled.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 253d82c..595750d 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -598,9 +598,17 @@
 			};
 
 			gpc: gpc at 020dc000 {
+				#address-cells = <1>;
+				#size-cells = <1>;
 				compatible = "fsl,imx6q-gpc";
 				reg = <0x020dc000 0x4000>;
 				interrupts = <0 89 0x04 0 90 0x04>;
+				pu-supply = <&reg_pu>;
+
+				pd_pu: power-domain at 020dc260 {
+					compatible = "fsl,power-domain";
+					reg = <0x020dc260 0x10>;
+				};
 			};
 
 			gpr: iomuxc-gpr at 020e0000 {
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [RFC PATCH 1/4] ARM: imx6: gpc: Add PU power domain for GPU/VPU
  2014-02-11 13:27     ` Philipp Zabel
@ 2014-02-12  7:17         ` Shawn Guo
  -1 siblings, 0 replies; 22+ messages in thread
From: Shawn Guo @ 2014-02-12  7:17 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Tue, Feb 11, 2014 at 02:27:08PM +0100, Philipp Zabel wrote:
> When generic pm domain support is enabled, the PGC can be used
> to completely gate power to the PU power domain containing GPU3D,
> GPU2D, and VPU cores.
> This code triggers the PGC powerdown sequence to disable the GPU/VPU
> isolation cells and gate power and then disables the PU regulator.
> To reenable, the reverse powerup sequence is triggered after the PU
> regulaotor is enabled again.
> 
> Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> ---
>  arch/arm/mach-imx/Kconfig |   2 +
>  arch/arm/mach-imx/gpc.c   | 169 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 171 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 33567aa..3c58f2e 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -808,6 +808,7 @@ config SOC_IMX6Q
>  	select PL310_ERRATA_727915 if CACHE_PL310
>  	select PL310_ERRATA_769419 if CACHE_PL310
>  	select PM_OPP if PM
> +	select PM_GENERIC_DOMAINS if PM
>  
>  	help
>  	  This enables support for Freescale i.MX6 Quad processor.
> @@ -827,6 +828,7 @@ config SOC_IMX6SL
>  	select PL310_ERRATA_588369 if CACHE_PL310
>  	select PL310_ERRATA_727915 if CACHE_PL310
>  	select PL310_ERRATA_769419 if CACHE_PL310
> +	select PM_GENERIC_DOMAINS if PM
>  
>  	help
>  	  This enables support for Freescale i.MX6 SoloLite processor.
> diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
> index 586e017..c3ec2c5 100644
> --- a/arch/arm/mach-imx/gpc.c
> +++ b/arch/arm/mach-imx/gpc.c
> @@ -10,19 +10,32 @@
>   * http://www.gnu.org/copyleft/gpl.html
>   */
>  
> +#include <linux/clk.h>
> +#include <linux/delay.h>
>  #include <linux/io.h>
>  #include <linux/irq.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/regulator/consumer.h>
>  #include <linux/irqchip/arm-gic.h>
>  #include "common.h"
> +#include "hardware.h"
>  
> +#define GPC_CNTR		0x000
>  #define GPC_IMR1		0x008
> +#define GPC_PGC_GPU_PDN		0x260
> +#define GPC_PGC_GPU_PUPSCR	0x264
> +#define GPC_PGC_GPU_PDNSCR	0x268
>  #define GPC_PGC_CPU_PDN		0x2a0
>  
>  #define IMR_NUM			4
>  
> +#define GPU_VPU_PUP_REQ		BIT(1)
> +#define GPU_VPU_PDN_REQ		BIT(0)
> +
>  static void __iomem *gpc_base;
>  static u32 gpc_wake_irqs[IMR_NUM];
>  static u32 gpc_saved_imrs[IMR_NUM];
> @@ -138,3 +151,159 @@ void __init imx_gpc_init(void)
>  	gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
>  	gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
>  }
> +
> +static struct regulator *pu_reg;
> +
> +static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
> +{
> +	u32 val;
> +	int iso, iso2sw;
> +
> +	/* GPU3D, GPU2D, and VPU clocks should be disabled here */

The comment should be dropped?

> +
> +	/* Read ISO and ISO2SW power down delays */
> +	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR);
> +	iso = val & 0x3f;
> +	iso2sw = (val >> 8) & 0x3f;
> +
> +	/* Gate off PU domain when GPU/VPU when powered down */
> +	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
> +
> +	/* Request GPC to power down GPU/VPU */
> +	val = readl_relaxed(gpc_base + GPC_CNTR);
> +	val |= GPU_VPU_PDN_REQ;
> +	writel_relaxed(val, gpc_base + GPC_CNTR);
> +
> +	/* Wait ISO + ISO2SW IPG clock cycles */
> +	ndelay((iso + iso2sw) * 1000 / 66);
> +
> +	regulator_disable(pu_reg);
> +
> +	return 0;
> +}
> +
> +static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
> +{
> +	int ret;
> +	u32 val;
> +	int sw, sw2iso;
> +
> +	ret = regulator_enable(pu_reg);
> +	if (ret) {
> +		pr_err("%s: failed to enable regulator: %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	/* Gate off PU domain when GPU/VPU when powered down */
> +	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
> +
> +	/* Read ISO and ISO2SW power down delays */
> +	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR);
> +	sw = val & 0x3f;
> +	sw2iso = (val >> 8) & 0x3f;
> +
> +	/* Request GPC to power up GPU/VPU */
> +	val = readl_relaxed(gpc_base + GPC_CNTR);
> +	val |= GPU_VPU_PUP_REQ;
> +	writel_relaxed(val, gpc_base + GPC_CNTR);
> +
> +	/* Wait ISO + ISO2SW IPG clock cycles */
> +	ndelay((sw + sw2iso) * 1000 / 66);
> +
> +	return 0;
> +}
> +
> +static struct generic_pm_domain imx6q_pu_domain = {
> +	.name = "PU",
> +	.power_off = imx6q_pm_pu_power_off,
> +	.power_on = imx6q_pm_pu_power_on,
> +};
> +
> +static int imx6q_pm_notifier_call(struct notifier_block *nb,
> +				  unsigned long event, void *data)
> +{
> +	struct generic_pm_domain *genpd;
> +	struct device *dev = data;
> +	struct device_node *np;
> +	int ret;
> +
> +	switch (event) {
> +	case BUS_NOTIFY_BIND_DRIVER:
> +		np = of_parse_phandle(dev->of_node, "power-domain", 0);
> +		if (!np)
> +			return NOTIFY_DONE;
> +
> +		ret = pm_genpd_of_add_device(np, dev);
> +		if (ret)
> +			dev_err(dev, "failed to add to power domain: %d\n",
> +				ret);
> +		break;
> +	case BUS_NOTIFY_UNBOUND_DRIVER:
> +		genpd = dev_to_genpd(dev);
> +		if (IS_ERR(genpd))
> +			return NOTIFY_DONE;
> +		ret = pm_genpd_remove_device(genpd, dev);
> +		if (ret)
> +			dev_err(dev, "failed to remove from power domain: %d\n",
> +				ret);
> +		break;
> +	}
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block imx6q_platform_nb = {
> +	.notifier_call = imx6q_pm_notifier_call,
> +};
> +
> +static int imx_gpc_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np;
> +	int ret;
> +
> +	np = of_get_child_by_name(pdev->dev.of_node, "power-domain");
> +	if (!np) {
> +		dev_err(&pdev->dev, "missing power-domain node\n");
> +		return -EINVAL;
> +	}
> +
> +	pu_reg = devm_regulator_get(&pdev->dev, "pu");
> +	if (IS_ERR(pu_reg)) {
> +		ret = PTR_ERR(pu_reg);
> +		dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* The regulator is initially enabled */
> +	ret = regulator_enable(pu_reg);

That means the PU power domain will be always on when neither GPU nor
VPU is enabled?

Shawn

> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to enable pu regulator: %d\n", ret);
> +		return ret;
> +	}
> +
> +	imx6q_pu_domain.of_node = np;
> +	pm_genpd_init(&imx6q_pu_domain, NULL, false);
> +	bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);
> +
> +	return 0;
> +}
> +
> +static struct of_device_id imx_gpc_dt_ids[] = {
> +	{ .compatible = "fsl,imx6q-gpc" },
> +	{ }
> +};
> +
> +static struct platform_driver imx_gpc_driver = {
> +	.driver = {
> +		.name = "imx-gpc",
> +		.owner = THIS_MODULE,
> +		.of_match_table = imx_gpc_dt_ids,
> +	},
> +	.probe = imx_gpc_probe,
> +};
> +
> +static int __init imx_pgc_init(void)
> +{
> +	return platform_driver_register(&imx_gpc_driver);
> +}
> +subsys_initcall(imx_pgc_init);
> -- 
> 1.8.5.3
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC PATCH 1/4] ARM: imx6: gpc: Add PU power domain for GPU/VPU
@ 2014-02-12  7:17         ` Shawn Guo
  0 siblings, 0 replies; 22+ messages in thread
From: Shawn Guo @ 2014-02-12  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 11, 2014 at 02:27:08PM +0100, Philipp Zabel wrote:
> When generic pm domain support is enabled, the PGC can be used
> to completely gate power to the PU power domain containing GPU3D,
> GPU2D, and VPU cores.
> This code triggers the PGC powerdown sequence to disable the GPU/VPU
> isolation cells and gate power and then disables the PU regulator.
> To reenable, the reverse powerup sequence is triggered after the PU
> regulaotor is enabled again.
> 
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
>  arch/arm/mach-imx/Kconfig |   2 +
>  arch/arm/mach-imx/gpc.c   | 169 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 171 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 33567aa..3c58f2e 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -808,6 +808,7 @@ config SOC_IMX6Q
>  	select PL310_ERRATA_727915 if CACHE_PL310
>  	select PL310_ERRATA_769419 if CACHE_PL310
>  	select PM_OPP if PM
> +	select PM_GENERIC_DOMAINS if PM
>  
>  	help
>  	  This enables support for Freescale i.MX6 Quad processor.
> @@ -827,6 +828,7 @@ config SOC_IMX6SL
>  	select PL310_ERRATA_588369 if CACHE_PL310
>  	select PL310_ERRATA_727915 if CACHE_PL310
>  	select PL310_ERRATA_769419 if CACHE_PL310
> +	select PM_GENERIC_DOMAINS if PM
>  
>  	help
>  	  This enables support for Freescale i.MX6 SoloLite processor.
> diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
> index 586e017..c3ec2c5 100644
> --- a/arch/arm/mach-imx/gpc.c
> +++ b/arch/arm/mach-imx/gpc.c
> @@ -10,19 +10,32 @@
>   * http://www.gnu.org/copyleft/gpl.html
>   */
>  
> +#include <linux/clk.h>
> +#include <linux/delay.h>
>  #include <linux/io.h>
>  #include <linux/irq.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/regulator/consumer.h>
>  #include <linux/irqchip/arm-gic.h>
>  #include "common.h"
> +#include "hardware.h"
>  
> +#define GPC_CNTR		0x000
>  #define GPC_IMR1		0x008
> +#define GPC_PGC_GPU_PDN		0x260
> +#define GPC_PGC_GPU_PUPSCR	0x264
> +#define GPC_PGC_GPU_PDNSCR	0x268
>  #define GPC_PGC_CPU_PDN		0x2a0
>  
>  #define IMR_NUM			4
>  
> +#define GPU_VPU_PUP_REQ		BIT(1)
> +#define GPU_VPU_PDN_REQ		BIT(0)
> +
>  static void __iomem *gpc_base;
>  static u32 gpc_wake_irqs[IMR_NUM];
>  static u32 gpc_saved_imrs[IMR_NUM];
> @@ -138,3 +151,159 @@ void __init imx_gpc_init(void)
>  	gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
>  	gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
>  }
> +
> +static struct regulator *pu_reg;
> +
> +static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
> +{
> +	u32 val;
> +	int iso, iso2sw;
> +
> +	/* GPU3D, GPU2D, and VPU clocks should be disabled here */

The comment should be dropped?

> +
> +	/* Read ISO and ISO2SW power down delays */
> +	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR);
> +	iso = val & 0x3f;
> +	iso2sw = (val >> 8) & 0x3f;
> +
> +	/* Gate off PU domain when GPU/VPU when powered down */
> +	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
> +
> +	/* Request GPC to power down GPU/VPU */
> +	val = readl_relaxed(gpc_base + GPC_CNTR);
> +	val |= GPU_VPU_PDN_REQ;
> +	writel_relaxed(val, gpc_base + GPC_CNTR);
> +
> +	/* Wait ISO + ISO2SW IPG clock cycles */
> +	ndelay((iso + iso2sw) * 1000 / 66);
> +
> +	regulator_disable(pu_reg);
> +
> +	return 0;
> +}
> +
> +static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd)
> +{
> +	int ret;
> +	u32 val;
> +	int sw, sw2iso;
> +
> +	ret = regulator_enable(pu_reg);
> +	if (ret) {
> +		pr_err("%s: failed to enable regulator: %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	/* Gate off PU domain when GPU/VPU when powered down */
> +	writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN);
> +
> +	/* Read ISO and ISO2SW power down delays */
> +	val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR);
> +	sw = val & 0x3f;
> +	sw2iso = (val >> 8) & 0x3f;
> +
> +	/* Request GPC to power up GPU/VPU */
> +	val = readl_relaxed(gpc_base + GPC_CNTR);
> +	val |= GPU_VPU_PUP_REQ;
> +	writel_relaxed(val, gpc_base + GPC_CNTR);
> +
> +	/* Wait ISO + ISO2SW IPG clock cycles */
> +	ndelay((sw + sw2iso) * 1000 / 66);
> +
> +	return 0;
> +}
> +
> +static struct generic_pm_domain imx6q_pu_domain = {
> +	.name = "PU",
> +	.power_off = imx6q_pm_pu_power_off,
> +	.power_on = imx6q_pm_pu_power_on,
> +};
> +
> +static int imx6q_pm_notifier_call(struct notifier_block *nb,
> +				  unsigned long event, void *data)
> +{
> +	struct generic_pm_domain *genpd;
> +	struct device *dev = data;
> +	struct device_node *np;
> +	int ret;
> +
> +	switch (event) {
> +	case BUS_NOTIFY_BIND_DRIVER:
> +		np = of_parse_phandle(dev->of_node, "power-domain", 0);
> +		if (!np)
> +			return NOTIFY_DONE;
> +
> +		ret = pm_genpd_of_add_device(np, dev);
> +		if (ret)
> +			dev_err(dev, "failed to add to power domain: %d\n",
> +				ret);
> +		break;
> +	case BUS_NOTIFY_UNBOUND_DRIVER:
> +		genpd = dev_to_genpd(dev);
> +		if (IS_ERR(genpd))
> +			return NOTIFY_DONE;
> +		ret = pm_genpd_remove_device(genpd, dev);
> +		if (ret)
> +			dev_err(dev, "failed to remove from power domain: %d\n",
> +				ret);
> +		break;
> +	}
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block imx6q_platform_nb = {
> +	.notifier_call = imx6q_pm_notifier_call,
> +};
> +
> +static int imx_gpc_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np;
> +	int ret;
> +
> +	np = of_get_child_by_name(pdev->dev.of_node, "power-domain");
> +	if (!np) {
> +		dev_err(&pdev->dev, "missing power-domain node\n");
> +		return -EINVAL;
> +	}
> +
> +	pu_reg = devm_regulator_get(&pdev->dev, "pu");
> +	if (IS_ERR(pu_reg)) {
> +		ret = PTR_ERR(pu_reg);
> +		dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* The regulator is initially enabled */
> +	ret = regulator_enable(pu_reg);

That means the PU power domain will be always on when neither GPU nor
VPU is enabled?

Shawn

> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to enable pu regulator: %d\n", ret);
> +		return ret;
> +	}
> +
> +	imx6q_pu_domain.of_node = np;
> +	pm_genpd_init(&imx6q_pu_domain, NULL, false);
> +	bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);
> +
> +	return 0;
> +}
> +
> +static struct of_device_id imx_gpc_dt_ids[] = {
> +	{ .compatible = "fsl,imx6q-gpc" },
> +	{ }
> +};
> +
> +static struct platform_driver imx_gpc_driver = {
> +	.driver = {
> +		.name = "imx-gpc",
> +		.owner = THIS_MODULE,
> +		.of_match_table = imx_gpc_dt_ids,
> +	},
> +	.probe = imx_gpc_probe,
> +};
> +
> +static int __init imx_pgc_init(void)
> +{
> +	return platform_driver_register(&imx_gpc_driver);
> +}
> +subsys_initcall(imx_pgc_init);
> -- 
> 1.8.5.3
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node
  2014-02-11 13:27     ` Philipp Zabel
@ 2014-02-12  7:25         ` Shawn Guo
  -1 siblings, 0 replies; 22+ messages in thread
From: Shawn Guo @ 2014-02-12  7:25 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Tue, Feb 11, 2014 at 02:27:11PM +0100, Philipp Zabel wrote:
> The PGC that is part of GPC controls isolation and power sequencing of the
> PU power domain. The power domain will be handled by the generic pm domain
> framework and needs a phandle to the PU regulator to turn off power when
> the domain is disabled.
> 
> Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> ---
>  arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> index 253d82c..595750d 100644
> --- a/arch/arm/boot/dts/imx6qdl.dtsi
> +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> @@ -598,9 +598,17 @@
>  			};
>  
>  			gpc: gpc@020dc000 {
> +				#address-cells = <1>;
> +				#size-cells = <1>;
>  				compatible = "fsl,imx6q-gpc";
>  				reg = <0x020dc000 0x4000>;
>  				interrupts = <0 89 0x04 0 90 0x04>;
> +				pu-supply = <&reg_pu>;
> +
> +				pd_pu: power-domain@020dc260 {
> +					compatible = "fsl,power-domain";
> +					reg = <0x020dc260 0x10>;
> +				};

It's time to have a binding doc for gpc/pgc?  And I'm not sure
"fsl,power-domain" is a good compatible as it's so generic.

Shawn

>  			};
>  
>  			gpr: iomuxc-gpr@020e0000 {
> -- 
> 1.8.5.3
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node
@ 2014-02-12  7:25         ` Shawn Guo
  0 siblings, 0 replies; 22+ messages in thread
From: Shawn Guo @ 2014-02-12  7:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 11, 2014 at 02:27:11PM +0100, Philipp Zabel wrote:
> The PGC that is part of GPC controls isolation and power sequencing of the
> PU power domain. The power domain will be handled by the generic pm domain
> framework and needs a phandle to the PU regulator to turn off power when
> the domain is disabled.
> 
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
>  arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> index 253d82c..595750d 100644
> --- a/arch/arm/boot/dts/imx6qdl.dtsi
> +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> @@ -598,9 +598,17 @@
>  			};
>  
>  			gpc: gpc at 020dc000 {
> +				#address-cells = <1>;
> +				#size-cells = <1>;
>  				compatible = "fsl,imx6q-gpc";
>  				reg = <0x020dc000 0x4000>;
>  				interrupts = <0 89 0x04 0 90 0x04>;
> +				pu-supply = <&reg_pu>;
> +
> +				pd_pu: power-domain at 020dc260 {
> +					compatible = "fsl,power-domain";
> +					reg = <0x020dc260 0x10>;
> +				};

It's time to have a binding doc for gpc/pgc?  And I'm not sure
"fsl,power-domain" is a good compatible as it's so generic.

Shawn

>  			};
>  
>  			gpr: iomuxc-gpr at 020e0000 {
> -- 
> 1.8.5.3
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC PATCH 0/4] i.MX6 PU power domain support
  2014-02-11 13:27 ` Philipp Zabel
@ 2014-02-12  7:26     ` Shawn Guo
  -1 siblings, 0 replies; 22+ messages in thread
From: Shawn Guo @ 2014-02-12  7:26 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Tue, Feb 11, 2014 at 02:27:07PM +0100, Philipp Zabel wrote:
> The i.MX6Q can gate off the CPU and PU (GPU/VPU) power domains using the
> Power Gating Controller (PGC) in the GPC register space. The CPU power
> domain is already handled by wait state code, but the PU power domain can
> be controlled using the generic power domain framework and power off the PU
> supply regulator if all devices in the power domain are (runtime) suspended.
> 
> This patchset adds a GPC platform device initialized at subsys_initcall time
> (after anatop regulators) that binds to the gpc device tree node and sets up
> the PU power domain:
> 
> 	gpc: gpc@020dc000 {
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 		compatible = "fsl,imx6q-gpc";
> 		reg = <0x020dc000 0x4000>;
> 		interrupts = <0 89 0x04 0 90 0x04>;
> 		pu-supply = <&reg_pu>;
> 
> 		pd_pu: power-domain@020dc260 {
> 			compatible = "fsl,power-domain";
> 			reg = <0x020dc260 0x10>;
> 		};
> 	};
> 
> It registers a platform bus notifier so that it can add GPU and VPU devices
> to the power domain when they are bound. If finds devices to be added to the
> power domain by scanning the device tree for nodes that contain a
> 	power-domain = <&pd_pu>;
> property.

I replied the individual patches with some small comments, but overall I
like it much.  Thanks for the work!

Shawn

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC PATCH 0/4] i.MX6 PU power domain support
@ 2014-02-12  7:26     ` Shawn Guo
  0 siblings, 0 replies; 22+ messages in thread
From: Shawn Guo @ 2014-02-12  7:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 11, 2014 at 02:27:07PM +0100, Philipp Zabel wrote:
> The i.MX6Q can gate off the CPU and PU (GPU/VPU) power domains using the
> Power Gating Controller (PGC) in the GPC register space. The CPU power
> domain is already handled by wait state code, but the PU power domain can
> be controlled using the generic power domain framework and power off the PU
> supply regulator if all devices in the power domain are (runtime) suspended.
> 
> This patchset adds a GPC platform device initialized at subsys_initcall time
> (after anatop regulators) that binds to the gpc device tree node and sets up
> the PU power domain:
> 
> 	gpc: gpc at 020dc000 {
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 		compatible = "fsl,imx6q-gpc";
> 		reg = <0x020dc000 0x4000>;
> 		interrupts = <0 89 0x04 0 90 0x04>;
> 		pu-supply = <&reg_pu>;
> 
> 		pd_pu: power-domain at 020dc260 {
> 			compatible = "fsl,power-domain";
> 			reg = <0x020dc260 0x10>;
> 		};
> 	};
> 
> It registers a platform bus notifier so that it can add GPU and VPU devices
> to the power domain when they are bound. If finds devices to be added to the
> power domain by scanning the device tree for nodes that contain a
> 	power-domain = <&pd_pu>;
> property.

I replied the individual patches with some small comments, but overall I
like it much.  Thanks for the work!

Shawn

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC PATCH 1/4] ARM: imx6: gpc: Add PU power domain for GPU/VPU
  2014-02-12  7:17         ` Shawn Guo
@ 2014-02-12 10:13             ` Philipp Zabel
  -1 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-12 10:13 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Shawn,

thanks you for the comments.

Am Mittwoch, den 12.02.2014, 15:17 +0800 schrieb Shawn Guo:
> > +static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
> > +{
> > +	u32 val;
> > +	int iso, iso2sw;
> > +
> > +	/* GPU3D, GPU2D, and VPU clocks should be disabled here */
> 
> The comment should be dropped?

Ok.

[...]
> > +static int imx_gpc_probe(struct platform_device *pdev)
> > +{
> > +	struct device_node *np;
> > +	int ret;
> > +
> > +	np = of_get_child_by_name(pdev->dev.of_node, "power-domain");
> > +	if (!np) {
> > +		dev_err(&pdev->dev, "missing power-domain node\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	pu_reg = devm_regulator_get(&pdev->dev, "pu");
> > +	if (IS_ERR(pu_reg)) {
> > +		ret = PTR_ERR(pu_reg);
> > +		dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* The regulator is initially enabled */
> > +	ret = regulator_enable(pu_reg);
> 
> That means the PU power domain will be always on when neither GPU nor
> VPU is enabled?

You are right, if there is no device in the power domain, it will never
be disabled by the genpd framework. Disabling the domain by default
should help:

> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "failed to enable pu regulator: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	imx6q_pu_domain.of_node = np;
> > +	pm_genpd_init(&imx6q_pu_domain, NULL, false);
> > +	bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);

diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 65e0f2c..2fc4ea1 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -356,7 +356,8 @@ static int imx_gpc_probe(struct platform_device
*pdev)
        }
 
        imx6q_pu_domain.of_node = np;
-       pm_genpd_init(&imx6q_pu_domain, NULL, false);
+       imx6q_pm_pu_power_off(&imx6q_pu_domain);
+       pm_genpd_init(&imx6q_pu_domain, NULL, true);
        bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);
 
        return 0;

> > +
> > +	return 0;
> > +}
> > +
> > +static struct of_device_id imx_gpc_dt_ids[] = {
> > +	{ .compatible = "fsl,imx6q-gpc" },
> > +	{ }
> > +};
> > +
> > +static struct platform_driver imx_gpc_driver = {
> > +	.driver = {
> > +		.name = "imx-gpc",
> > +		.owner = THIS_MODULE,
> > +		.of_match_table = imx_gpc_dt_ids,
> > +	},
> > +	.probe = imx_gpc_probe,
> > +};
> > +
> > +static int __init imx_pgc_init(void)
> > +{
> > +	return platform_driver_register(&imx_gpc_driver);
> > +}
> > +subsys_initcall(imx_pgc_init);
> > -- 
> > 1.8.5.3
> > 

regards
Philipp

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [RFC PATCH 1/4] ARM: imx6: gpc: Add PU power domain for GPU/VPU
@ 2014-02-12 10:13             ` Philipp Zabel
  0 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-12 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

thanks you for the comments.

Am Mittwoch, den 12.02.2014, 15:17 +0800 schrieb Shawn Guo:
> > +static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd)
> > +{
> > +	u32 val;
> > +	int iso, iso2sw;
> > +
> > +	/* GPU3D, GPU2D, and VPU clocks should be disabled here */
> 
> The comment should be dropped?

Ok.

[...]
> > +static int imx_gpc_probe(struct platform_device *pdev)
> > +{
> > +	struct device_node *np;
> > +	int ret;
> > +
> > +	np = of_get_child_by_name(pdev->dev.of_node, "power-domain");
> > +	if (!np) {
> > +		dev_err(&pdev->dev, "missing power-domain node\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	pu_reg = devm_regulator_get(&pdev->dev, "pu");
> > +	if (IS_ERR(pu_reg)) {
> > +		ret = PTR_ERR(pu_reg);
> > +		dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* The regulator is initially enabled */
> > +	ret = regulator_enable(pu_reg);
> 
> That means the PU power domain will be always on when neither GPU nor
> VPU is enabled?

You are right, if there is no device in the power domain, it will never
be disabled by the genpd framework. Disabling the domain by default
should help:

> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "failed to enable pu regulator: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	imx6q_pu_domain.of_node = np;
> > +	pm_genpd_init(&imx6q_pu_domain, NULL, false);
> > +	bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);

diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 65e0f2c..2fc4ea1 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -356,7 +356,8 @@ static int imx_gpc_probe(struct platform_device
*pdev)
        }
 
        imx6q_pu_domain.of_node = np;
-       pm_genpd_init(&imx6q_pu_domain, NULL, false);
+       imx6q_pm_pu_power_off(&imx6q_pu_domain);
+       pm_genpd_init(&imx6q_pu_domain, NULL, true);
        bus_register_notifier(&platform_bus_type, &imx6q_platform_nb);
 
        return 0;

> > +
> > +	return 0;
> > +}
> > +
> > +static struct of_device_id imx_gpc_dt_ids[] = {
> > +	{ .compatible = "fsl,imx6q-gpc" },
> > +	{ }
> > +};
> > +
> > +static struct platform_driver imx_gpc_driver = {
> > +	.driver = {
> > +		.name = "imx-gpc",
> > +		.owner = THIS_MODULE,
> > +		.of_match_table = imx_gpc_dt_ids,
> > +	},
> > +	.probe = imx_gpc_probe,
> > +};
> > +
> > +static int __init imx_pgc_init(void)
> > +{
> > +	return platform_driver_register(&imx_gpc_driver);
> > +}
> > +subsys_initcall(imx_pgc_init);
> > -- 
> > 1.8.5.3
> > 

regards
Philipp

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node
  2014-02-12  7:25         ` Shawn Guo
@ 2014-02-12 10:20             ` Philipp Zabel
  -1 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-12 10:20 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA

Am Mittwoch, den 12.02.2014, 15:25 +0800 schrieb Shawn Guo:
> On Tue, Feb 11, 2014 at 02:27:11PM +0100, Philipp Zabel wrote:
> > The PGC that is part of GPC controls isolation and power sequencing of the
> > PU power domain. The power domain will be handled by the generic pm domain
> > framework and needs a phandle to the PU regulator to turn off power when
> > the domain is disabled.
> > 
> > Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> > ---
> >  arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> > index 253d82c..595750d 100644
> > --- a/arch/arm/boot/dts/imx6qdl.dtsi
> > +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> > @@ -598,9 +598,17 @@
> >  			};
> >  
> >  			gpc: gpc@020dc000 {
> > +				#address-cells = <1>;
> > +				#size-cells = <1>;
> >  				compatible = "fsl,imx6q-gpc";
> >  				reg = <0x020dc000 0x4000>;
> >  				interrupts = <0 89 0x04 0 90 0x04>;
> > +				pu-supply = <&reg_pu>;
> > +
> > +				pd_pu: power-domain@020dc260 {
> > +					compatible = "fsl,power-domain";
> > +					reg = <0x020dc260 0x10>;
> > +				};
> 
> It's time to have a binding doc for gpc/pgc?

Yes, I'll add one for the next version.

> And I'm not sure
> "fsl,power-domain" is a good compatible as it's so generic.

fsl,imx6q-power-domain ?

Currently there is no need for a compatible property at all, since this
node is just used as a phandle target.
Even the 0x260 register offset is hardcoded in the driver, but this
might change when imx6sl support is added.

regards
Philipp

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node
@ 2014-02-12 10:20             ` Philipp Zabel
  0 siblings, 0 replies; 22+ messages in thread
From: Philipp Zabel @ 2014-02-12 10:20 UTC (permalink / raw)
  To: linux-arm-kernel

Am Mittwoch, den 12.02.2014, 15:25 +0800 schrieb Shawn Guo:
> On Tue, Feb 11, 2014 at 02:27:11PM +0100, Philipp Zabel wrote:
> > The PGC that is part of GPC controls isolation and power sequencing of the
> > PU power domain. The power domain will be handled by the generic pm domain
> > framework and needs a phandle to the PU regulator to turn off power when
> > the domain is disabled.
> > 
> > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> > ---
> >  arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> > index 253d82c..595750d 100644
> > --- a/arch/arm/boot/dts/imx6qdl.dtsi
> > +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> > @@ -598,9 +598,17 @@
> >  			};
> >  
> >  			gpc: gpc at 020dc000 {
> > +				#address-cells = <1>;
> > +				#size-cells = <1>;
> >  				compatible = "fsl,imx6q-gpc";
> >  				reg = <0x020dc000 0x4000>;
> >  				interrupts = <0 89 0x04 0 90 0x04>;
> > +				pu-supply = <&reg_pu>;
> > +
> > +				pd_pu: power-domain at 020dc260 {
> > +					compatible = "fsl,power-domain";
> > +					reg = <0x020dc260 0x10>;
> > +				};
> 
> It's time to have a binding doc for gpc/pgc?

Yes, I'll add one for the next version.

> And I'm not sure
> "fsl,power-domain" is a good compatible as it's so generic.

fsl,imx6q-power-domain ?

Currently there is no need for a compatible property at all, since this
node is just used as a phandle target.
Even the 0x260 register offset is hardcoded in the driver, but this
might change when imx6sl support is added.

regards
Philipp

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node
  2014-02-12 10:20             ` Philipp Zabel
@ 2014-02-12 11:15                 ` Shawn Guo
  -1 siblings, 0 replies; 22+ messages in thread
From: Shawn Guo @ 2014-02-12 11:15 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Rob Herring, Mark Rutland, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Wed, Feb 12, 2014 at 11:20:55AM +0100, Philipp Zabel wrote:
> > > @@ -598,9 +598,17 @@
> > >  			};
> > >  
> > >  			gpc: gpc@020dc000 {
> > > +				#address-cells = <1>;
> > > +				#size-cells = <1>;
> > >  				compatible = "fsl,imx6q-gpc";
> > >  				reg = <0x020dc000 0x4000>;
> > >  				interrupts = <0 89 0x04 0 90 0x04>;
> > > +				pu-supply = <&reg_pu>;
> > > +
> > > +				pd_pu: power-domain@020dc260 {
> > > +					compatible = "fsl,power-domain";
> > > +					reg = <0x020dc260 0x10>;
> > > +				};
> > 
> > It's time to have a binding doc for gpc/pgc?
> 
> Yes, I'll add one for the next version.
> 
> > And I'm not sure
> > "fsl,power-domain" is a good compatible as it's so generic.
> 
> fsl,imx6q-power-domain ?

It looks good to me.

Shawn

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node
@ 2014-02-12 11:15                 ` Shawn Guo
  0 siblings, 0 replies; 22+ messages in thread
From: Shawn Guo @ 2014-02-12 11:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 12, 2014 at 11:20:55AM +0100, Philipp Zabel wrote:
> > > @@ -598,9 +598,17 @@
> > >  			};
> > >  
> > >  			gpc: gpc at 020dc000 {
> > > +				#address-cells = <1>;
> > > +				#size-cells = <1>;
> > >  				compatible = "fsl,imx6q-gpc";
> > >  				reg = <0x020dc000 0x4000>;
> > >  				interrupts = <0 89 0x04 0 90 0x04>;
> > > +				pu-supply = <&reg_pu>;
> > > +
> > > +				pd_pu: power-domain at 020dc260 {
> > > +					compatible = "fsl,power-domain";
> > > +					reg = <0x020dc260 0x10>;
> > > +				};
> > 
> > It's time to have a binding doc for gpc/pgc?
> 
> Yes, I'll add one for the next version.
> 
> > And I'm not sure
> > "fsl,power-domain" is a good compatible as it's so generic.
> 
> fsl,imx6q-power-domain ?

It looks good to me.

Shawn

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2014-02-12 11:15 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-11 13:27 [RFC PATCH 0/4] i.MX6 PU power domain support Philipp Zabel
2014-02-11 13:27 ` Philipp Zabel
     [not found] ` <1392125231-28387-1-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2014-02-11 13:27   ` [RFC PATCH 1/4] ARM: imx6: gpc: Add PU power domain for GPU/VPU Philipp Zabel
2014-02-11 13:27     ` Philipp Zabel
     [not found]     ` <1392125231-28387-2-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2014-02-12  7:17       ` Shawn Guo
2014-02-12  7:17         ` Shawn Guo
     [not found]         ` <20140212071731.GH31484-rvtDTF3kK1ictlrPMvKcciBecyulp+rMXqFh9Ls21Oc@public.gmane.org>
2014-02-12 10:13           ` Philipp Zabel
2014-02-12 10:13             ` Philipp Zabel
2014-02-11 13:27   ` [RFC PATCH 2/4] ARM: imx6: gpc: Add pm clock support to PU power domain Philipp Zabel
2014-02-11 13:27     ` Philipp Zabel
2014-02-11 13:27   ` [RFC PATCH 3/4] ARM: dts: imx6qdl: Allow disabling the PU regulator, add a enable ramp delay Philipp Zabel
2014-02-11 13:27     ` Philipp Zabel
2014-02-11 13:27   ` [RFC PATCH 4/4] ARM: dts: imx6qdl: Add PU power-domain information to gpc node Philipp Zabel
2014-02-11 13:27     ` Philipp Zabel
     [not found]     ` <1392125231-28387-5-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2014-02-12  7:25       ` Shawn Guo
2014-02-12  7:25         ` Shawn Guo
     [not found]         ` <20140212072510.GI31484-rvtDTF3kK1ictlrPMvKcciBecyulp+rMXqFh9Ls21Oc@public.gmane.org>
2014-02-12 10:20           ` Philipp Zabel
2014-02-12 10:20             ` Philipp Zabel
     [not found]             ` <1392200455.5536.36.camel-/rZezPiN1rtR6QfukMTsflXZhhPuCNm+@public.gmane.org>
2014-02-12 11:15               ` Shawn Guo
2014-02-12 11:15                 ` Shawn Guo
2014-02-12  7:26   ` [RFC PATCH 0/4] i.MX6 PU power domain support Shawn Guo
2014-02-12  7:26     ` Shawn Guo

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.