diff mbox series

[U-Boot,v2,14/24] power domain: Introduce TI System Control Interface (TI SCI) power domain driver

Message ID 20180827102755.5784-15-lokeshvutla@ti.com
State Accepted
Delegated to: Tom Rini
Headers show
Series Initial support Texas Instrument's AM654 Platform | expand

Commit Message

Lokesh Vutla Aug. 27, 2018, 10:27 a.m. UTC
From: Andreas Dannenberg <dannenberg@ti.com>

Some TI Keystone 2 and K3 family of SoCs contain a system controller
(like the Power Management Micro Controller (PMMC) on 66AK2G SoCs and
the Device Management and Security Controller on AM65x SoCs) that manage
the low-level device control (like clocks, resets etc) for the various
hardware modules present on the SoC. These device control operations are
provided to the host processor OS through a communication protocol
called the TI System Control Interface (TI SCI) protocol.

This patch adds a power domain driver that communicates to the system
controller over the TI SCI protocol for performing power management of
various devices present on the SoC. Various power domain functionalities
are achieved by the means of different TI SCI device operations provided
by the TI SCI framework.

This code is loosely based on the drivers/soc/ti/ti_sci_pm_domains.c
driver of the Linux kernel.

Reviewed-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Andreas Dannenberg <dannenberg@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 .../power/ti,sci-pm-domain.txt                |  52 +++++++++
 drivers/power/domain/Kconfig                  |   7 ++
 drivers/power/domain/Makefile                 |   1 +
 drivers/power/domain/ti-sci-power-domain.c    | 107 ++++++++++++++++++
 4 files changed, 167 insertions(+)
 create mode 100644 doc/device-tree-bindings/power/ti,sci-pm-domain.txt
 create mode 100644 drivers/power/domain/ti-sci-power-domain.c

Comments

Tom Rini Sept. 12, 2018, 12:41 a.m. UTC | #1
On Mon, Aug 27, 2018 at 03:57:45PM +0530, Lokesh Vutla wrote:

> From: Andreas Dannenberg <dannenberg@ti.com>
> 
> Some TI Keystone 2 and K3 family of SoCs contain a system controller
> (like the Power Management Micro Controller (PMMC) on 66AK2G SoCs and
> the Device Management and Security Controller on AM65x SoCs) that manage
> the low-level device control (like clocks, resets etc) for the various
> hardware modules present on the SoC. These device control operations are
> provided to the host processor OS through a communication protocol
> called the TI System Control Interface (TI SCI) protocol.
> 
> This patch adds a power domain driver that communicates to the system
> controller over the TI SCI protocol for performing power management of
> various devices present on the SoC. Various power domain functionalities
> are achieved by the means of different TI SCI device operations provided
> by the TI SCI framework.
> 
> This code is loosely based on the drivers/soc/ti/ti_sci_pm_domains.c
> driver of the Linux kernel.
> 
> Reviewed-by: Tom Rini <trini@konsulko.com>
> Signed-off-by: Andreas Dannenberg <dannenberg@ti.com>
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/doc/device-tree-bindings/power/ti,sci-pm-domain.txt b/doc/device-tree-bindings/power/ti,sci-pm-domain.txt
new file mode 100644
index 0000000000..0e190e20fe
--- /dev/null
+++ b/doc/device-tree-bindings/power/ti,sci-pm-domain.txt
@@ -0,0 +1,52 @@ 
+Texas Instruments TI SCI Generic Power Domain
+=============================================
+
+Some TI SoCs contain a system controller (like the SYSFW, etc...) that is
+responsible for controlling the state of the IPs that are present.
+Communication between the host processor running an OS and the system
+controller happens through a protocol known as TI SCI [1].
+
+[1] http://processors.wiki.ti.com/index.php/TISCI
+
+PM Domain Node
+==============
+The PM domain node represents the global PM domain managed by the SYSFW. Because
+this relies on the TI SCI protocol to communicate with the SYSFW it must be a
+child of the sysfw node.
+
+Required Properties:
+--------------------
+- compatible: Must be "ti,sci-pm-domain"
+- #power-domain-cells: Must be 1 so that an id can be provided in each
+		       device node.
+
+Example (AM65x):
+----------------
+	sysfw: sysfw {
+		compatible = "ti,am654-system-controller";
+		...
+		k3_pds: power-controller {
+			compatible = "ti,sci-pm-domain";
+			#power-domain-cells = <1>;
+		};
+	};
+
+PM Domain Consumers
+===================
+Hardware blocks belonging to a PM domain should contain a "power-domains"
+property that is a phandle pointing to the corresponding PM domain node
+along with an index representing the device id to be passed to the PMMC
+for device control.
+
+Required Properties:
+--------------------
+- power-domains: phandle pointing to the corresponding PM domain node
+		 and an ID representing the device.
+
+Example (AM65x):
+----------------
+	uart2: serial@02800000 {
+		compatible = "ti,omap4-uart";
+		...
+		power-domains = <&k3_pds 0x3f>;
+	};
diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index 7cfa761498..80b0b48b0f 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -31,4 +31,11 @@  config TEGRA186_POWER_DOMAIN
 	  Enable support for manipulating Tegra's on-SoC power domains via IPC
 	  requests to the BPMP (Boot and Power Management Processor).
 
+config TI_SCI_POWER_DOMAIN
+	bool "Enable the TI SCI-based power domain driver"
+	depends on POWER_DOMAIN && TI_SCI_PROTOCOL
+	help
+	  Generic power domain implementation for TI devices implementing the
+	  TI SCI protocol.
+
 endmenu
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index 020eee2378..9c6399b722 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -7,3 +7,4 @@  obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
 obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o
+obj-$(CONFIG_TI_SCI_POWER_DOMAIN) += ti-sci-power-domain.o
diff --git a/drivers/power/domain/ti-sci-power-domain.c b/drivers/power/domain/ti-sci-power-domain.c
new file mode 100644
index 0000000000..aafde62cbf
--- /dev/null
+++ b/drivers/power/domain/ti-sci-power-domain.c
@@ -0,0 +1,107 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments System Control Interface (TI SCI) power domain driver
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *	Andreas Dannenberg <dannenberg@ti.com>
+ *
+ * Loosely based on Linux kernel ti_sci_pm_domains.c...
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <power-domain-uclass.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+/**
+ * struct ti_sci_power_domain_data - pm domain controller information structure
+ * @sci: TI SCI handle used for communication with system controller
+ */
+struct ti_sci_power_domain_data {
+	const struct ti_sci_handle *sci;
+};
+
+static int ti_sci_power_domain_probe(struct udevice *dev)
+{
+	struct ti_sci_power_domain_data *data = dev_get_priv(dev);
+
+	debug("%s(dev=%p)\n", __func__, dev);
+
+	if (!data)
+		return -ENOMEM;
+
+	/* Store handle for communication with the system controller */
+	data->sci = ti_sci_get_handle(dev);
+	if (IS_ERR(data->sci))
+		return PTR_ERR(data->sci);
+
+	return 0;
+}
+
+static int ti_sci_power_domain_request(struct power_domain *pd)
+{
+	debug("%s(pd=%p)\n", __func__, pd);
+	return 0;
+}
+
+static int ti_sci_power_domain_free(struct power_domain *pd)
+{
+	debug("%s(pd=%p)\n", __func__, pd);
+	return 0;
+}
+
+static int ti_sci_power_domain_on(struct power_domain *pd)
+{
+	struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev);
+	const struct ti_sci_handle *sci = data->sci;
+	const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops;
+	int ret;
+
+	debug("%s(pd=%p)\n", __func__, pd);
+
+	ret = dops->get_device(sci, pd->id);
+	if (ret)
+		dev_err(power_domain->dev, "%s: get_device failed (%d)\n",
+			__func__, ret);
+
+	return ret;
+}
+
+static int ti_sci_power_domain_off(struct power_domain *pd)
+{
+	struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev);
+	const struct ti_sci_handle *sci = data->sci;
+	const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops;
+	int ret;
+
+	debug("%s(pd=%p)\n", __func__, pd);
+
+	ret = dops->put_device(sci, pd->id);
+	if (ret)
+		dev_err(power_domain->dev, "%s: put_device failed (%d)\n",
+			__func__, ret);
+
+	return ret;
+}
+
+static const struct udevice_id ti_sci_power_domain_of_match[] = {
+	{ .compatible = "ti,sci-pm-domain" },
+	{ /* sentinel */ }
+};
+
+static struct power_domain_ops ti_sci_power_domain_ops = {
+	.request = ti_sci_power_domain_request,
+	.free = ti_sci_power_domain_free,
+	.on = ti_sci_power_domain_on,
+	.off = ti_sci_power_domain_off,
+};
+
+U_BOOT_DRIVER(ti_sci_pm_domains) = {
+	.name = "ti-sci-pm-domains",
+	.id = UCLASS_POWER_DOMAIN,
+	.of_match = ti_sci_power_domain_of_match,
+	.probe = ti_sci_power_domain_probe,
+	.priv_auto_alloc_size = sizeof(struct ti_sci_power_domain_data),
+	.ops = &ti_sci_power_domain_ops,
+};