public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] OMAP PM interface, version 3
@ 2008-07-17  1:57 Paul Walmsley
  2008-07-17  1:58 ` [PATCH] OMAP2/3 PM: create the OMAP PM interface and add a default no-op layer Paul Walmsley
  2008-08-05 14:18 ` [PATCH] OMAP PM interface, version 3 Tony Lindgren
  0 siblings, 2 replies; 3+ messages in thread
From: Paul Walmsley @ 2008-07-17  1:57 UTC (permalink / raw)
  To: linux-omap; +Cc: jouni.hogander, rnayak


Hello everyone,

this is the third version of the OMAP PM interface patch.

Major changes since the second revision:

1. set_max_mpu_wakeup_lat() has been added.  This is intended to limit
   the amount of time needed for the MPU to wake up and enter a device
   driver's interrupt handler.

2. set_max_dma_lat() has been renamed to set_max_sdma_lat()

3. omap_pm_dsp_get_opp_table() and struct omap_opp have been added for
   future DSPBridge/CPUFreq use.  omap_pm_if_init() now takes pointers
   to struct omap_opp arrays that are intended to be passed in from the
   board-*.c files.

4. Interface documentation has been moved to the 
   include/asm-arm/arch-omap/omap-pm.h file.

5. Documentation updated and moved into Documentation/arm/OMAP/omap_pm


Further comments welcome,


- Paul 

---------------------------------

This message proposes the third version of a power management
interface (the "OMAP PM interface") for the linux-omap kernel tree.

It includes a general device driver PM interface, along with some
specialized interfaces for CPUFreq, DSPBridge, and the
powerdomain/clockdomain code.  This message focuses on the general
device driver portion, since it is most relevant to the larger
community of OMAP device driver developers.

The interface is intended to allow drivers to take advantage of OMAP
power management features:

- without locking drivers into a particular underlying implementation;

- without adding constraints that are specific to particular OMAP
  variants; and

- without affecting other architectures.

The device driver portion of the interface covers four types of PM
constraints:

1. Set the maximum MPU wakeup latency

2. Set the maximum device wakeup latency

3. Set the maximum system DMA transfer start latency (CORE pwrdm)

4. Set the minimum bus throughput needed by a device


These are described in more detail in the patch.

This interface is intended to be temporary, to survive only until the
Linux PM QoS layer supports these features.

This interface is a collaborative product of many people from Nokia
and TI: Karthik Dasu, Jouni Högander, Tony Lindgren, Rajendra Nayak,
Sakari Poussa, Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul
Walmsley, and Richard Woodruff.

Included in the patch is a 'no-op' implementation that documents the
interface and emits debug messages.  Rajendra Nayak at TI has
developed an initial implementation of the OMAP PM interface that
relies mostly on TI's Shared Resource Framework.  Also under
development is an implementation of the OMAP PM code that uses the
existing Linux PM QoS code.


Comments welcomed,

- Paul

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

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

* [PATCH] OMAP2/3 PM: create the OMAP PM interface and add a default no-op layer.
  2008-07-17  1:57 [PATCH] OMAP PM interface, version 3 Paul Walmsley
@ 2008-07-17  1:58 ` Paul Walmsley
  2008-08-05 14:18 ` [PATCH] OMAP PM interface, version 3 Tony Lindgren
  1 sibling, 0 replies; 3+ messages in thread
From: Paul Walmsley @ 2008-07-17  1:58 UTC (permalink / raw)
  To: linux-omap; +Cc: jouni.hogander, rnayak

The interface provides device drivers, CPUFreq, and DSP Bridge with a
means of controlling OMAP power management parameters that are not yet
supported by the Linux PM PMQOS interface.  Copious documentation and
rationale is in the patch in Documentation/arm/OMAP/omap_pm and the
interface header file, include/asm-arm/arch-omap/omap-pm.h.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---

 Documentation/arm/OMAP/omap_pm      |  185 +++++++++++++++++++++
 arch/arm/mach-omap2/io.c            |    4 
 arch/arm/plat-omap/Kconfig          |   13 +
 arch/arm/plat-omap/Makefile         |    1 
 arch/arm/plat-omap/omap-pm-noop.c   |  309 +++++++++++++++++++++++++++++++++++
 include/asm-arm/arch-omap/omap-pm.h |  300 ++++++++++++++++++++++++++++++++++
 6 files changed, 812 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/arm/OMAP/omap_pm
 create mode 100644 arch/arm/plat-omap/omap-pm-noop.c
 create mode 100644 include/asm-arm/arch-omap/omap-pm.h

diff --git a/Documentation/arm/OMAP/omap_pm b/Documentation/arm/OMAP/omap_pm
new file mode 100644
index 0000000..2ec2034
--- /dev/null
+++ b/Documentation/arm/OMAP/omap_pm
@@ -0,0 +1,185 @@
+
+Rationale: the OMAP PM interface
+================================
+
+
+Existing PM interfaces are currently not ideal for OMAP
+-------------------------------------------------------
+
+There are two PM interfaces in use with publicly-distributed OMAP
+Linux code: the TI Shared Resource Framework (SRF) and the Linux PM
+QoS parameters code.  Neither interface is ideal for Linux OMAP code.
+
+TI Shared Resource Framework:
+
+The TI CDP 12.14 tree drivers currently use the TI Shared Resource
+Framework (SRF) to control chip power management.  Use of the SRF
+allowed TI to get the drivers up and running quickly with considerable
+power savings; and the SRF provided debugging support.  However, many
+of the SRF parameters are specified in OMAP-specific terms, such as
+target OPPs, rather than in terms of actual latency or throughput
+requirements.  OPPs change depending on OMAP silicon revisions or OMAP
+types, and are meaningless for other architectures, so drivers shared
+between OMAP and other architectures would also have to #ifdef out the
+SRF constraints.
+
+Linux PM QoS parameters:
+
+In February 2008, the mainline Linux kernel added code that is
+somewhat similar to the SRF: the Linux PM QoS parameters code, located
+in kernel/pm_qos_params.c.  (This code replaced the latency management
+code that was present in earlier kernels.)  Ideally, OMAP drivers
+would be able to use this Linux PM QoS code directly, but the PM QoS
+code has some drawbacks:
+
+- It combines some power management parameters that should be kept
+  separate for maximum power savings on OMAP3.  For example, in the PM
+  QoS code, CPU and system DMA wakeup latency are combined into one
+  parameter; but on OMAP3, these are distinct parameters.  The Linux
+  PM QoS code also combines all network power management knobs into
+  two non-device-specific parameters.  OMAP2/3 systems can have
+  different network devices with different power management
+  requirements - for example, a wired Ethernet interface may have
+  different latency and throughput constraints than a WiFi interface.
+
+- It does not yet cover all of the power management capabilities of
+  the OMAP3 architecture.  It does not express latency constraints on
+  a per-device or per-powerdomain basis; it only covers
+  cpu_dma_latency and network throughput and latency, which would not
+  cover most of the OMAP3 devices.
+
+The result is that drivers using the current Linux PM QoS layer
+directly are unlikely to reach the same level of power efficiency as
+driver code using the Shared Resource Framework.
+
+To summarize, the SRF provides significant power savings, but
+expresses power constraints in an OMAP- and silicon-revision-specific
+way; and the PM QoS layer expresses PM constraints in a cross-platform
+manner (in terms of fundamental physical units), but does not support
+per-powerdomain constraints and does not cover many of the OMAP power
+management features.
+
+
+A medium-term alternative: the OMAP PM interface
+------------------------------------------------
+
+We need a way for driver code to express PM parameters which:
+
+- supports the range of power management parameters present in the TI SRF;
+
+- separates the drivers from the underlying PM parameter
+  implementation, whether it is the TI SRF or Linux PM QoS or Linux
+  latency framework or something else;
+
+- specifies PM parameters in terms of fundamental units, such as
+  latency and throughput, rather than units which are specific to OMAP
+  or to particular OMAP variants;
+
+- allows drivers which are shared with other architectures (e.g.,
+  DaVinci) to add these constraints in a way which won't affect non-OMAP
+  systems,
+
+- can be implemented immediately with minimal disruption of other
+  architectures.
+
+
+We therefore propose the OMAP PM interface, including the following
+four power management functions for driver code:
+
+1. Set the maximum MPU wakeup latency:
+   (*pdata->set_max_mpu_wakeup_lat)(struct device *dev, unsigned long t)
+
+2. Set the maximum device wakeup latency:
+   (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)
+
+3. Set the maximum system DMA transfer start latency (CORE pwrdm):
+   (*pdata->set_max_sdma_lat)(struct device *dev, long t)
+
+4. Set the minimum bus throughput needed by a device:
+   (*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r)
+
+
+These functions are extensively documented in the OMAP PM interface header
+file, included in the patch.
+
+
+The OMAP PM layer is intended to be temporary
+---------------------------------------------
+
+The intention is that, in time, the Linux PM QoS layer should support
+the range of power management features present in OMAP3.  As this
+happens, existing drivers using the OMAP PM interface can be modified
+to use the Linux PM QoS code; and the OMAP PM interface can disappear.
+
+
+Driver usage of the OMAP PM functions
+-------------------------------------
+
+As the 'pdata' in the above examples indicates, these functions are
+exposed to drivers through function pointers in driver .platform_data
+structures.  The function pointers are initialized by the board-*.c
+files to point to the corresponding OMAP PM functions:
+.set_max_dev_wakeup_lat will point to
+omap_pm_set_max_dev_wakeup_lat(), etc.  Other architectures which do
+not support these functions should leave these function pointers set
+to NULL.  Drivers should use the following idiom:
+
+        if (pdata->set_max_dev_wakeup_lat)
+            (*pdata->set_max_dev_wakeup_lat)(dev, t);
+
+The most common usage of these functions will probably be to specify
+the maximum time from when an interrupt occurs, to when the device
+becomes accessible.  To accomplish this, driver writers should use the
+set_max_mpu_wakeup_lat() function to to constrain the MPU wakeup
+latency, and the set_max_dev_wakeup_lat() function to constrain the
+device wakeup latency (from clk_enable() to accessibility).  For
+example,
+
+        /* Limit MPU wakeup latency */
+        if (pdata->set_max_mpu_wakeup_lat)
+            (*pdata->set_max_mpu_wakeup_lat)(dev, tc);
+
+        /* Limit device powerdomain wakeup latency */
+        if (pdata->set_max_dev_wakeup_lat)
+            (*pdata->set_max_dev_wakeup_lat)(dev, td);
+
+        /* total wakeup latency in this example: (tc + td) */
+
+
+The PM parameters can be overwritten by calling the function again
+with the new value.  The settings can be removed by calling the
+function with a t argument of -1 (except in the case of
+set_max_bus_tput(), which should be called with an r argument of 0).
+
+
+Other specialized interface functions
+-------------------------------------
+
+The four functions listed above are intended to be usable by any
+device driver.  However, DSPBridge and CPUFreq have special
+requirements.  DSPBridge expresses target DSP performance levels in
+terms of OPP IDs.  CPUFreq expresses target MPU performance levels in
+terms of MPU frequency.  The OMAP PM interface contains functions for
+these specialized cases to convert that input information (OPPs/MPU
+frequency) into the form that the underlying power management
+implementation needs:
+
+5. (*pdata->omap_pm_dsp_get_opp_table)(void)
+
+6. (*pdata->omap_pm_dsp_set_min_opp)(u8 opp_id)
+
+7. (*pdata->omap_pm_dsp_get_opp)(void)
+
+8. (*pdata->omap_pm_cpu_get_freq_table)(void)
+
+9. (*pdata->omap_pm_cpu_set_freq)(unsigned long f)
+
+10. (*pdata->omap_pm_cpu_get_freq)(void)
+
+
+There are also functions for use by the clockdomain layer to indicate
+that a powerdomain should wake up or be put to sleep:
+
+11. (*pdata->omap_pm_pwrdm_active)(struct powerdomain *pwrdm)
+
+12. (*pdata->omap_pm_pwrdm_inactive)(struct powerdomain *pwrdm)
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 314994b..645d453 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -38,6 +38,8 @@
 #include <asm/arch/clockdomain.h>
 #include "clockdomains.h"
 
+#include <asm/arch/omap-pm.h>
+
 /*
  * The machine specific code may provide the extra mapping besides the
  * default mapping provided here.
@@ -197,9 +199,11 @@ void __init omap2_map_common_io(void)
 void __init omap2_init_common_hw(void)
 {
 	omap2_mux_init();
+	omap_pm_if_early_init();
 	pwrdm_init(powerdomains_omap);
 	clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
 	omap2_clk_init();
+	omap_pm_if_init(NULL, NULL);
 	omap2_init_memory();
 	gpmc_init();
 }
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 960c13f..ca790ac 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -247,4 +247,17 @@ config OMAP_SERIAL_WAKE
 
 endmenu
 
+choice
+	prompt "OMAP PM layer selection"
+	depends on ARCH_OMAP
+	default OMAP_PM_NOOP
+
+config OMAP_PM_NONE
+	bool "No PM layer"
+
+config OMAP_PM_NOOP
+	bool "No-op/debug PM layer"
+
+endchoice
+
 endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 93bbb64..d5453d5 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_OMAP_MMU_FWK) += mmu.o
 # OMAP mailbox framework
 obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
 
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
\ No newline at end of file
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
new file mode 100644
index 0000000..5ff7962
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -0,0 +1,309 @@
+/*
+ * omap-pm-noop.c - OMAP power management interface - dummy version
+ *
+ * This code implements the OMAP power management interface to
+ * drivers, CPUIdle, CPUFreq, and DSP Bridge.  It is strictly for
+ * debug/demonstration use, as it does nothing but printk() whenever a
+ * function is called (when DEBUG is defined, below)
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order):
+ * Karthik Dasu, Amish Lakhani, Tony Lindgren, Rajendra Nayak, Sakari
+ * Poussa, Veeramanikandan Raju, Igor Stoppa, Paul Walmsley, Richard
+ * Woodruff
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+
+/* Interface documentation is in asm/arch/omap-pm.h */
+#include <asm/arch/omap-pm.h>
+
+#include <asm/arch/powerdomain.h>
+
+static struct omap_opp *dsp_opps;
+static struct omap_opp *mpu_opps;
+
+/*
+ * Device-driver-originated constraints (via board-*.c files)
+ */
+
+void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN_ON(1);
+		return;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux, this needs to map the MPU to a
+	 * powerdomain, then go through the list of current max lat
+	 * constraints on the MPU and find the smallest.  If
+	 * the latency constraint has changed, the code should
+	 * recompute the state to enter for the next powerdomain
+	 * state.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+}
+
+void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+{
+	if (!dev || agent_id != OCP_INITIATOR_AGENT ||
+	    agent_id != OCP_TARGET_AGENT) {
+		WARN_ON(1);
+		return;
+	};
+
+	if (r == 0)
+		pr_debug("OMAP PM: remove min bus tput constraint: "
+			 "dev %s for agent_id %d\n", dev_name(dev), agent_id);
+	else
+		pr_debug("OMAP PM: add min bus tput constraint: "
+			 "dev %s for agent_id %d: rate %ld KiB\n",
+			 dev_name(dev), agent_id, r);
+
+	/*
+	 * This code should model the interconnect and compute the
+	 * required clock frequency, convert that to a VDD2 OPP ID, then
+	 * set the VDD2 OPP appropriately.
+	 *
+	 * TI CDP code can call constraint_set here on the VDD2 OPP.
+	 */
+}
+
+void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN_ON(1);
+		return;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max device latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max device latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux, this needs to map the device to a
+	 * powerdomain, then go through the list of current max lat
+	 * constraints on that powerdomain and find the smallest.  If
+	 * the latency constraint has changed, the code should
+	 * recompute the state to enter for the next powerdomain
+	 * state.  Conceivably, this code should also determine
+	 * whether to actually disable the device clocks or not,
+	 * depending on how long it takes to re-enable the clocks.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+}
+
+void omap_pm_set_max_sdma_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN_ON(1);
+		return;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max DMA latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max DMA latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux PM QOS params, this code should scan the
+	 * list of maximum CPU and DMA latencies and select the
+	 * smallest, then set cpu_dma_latency pm_qos_param
+	 * accordingly.
+	 *
+	 * For future Linux PM QOS params, with separate CPU and DMA
+	 * latency params, this code should just set the dma_latency param.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+
+}
+
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+const struct omap_opp *omap_pm_dsp_get_opp_table(void)
+{
+	pr_debug("OMAP PM: DSP request for OPP table\n");
+
+	/*
+	 * Return DSP frequency table here:  The final item in the
+	 * array should have .rate = .opp_id = 0.
+	 */
+
+	return NULL;
+}
+
+void omap_pm_dsp_set_min_opp(u8 opp_id)
+{
+	if (opp_id == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
+
+	/*
+	 *
+	 * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
+	 * can just test to see which is higher, the CPU's desired OPP
+	 * ID or the DSP's desired OPP ID, and use whichever is
+	 * highest.
+	 *
+	 * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
+	 * rate is keyed on MPU speed, not the OPP ID.  So we need to
+	 * map the OPP ID to the MPU speed for use with clk_set_rate()
+	 * if it is higher than the current OPP clock rate.
+	 *
+	 */
+}
+
+
+u8 omap_pm_dsp_get_opp(void)
+{
+	pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
+
+	/*
+	 * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
+	 *
+	 * CDP12.14+:
+	 * Call clk_get_rate() on the OPP custom clock, map that to an
+	 * OPP ID using the tables defined in board-*.c/chip-*.c files.
+	 */
+
+	return 0;
+}
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
+{
+	pr_debug("OMAP PM: CPUFreq request for frequency table\n");
+
+	/*
+	 * Return CPUFreq frequency table here: loop over
+	 * all VDD1 clkrates, pull out the mpu_ck frequencies, build
+	 * table
+	 */
+
+	return NULL;
+}
+
+void omap_pm_cpu_set_freq(unsigned long f)
+{
+	if (f == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
+		 f);
+
+	/*
+	 * For l-o dev tree, determine whether MPU freq or DSP OPP id
+	 * freq is higher.  Find the OPP ID corresponding to the
+	 * higher frequency.  Call clk_round_rate() and clk_set_rate()
+	 * on the OPP custom clock.
+	 *
+	 * CDP should just be able to set the VDD1 OPP clock rate here.
+	 */
+}
+
+unsigned long omap_pm_cpu_get_freq(void)
+{
+	pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
+
+	/*
+	 * Call clk_get_rate() on the mpu_ck.
+	 */
+
+	return 0;
+}
+
+/*
+ * Powerdomain usecounting hooks
+ */
+
+void omap_pm_pwrdm_active(struct powerdomain *pwrdm)
+{
+	if (!pwrdm) {
+		WARN_ON(1);
+		return;
+	};
+
+	pr_debug("OMAP PM: powerdomain %s is becoming active\n", pwrdm->name);
+
+	/*
+	 * CDP code apparently will need these for the enable_power_domain()
+	 * and disable_power_domain() functions.
+	 */
+}
+
+void omap_pm_pwrdm_inactive(struct powerdomain *pwrdm)
+{
+	if (!pwrdm) {
+		WARN_ON(1);
+		return;
+	};
+
+	pr_debug("OMAP PM: powerdomain %s is becoming inactive\n",
+		 pwrdm->name);
+
+	/*
+	 * CDP code apparently will need these for the enable_power_domain()
+	 * and disable_power_domain() functions.
+	 */
+}
+
+/*
+ * Should be called before clk framework since clk fw will call
+ * omap_pm_pwrdm_{in,}active()
+ */
+int __init omap_pm_if_early_init(void)
+{
+	return 0;
+}
+
+/* Must be called after clock framework is initialized */
+int __init omap_pm_if_init(struct omap_opp *mpu_opp_table,
+			   struct omap_opp *dsp_opp_table)
+{
+	mpu_opps = mpu_opp_table;
+	dsp_opps = dsp_opp_table;
+	return 0;
+}
+
+void omap_pm_if_exit(void)
+{
+	/* Deallocate CPUFreq frequency table here */
+}
+
diff --git a/include/asm-arm/arch-omap/omap-pm.h b/include/asm-arm/arch-omap/omap-pm.h
new file mode 100644
index 0000000..d272dba
--- /dev/null
+++ b/include/asm-arm/arch-omap/omap-pm.h
@@ -0,0 +1,300 @@
+/*
+ * omap-pm.h - OMAP power management interface
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
+ * Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa,
+ * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
+ * Richard Woodruff
+ */
+
+#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H
+#define ASM_ARM_ARCH_OMAP_OMAP_PM_H
+
+#include <linux/device.h>
+#include <linux/cpufreq.h>
+
+#include "powerdomain.h"
+
+/**
+ * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
+ * @rate: target clock rate
+ * @opp_id: OPP ID
+ * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
+ *
+ * Operating performance point data.  Can vary by OMAP chip and board.
+ */
+struct omap_opp {
+	unsigned long rate;
+	u8 opp_id;
+	u16 min_vdd;
+};
+
+/*
+ * agent_id values for use with omap_pm_set_min_bus_tput():
+ *
+ * OCP_INITIATOR_AGENT is only valid for devices that can act as
+ * initiators -- it represents the device's L3 interconnect
+ * connection.  OCP_TARGET_AGENT represents the device's L4
+ * interconnect connection.
+ */
+#define OCP_TARGET_AGENT		1
+#define OCP_INITIATOR_AGENT		2
+
+/**
+ * omap_pm_if_early_init - OMAP PM init code called before clock fw init
+ *
+ * Initialize anything that must be configured before the clock
+ * framework starts.  The "_if_" is to avoid name collisions with the
+ * PM idle-loop code.
+ */
+int __init omap_pm_if_early_init(void);
+
+/**
+ * omap_pm_if_init - OMAP PM init code called after clock fw init
+ * @mpu_opp_table: array ptr to struct omap_opp for MPU
+ * @dsp_opp_table: array ptr to struct omap_opp for DSP
+ *
+ * The main initialization code.  OPP tables are passed in here.  The
+ * "_if_" is to avoid name collisions with the PM idle-loop code.
+ */
+int __init omap_pm_if_init(struct omap_opp *mpu_opp_table,
+			   struct omap_opp *dsp_opp_table);
+
+/**
+ * omap_pm_if_exit - OMAP PM exit code
+ *
+ * Exit code; currently unused.  The "_if_" is to avoid name
+ * collisions with the PM idle-loop code.
+ */
+void omap_pm_if_exit(void);
+
+/*
+ * Device-driver-originated constraints (via board-*.c files, platform_data)
+ */
+
+
+/**
+ * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
+ * @dev: struct device * requesting the constraint
+ * @t: maximum MPU wakeup latency in microseconds
+ *
+ * Request that the maximum interrupt latency for the MPU to be no
+ * greater than 't' microseconds. "Interrupt latency" in this case is
+ * defined as the elapsed time from the occurrence of a hardware or
+ * timer interrupt to the time when the device driver's interrupt
+ * service routine has been entered by the MPU.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the MPU powerdomain into, and
+ * possibly the CORE powerdomain as well, since interrupt handling
+ * code currently runs from SDRAM.  Advanced PM or board*.c code may
+ * also configure interrupt controller priorities, OCP bus priorities,
+ * CPU speed(s), etc.
+ *
+ * This function will not affect device wakeup latency, e.g., time
+ * elapsed from when a device driver enables a hardware device with
+ * clk_enable(), to when the device is ready for register access or
+ * other use.  To control this device wakeup latency, use
+ * set_max_dev_wakeup_lat()
+ *
+ * Multiple calls to set_max_mpu_wakeup_lat() will replace the
+ * previous t value.  To remove the latency target for the MPU, call
+ * with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
+
+
+/**
+ * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
+ * @dev: struct device * requesting the constraint
+ * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
+ * @r: minimum throughput (in KiB/s)
+ *
+ * Request that the minimum data throughput on the OCP interconnect
+ * attached to device 'dev' interconnect agent 'tbus_id' be no less
+ * than 'r' KiB/s.
+ *
+ * It is expected that the OMAP PM or bus code will use this
+ * information to set the interconnect clock to run at the lowest
+ * possible speed that satisfies all current system users.  The PM or
+ * bus code will adjust the estimate based on its model of the bus, so
+ * device driver authors should attempt to specify an accurate
+ * quantity for their device use case, and let the PM or bus code
+ * overestimate the numbers as necessary to handle request/response
+ * latency, other competing users on the system, etc.  On OMAP2/3, if
+ * a driver requests a minimum L4 interconnect speed constraint, the
+ * code will also need to add an minimum L3 interconnect speed
+ * constraint,
+ *
+ * Multiple calls to set_min_bus_tput() will replace the previous rate
+ * value for this device.  To remove the interconnect throughput
+ * restriction for this device, call with r = 0.
+ *
+ * No return value.
+ */
+void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
+
+
+/**
+ * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
+ * @dev: struct device *
+ * @t: maximum device wakeup latency in microseconds
+ *
+ * Request that the maximum amount of time necessary for a device to
+ * become accessible after its clocks are enabled should be no greater
+ * than 't' microseconds.  Specifically, this represents the time from
+ * when a device driver enables device clocks with clk_enable(), to
+ * when the register reads and writes on the device will succeed.
+ * This function should be called before clk_disable() is called,
+ * since the power state transition decision may be made during
+ * clk_disable().
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the powerdomain enclosing this
+ * device into.
+ *
+ * Multiple calls to set_max_dev_wakeup_lat() will replace the
+ * previous wakeup latency values for this device.  To remove the wakeup
+ * latency restriction for this device, call with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
+
+
+/**
+ * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
+ * @dev: struct device *
+ * @t: maximum DMA transfer start latency in microseconds
+ *
+ * Request that the maximum system DMA transfer start latency for this
+ * device 'dev' should be no greater than 't' microseconds.  "DMA
+ * transfer start latency" here is defined as the elapsed time from
+ * when a device (e.g., McBSP) requests that a system DMA transfer
+ * start or continue, to the time at which data starts to flow into
+ * that device from the system DMA controller.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the CORE powerdomain into.
+ *
+ * Since system DMA transfers may not involve the MPU, this function
+ * will not affect MPU wakeup latency.  Use set_max_cpu_lat() to do
+ * so.  Similarly, this function will not affect device wakeup latency
+ * -- use set_max_dev_wakeup_lat() to affect that.
+ *
+ * Multiple calls to set_max_sdma_lat() will replace the previous t
+ * value for this device.  To remove the maximum DMA latency for this
+ * device, call with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_sdma_lat(struct device *dev, long t);
+
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+/**
+ * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table
+ *
+ * Intended for use by DSPBridge.  Returns an array of OPP->DSP clock
+ * frequency entries.  The final item in the array should have .rate =
+ * .opp_id = 0.
+ */
+const struct omap_opp *omap_pm_dsp_get_opp_table(void);
+
+/**
+ * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge
+ * @opp_id: target DSP OPP ID
+ *
+ * Set a minimum OPP ID for the DSP.  This is intended to be called
+ * only from the DSP Bridge MPU-side driver.  Unfortunately, the only
+ * information that code receives from the DSP/BIOS load estimator is the
+ * target OPP ID; hence, this interface.  No return value.
+ */
+void omap_pm_dsp_set_min_opp(u8 opp_id);
+
+/**
+ * omap_pm_dsp_get_opp - report the current DSP OPP ID
+ *
+ * Report the current OPP for the DSP.  Since on OMAP3, the DSP and
+ * MPU share a single voltage domain, the OPP ID returned back may
+ * represent a higher DSP speed than the OPP requested via
+ * omap_pm_dsp_set_min_opp().
+ *
+ * Returns the current VDD1 OPP ID, or 0 upon error.
+ */
+u8 omap_pm_dsp_get_opp(void);
+
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+/**
+ * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr
+ *
+ * Provide a frequency table usable by CPUFreq for the current chip/board.
+ * Returns a pointer to a struct cpufreq_frequency_table array or NULL
+ * upon error.
+ */
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
+
+/**
+ * omap_pm_cpu_set_freq - set the current minimum MPU frequency
+ * @f: MPU frequency in Hz
+ *
+ * Set the current minimum CPU frequency.  The actual CPU frequency
+ * used could end up higher if the DSP requested a higher OPP.
+ * Intended to be called by plat-omap/cpu_omap.c:omap_target().  No
+ * return value.
+ */
+void omap_pm_cpu_set_freq(unsigned long f);
+
+/**
+ * omap_pm_cpu_get_freq - report the current CPU frequency
+ *
+ * Returns the current MPU frequency, or 0 upon error.
+ */
+unsigned long omap_pm_cpu_get_freq(void);
+
+
+/*
+ * Powerdomain usecounting hooks
+ */
+
+/**
+ * omap_pm_pwrdm_active - indicate that a power domain has become active
+ * @pwrdm: struct powerdomain *
+ *
+ * Notify the OMAP PM layer that the power domain 'pwrdm' has become active,
+ * presumably due to a device driver enabling an underlying clock.  This
+ * function is intended to be called by a clockdomain node in the clock
+ * framework.  No return value.
+ */
+void omap_pm_pwrdm_active(struct powerdomain *pwrdm);
+
+
+/**
+ * omap_pm_pwrdm_inactive - indicate that a power domain has become inactive
+ * @pwrdm: struct powerdomain *
+ *
+ * Notify the OMAP PM layer that the power domain 'pwrdm' has become
+ * inactive, presumably due to a device driver disabling an underlying
+ * clock.  This function is intended to be called by a clockdomain
+ * node in the clock framework.  No return value.
+ */
+void omap_pm_pwrdm_inactive(struct powerdomain *pwrdm);
+
+
+#endif


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

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

* Re: [PATCH] OMAP PM interface, version 3
  2008-07-17  1:57 [PATCH] OMAP PM interface, version 3 Paul Walmsley
  2008-07-17  1:58 ` [PATCH] OMAP2/3 PM: create the OMAP PM interface and add a default no-op layer Paul Walmsley
@ 2008-08-05 14:18 ` Tony Lindgren
  1 sibling, 0 replies; 3+ messages in thread
From: Tony Lindgren @ 2008-08-05 14:18 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, jouni.hogander, rnayak

* Paul Walmsley <paul@pwsan.com> [080717 05:00]:
> 
> Hello everyone,
> 
> this is the third version of the OMAP PM interface patch.
> 
> Major changes since the second revision:
> 
> 1. set_max_mpu_wakeup_lat() has been added.  This is intended to limit
>    the amount of time needed for the MPU to wake up and enter a device
>    driver's interrupt handler.
> 
> 2. set_max_dma_lat() has been renamed to set_max_sdma_lat()
> 
> 3. omap_pm_dsp_get_opp_table() and struct omap_opp have been added for
>    future DSPBridge/CPUFreq use.  omap_pm_if_init() now takes pointers
>    to struct omap_opp arrays that are intended to be passed in from the
>    board-*.c files.
> 
> 4. Interface documentation has been moved to the 
>    include/asm-arm/arch-omap/omap-pm.h file.
> 
> 5. Documentation updated and moved into Documentation/arm/OMAP/omap_pm
> 
> 
> Further comments welcome,

I think we need to run this by LKML, linux-arm-kernel, and linux-pm
before we integrate these. Can you repost these for comments one
more time so we get comments from other mailing lists?

Thanks,

Tony


> 
> 
> - Paul 
> 
> ---------------------------------
> 
> This message proposes the third version of a power management
> interface (the "OMAP PM interface") for the linux-omap kernel tree.
> 
> It includes a general device driver PM interface, along with some
> specialized interfaces for CPUFreq, DSPBridge, and the
> powerdomain/clockdomain code.  This message focuses on the general
> device driver portion, since it is most relevant to the larger
> community of OMAP device driver developers.
> 
> The interface is intended to allow drivers to take advantage of OMAP
> power management features:
> 
> - without locking drivers into a particular underlying implementation;
> 
> - without adding constraints that are specific to particular OMAP
>   variants; and
> 
> - without affecting other architectures.
> 
> The device driver portion of the interface covers four types of PM
> constraints:
> 
> 1. Set the maximum MPU wakeup latency
> 
> 2. Set the maximum device wakeup latency
> 
> 3. Set the maximum system DMA transfer start latency (CORE pwrdm)
> 
> 4. Set the minimum bus throughput needed by a device
> 
> 
> These are described in more detail in the patch.
> 
> This interface is intended to be temporary, to survive only until the
> Linux PM QoS layer supports these features.
> 
> This interface is a collaborative product of many people from Nokia
> and TI: Karthik Dasu, Jouni Högander, Tony Lindgren, Rajendra Nayak,
> Sakari Poussa, Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul
> Walmsley, and Richard Woodruff.
> 
> Included in the patch is a 'no-op' implementation that documents the
> interface and emits debug messages.  Rajendra Nayak at TI has
> developed an initial implementation of the OMAP PM interface that
> relies mostly on TI's Shared Resource Framework.  Also under
> development is an implementation of the OMAP PM code that uses the
> existing Linux PM QoS code.
> 
> 
> Comments welcomed,
> 
> - Paul
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2008-08-05 14:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-17  1:57 [PATCH] OMAP PM interface, version 3 Paul Walmsley
2008-07-17  1:58 ` [PATCH] OMAP2/3 PM: create the OMAP PM interface and add a default no-op layer Paul Walmsley
2008-08-05 14:18 ` [PATCH] OMAP PM interface, version 3 Tony Lindgren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox