linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: paul@pwsan.com (Paul Walmsley)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 20/20] OMAP: PM constraints: add omap_pm_set_min_clk_rate()
Date: Fri, 02 Jul 2010 09:30:06 -0600	[thread overview]
Message-ID: <20100702152958.6221.35036.stgit@localhost.localdomain> (raw)
In-Reply-To: <20100702152703.6221.33529.stgit@localhost.localdomain>

Add omap_pm_set_min_clk_rate().  This constraint is meant for use by
device drivers to translate a certain device-specific performance
constraint (e.g., "minimum polygons per second") to a clock rate for
the driver's device, given the driver's intimate knowledge of the
device hardware (e.g., device type, device hardware revision, firmware
revision, etc.)  From a general PM core perspective, clock rate is
probably the closest general analog to "performance" that is
available, but the exact mapping from a use-case-specific performance
constraint to clock rate must be done by the driver.  Drivers intended for
upstream merging shouldn't hardcode specific clock rates in their code
without basing those rates on some performance criteria requested through
the driver's subsystem (ideally, from userspace).

Imre Deak <imre.deak@nokia.com> described the need and use-case for
this constraint, and discussed the implementation - thanks, Imre.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Imre Deak <imre.deak@nokia.com>
---
 arch/arm/plat-omap/include/plat/omap-pm.h |   61 +++++++++++++++++++++++++++++
 arch/arm/plat-omap/omap-pm-noop.c         |   27 +++++++++++++
 2 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 3d468ba..728fbb9 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -16,6 +16,7 @@
 
 #include <linux/device.h>
 #include <linux/cpufreq.h>
+#include <linux/clk.h>
 
 #include "powerdomain.h"
 
@@ -212,6 +213,66 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
 int omap_pm_set_max_sdma_lat(struct device *dev, long t);
 
 
+/**
+ * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
+ * @dev: struct device * requesting the constraint
+ * @clk: struct clk * to set the minimum rate constraint on
+ * @r: minimum rate in Hz
+ *
+ * Request that the minimum clock rate on the device @dev's clk @clk
+ * be no less than @r Hz.
+ *
+ * It is expected that the OMAP PM code will use this information to
+ * find an OPP or clock setting that will satisfy this clock rate
+ * constraint, along with any other applicable system constraints on
+ * the clock rate or corresponding voltage, etc.
+ *
+ * omap_pm_set_min_clk_rate() differs from the clock code's
+ * clk_set_rate() in that it considers other constraints before taking
+ * any hardware action, and may change a system OPP rather than just a
+ * clock rate.  clk_set_rate() is intended to be a low-level
+ * interface.
+ *
+ * omap_pm_set_min_clk_rate() is easily open to abuse.  A better API
+ * would be something like "omap_pm_set_min_dev_performance()";
+ * however, there is no easily-generalizable concept of performance
+ * that applies to all devices.  Only a device (and possibly the
+ * device subsystem) has both the subsystem-specific knowledge, and
+ * the hardware IP block-specific knowledge, to translate a constraint
+ * on "touchscreen sampling accuracy" or "number of pixels or polygons
+ * rendered per second" to a clock rate.  This translation can be
+ * dependent on the hardware IP block's revision, or firmware version,
+ * and the driver is the only code on the system that has this
+ * information and can know how to translate that into a clock rate.
+ *
+ * The intended use-case for this function is for userspace or other
+ * kernel code to communicate a particular performance requirement to
+ * a subsystem; then for the subsystem to communicate that requirement
+ * to something that is meaningful to the device driver; then for the
+ * device driver to convert that requirement to a clock rate, and to
+ * then call omap_pm_set_min_clk_rate().
+ *
+ * Users of this function (such as device drivers) should not simply
+ * call this function with some high clock rate to ensure "high
+ * performance."  Rather, the device driver should take a performance
+ * constraint from its subsystem, such as "render at least X polygons
+ * per second," and use some formula or table to convert that into a
+ * clock rate constraint given the hardware type and hardware
+ * revision.  Device drivers or subsystems should not assume that they
+ * know how to make a power/performance tradeoff - some device use
+ * cases may tolerate a lower-fidelity device function for lower power
+ * consumption; others may demand a higher-fidelity device function,
+ * no matter what the power consumption.
+ *
+ * Multiple calls to omap_pm_set_min_clk_rate() will replace the
+ * previous rate value for the device @dev.  To remove the minimum clock
+ * rate constraint for the device, call with r = 0.
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r);
+
 /*
  * DSP Bridge-specific constraints
  */
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index b0414f9..e129ce8 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -149,6 +149,33 @@ int omap_pm_set_max_sdma_lat(struct device *dev, long t)
 	return 0;
 }
 
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
+{
+	if (!dev || !c || r < 0) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	}
+
+	if (r == 0)
+		pr_debug("OMAP PM: remove min clk rate constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add min clk rate constraint: "
+			 "dev %s, rate = %ld Hz\n", dev_name(dev), r);
+
+	/*
+	 * Code in a real implementation should keep track of these
+	 * constraints on the clock, and determine the highest minimum
+	 * clock rate.  It should iterate over each OPP and determine
+	 * whether the OPP will result in a clock rate that would
+	 * satisfy this constraint (and any other PM constraint in effect
+	 *@that time).  Once it finds the lowest-voltage OPP that
+	 * meets those conditions, it should switch to it, or return
+	 * an error if the code is not capable of doing so.
+	 */
+
+	return 0;
+}
 
 /*
  * DSP Bridge-specific constraints

      parent reply	other threads:[~2010-07-02 15:30 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-02 15:29 [PATCH 00/20] OMAP: clock, hwmod, omap_device, PM constraints: patches for 2.6.36 Paul Walmsley
2010-07-02 15:29 ` [PATCH 01/20] OMAP3: wait on IDLEST after enabling USBTLL fclk Paul Walmsley
2010-07-02 15:29 ` [PATCH 02/20] OMAP: clock: add kerneldoc for structures; move flags closer to structs Paul Walmsley
2010-07-02 15:29 ` [PATCH 03/20] OMAP1: OPP: add KConfig entry for 96MHz ARM rate (using a 12MHz oscillator) Paul Walmsley
2010-07-02 15:29 ` [PATCH 04/20] OMAP1: clock: some cleanup Paul Walmsley
2010-07-02 15:29 ` [PATCH 05/20] OMAP24xx: CM: fix mask used for checking IDLEST status Paul Walmsley
2010-07-02 15:29 ` [PATCH 06/20] OMAP2/3: hwmod: L3 and L4 CORE/PER/WKUP hwmods don't have IDLEST Paul Walmsley
2010-07-02 15:29 ` [PATCH 07/20] OMAP2&3: hwmod: Remove _hwmod prefix in name string Paul Walmsley
2010-07-02 15:29 ` [PATCH 08/20] OMAP: hwmod: add non-locking versions of enable and idle functions Paul Walmsley
2010-07-02 15:29 ` [PATCH 09/20] OMAP: hwmod: allow omap_hwmod_late_init() caller to skip module idle in _setup() Paul Walmsley
2010-07-02 15:29 ` [PATCH 10/20] OMAP4: hwmod: Enable omap_device build for OMAP4 Paul Walmsley
2010-07-02 15:29 ` [PATCH 11/20] OMAP: omap_device: ensure hwmod tracks attached omap_device pointer Paul Walmsley
2010-07-02 15:29 ` [PATCH 12/20] OMAP: PM: create omap_devices for MPU, DSP, L3 Paul Walmsley
2010-07-15  5:25   ` Gopinath, Thara
2010-07-24  6:43     ` Gopinath, Thara
2010-07-27  7:22       ` Paul Walmsley
2010-07-27  7:37   ` Basak, Partha
2010-07-27  8:14     ` Gopinath, Thara
2010-07-02 15:29 ` [PATCH 13/20] OMAP: hwmod data: add class for IVA hwmods Paul Walmsley
2010-07-02 15:29 ` [PATCH 14/20] OMAP2&3: hwmod: Replace l3 -> l3_main Paul Walmsley
2010-07-02 15:29 ` [PATCH 15/20] OMAP3: hwmod data: add data for OMAP3 IVA2 Paul Walmsley
2010-07-02 15:29 ` [PATCH 16/20] OMAP2: hwmod data: add IVA1 (2420), IVA2 (2430) hwmods Paul Walmsley
2010-07-02 15:29 ` [PATCH 17/20] OMAP: hwmod/device: add omap_{device, hwmod}_get_mpu_rt_va Paul Walmsley
2010-07-03  9:21   ` Shilimkar, Santosh
2010-07-02 15:29 ` [PATCH 18/20] OMAP2+: hwmod/device: update documentation and copyright Paul Walmsley
2010-07-02 15:29 ` [PATCH 19/20] OMAP: PM constraints: add return values; add requesting device param to omap_pm_set_max_dev_wakeup_lat() Paul Walmsley
2010-07-02 15:30 ` Paul Walmsley [this message]

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20100702152958.6221.35036.stgit@localhost.localdomain \
    --to=paul@pwsan.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).