public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] OMAP PM interface, version 2
@ 2008-06-17 15:01 Paul Walmsley
  2008-06-17 15:01 ` [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer Paul Walmsley
  2008-06-18 11:12 ` [PATCH] OMAP PM interface, version 2 Högander Jouni
  0 siblings, 2 replies; 11+ messages in thread
From: Paul Walmsley @ 2008-06-17 15:01 UTC (permalink / raw)
  To: linux-omap; +Cc: tony, jouni.hogander, khilman

Hello everyone,

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

Major changes since the first version:

1. Jouni Hogander suggested that the set_max_cpu_lat() function be
   merged into set_max_dev_wakeup_lat(), when set_max_dev_wakeup_lat()
   is called with the CPU0 sys_device (via get_cpu_sysdev(0)).  He feels
   that this will be easier for device driver developers to use.  This
   change has been made.

2. set_max_bus_lat() now takes an "agent_id" parameter instead of a 
   "struct bus *bus".  agent_id will be either OCP_TARGET_AGENT or
   OCP_INITIATOR_AGENT.

3. Initialization is now split into an early init section, called before
   the clock framework initializes; and a later init section, called
   after clock framework init.  Init functions also renamed to avoid
   clashing with existing function names.

4. Several documentation bugs fixed.


Thanks also to Kevin Hilman <khilman@mvista.com> for his comments.

Further comments welcome,


- Paul 

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

This message proposes the second 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 three types of PM
constraints:

1. Set the minimum bus throughput needed by a device;

2. Set the maximum device wakeup latency (also includes MPU).

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

These are described in more detail below.

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



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, 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 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 minimum bus throughput needed by a device:
   (*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r)

2. Set the maximum device wakeup latency:
   (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)

3. Set the maximum DMA transfer start latency (CORE pwrdm):
   (*pdata->set_max_dma_lat)(struct device *dev, long t)


These functions are extensively documented in the no-op OMAP PM layer
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_dev_wakeup_lat() function twice: once to constrain the MPU
wakeup latency, and once to constrain the device wakeup latency (from
clk_enable() to accessibility).  For example,

        if (pdata->set_max_dev_wakeup_lat) {
            struct sys_device *cpu0_dev;

            /* Limit MPU wakeup latency */
            cpu0_dev = get_cpu_sysdev(0); 
            (*pdata->set_max_dev_wakeup_lat)(cpu0_dev, tc);

            /* Limit device powerdomain wakeup latency */
            (*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 three 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:

4. (*pdata->omap_pm_dsp_set_min_opp)(u8 opp_id)

5. (*pdata->omap_pm_dsp_get_opp)(void)

6. (*pdata->omap_pm_cpu_get_freq_table)(void)

7. (*pdata->omap_pm_cpu_set_freq)(unsigned long f)

8. (*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:

9. (*pdata->omap_pm_pwrdm_active)(struct powerdomain *pwrdm)

10. (*pdata->omap_pm_pwrdm_inactive)(struct powerdomain *pwrdm)


These functions are documented in the patch.

---

Paul Walmsley (1):
      OMAP2/3 PM: Add OMAP PM no-op layer


 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   |  409 +++++++++++++++++++++++++++++++++++
 include/asm-arm/arch-omap/omap-pm.h |   54 +++++
 5 files changed, 481 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-omap/omap-pm-noop.c
 create mode 100644 include/asm-arm/arch-omap/omap-pm.h



--
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] 11+ messages in thread

* [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer
  2008-06-17 15:01 [PATCH] OMAP PM interface, version 2 Paul Walmsley
@ 2008-06-17 15:01 ` Paul Walmsley
  2008-06-18 14:56   ` Ramesh Gupta G
  2008-06-18 11:12 ` [PATCH] OMAP PM interface, version 2 Högander Jouni
  1 sibling, 1 reply; 11+ messages in thread
From: Paul Walmsley @ 2008-06-17 15:01 UTC (permalink / raw)
  To: linux-omap; +Cc: tony, jouni.hogander, khilman

Add a default OMAP PM no-op layer, defining the interface between
device drivers, CPUFreq, and DSP Bridge on one side; and hardware-specific
APIs on the other (e.g., powerdomain API, clock framework, etc).
Copious documentation is in the omap-pm-noop.c file itself.

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

---

 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   |  409 +++++++++++++++++++++++++++++++++++
 include/asm-arm/arch-omap/omap-pm.h |   54 +++++
 5 files changed, 481 insertions(+), 0 deletions(-)
 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/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 314994b..3070c1c 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();
 	omap2_init_memory();
 	gpmc_init();
 }
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index b085b07..aad8f24 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -216,4 +216,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..43cbee0
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -0,0 +1,409 @@
+/*
+ * 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>
+
+#include <asm/arch/omap-pm.h>
+
+#include <asm/arch/powerdomain.h>
+
+
+/*
+ * Device-driver-originated constraints (via board-*.c files)
+ */
+
+/**
+ * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
+ * @dev: struct device *
+ * @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)
+{
+	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.
+	 */
+}
+
+
+/**
+ * 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.
+ *
+ * MPU wakeup latency can also be adjusted by this function, by
+ * passing the CPU device from get_cpu_sysdev(0).  In this case,
+ * set_max_dev_wakeup_lat() is intended to constrain the amount of
+ * time required for the MPU to respond to an interrupt and enter
+ * device driver code.
+ *
+ * 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)
+{
+	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.
+	 */
+}
+
+
+/**
+ * omap_pm_set_max_dma_lat - set the maximum DMA transfer start latency
+ * @dev: struct device *
+ * @t: maximum DMA transfer start latency in microseconds
+ *
+ * Request that the maximum 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 DMA transfer start or continue,
+ * to the time at which data starts to flow into that device from the
+ * 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 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_dma_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_dma_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
+ */
+
+/**
+ * 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)
+{
+	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.
+	 *
+	 */
+}
+
+
+/**
+ * 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)
+{
+	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.
+ */
+
+/**
+ * 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)
+{
+	pr_debug("OMAP PM: CPUFreq request for frequency table\n");
+
+	/*
+	 * Allocate and build CPUFreq frequency table here: loop over
+	 * all VDD1 clkrates, pull out the mpu_ck frequencies, build
+	 * table
+	 */
+
+	return NULL;
+}
+
+/**
+ * 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)
+{
+	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.
+	 */
+}
+
+/**
+ * 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)
+{
+	pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
+
+	/*
+	 * Call clk_get_rate() on the mpu_ck.
+	 */
+
+	return 0;
+}
+
+/*
+ * 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)
+{
+	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.
+	 */
+}
+
+/**
+ * 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)
+{
+	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(void)
+{
+	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..71565bf
--- /dev/null
+++ b/include/asm-arm/arch-omap/omap-pm.h
@@ -0,0 +1,54 @@
+/*
+ * 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"
+
+
+/*
+ * 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
+
+
+int __init omap_pm_if_early_init(void);
+int __init omap_pm_if_init(void);
+void omap_pm_if_exit(void);
+
+void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
+void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
+void omap_pm_set_max_dma_lat(struct device *dev, long t);
+
+void omap_pm_dsp_set_min_opp(u8 opp_id);
+u8 omap_pm_dsp_get_opp(void);
+
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
+void omap_pm_cpu_set_freq(unsigned long f);
+unsigned long omap_pm_cpu_get_freq(void);
+
+void omap_pm_pwrdm_active(struct powerdomain *pwrdm);
+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] 11+ messages in thread

* Re: [PATCH] OMAP PM interface, version 2
  2008-06-17 15:01 [PATCH] OMAP PM interface, version 2 Paul Walmsley
  2008-06-17 15:01 ` [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer Paul Walmsley
@ 2008-06-18 11:12 ` Högander Jouni
  2008-06-19  5:49   ` Paul Walmsley
  1 sibling, 1 reply; 11+ messages in thread
From: Högander Jouni @ 2008-06-18 11:12 UTC (permalink / raw)
  To: ext Paul Walmsley; +Cc: linux-omap, tony, khilman

"ext Paul Walmsley" <paul@pwsan.com> writes:

> Hello everyone,
>
> this is the second version of the OMAP PM interface patch.
>
> Major changes since the first version:
>
> 1. Jouni Hogander suggested that the set_max_cpu_lat() function be
>    merged into set_max_dev_wakeup_lat(), when set_max_dev_wakeup_lat()
>    is called with the CPU0 sys_device (via get_cpu_sysdev(0)).  He feels
>    that this will be easier for device driver developers to use.  This
>    change has been made.

I just noticed that this won't work. We have this declaration:

(*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)

In case of cpu it is not possible to underlying code to identify the
caller. This derives a question should we have parameter for caller
identification in set_max_dev_wakeup_lat()?

I mean currently we are assuming that there is only one caller for
each device. Is this correct assumination? If we think
e.g. busses. There might be drivers for devices on some specific
bus. Each of them might want to set latency constraint for the bus.


-- 
Jouni Högander

--
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] 11+ messages in thread

* Re: [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer
  2008-06-17 15:01 ` [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer Paul Walmsley
@ 2008-06-18 14:56   ` Ramesh Gupta G
  2008-06-20  5:38     ` Kanigeri, Hari
  2008-06-24  7:33     ` Paul Walmsley
  0 siblings, 2 replies; 11+ messages in thread
From: Ramesh Gupta G @ 2008-06-18 14:56 UTC (permalink / raw)
  To: Paul Walmsley, linux-omap
  Cc: tony, jouni.hogander, khilman, Hiroshi DOYU, vpasam

Hi Paul,

----- Original Message ----- 
From: "Paul Walmsley" <paul@pwsan.com>
To: <linux-omap@vger.kernel.org>
Cc: <tony@atomide.com>; <jouni.hogander@nokia.com>; <khilman@mvista.com>
Sent: Tuesday, June 17, 2008 8:31 PM
Subject: [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer



> +/**
> + * 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)
> +{
> + pr_debug("OMAP PM: CPUFreq request for frequency table\n");
> +
> + /*
> + * Allocate and build CPUFreq frequency table here: loop over
> + * all VDD1 clkrates, pull out the mpu_ck frequencies, build
> + * table
> + */
> +
> + return NULL;
> +}
> +

Will this interface provides information of max number if OPPs supported and
the frequency corresponding to eah OPP level?

Notification of OPP level change to DSP
------------------------------------------
MPU Bridge is required to inform the DSP about OPP level change for load
predictor use in DSP;
this is done as part of in post notification in dspbridge. Do we have
support for Post Notification in this framework?

Please let us know your comments.

Thanks & regards
Ramesh Gupta G


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

* Re: [PATCH] OMAP PM interface, version 2
  2008-06-18 11:12 ` [PATCH] OMAP PM interface, version 2 Högander Jouni
@ 2008-06-19  5:49   ` Paul Walmsley
  2008-06-19  6:21     ` Högander Jouni
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Walmsley @ 2008-06-19  5:49 UTC (permalink / raw)
  To: Högander Jouni; +Cc: linux-omap, tony, khilman

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1661 bytes --]

Hello Jouni, 

On Wed, 18 Jun 2008, Högander Jouni wrote:

> "ext Paul Walmsley" <paul@pwsan.com> writes:
> 
> > Major changes since the first version:
> >
> > 1. Jouni Hogander suggested that the set_max_cpu_lat() function be
> >    merged into set_max_dev_wakeup_lat(), when set_max_dev_wakeup_lat()
> >    is called with the CPU0 sys_device (via get_cpu_sysdev(0)).  He feels
> >    that this will be easier for device driver developers to use.  This
> >    change has been made.
> 
> I just noticed that this won't work. We have this declaration:
> 
> (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)
> 
> In case of cpu it is not possible to underlying code to identify the
> caller. 

Eh, nice catch.  Let's add set_max_intr_lat() back in - perhaps call it 
set_max_mpu_wakeup_lat() instead for symmetry?

> This derives a question should we have parameter for caller
> identification in set_max_dev_wakeup_lat()?
> 
> I mean currently we are assuming that there is only one caller for each 
> device. Is this correct assumination?  If we think e.g. busses. There 
> might be drivers for devices on some specific bus. Each of them might 
> want to set latency constraint for the bus.

In the case of bus wakeup latency, all of the on-chip interconnects share 
the same wakeup latency - the CORE powerdomain wakeup latency.  So 
set_max_dma_lat() covers all of the interconnect latencies.

We could call it set_max_bus_wakeup_lat(), with a prototype similar to 
set_max_dev_wakeup_lat(), for consistency. (The bus agent argument would 
effectively be ignored in OMAP2/3.)

Thoughts?


- Paul

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

* Re: [PATCH] OMAP PM interface, version 2
  2008-06-19  5:49   ` Paul Walmsley
@ 2008-06-19  6:21     ` Högander Jouni
  0 siblings, 0 replies; 11+ messages in thread
From: Högander Jouni @ 2008-06-19  6:21 UTC (permalink / raw)
  To: ext Paul Walmsley; +Cc: linux-omap, tony, khilman

"ext Paul Walmsley" <paul@pwsan.com> writes:

> Hello Jouni, 
>
> On Wed, 18 Jun 2008, Högander Jouni wrote:
>
>> "ext Paul Walmsley" <paul@pwsan.com> writes:
>> 
>> > Major changes since the first version:
>> >
>> > 1. Jouni Hogander suggested that the set_max_cpu_lat() function be
>> >    merged into set_max_dev_wakeup_lat(), when set_max_dev_wakeup_lat()
>> >    is called with the CPU0 sys_device (via get_cpu_sysdev(0)).  He feels
>> >    that this will be easier for device driver developers to use.  This
>> >    change has been made.
>> 
>> I just noticed that this won't work. We have this declaration:
>> 
>> (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)
>> 
>> In case of cpu it is not possible to underlying code to identify the
>> caller. 
>
> Eh, nice catch.  Let's add set_max_intr_lat() back in - perhaps call it 
> set_max_mpu_wakeup_lat() instead for symmetry?

Yes, I agree. Originally my idea to change this was related to that pm
qos extending and actually I didn't expect you to do this change.

>
>> This derives a question should we have parameter for caller
>> identification in set_max_dev_wakeup_lat()?
>> 
>> I mean currently we are assuming that there is only one caller for each 
>> device. Is this correct assumination?  If we think e.g. busses. There 
>> might be drivers for devices on some specific bus. Each of them might 
>> want to set latency constraint for the bus.
>
> In the case of bus wakeup latency, all of the on-chip interconnects share 
> the same wakeup latency - the CORE powerdomain wakeup latency.  So 
> set_max_dma_lat() covers all of the interconnect latencies.

Well I didn't mean interconnect busses here. I was thinking busses
like spi, which can have multiple devices on it. Drivers for theses
devices might want to set latency constraints for spi bus. In current
plan we are assuming that spi driver is the only one who sets the
latency constraint for spi bus. How could spi driver know what is the
spi latency requirement for the device that is connected to it?

>
> We could call it set_max_bus_wakeup_lat(), with a prototype similar to 
> set_max_dev_wakeup_lat(), for consistency. (The bus agent argument would 
> effectively be ignored in OMAP2/3.)

Lets not change that, originally it was planned to control sdma
latency constraint, without caring that it actually affects also to
interconnect bus latencies. Is this plan changed? At some point it was
thought to be changed to set_max_sdma_lat(), right?

If we are some day at point where interconnect busses are modelled as a
bus, then adding set_max_bus_wakeup_lat() could be good idea. Further
if also sdma will be modelled as a platform device, then
set_max_dma_lat() could be removed and set_max_dev_wakeup_lat() used
instead for sdma.

Currently set_max_intr_lat() could be already removed with adding one
more parameter to set_max_dev_wakeup_lat():

set_max_dev_wakeup_lat(struct device *dev, struct device *req, unsigned
long t);

This is just an idea, please do not change:) Instead I think your idea
to change it back to what it was is better at this point.

-- 
Jouni Högander

--
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] 11+ messages in thread

* RE: [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer
  2008-06-18 14:56   ` Ramesh Gupta G
@ 2008-06-20  5:38     ` Kanigeri, Hari
  2008-06-24  7:33     ` Paul Walmsley
  1 sibling, 0 replies; 11+ messages in thread
From: Kanigeri, Hari @ 2008-06-20  5:38 UTC (permalink / raw)
  To: Gupta, Ramesh, Paul Walmsley, linux-omap@vger.kernel.org
  Cc: tony@atomide.com, jouni.hogander@nokia.com, khilman@mvista.com,
	Hiroshi DOYU, Pasam, Vijay

Hi Paul,

>
> Will this interface provides information of max number if OPPs supported
> and
> the frequency corresponding to eah OPP level?
>
> Notification of OPP level change to DSP
> ------------------------------------------
> MPU Bridge is required to inform the DSP about OPP level change for load
> predictor use in DSP;
> this is done as part of in post notification in dspbridge. Do we have
> support for Post Notification in this framework?
>

        Can I please know when would the PM patch available with the functionality mentioned by Ramesh ?

Thank you,
Best regards,
Hari


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

* Re: [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer
  2008-06-18 14:56   ` Ramesh Gupta G
  2008-06-20  5:38     ` Kanigeri, Hari
@ 2008-06-24  7:33     ` Paul Walmsley
  2008-06-24 13:46       ` Ramesh Gupta G
  2008-07-03 11:01       ` Ramesh Gupta G
  1 sibling, 2 replies; 11+ messages in thread
From: Paul Walmsley @ 2008-06-24  7:33 UTC (permalink / raw)
  To: Ramesh Gupta G
  Cc: linux-omap, tony, h-kanigeri2, jouni.hogander, khilman,
	Hiroshi DOYU, vpasam

Hello Ramesh, 

On Wed, 18 Jun 2008, Ramesh Gupta G wrote:

> Will this interface provides information of max number if OPPs supported and
> the frequency corresponding to eah OPP level?

It could be added.  This is for DSPBridge use, not for the MPU, correct?  
Is the idea essentially to replace the vdd1_dsp_freq[] array in 
mpu_driver/src/rmgr/linux/common/drv_interface.c?  Can you tell me what 
each of the 4 fields in vdd1_dsp_freq[] means?

Perhaps something similar to an OMAP PM function 
"omap_pm_dsp_get_opp_table()" that DSPBridge could call on startup?

> MPU Bridge is required to inform the DSP about OPP level change for load 
> predictor use in DSP; this is done as part of in post notification in 
> dspbridge. Do we have support for Post Notification in this framework?

I just posted some patches for that a few days ago.  You should be able to 
use those to notify DSPBridge of changes to iva2_ck.


- Paul

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

* Re: [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer
  2008-06-24  7:33     ` Paul Walmsley
@ 2008-06-24 13:46       ` Ramesh Gupta G
  2008-07-03 11:01       ` Ramesh Gupta G
  1 sibling, 0 replies; 11+ messages in thread
From: Ramesh Gupta G @ 2008-06-24 13:46 UTC (permalink / raw)
  To: Paul Walmsley, Ramesh Gupta G
  Cc: linux-omap, tony, h-kanigeri2, jouni.hogander, khilman,
	Hiroshi DOYU, vpasam

Hello Paul,

>> Will this interface provides information of max number if OPPs supported 
>> and
>> the frequency corresponding to eah OPP level?
>
> It could be added.  This is for DSPBridge use, not for the MPU, correct?
> Is the idea essentially to replace the vdd1_dsp_freq[] array in
> mpu_driver/src/rmgr/linux/common/drv_interface.c?

Yes, this is to replace the  table in drv_interface.c

>Can you tell me what
> each of the 4 fields in vdd1_dsp_freq[] means?

The 4 fileds of vdd1_freq[] are as below.

voltage
opp frequency
min frequency
max frequency

we are currently not using the field 'voltage', this is for future usage.
the min_frequency and max_frequency are threshold frequencies set by DSP and 
are configurable.

>
> Perhaps something similar to an OMAP PM function
> "omap_pm_dsp_get_opp_table()" that DSPBridge could call on startup?
>

Sure, we can call this function on startup.

>> MPU Bridge is required to inform the DSP about OPP level change for load
>> predictor use in DSP; this is done as part of in post notification in
>> dspbridge. Do we have support for Post Notification in this framework?
>
> I just posted some patches for that a few days ago.  You should be able to
> use those to notify DSPBridge of changes to iva2_ck.

Thanks for that, we will look into that.

Also can you please provide the tentative dates these patches are avialable 
with above changes.

Please let us know your comments.

regards
Ramesh Gupta G


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

* Re: [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer
  2008-06-24  7:33     ` Paul Walmsley
  2008-06-24 13:46       ` Ramesh Gupta G
@ 2008-07-03 11:01       ` Ramesh Gupta G
  2008-07-03 15:09         ` Paul Walmsley
  1 sibling, 1 reply; 11+ messages in thread
From: Ramesh Gupta G @ 2008-07-03 11:01 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: linux-omap, tony, h-kanigeri2, jouni.hogander, khilman,
	Hiroshi DOYU, vpasam

Hi Paul,


> Perhaps something similar to an OMAP PM function
> "omap_pm_dsp_get_opp_table()" that DSPBridge could call on startup?

Can you please provide tentative dates for the patches available with above 
function?

thanks
Ramesh Gupta G 


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

* Re: [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer
  2008-07-03 11:01       ` Ramesh Gupta G
@ 2008-07-03 15:09         ` Paul Walmsley
  0 siblings, 0 replies; 11+ messages in thread
From: Paul Walmsley @ 2008-07-03 15:09 UTC (permalink / raw)
  To: Ramesh Gupta G
  Cc: linux-omap, tony, h-kanigeri2, jouni.hogander, khilman,
	Hiroshi DOYU, vpasam

Hello Ramesh,

On Thu, 3 Jul 2008, Ramesh Gupta G wrote:

> > Perhaps something similar to an OMAP PM function
> > "omap_pm_dsp_get_opp_table()" that DSPBridge could call on startup?
> 
> Can you please provide tentative dates for the patches available with above
> function?

DSPBridge already has all of that OPP/frequency information inside its 
code, so that's what you should use until that function becomes available.


- Paul

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

end of thread, other threads:[~2008-07-03 15:09 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-17 15:01 [PATCH] OMAP PM interface, version 2 Paul Walmsley
2008-06-17 15:01 ` [PATCH] OMAP2/3 PM: Add OMAP PM no-op layer Paul Walmsley
2008-06-18 14:56   ` Ramesh Gupta G
2008-06-20  5:38     ` Kanigeri, Hari
2008-06-24  7:33     ` Paul Walmsley
2008-06-24 13:46       ` Ramesh Gupta G
2008-07-03 11:01       ` Ramesh Gupta G
2008-07-03 15:09         ` Paul Walmsley
2008-06-18 11:12 ` [PATCH] OMAP PM interface, version 2 Högander Jouni
2008-06-19  5:49   ` Paul Walmsley
2008-06-19  6:21     ` Högander Jouni

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