All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/7] OMAP: Basic DVFS framework
@ 2010-07-02 10:18 Thara Gopinath
  2010-07-02 10:18 ` [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
  2010-08-03 23:49 ` [RFC 0/7] OMAP: Basic DVFS framework Kevin Hilman
  0 siblings, 2 replies; 22+ messages in thread
From: Thara Gopinath @ 2010-07-02 10:18 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2,
	Thara Gopinath

This patch series is RFC for support of Dynamic Voltage and
Frequency Scaling (DVFS) for OMAP devices. DVFS is a technique that
uses the optimal operating frequency and voltage to allow a task to be
performed in the required amount of time.
OMAP processors have voltage domains whose voltage can be scaled to
various levels depending on which the operating frequencies of certain
devices belonging to the domain will also need to be scaled. This voltage
frequency tuple is known as Operating Performance Point (OPP). A device
can have multiple OPP's. Also a voltage domain could be shared between
multiple devices. Also there could be dependencies between various
voltage domains for maintaining system performance like VDD<X>
should be at voltage v1 when VDD<Y> is at voltage v2.

The design of this framework take into account all the above mentioned points.
To summarize the basic design of DVFS framework:-

1. Have device opp tables for each device whose operating frequency can be
   scaled. This is easy now due to the existance of hwmod layer which
   allow storing of device specific info. The device opp tables contain
   the opp pairs (frequency voltage tuples), the voltage domain pointer
   to which the device belongs to, the device specific set_rate and
   get_rate API's which will do the actual scaling of the device frequency
   and retrieve the current device frequency.
2. Introduce use counting on a per VDD basis. This is to take care multiple
   requests to scale a VDD. The VDD will be scaled to the maximum of the
   voltages requested.
3. Keep track of all scalable devices belonging to a particular voltage
   domain the voltage layer.
4. Generic API in the omap device layer which can be called by anybody
   to scale a device opp. This API will take in the device pointer and
   frequency to which the device needs to be scaled to. This API will
   then internally find out the voltage domain to which the device
   belongs to and the voltage to which the voltage domain needs to
   be put to for the device to be scaled to the new frequency from
   the device opp table. Then this API will call into the newly
   introduced API in voltage layer (as mentioned in 2) to see if
   there are other requests for the associated voltage domain to
   be at a voltage higher than the current chosen one. If not this
   API will go ahead and scale the voltage domain to the new voltage,
   run through the list of all scalable devices belonging to this
   voltage domain and scale them to the appropriate frequencies using
   the set_rate pointer in the device opp table.s

Work pending -
1. Handle inter VDD dependencies.
2. Add OMAP4 support.

Contributors to conceptualization of the design include
Benoit Cousson <b-cousson@ti.com>,
Kevin Hilman <khilman@deeprootsystems.com>,
Paul Wamsley <paul@pwsan.com>,
Vishwanath Sripathy <vishwanath.bs@ti.com>
Parthasarathy Basak <p-basak2@ti.com>
Anand Sawant <sawant@ti.com>

This patch series is primarily based of pm-sr branch of kevin's PM tree due to
it's dependency on the newly introduced opp and voltage layer. On top of this
branch I had to apply a few patches to test out dvfs using cpufreq framework.
The following are the link to these additional patches.
	https://patchwork.kernel.org/patch/107876/
	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=aa14cb9937e67c48f760c99a3c7fb3b2e7f5e623
	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=8f1298921d10789bb2f0a2d56cd3b92d844a1450
	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=10474ce3b07949d791b419aad433590e072e7159
	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=52fd40b873f8cd5aaea2d01d86ef35017c207eba
	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=57a2e45ff4a596a175aba27ae55a2b0d99adc3b5	

This series has been tested on OMAP3430 SDP for mpu and iva DVFS through
cpu freq framework.

Thara Gopinath (7):
  OMAP: Introduce a user list for each voltage domain instance in the
    voltage driver.
  OMAP: Introduce API in the OPP layer to find the opp entry
    corresponding to a voltage.
  OMAP: Introduce voltage domain pointer and device specific set rate
    and get rate in device opp structures.
  OMAP: Voltage layer changes to support DVFS.
  OMAP: Introduce device set_rate and get_rate.
  OMAP3: Update OMAP3 opp tables to contain the voltage domain and
    device set rate get rate info
  OMAP3: Update cpufreq driver to use the new set_rate API

 arch/arm/mach-omap2/cpufreq34xx.c             |  160 +++++++++++++++++++----
 arch/arm/mach-omap2/voltage.c                 |  172 ++++++++++++++++++++++++-
 arch/arm/plat-omap/cpu-omap.c                 |    5 +-
 arch/arm/plat-omap/include/plat/omap_device.h |    2 +
 arch/arm/plat-omap/include/plat/opp.h         |   39 ++++++-
 arch/arm/plat-omap/include/plat/voltage.h     |    6 +-
 arch/arm/plat-omap/omap_device.c              |   87 +++++++++++++
 arch/arm/plat-omap/opp.c                      |   75 +++++++++--
 8 files changed, 505 insertions(+), 41 deletions(-)


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

* [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
  2010-07-02 10:18 [RFC 0/7] OMAP: Basic DVFS framework Thara Gopinath
@ 2010-07-02 10:18 ` Thara Gopinath
  2010-07-02 10:18   ` [RFC 2/7] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage Thara Gopinath
  2010-07-02 11:44   ` [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Sripathy, Vishwanath
  2010-08-03 23:49 ` [RFC 0/7] OMAP: Basic DVFS framework Kevin Hilman
  1 sibling, 2 replies; 22+ messages in thread
From: Thara Gopinath @ 2010-07-02 10:18 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2,
	Thara Gopinath

This patch introduces a user list of devices associated with each
voltage domain instance. The user list is implemented using plist
structure with priority node populated with the voltage values.
This patch also adds an API which will take in a device and
requested voltage as parameters, adds the info to the user list
and returns back the maximum voltage requested by all the user
devices. This can be used anytime to get the voltage that the
voltage domain instance can be transitioned into.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/voltage.c             |   83 +++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/voltage.h |    2 +
 2 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 30f1770..a2f30a4 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -24,6 +24,9 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/debugfs.h>
+#include <linux/spinlock.h>
+#include <linux/plist.h>
+#include <linux/slab.h>
 
 #include <plat/omap-pm.h>
 #include <plat/omap34xx.h>
@@ -93,6 +96,20 @@ struct vp_reg_val {
 };
 
 /**
+ * omap_vdd_user_list	- The per vdd user list
+ *
+ * @dev		: The device asking for the vdd to be set at a particular
+ *		  voltage
+ * @node	: The list head entry
+ * @volt	: The voltage requested by the device <dev>
+ */
+struct omap_vdd_user_list {
+	struct device *dev;
+	struct plist_node node;
+	u32 volt;
+};
+
+/**
  * omap_vdd_info - Per Voltage Domain info
  *
  * @volt_data		: voltage table having the distinct voltages supported
@@ -103,6 +120,9 @@ struct vp_reg_val {
  *			  vp registers
  * @volt_clk		: the clock associated with the vdd.
  * @opp_dev		: the 'struct device' associated with this vdd.
+ * @user_lock		: the lock to be used by the plist user_list
+ * @user_list		: the list head maintaining the various users
+ *			  of this vdd with the voltage requested by each user.
  * @volt_data_count	: Number of distinct voltages supported by this vdd.
  * @nominal_volt	: Nominal voltaged for this vdd.
  * cmdval_reg		: Voltage controller cmdval register.
@@ -115,6 +135,8 @@ struct omap_vdd_info{
 	struct clk *volt_clk;
 	struct device *opp_dev;
 	struct omap_volt_domain volt_domain;
+	spinlock_t user_lock;
+	struct plist_head user_list;
 	int volt_data_count;
 	unsigned long nominal_volt;
 	u8 cmdval_reg;
@@ -361,6 +383,10 @@ static void __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
 	struct clk *sys_ck;
 	u32 sys_clk_speed, timeout_val, waittime;
 
+	/* Init the plist */
+	spin_lock_init(&vdd->user_lock);
+	plist_head_init(&vdd->user_list, &vdd->user_lock);
+
 	if (!strcmp(vdd->volt_domain.name, "mpu")) {
 		if (cpu_is_omap3630()) {
 			vdd->vp_reg.vlimitto_vddmin =
@@ -881,6 +907,63 @@ unsigned long omap_voltageprocessor_get_curr_volt(
 }
 
 /**
+ * omap_voltage_get_final : API to keep track of various requests to
+ *			    scale the VDD and returns the best possible
+ *			    voltage the VDD can be put to.
+ * @volt_domain: pointer to the voltage domain.
+ * @dev : the device pointer.
+ * @volt : the voltage which is requested by the device.
+ *
+ * This API is to be called before the actual voltage scaling is
+ * done to determine what is the best possible voltage the VDD can
+ * be put to. This API adds the device <dev> in the user list of the
+ * vdd <volt_domain> with <volt> as the requested voltage. The user list
+ * is a plist with the priority element absolute voltage values.
+ * The API then finds the maximum of all the requested voltages for
+ * the VDD and returns it back through <volt> pointer itself.
+ * Returns error value in case of any errors.
+ */
+int omap_volt_get_final(struct omap_volt_domain *volt_domain,
+		struct device *dev, unsigned long *volt)
+{
+	struct omap_vdd_info *vdd;
+	struct omap_vdd_user_list *user;
+	struct plist_node *node;
+	int found = 0;
+
+	if (!volt_domain || IS_ERR(volt_domain)) {
+		pr_warning("%s: VDD specified does not exist!\n", __func__);
+		return -EINVAL;
+	}
+
+	vdd = container_of(volt_domain, struct omap_vdd_info, volt_domain);
+
+	plist_for_each_entry(user, &vdd->user_list, node) {
+		if (user->dev == dev) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		user = kzalloc(sizeof(struct omap_vdd_user_list), GFP_KERNEL);
+		if (!user) {
+			pr_err("%s: Unable to creat a new user for vdd_%s\n",
+				__func__, volt_domain->name);
+			return -ENOMEM;
+		}
+		user->dev = dev;
+		plist_node_init(&user->node, *volt);
+		plist_add(&user->node, &vdd->user_list);
+	}
+
+	user->node.prio = *volt;
+	node = plist_first(&vdd->user_list);
+	*volt = node->prio;
+	return 0;
+}
+
+/**
  * omap_voltageprocessor_enable : API to enable a particular VP
  * @volt_domain: pointer to the VDD whose VP is to be enabled.
  *
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index b7ac318..bc1e4d3 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -128,6 +128,8 @@ int omap_get_voltage_table(struct omap_volt_domain *volt_domain,
 struct omap_volt_data *omap_get_volt_data(
 		struct omap_volt_domain *volt_domain, unsigned long volt);
 unsigned long get_curr_voltage(struct omap_volt_domain *volt_domain);
+int omap_volt_get_final(struct omap_volt_domain *volt_domain,
+		struct device *dev, unsigned long *volt);
 #ifdef CONFIG_PM
 void omap_voltage_init_vc(struct omap_volt_vc_data *setup_vc);
 #else
-- 
1.7.0.rc1.33.g07cf0f


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

* [RFC 2/7] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage.
  2010-07-02 10:18 ` [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
@ 2010-07-02 10:18   ` Thara Gopinath
  2010-07-02 10:18     ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thara Gopinath
  2010-07-02 11:44   ` [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Sripathy, Vishwanath
  1 sibling, 1 reply; 22+ messages in thread
From: Thara Gopinath @ 2010-07-02 10:18 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2,
	Thara Gopinath

This patch adds an API in the opp layer to get the opp table entry
corresponding to the voltage passed as the parameter.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/plat-omap/include/plat/opp.h |    2 ++
 arch/arm/plat-omap/opp.c              |   28 ++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index 29e3d03..893731f 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -75,6 +75,8 @@ struct omap_opp *opp_find_freq_floor(struct device *dev, unsigned long *freq);
 
 struct omap_opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq);
 
+struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt);
+
 int opp_add(const struct omap_opp_def *opp_def);
 
 int opp_enable(struct omap_opp *opp);
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 0273497..070ff5b 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -302,6 +302,34 @@ struct omap_opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
 	return opp;
 }
 
+/**
+ * opp_find_voltage() - search for an exact voltage
+ * @dev:	device pointer associated with the opp type
+ * @volt:	voltage to search for
+ *
+ * Searches for exact match in the opp list and returns handle to the matching
+ * opp if found, else returns ERR_PTR in case of error and should be handled
+ * using IS_ERR.
+ */
+struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt)
+{
+	struct device_opp *dev_opp;
+	struct omap_opp *temp_opp, *opp = ERR_PTR(-ENODEV);
+
+	dev_opp = find_device_opp(dev);
+	if (IS_ERR(dev_opp))
+		return opp;
+
+	list_for_each_entry(temp_opp, &dev_opp->opp_list, node) {
+		if (temp_opp->enabled && temp_opp->u_volt == volt) {
+			opp = temp_opp;
+			break;
+		}
+	}
+
+	return opp;
+}
+
 /* wrapper to reuse converting opp_def to opp struct */
 static void omap_opp_populate(struct omap_opp *opp,
 			      const struct omap_opp_def *opp_def)
-- 
1.7.0.rc1.33.g07cf0f


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

* [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-07-02 10:18   ` [RFC 2/7] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage Thara Gopinath
@ 2010-07-02 10:18     ` Thara Gopinath
  2010-07-02 10:18       ` [RFC 4/7] OMAP: Voltage layer changes to support DVFS Thara Gopinath
                         ` (3 more replies)
  0 siblings, 4 replies; 22+ messages in thread
From: Thara Gopinath @ 2010-07-02 10:18 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2,
	Thara Gopinath

This patch extends the device opp structure to contain
info about the voltage domain to which the device belongs to
and to contain pointers to scale the operating rate of the
device. This patch also adds an API in the opp layer that
can be used by the voltage layer to get a list of all the
scalable devices belonging to a particular voltage domain.
This API is to be typically called only once by the voltage
layer per voltage domain instance and the device list should
be stored. This approach makes it easy during dvfs to scale
all the devices associated with a voltage domain and then
scale the voltage domain.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/plat-omap/include/plat/opp.h |   37 +++++++++++++++++++++++++-
 arch/arm/plat-omap/opp.c              |   47 +++++++++++++++++++++++++-------
 2 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index 893731f..15e1e70 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -16,6 +16,7 @@
 
 #include <linux/err.h>
 #include <linux/cpufreq.h>
+#include <linux/clk.h>
 
 #include <plat/common.h>
 
@@ -38,21 +39,45 @@
  */
 struct omap_opp_def {
 	char *hwmod_name;
+	char *vdd_name;
 
 	unsigned long freq;
 	unsigned long u_volt;
 
+	int (*set_rate)(struct device *dev, unsigned long rate);
+	unsigned long (*get_rate) (struct device *dev);
+
 	bool enabled;
 };
 
+struct device_opp {
+	struct list_head node;
+	char *vdd_name;
+
+	struct omap_hwmod *oh;
+	struct device *dev;
+	struct omap_volt_domain *volt_domain;
+
+	struct list_head opp_list;
+	u32 opp_count;
+	u32 enabled_opp_count;
+
+	int (*set_rate)(struct device *dev, unsigned long rate);
+	unsigned long (*get_rate) (struct device *dev);
+};
+
 /*
  * Initialization wrapper used to define an OPP.
  * To point at the end of a terminator of a list of OPPs,
  * use OMAP_OPP_DEF(0, 0, 0)
  */
-#define OMAP_OPP_DEF(_hwmod_name, _enabled, _freq, _uv)	\
+#define OMAP_OPP_DEF(_hwmod_name, _vdd_name, _set_rate, _get_rate, \
+			_enabled, _freq, _uv)	\
 {						\
 	.hwmod_name	= _hwmod_name,		\
+	.vdd_name	= _vdd_name,		\
+	.set_rate	= _set_rate,		\
+	.get_rate	= _get_rate,		\
 	.enabled	= _enabled,		\
 	.freq		= _freq,		\
 	.u_volt		= _uv,			\
@@ -77,6 +102,8 @@ struct omap_opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq);
 
 struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt);
 
+struct device_opp *opp_find_dev_opp(struct device *dev);
+
 int opp_add(const struct omap_opp_def *opp_def);
 
 int opp_enable(struct omap_opp *opp);
@@ -89,6 +116,9 @@ u8 __deprecated opp_get_opp_id(struct omap_opp *opp);
 
 void opp_init_cpufreq_table(struct device *dev,
 			    struct cpufreq_frequency_table **table);
+
+struct device **opp_init_voltage_params(struct omap_volt_domain *volt_domain,
+		int *dev_count);
 #else
 static inline unsigned long opp_get_voltage(const struct omap_opp *opp)
 {
@@ -124,6 +154,11 @@ static inline struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl,
 	return ERR_PTR(-EINVAL);
 }
 
+static inline struct device_opp *opp_find_dev_opp(struct device *dev)
+{
+	return ERR_PTR(-EINVAL);
+}
+
 static inline struct omap_opp *opp_add(struct omap_opp *oppl,
 				       const struct omap_opp_def *opp_def)
 {
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 070ff5b..9bc53e8 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -22,6 +22,7 @@
 #include <plat/opp_twl_tps.h>
 #include <plat/opp.h>
 #include <plat/omap_device.h>
+#include <plat/voltage.h>
 
 /**
  * struct omap_opp - OMAP OPP description structure
@@ -43,17 +44,6 @@ struct omap_opp {
 	struct device_opp *dev_opp;  /* containing device_opp struct */
 };
 
-struct device_opp {
-	struct list_head node;
-
-	struct omap_hwmod *oh;
-	struct device *dev;
-
-	struct list_head opp_list;
-	u32 opp_count;
-	u32 enabled_opp_count;
-};
-
 static LIST_HEAD(dev_opp_list);
 
 /**
@@ -330,6 +320,11 @@ struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt)
 	return opp;
 }
 
+struct device_opp *opp_find_dev_opp(struct device *dev)
+{
+	return find_device_opp(dev);
+}
+
 /* wrapper to reuse converting opp_def to opp struct */
 static void omap_opp_populate(struct omap_opp *opp,
 			      const struct omap_opp_def *opp_def)
@@ -385,6 +380,11 @@ int opp_add(const struct omap_opp_def *opp_def)
 
 		dev_opp->oh = oh;
 		dev_opp->dev = &oh->od->pdev.dev;
+		dev_opp->vdd_name = kzalloc(strlen(opp_def->vdd_name) + 1,
+				GFP_KERNEL);
+		strcpy(dev_opp->vdd_name, opp_def->vdd_name);
+		dev_opp->set_rate = opp_def->set_rate;
+		dev_opp->get_rate = opp_def->get_rate;
 		INIT_LIST_HEAD(&dev_opp->opp_list);
 
 		list_add(&dev_opp->node, &dev_opp_list);
@@ -511,3 +511,28 @@ void opp_init_cpufreq_table(struct device *dev,
 
 	*table = &freq_table[0];
 }
+
+struct device **opp_init_voltage_params(struct omap_volt_domain *volt_domain,
+		int *dev_count)
+{
+	struct device_opp *dev_opp;
+	struct device **dev_list;
+	int count = 0, i = 0;
+
+	list_for_each_entry(dev_opp, &dev_opp_list, node) {
+		if (!strcmp(dev_opp->vdd_name, volt_domain->name)) {
+			dev_opp->volt_domain = volt_domain;
+			count++;
+		}
+	}
+
+	dev_list = kzalloc(sizeof(struct device *) * count, GFP_KERNEL);
+
+	list_for_each_entry(dev_opp, &dev_opp_list, node) {
+		if (dev_opp->volt_domain == volt_domain)
+			dev_list[i++] = dev_opp->dev;
+	}
+
+	*dev_count = count;
+	return dev_list;
+}
-- 
1.7.0.rc1.33.g07cf0f


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

* [RFC 4/7] OMAP: Voltage layer changes to support DVFS.
  2010-07-02 10:18     ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thara Gopinath
@ 2010-07-02 10:18       ` Thara Gopinath
  2010-07-02 10:18         ` [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer Thara Gopinath
  2010-07-12 14:48       ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thomas Petazzoni
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 22+ messages in thread
From: Thara Gopinath @ 2010-07-02 10:18 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2,
	Thara Gopinath

This patch introduces a list of scalable devices associated with
a particular voltage domain instance. This list is obtained from
the opp layer during init. This patch also introduces an API
to take in the voltage domain and the new voltage as parameter
and to scale all the scalable devices associated with the the
voltage domain to the rate corresponding to the new voltage and
scale the voltage domain to the new voltage.

This patch renames the previous omap_voltage_scale API to
omap_voltage_scale_vdd.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/voltage.c             |   89 ++++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/voltage.h |    4 +-
 2 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index a2f30a4..1e6712e 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -137,6 +137,8 @@ struct omap_vdd_info{
 	struct omap_volt_domain volt_domain;
 	spinlock_t user_lock;
 	struct plist_head user_list;
+	struct device **dev_list;
+	int dev_count;
 	int volt_data_count;
 	unsigned long nominal_volt;
 	u8 cmdval_reg;
@@ -387,6 +389,10 @@ static void __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
 	spin_lock_init(&vdd->user_lock);
 	plist_head_init(&vdd->user_list, &vdd->user_lock);
 
+	/* Get the devices associated with this VDD */
+	vdd->dev_list = opp_init_voltage_params(&vdd->volt_domain,
+			&vdd->dev_count);
+
 	if (!strcmp(vdd->volt_domain.name, "mpu")) {
 		if (cpu_is_omap3630()) {
 			vdd->vp_reg.vlimitto_vddmin =
@@ -1073,7 +1079,8 @@ void omap_voltageprocessor_disable(struct omap_volt_domain *volt_domain)
 }
 
 /**
- * omap_voltage_scale : API to scale voltage of a particular voltage domain.
+ * omap_voltage_scale_vdd : API to scale voltage of a particular
+ *			    voltage domain.
  * @volt_domain: pointer to the VDD which is to be scaled.
  * @target_vsel : The target voltage of the voltage domain
  * @current_vsel : the current voltage of the voltage domain.
@@ -1081,7 +1088,7 @@ void omap_voltageprocessor_disable(struct omap_volt_domain *volt_domain)
  * This API should be called by the kernel to do the voltage scaling
  * for a particular voltage domain during dvfs or any other situation.
  */
-int omap_voltage_scale(struct omap_volt_domain *volt_domain,
+int omap_voltage_scale_vdd(struct omap_volt_domain *volt_domain,
 					unsigned long target_volt)
 {
 	struct omap_vdd_info *vdd;
@@ -1290,6 +1297,84 @@ struct omap_volt_domain *omap_volt_domain_get(char *name)
 }
 
 /**
+ * omap_voltage_scale : API to scale the devices associated with a
+ *			voltage domain vdd voltage.
+ * @volt_domain : the voltage domain to be scaled
+ * @volt : the new voltage for the voltage domain
+ *
+ * This API runs through the list of devices associated with the
+ * voltage domain and scales the device rates to those corresponding
+ * to the new voltage of the voltage domain. This API also scales
+ * the voltage domain voltage to the new value. Returns 0 on success
+ * else the error value.
+ */
+int omap_voltage_scale(struct omap_volt_domain *volt_domain,
+		unsigned long volt)
+{
+	unsigned long curr_volt;
+	int is_volt_scaled = 0, i;
+	struct omap_vdd_info *vdd;
+
+	if (!volt_domain || IS_ERR(volt_domain)) {
+		pr_warning("%s: VDD specified does not exist!\n", __func__);
+		return -EINVAL;
+	}
+
+	vdd = container_of(volt_domain, struct omap_vdd_info, volt_domain);
+	curr_volt = get_curr_voltage(volt_domain);
+
+	if (curr_volt == volt) {
+		is_volt_scaled = 1;
+	} else if (curr_volt < volt) {
+		omap_voltage_scale_vdd(volt_domain, volt);
+		is_volt_scaled = 1;
+	}
+
+	for (i = 0; i < vdd->dev_count; i++) {
+		struct device_opp *dev_opp;
+		struct omap_opp *opp;
+		unsigned long freq;
+
+		dev_opp = opp_find_dev_opp(vdd->dev_list[i]);
+		if (IS_ERR(dev_opp)) {
+			dev_err(vdd->dev_list[i], "%s: Unable to find device"
+				"opp table\n", __func__);
+			continue;
+		}
+		if (!dev_opp->set_rate) {
+			dev_err(vdd->dev_list[i], "%s: No set_rate API"
+				"for scaling opp\n", __func__);
+			continue;
+		}
+
+		opp = opp_find_voltage(vdd->dev_list[i], volt);
+		if (IS_ERR(opp)) {
+			dev_err(vdd->dev_list[i], "%s: Unable to find OPP for"
+				"volt%ld\n", __func__, volt);
+			continue;
+		}
+
+		freq = opp_get_freq(opp);
+
+		if (dev_opp->get_rate) {
+			if (freq == dev_opp->get_rate(vdd->dev_list[i])) {
+				dev_err(vdd->dev_list[i], "%s: Already at the"
+					"requested rate %ld\n",
+					__func__, freq);
+				continue;
+			}
+		}
+
+		dev_opp->set_rate(vdd->dev_list[i], freq);
+	}
+
+	if (!is_volt_scaled)
+		omap_voltage_scale_vdd(volt_domain, volt);
+
+	return 0;
+}
+
+/**
  * omap_voltage_init : Volatage init API which does VP and VC init.
  */
 static int __init omap_voltage_init(void)
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index bc1e4d3..072ee76 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -120,8 +120,10 @@ unsigned long omap_voltageprocessor_get_curr_volt(
 		struct omap_volt_domain *volt_domain);
 void omap_voltageprocessor_enable(struct omap_volt_domain *volt_domain);
 void omap_voltageprocessor_disable(struct omap_volt_domain *volt_domain);
-int omap_voltage_scale(struct omap_volt_domain *volt_domain,
+int omap_voltage_scale_vdd(struct omap_volt_domain *volt_domain,
 		unsigned long target_volt);
+int omap_voltage_scale(struct omap_volt_domain *volt_domain,
+		unsigned long volt);
 void omap_reset_voltage(struct omap_volt_domain *volt_domain);
 int omap_get_voltage_table(struct omap_volt_domain *volt_domain,
 					struct omap_volt_data **volt_data);
-- 
1.7.0.rc1.33.g07cf0f


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

* [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer
  2010-07-02 10:18       ` [RFC 4/7] OMAP: Voltage layer changes to support DVFS Thara Gopinath
@ 2010-07-02 10:18         ` Thara Gopinath
  2010-07-02 10:18           ` [RFC 6/7] OMAP3: Update OMAP3 opp tables to contain the voltage domain and device set rate get rate info Thara Gopinath
  2010-07-02 11:52           ` [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer Sripathy, Vishwanath
  0 siblings, 2 replies; 22+ messages in thread
From: Thara Gopinath @ 2010-07-02 10:18 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2,
	Thara Gopinath

This patch adds omap_device_set_rate and omap_device_get_rate
API's which can be used to generic device rate scaling.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/plat-omap/include/plat/omap_device.h |    2 +
 arch/arm/plat-omap/omap_device.c              |   87 +++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 3694b62..e0d06bb 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -114,6 +114,8 @@ int omap_device_enable_hwmods(struct omap_device *od);
 int omap_device_disable_clocks(struct omap_device *od);
 int omap_device_enable_clocks(struct omap_device *od);
 
+int omap_device_set_rate(struct device *dev, unsigned long rate);
+unsigned long omap_device_get_rate(struct device *dev);
 
 /*
  * Entries should be kept in latency order ascending
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 6614cba..900bb5d 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -85,6 +85,8 @@
 
 #include <plat/omap_device.h>
 #include <plat/omap_hwmod.h>
+#include <plat/opp.h>
+#include <plat/voltage.h>
 
 /* These parameters are passed to _omap_device_{de,}activate() */
 #define USE_WAKEUP_LAT			0
@@ -734,3 +736,88 @@ int omap_device_enable_clocks(struct omap_device *od)
 	/* XXX pass along return value here? */
 	return 0;
 }
+
+/**
+ * omap_device_set_rate - Set a new rate at which the device is to operate
+ * @dev : the device pointer
+ * @rate : the rnew rate for the device.
+ *
+ * This API gets the device opp table associated with this device and
+ * tries putting the device to the requested rate and the voltage domain
+ * associated with the device to the voltage corresponding to the
+ * requested rate. Since multiple devices can be assocciated with a
+ * voltage domain this API finds out the possible voltage the
+ * voltage domain can enter and then decides on the final device
+ * rate. Return 0 on success else the error value
+ */
+int omap_device_set_rate(struct device *dev, unsigned long rate)
+{
+	struct device_opp *dev_opp;
+	struct omap_opp *opp;
+	unsigned long volt, freq;
+	int ret;
+
+	dev_opp = opp_find_dev_opp(dev);
+	if (IS_ERR(dev_opp)) {
+		dev_warn(dev, "%s: Unable to find device opp table\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	/* Get the possible rate from the opp layer */
+	freq = rate;
+	opp = opp_find_freq_ceil(dev, &freq);
+	if (IS_ERR(opp)) {
+		dev_err(dev, "%s: Unable to find OPP for freq%ld\n",
+			__func__, rate);
+		return -ENODEV;
+	}
+	if (unlikely(freq != rate))
+		dev_warn(dev, "%s: Available freq %ld != dpll freq %ld.\n",
+			__func__, freq, rate);
+
+	/* Get the voltage corresponding to the requested frequency */
+	volt = opp_get_voltage(opp);
+
+	/*
+	 * Call into the voltage layer to get the final voltage possible
+	 * for the voltage domain associated with the device.
+	 */
+
+	ret = omap_volt_get_final(dev_opp->volt_domain, dev, &volt);
+	if (ret) {
+		dev_err(dev, "%s: Unable to get the final volt for scaling\n",
+			__func__);
+		return ret;
+	}
+
+	/* Do the actual scaling */
+	return omap_voltage_scale(dev_opp->volt_domain, volt);
+}
+
+/**
+ * omap_device_get_rate - Gets the current operating rate of the device
+ * @dev - the device pointer
+ *
+ * This API returns the current operating rate of the device on success.
+ * Else returns the error value.
+ */
+unsigned long omap_device_get_rate(struct device *dev)
+{
+	struct device_opp *dev_opp;
+
+	dev_opp = opp_find_dev_opp(dev);
+
+	if (IS_ERR(dev_opp)) {
+		dev_warn(dev, "%s: Unable to find device opp table\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	if (!dev_opp->get_rate) {
+		dev_warn(dev, "%s: No get_rate API\n", __func__);
+		return -EINVAL;
+	}
+
+	return dev_opp->get_rate(dev);
+}
-- 
1.7.0.rc1.33.g07cf0f


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

* [RFC 6/7] OMAP3: Update OMAP3 opp tables to contain the voltage domain and device set rate get rate info
  2010-07-02 10:18         ` [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer Thara Gopinath
@ 2010-07-02 10:18           ` Thara Gopinath
  2010-07-02 10:18             ` [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API Thara Gopinath
  2010-07-02 11:52           ` [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer Sripathy, Vishwanath
  1 sibling, 1 reply; 22+ messages in thread
From: Thara Gopinath @ 2010-07-02 10:18 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2,
	Thara Gopinath

This patch updates the omap3 opp tables to contain the voltage domain
associated with the opp. This patch also introduces
omap3_mpu_set_rate, omap3_iva_set_rate, omap3_l3_set_rate,
omap3_mpu_get_rate, omap3_iva_get_rate, omap3_l3_get_rate as device
specific set rate and get rate API's for OMAP3 mpu, iva and l3_main devices
and hooks them up in the correspoinding opp table entries.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/cpufreq34xx.c |  160 +++++++++++++++++++++++++++++++------
 1 files changed, 136 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-omap2/cpufreq34xx.c b/arch/arm/mach-omap2/cpufreq34xx.c
index 1589542..1f65f7e 100644
--- a/arch/arm/mach-omap2/cpufreq34xx.c
+++ b/arch/arm/mach-omap2/cpufreq34xx.c
@@ -21,22 +21,41 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/cpufreq.h>
 
 #include <plat/opp.h>
 #include <plat/cpu.h>
+#include <plat/clock.h>
+#include "cm-regbits-34xx.h"
+#include "prm.h"
 #include "omap3-opp.h"
 
+static int omap3_mpu_set_rate(struct device *dev, unsigned long rate);
+static int omap3_iva_set_rate(struct device *dev, unsigned long rate);
+static int omap3_l3_set_rate(struct device *dev, unsigned long rate);
+
+static unsigned long omap3_mpu_get_rate(struct device *dev);
+static unsigned long omap3_iva_get_rate(struct device *dev);
+static unsigned long omap3_l3_get_rate(struct device *dev);
+
+struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
+
 static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
 	/* MPU OPP1 */
-	OMAP_OPP_DEF("mpu", true, 125000000, 975000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+			true, 125000000, 975000),
 	/* MPU OPP2 */
-	OMAP_OPP_DEF("mpu", true, 250000000, 1075000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+		true, 250000000, 1075000),
 	/* MPU OPP3 */
-	OMAP_OPP_DEF("mpu", true, 500000000, 1200000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+			true, 500000000, 1200000),
 	/* MPU OPP4 */
-	OMAP_OPP_DEF("mpu", true, 550000000, 1270000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+			true, 550000000, 1270000),
 	/* MPU OPP5 */
-	OMAP_OPP_DEF("mpu", true, 600000000, 1350000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+			true, 600000000, 1350000),
 
 	/*
 	 * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
@@ -46,52 +65,141 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
 	 * impact that frequency will do to the MPU and the whole system in
 	 * general.
 	 */
-	OMAP_OPP_DEF("l3_main", false, 41500000, 975000),
+	OMAP_OPP_DEF("l3_main", "core", omap3_l3_set_rate, omap3_l3_get_rate,
+			false, 41500000, 975000),
 	/* L3 OPP2 */
-	OMAP_OPP_DEF("l3_main", true, 83000000, 1050000),
+	OMAP_OPP_DEF("l3_main", "core", omap3_l3_set_rate, omap3_l3_get_rate,
+			true, 83000000, 1050000),
 	/* L3 OPP3 */
-	OMAP_OPP_DEF("l3_main", true, 166000000, 1150000),
-
+	OMAP_OPP_DEF("l3_main", "core", omap3_l3_set_rate, omap3_l3_get_rate,
+			true, 166000000, 1150000),
 
 	/* DSP OPP1 */
-	OMAP_OPP_DEF("iva", true, 90000000, 975000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			true, 90000000, 975000),
 	/* DSP OPP2 */
-	OMAP_OPP_DEF("iva", true, 180000000, 1075000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			true, 180000000, 1075000),
 	/* DSP OPP3 */
-	OMAP_OPP_DEF("iva", true, 360000000, 1200000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			true, 360000000, 1200000),
 	/* DSP OPP4 */
-	OMAP_OPP_DEF("iva", true, 400000000, 1270000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			true, 400000000, 1270000),
 	/* DSP OPP5 */
-	OMAP_OPP_DEF("iva", true, 430000000, 1350000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			true, 430000000, 1350000),
 };
 static u32 omap34xx_opp_def_size = ARRAY_SIZE(omap34xx_opp_def_list);
 
 static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
 	/* MPU OPP1 - OPP50 */
-	OMAP_OPP_DEF("mpu", true,  300000000, 930000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+			true, 300000000, 930000),
 	/* MPU OPP2 - OPP100 */
-	OMAP_OPP_DEF("mpu", true,  600000000, 1100000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+			true,  600000000, 1100000),
 	/* MPU OPP3 - OPP-Turbo */
-	OMAP_OPP_DEF("mpu", false, 800000000, 1260000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+			false, 800000000, 1260000),
 	/* MPU OPP4 - OPP-SB */
-	OMAP_OPP_DEF("mpu", false, 1000000000, 1350000),
+	OMAP_OPP_DEF("mpu", "mpu", omap3_mpu_set_rate, omap3_mpu_get_rate,
+			false, 1000000000, 1350000),
 
 	/* L3 OPP1 - OPP50 */
-	OMAP_OPP_DEF("l3_main", true, 100000000, 930000),
+	OMAP_OPP_DEF("l3_main", "core", omap3_l3_set_rate, omap3_l3_get_rate,
+			true, 100000000, 930000),
 	/* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
-	OMAP_OPP_DEF("l3_main", true, 200000000, 1137500),
+	OMAP_OPP_DEF("l3_main", "core", omap3_l3_set_rate, omap3_l3_get_rate,
+			true, 200000000, 1137500),
 
 	/* DSP OPP1 - OPP50 */
-	OMAP_OPP_DEF("iva", true,  260000000, 930000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			true,  260000000, 930000),
 	/* DSP OPP2 - OPP100 */
-	OMAP_OPP_DEF("iva", true,  520000000, 1100000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			true,  520000000, 1100000),
 	/* DSP OPP3 - OPP-Turbo */
-	OMAP_OPP_DEF("iva", false, 660000000, 1260000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			false, 660000000, 1260000),
 	/* DSP OPP4 - OPP-SB */
-	OMAP_OPP_DEF("iva", false, 800000000, 1350000),
+	OMAP_OPP_DEF("iva", "mpu", omap3_iva_set_rate, omap3_iva_get_rate,
+			false, 800000000, 1350000),
 };
 static u32 omap36xx_opp_def_size = ARRAY_SIZE(omap36xx_opp_def_list);
 
+static int omap3_iva_set_rate(struct device *dev, unsigned long rate)
+{
+	dev_warn(dev, "%s: Setting device rate to %ld", __func__, rate);
+	return clk_set_rate(dpll2_clk, rate);
+}
+
+static unsigned long omap3_iva_get_rate(struct device *dev)
+{
+	return dpll2_clk->rate;
+}
+
+static int omap3_mpu_set_rate(struct device *dev, unsigned long rate)
+{
+	unsigned long cur_rate = omap3_mpu_get_rate(dev);
+	int ret;
+
+#ifdef CONFIG_CPU_FREQ
+	struct cpufreq_freqs freqs_notify;
+
+	freqs_notify.old = cur_rate / 1000;
+	freqs_notify.new = rate / 1000;
+	freqs_notify.cpu = 0;
+	/* Send pre notification to CPUFreq */
+	cpufreq_notify_transition(&freqs_notify, CPUFREQ_PRECHANGE);
+#endif
+	dev_warn(dev, "%s: Setting device rate to %ld", __func__, rate);
+	ret = clk_set_rate(dpll1_clk, rate);
+	if (ret) {
+		dev_warn(dev, "%s: Unable to set rate to %ld\n",
+			__func__, rate);
+		return ret;
+	}
+
+#ifdef CONFIG_CPU_FREQ
+	/* Send a post notification to CPUFreq */
+	cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
+#endif
+
+#ifndef CONFIG_CPU_FREQ
+	/*Update loops_per_jiffy if processor speed is being changed*/
+	loops_per_jiffy = compute_lpj(loops_per_jiffy,
+			cur_rate / 1000, rate / 1000);
+#endif
+	return 0;
+}
+
+static unsigned long omap3_mpu_get_rate(struct device *dev)
+{
+	return dpll1_clk->rate;
+}
+
+static int omap3_l3_set_rate(struct device *dev, unsigned long rate)
+{
+	int l3_div;
+
+	dev_warn(dev, "%s: Setting device rate to %ld", __func__, rate);
+
+	l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+			OMAP3430_CLKSEL_L3_MASK;
+
+	return clk_set_rate(dpll3_clk, rate * l3_div);
+}
+
+static unsigned long omap3_l3_get_rate(struct device *dev)
+{
+	int l3_div;
+
+	l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+			OMAP3430_CLKSEL_L3_MASK;
+	return dpll3_clk->rate / l3_div;
+}
+
 /* Temp variable to allow multiple calls */
 static u8 __initdata omap3_table_init;
 
@@ -122,6 +230,10 @@ int __init omap3_pm_init_opp_table(void)
 				opp_def->freq, opp_def->hwmod_name);
 	}
 
+	dpll1_clk = clk_get(NULL, "dpll1_ck");
+	dpll2_clk = clk_get(NULL, "dpll2_ck");
+	dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
+
 	return 0;
 }
 
-- 
1.7.0.rc1.33.g07cf0f


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

* [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API
  2010-07-02 10:18           ` [RFC 6/7] OMAP3: Update OMAP3 opp tables to contain the voltage domain and device set rate get rate info Thara Gopinath
@ 2010-07-02 10:18             ` Thara Gopinath
  2010-07-08  3:10               ` Pandita, Vikram
  0 siblings, 1 reply; 22+ messages in thread
From: Thara Gopinath @ 2010-07-02 10:18 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2,
	Thara Gopinath

This patch updates the cpufreq driver to use the device
set rate API to scale the mpu frequency for OMAP3.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/plat-omap/cpu-omap.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 9467827..cde02b5 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -29,6 +29,7 @@
 #include <mach/hardware.h>
 #include <plat/clock.h>
 #include <asm/system.h>
+#include <plat/omap_device.h>
 
 #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
 #include <plat/omap-pm.h>
@@ -84,7 +85,7 @@ static int omap_target(struct cpufreq_policy *policy,
 		       unsigned int target_freq,
 		       unsigned int relation)
 {
-#ifdef CONFIG_ARCH_OMAP1
+#ifdef CONFIG_ARiCH_OMAP1
 	struct cpufreq_freqs freqs;
 #endif
 #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
@@ -117,7 +118,7 @@ static int omap_target(struct cpufreq_policy *policy,
 #elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
 	freq = target_freq * 1000;
 	if (opp_find_freq_ceil(mpu_dev, &freq))
-		omap_pm_cpu_set_freq(freq);
+		omap_device_set_rate(mpu_dev, freq);
 #endif
 	return ret;
 }
-- 
1.7.0.rc1.33.g07cf0f


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

* RE: [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
  2010-07-02 10:18 ` [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
  2010-07-02 10:18   ` [RFC 2/7] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage Thara Gopinath
@ 2010-07-02 11:44   ` Sripathy, Vishwanath
  1 sibling, 0 replies; 22+ messages in thread
From: Sripathy, Vishwanath @ 2010-07-02 11:44 UTC (permalink / raw)
  To: Gopinath, Thara, linux-omap
  Cc: khilman, paul, Cousson, Benoit, Sawant, Anand, Basak, Partha

Thara,

> -----Original Message-----
> From: Gopinath, Thara
> Sent: Friday, July 02, 2010 3:48 PM
> To: linux-omap@vger.kernel.org
> Cc: khilman@deeprootsystems.com; paul@pwsan.com; Cousson, Benoit; Sripathy,
> Vishwanath; Sawant, Anand; Basak, Partha; Gopinath, Thara
> Subject: [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in
> the voltage driver.
> 
> This patch introduces a user list of devices associated with each
> voltage domain instance. The user list is implemented using plist
> structure with priority node populated with the voltage values.
> This patch also adds an API which will take in a device and
> requested voltage as parameters, adds the info to the user list
> and returns back the maximum voltage requested by all the user
> devices. This can be used anytime to get the voltage that the
> voltage domain instance can be transitioned into.
> 
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
>  arch/arm/mach-omap2/voltage.c             |   83
> +++++++++++++++++++++++++++++
>  arch/arm/plat-omap/include/plat/voltage.h |    2 +
>  2 files changed, 85 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index 30f1770..a2f30a4 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -24,6 +24,9 @@
>  #include <linux/clk.h>
>  #include <linux/err.h>
>  #include <linux/debugfs.h>
> +#include <linux/spinlock.h>
> +#include <linux/plist.h>
> +#include <linux/slab.h>
> 
>  #include <plat/omap-pm.h>
>  #include <plat/omap34xx.h>
> @@ -93,6 +96,20 @@ struct vp_reg_val {
>  };
> 
>  /**
> + * omap_vdd_user_list	- The per vdd user list
> + *
> + * @dev		: The device asking for the vdd to be set at a particular
> + *		  voltage
> + * @node	: The list head entry
> + * @volt	: The voltage requested by the device <dev>
> + */
> +struct omap_vdd_user_list {
> +	struct device *dev;
> +	struct plist_node node;
> +	u32 volt;
> +};
> +
> +/**
>   * omap_vdd_info - Per Voltage Domain info
>   *
>   * @volt_data		: voltage table having the distinct voltages supported
> @@ -103,6 +120,9 @@ struct vp_reg_val {
>   *			  vp registers
>   * @volt_clk		: the clock associated with the vdd.
>   * @opp_dev		: the 'struct device' associated with this vdd.
> + * @user_lock		: the lock to be used by the plist user_list
> + * @user_list		: the list head maintaining the various users
> + *			  of this vdd with the voltage requested by each user.
>   * @volt_data_count	: Number of distinct voltages supported by this vdd.
>   * @nominal_volt	: Nominal voltaged for this vdd.
>   * cmdval_reg		: Voltage controller cmdval register.
> @@ -115,6 +135,8 @@ struct omap_vdd_info{
>  	struct clk *volt_clk;
>  	struct device *opp_dev;
>  	struct omap_volt_domain volt_domain;
> +	spinlock_t user_lock;
> +	struct plist_head user_list;
>  	int volt_data_count;
>  	unsigned long nominal_volt;
>  	u8 cmdval_reg;
> @@ -361,6 +383,10 @@ static void __init omap3_vdd_data_configure(struct
> omap_vdd_info *vdd)
>  	struct clk *sys_ck;
>  	u32 sys_clk_speed, timeout_val, waittime;
> 
> +	/* Init the plist */
> +	spin_lock_init(&vdd->user_lock);
> +	plist_head_init(&vdd->user_list, &vdd->user_lock);
> +
>  	if (!strcmp(vdd->volt_domain.name, "mpu")) {
>  		if (cpu_is_omap3630()) {
>  			vdd->vp_reg.vlimitto_vddmin =
> @@ -881,6 +907,63 @@ unsigned long omap_voltageprocessor_get_curr_volt(
>  }
> 
>  /**
> + * omap_voltage_get_final : API to keep track of various requests to
[minor] This name does not match the actual API
> + *			    scale the VDD and returns the best possible
> + *			    voltage the VDD can be put to.
> + * @volt_domain: pointer to the voltage domain.
> + * @dev : the device pointer.
> + * @volt : the voltage which is requested by the device.
> + *
> + * This API is to be called before the actual voltage scaling is
> + * done to determine what is the best possible voltage the VDD can
> + * be put to. This API adds the device <dev> in the user list of the
> + * vdd <volt_domain> with <volt> as the requested voltage. The user list
> + * is a plist with the priority element absolute voltage values.
> + * The API then finds the maximum of all the requested voltages for
> + * the VDD and returns it back through <volt> pointer itself.
> + * Returns error value in case of any errors.
> + */
> +int omap_volt_get_final(struct omap_volt_domain *volt_domain,
> +		struct device *dev, unsigned long *volt)
> +{
> +	struct omap_vdd_info *vdd;
> +	struct omap_vdd_user_list *user;
> +	struct plist_node *node;
> +	int found = 0;
> +
> +	if (!volt_domain || IS_ERR(volt_domain)) {
> +		pr_warning("%s: VDD specified does not exist!\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	vdd = container_of(volt_domain, struct omap_vdd_info, volt_domain);
> +
> +	plist_for_each_entry(user, &vdd->user_list, node) {
> +		if (user->dev == dev) {
> +			found = 1;
> +			break;
> +		}
> +	}
> +
> +	if (!found) {
> +		user = kzalloc(sizeof(struct omap_vdd_user_list), GFP_KERNEL);
> +		if (!user) {
> +			pr_err("%s: Unable to creat a new user for vdd_%s\n",
> +				__func__, volt_domain->name);
> +			return -ENOMEM;
> +		}
> +		user->dev = dev;
> +		plist_node_init(&user->node, *volt);
> +		plist_add(&user->node, &vdd->user_list);
> +	}
> +
> +	user->node.prio = *volt;
> +	node = plist_first(&vdd->user_list);
> +	*volt = node->prio;
> +	return 0;
Shouldn't this function be protected using a mutex_lock/semaphore? It's possible that just after you are done with plist search, some other thread might get scheduled and try to add the same user.
> +}
> +
> +/**
>   * omap_voltageprocessor_enable : API to enable a particular VP
>   * @volt_domain: pointer to the VDD whose VP is to be enabled.
>   *
> diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-
> omap/include/plat/voltage.h
> index b7ac318..bc1e4d3 100644
> --- a/arch/arm/plat-omap/include/plat/voltage.h
> +++ b/arch/arm/plat-omap/include/plat/voltage.h
> @@ -128,6 +128,8 @@ int omap_get_voltage_table(struct omap_volt_domain
> *volt_domain,
>  struct omap_volt_data *omap_get_volt_data(
>  		struct omap_volt_domain *volt_domain, unsigned long volt);
>  unsigned long get_curr_voltage(struct omap_volt_domain *volt_domain);
> +int omap_volt_get_final(struct omap_volt_domain *volt_domain,
> +		struct device *dev, unsigned long *volt);
>  #ifdef CONFIG_PM
>  void omap_voltage_init_vc(struct omap_volt_vc_data *setup_vc);
>  #else
> --
> 1.7.0.rc1.33.g07cf0f


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

* RE: [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer
  2010-07-02 10:18         ` [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer Thara Gopinath
  2010-07-02 10:18           ` [RFC 6/7] OMAP3: Update OMAP3 opp tables to contain the voltage domain and device set rate get rate info Thara Gopinath
@ 2010-07-02 11:52           ` Sripathy, Vishwanath
  1 sibling, 0 replies; 22+ messages in thread
From: Sripathy, Vishwanath @ 2010-07-02 11:52 UTC (permalink / raw)
  To: Gopinath, Thara, linux-omap
  Cc: khilman, paul, Cousson, Benoit, Sawant, Anand, Basak, Partha



> -----Original Message-----
> From: Gopinath, Thara
> Sent: Friday, July 02, 2010 3:48 PM
> To: linux-omap@vger.kernel.org
> Cc: khilman@deeprootsystems.com; paul@pwsan.com; Cousson, Benoit; Sripathy,
> Vishwanath; Sawant, Anand; Basak, Partha; Gopinath, Thara
> Subject: [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer
> 
> This patch adds omap_device_set_rate and omap_device_get_rate
> API's which can be used to generic device rate scaling.
> 
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
>  arch/arm/plat-omap/include/plat/omap_device.h |    2 +
>  arch/arm/plat-omap/omap_device.c              |   87
> +++++++++++++++++++++++++
>  2 files changed, 89 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-
> omap/include/plat/omap_device.h
> index 3694b62..e0d06bb 100644
> --- a/arch/arm/plat-omap/include/plat/omap_device.h
> +++ b/arch/arm/plat-omap/include/plat/omap_device.h
> @@ -114,6 +114,8 @@ int omap_device_enable_hwmods(struct omap_device *od);
>  int omap_device_disable_clocks(struct omap_device *od);
>  int omap_device_enable_clocks(struct omap_device *od);
> 
> +int omap_device_set_rate(struct device *dev, unsigned long rate);
> +unsigned long omap_device_get_rate(struct device *dev);
> 
>  /*
>   * Entries should be kept in latency order ascending
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index 6614cba..900bb5d 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -85,6 +85,8 @@
> 
>  #include <plat/omap_device.h>
>  #include <plat/omap_hwmod.h>
> +#include <plat/opp.h>
> +#include <plat/voltage.h>
> 
>  /* These parameters are passed to _omap_device_{de,}activate() */
>  #define USE_WAKEUP_LAT			0
> @@ -734,3 +736,88 @@ int omap_device_enable_clocks(struct omap_device *od)
>  	/* XXX pass along return value here? */
>  	return 0;
>  }
> +
> +/**
> + * omap_device_set_rate - Set a new rate at which the device is to operate
> + * @dev : the device pointer
> + * @rate : the rnew rate for the device.
> + *
> + * This API gets the device opp table associated with this device and
> + * tries putting the device to the requested rate and the voltage domain
> + * associated with the device to the voltage corresponding to the
> + * requested rate. Since multiple devices can be assocciated with a
> + * voltage domain this API finds out the possible voltage the
> + * voltage domain can enter and then decides on the final device
> + * rate. Return 0 on success else the error value
> + */
> +int omap_device_set_rate(struct device *dev, unsigned long rate)
> +{
> +	struct device_opp *dev_opp;
> +	struct omap_opp *opp;
> +	unsigned long volt, freq;
> +	int ret;
> +
> +	dev_opp = opp_find_dev_opp(dev);
> +	if (IS_ERR(dev_opp)) {
> +		dev_warn(dev, "%s: Unable to find device opp table\n",
> +			__func__);
> +		return -ENODEV;
> +	}
> +
> +	/* Get the possible rate from the opp layer */
> +	freq = rate;
> +	opp = opp_find_freq_ceil(dev, &freq);
> +	if (IS_ERR(opp)) {
> +		dev_err(dev, "%s: Unable to find OPP for freq%ld\n",
> +			__func__, rate);
> +		return -ENODEV;
> +	}
> +	if (unlikely(freq != rate))
> +		dev_warn(dev, "%s: Available freq %ld != dpll freq %ld.\n",
> +			__func__, freq, rate);
> +
> +	/* Get the voltage corresponding to the requested frequency */
> +	volt = opp_get_voltage(opp);
> +
> +	/*
> +	 * Call into the voltage layer to get the final voltage possible
> +	 * for the voltage domain associated with the device.
> +	 */
> +
> +	ret = omap_volt_get_final(dev_opp->volt_domain, dev, &volt);
> +	if (ret) {
> +		dev_err(dev, "%s: Unable to get the final volt for scaling\n",
> +			__func__);
> +		return ret;
> +	}
> +
> +	/* Do the actual scaling */
> +	return omap_voltage_scale(dev_opp->volt_domain, volt);
This function also needs to be lock protected to avoid race conditions involved when multiple guys try to scale the voltage simultaneously.

> +}
> +
> +/**
> + * omap_device_get_rate - Gets the current operating rate of the device
> + * @dev - the device pointer
> + *
> + * This API returns the current operating rate of the device on success.
> + * Else returns the error value.
> + */
> +unsigned long omap_device_get_rate(struct device *dev)
> +{
> +	struct device_opp *dev_opp;
> +
> +	dev_opp = opp_find_dev_opp(dev);
> +
> +	if (IS_ERR(dev_opp)) {
> +		dev_warn(dev, "%s: Unable to find device opp table\n",
> +			__func__);
> +		return -ENODEV;
> +	}
> +
> +	if (!dev_opp->get_rate) {
> +		dev_warn(dev, "%s: No get_rate API\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	return dev_opp->get_rate(dev);
> +}
> --
> 1.7.0.rc1.33.g07cf0f


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

* RE: [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API
  2010-07-02 10:18             ` [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API Thara Gopinath
@ 2010-07-08  3:10               ` Pandita, Vikram
  2010-07-08  3:11                 ` Gopinath, Thara
  0 siblings, 1 reply; 22+ messages in thread
From: Pandita, Vikram @ 2010-07-08  3:10 UTC (permalink / raw)
  To: Gopinath, Thara, linux-omap
  Cc: khilman, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant,
	Anand, Basak, Partha



>-----Original Message-----
>From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
>owner@vger.kernel.org] On Behalf Of Gopinath, Thara
>Sent: Friday, July 02, 2010 5:18 AM
>To: linux-omap@vger.kernel.org
>Cc: khilman@deeprootsystems.com; paul@pwsan.com; Cousson, Benoit; Sripathy,
>Vishwanath; Sawant, Anand; Basak, Partha; Gopinath, Thara
>Subject: [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API
>
>This patch updates the cpufreq driver to use the device
>set rate API to scale the mpu frequency for OMAP3.
>
>Signed-off-by: Thara Gopinath <thara@ti.com>
>---
> arch/arm/plat-omap/cpu-omap.c |    5 +++--
> 1 files changed, 3 insertions(+), 2 deletions(-)
>
>diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
>index 9467827..cde02b5 100644
>--- a/arch/arm/plat-omap/cpu-omap.c
>+++ b/arch/arm/plat-omap/cpu-omap.c
>@@ -29,6 +29,7 @@
> #include <mach/hardware.h>
> #include <plat/clock.h>
> #include <asm/system.h>
>+#include <plat/omap_device.h>
>
> #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
> #include <plat/omap-pm.h>
>@@ -84,7 +85,7 @@ static int omap_target(struct cpufreq_policy *policy,
> 		       unsigned int target_freq,
> 		       unsigned int relation)
> {
>-#ifdef CONFIG_ARCH_OMAP1
>+#ifdef CONFIG_ARiCH_OMAP1
                ^^^^^^
		Typo I guess. Needs correction.


> 	struct cpufreq_freqs freqs;
> #endif
> #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
>@@ -117,7 +118,7 @@ static int omap_target(struct cpufreq_policy *policy,
> #elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
> 	freq = target_freq * 1000;
> 	if (opp_find_freq_ceil(mpu_dev, &freq))
>-		omap_pm_cpu_set_freq(freq);
>+		omap_device_set_rate(mpu_dev, freq);
> #endif
> 	return ret;
> }
>--
>1.7.0.rc1.33.g07cf0f
>
>--
>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] 22+ messages in thread

* RE: [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API
  2010-07-08  3:10               ` Pandita, Vikram
@ 2010-07-08  3:11                 ` Gopinath, Thara
  0 siblings, 0 replies; 22+ messages in thread
From: Gopinath, Thara @ 2010-07-08  3:11 UTC (permalink / raw)
  To: Pandita, Vikram, linux-omap
  Cc: khilman, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant,
	Anand, Basak, Partha



>>-----Original Message-----
>>From: Pandita, Vikram
>>Sent: Thursday, July 08, 2010 8:40 AM
>>To: Gopinath, Thara; linux-omap@vger.kernel.org
>>Cc: khilman@deeprootsystems.com; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant,
>>Anand; Basak, Partha
>>Subject: RE: [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API
>>
>>
>>
>>>-----Original Message-----
>>>From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
>>>owner@vger.kernel.org] On Behalf Of Gopinath, Thara
>>>Sent: Friday, July 02, 2010 5:18 AM
>>>To: linux-omap@vger.kernel.org
>>>Cc: khilman@deeprootsystems.com; paul@pwsan.com; Cousson, Benoit; Sripathy,
>>>Vishwanath; Sawant, Anand; Basak, Partha; Gopinath, Thara
>>>Subject: [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API
>>>
>>>This patch updates the cpufreq driver to use the device
>>>set rate API to scale the mpu frequency for OMAP3.
>>>
>>>Signed-off-by: Thara Gopinath <thara@ti.com>
>>>---
>>> arch/arm/plat-omap/cpu-omap.c |    5 +++--
>>> 1 files changed, 3 insertions(+), 2 deletions(-)
>>>
>>>diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
>>>index 9467827..cde02b5 100644
>>>--- a/arch/arm/plat-omap/cpu-omap.c
>>>+++ b/arch/arm/plat-omap/cpu-omap.c
>>>@@ -29,6 +29,7 @@
>>> #include <mach/hardware.h>
>>> #include <plat/clock.h>
>>> #include <asm/system.h>
>>>+#include <plat/omap_device.h>
>>>
>>> #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
>>> #include <plat/omap-pm.h>
>>>@@ -84,7 +85,7 @@ static int omap_target(struct cpufreq_policy *policy,
>>> 		       unsigned int target_freq,
>>> 		       unsigned int relation)
>>> {
>>>-#ifdef CONFIG_ARCH_OMAP1
>>>+#ifdef CONFIG_ARiCH_OMAP1
>>                ^^^^^^
>>		Typo I guess. Needs correction.

Yep.. Thanks..

Regards
Thara
>>
>>
>>> 	struct cpufreq_freqs freqs;
>>> #endif
>>> #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
>>>@@ -117,7 +118,7 @@ static int omap_target(struct cpufreq_policy *policy,
>>> #elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
>>> 	freq = target_freq * 1000;
>>> 	if (opp_find_freq_ceil(mpu_dev, &freq))
>>>-		omap_pm_cpu_set_freq(freq);
>>>+		omap_device_set_rate(mpu_dev, freq);
>>> #endif
>>> 	return ret;
>>> }
>>>--
>>>1.7.0.rc1.33.g07cf0f
>>>
>>>--
>>>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] 22+ messages in thread

* Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-07-02 10:18     ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thara Gopinath
  2010-07-02 10:18       ` [RFC 4/7] OMAP: Voltage layer changes to support DVFS Thara Gopinath
@ 2010-07-12 14:48       ` Thomas Petazzoni
  2010-07-12 16:01         ` Paul Walmsley
  2010-08-02 12:10       ` Cousson, Benoit
  2010-08-04  0:32       ` Kevin Hilman
  3 siblings, 1 reply; 22+ messages in thread
From: Thomas Petazzoni @ 2010-07-12 14:48 UTC (permalink / raw)
  To: Thara Gopinath
  Cc: linux-omap, khilman, paul, b-cousson, vishwanath.bs, sawant, p-basak2

Hello Thara,

On Fri,  2 Jul 2010 15:48:25 +0530
Thara Gopinath <thara@ti.com> wrote:

>  #include <plat/common.h>
>  
> @@ -38,21 +39,45 @@
>   */
>  struct omap_opp_def {
>  	char *hwmod_name;
> +	char *vdd_name;
>  
>  	unsigned long freq;
>  	unsigned long u_volt;
>  
> +	int (*set_rate)(struct device *dev, unsigned long rate);
> +	unsigned long (*get_rate) (struct device *dev);
> +
>  	bool enabled;
>  };

It looks strange to me that per-OPP methods are needed to set/get the
rate. These should only be needed at the device level, no ?

And indeed, in your patch 6/7, for every device, the same get/set rate
methods are used for all OPPs of a given device.

> +struct device_opp {
> +	struct list_head node;
> +	char *vdd_name;
> +
> +	struct omap_hwmod *oh;
> +	struct device *dev;
> +	struct omap_volt_domain *volt_domain;
> +
> +	struct list_head opp_list;
> +	u32 opp_count;
> +	u32 enabled_opp_count;
> +
> +	int (*set_rate)(struct device *dev, unsigned long rate);
> +	unsigned long (*get_rate) (struct device *dev);
> +};

I know this structure already exists, but do we really need a new
structure for this ? Couldn't these infos (OPP list, set/get rate
methods) be stored in an existing device-specific structure (omap_hwmod
for hardware-related things are omap_device for ~software-related
things) ?

For example, why aren't OPPs attached to the hwmod description of the
particular device ? These OPPs definitions really look like a
characteristic of a particular IP, don't they ?

Whatever choice is made, this structure probably needs a comment on top
of it explaining what it does, since the name isn't very obvious IMO.

Thanks!

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-07-12 14:48       ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thomas Petazzoni
@ 2010-07-12 16:01         ` Paul Walmsley
  0 siblings, 0 replies; 22+ messages in thread
From: Paul Walmsley @ 2010-07-12 16:01 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Thara Gopinath, linux-omap, khilman, b-cousson, vishwanath.bs,
	sawant, p-basak2

On Mon, 12 Jul 2010, Thomas Petazzoni wrote:

> I know this structure already exists, but do we really need a new
> structure for this ? Couldn't these infos (OPP list, set/get rate
> methods) be stored in an existing device-specific structure (omap_hwmod
> for hardware-related things are omap_device for ~software-related
> things) ?
> 
> For example, why aren't OPPs attached to the hwmod description of the
> particular device ? These OPPs definitions really look like a
> characteristic of a particular IP, don't they ?

hwmod data is intended to be used for RTL-level data, e.g., data that is 
invariant of the underlying process technology.  OPP data can vary by the 
underlying fabrication process or per-die speed validation (e.g., 
speed-binning).  So I don't think it belongs in the hwmod data.


- Paul

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

* Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-07-02 10:18     ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thara Gopinath
  2010-07-02 10:18       ` [RFC 4/7] OMAP: Voltage layer changes to support DVFS Thara Gopinath
  2010-07-12 14:48       ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thomas Petazzoni
@ 2010-08-02 12:10       ` Cousson, Benoit
  2010-08-04  4:01         ` Gopinath, Thara
  2010-08-04  0:32       ` Kevin Hilman
  3 siblings, 1 reply; 22+ messages in thread
From: Cousson, Benoit @ 2010-08-02 12:10 UTC (permalink / raw)
  To: Gopinath, Thara
  Cc: linux-omap, khilman, paul, Sripathy, Vishwanath, Sawant, Anand,
	Basak, Partha

Hi Thara,

On 7/2/2010 12:18 PM, Gopinath, Thara wrote:
> This patch extends the device opp structure to contain
> info about the voltage domain to which the device belongs to
> and to contain pointers to scale the operating rate of the
> device. This patch also adds an API in the opp layer that
> can be used by the voltage layer to get a list of all the
> scalable devices belonging to a particular voltage domain.
> This API is to be typically called only once by the voltage
> layer per voltage domain instance and the device list should
> be stored. This approach makes it easy during dvfs to scale
> all the devices associated with a voltage domain and then
> scale the voltage domain.
>
> Signed-off-by: Thara Gopinath<thara@ti.com>
> ---
>   arch/arm/plat-omap/include/plat/opp.h |   37 +++++++++++++++++++++++++-
>   arch/arm/plat-omap/opp.c              |   47 +++++++++++++++++++++++++-------
>   2 files changed, 72 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
> index 893731f..15e1e70 100644
> --- a/arch/arm/plat-omap/include/plat/opp.h
> +++ b/arch/arm/plat-omap/include/plat/opp.h
> @@ -16,6 +16,7 @@
>
>   #include<linux/err.h>
>   #include<linux/cpufreq.h>
> +#include<linux/clk.h>
>
>   #include<plat/common.h>
>
> @@ -38,21 +39,45 @@
>    */
>   struct omap_opp_def {
>   	char *hwmod_name;
> +	char *vdd_name;

vdd should be an attribute of hwmod. For one hwmod in a soc we will 
always have the same vdd.
That will avoid to duplicate information and to have to populate that in 
each OPP entry (cf patch 6).

>
>   	unsigned long freq;
>   	unsigned long u_volt;
>
> +	int (*set_rate)(struct device *dev, unsigned long rate);
> +	unsigned long (*get_rate) (struct device *dev);

We might already discussed that, but why should we store that per OPP?
Cannot we store that per device?

Regards,
Benoit

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

* Re: [RFC 0/7] OMAP: Basic DVFS framework
  2010-07-02 10:18 [RFC 0/7] OMAP: Basic DVFS framework Thara Gopinath
  2010-07-02 10:18 ` [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
@ 2010-08-03 23:49 ` Kevin Hilman
  2010-08-04  3:54   ` Gopinath, Thara
  1 sibling, 1 reply; 22+ messages in thread
From: Kevin Hilman @ 2010-08-03 23:49 UTC (permalink / raw)
  To: Thara Gopinath
  Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant, p-basak2

Thara Gopinath <thara@ti.com> writes:

> This patch series is RFC for support of Dynamic Voltage and
> Frequency Scaling (DVFS) for OMAP devices. DVFS is a technique that
> uses the optimal operating frequency and voltage to allow a task to be
> performed in the required amount of time.
> OMAP processors have voltage domains whose voltage can be scaled to
> various levels depending on which the operating frequencies of certain
> devices belonging to the domain will also need to be scaled. This voltage
> frequency tuple is known as Operating Performance Point (OPP). A device
> can have multiple OPP's. Also a voltage domain could be shared between
> multiple devices. Also there could be dependencies between various
> voltage domains for maintaining system performance like VDD<X>
> should be at voltage v1 when VDD<Y> is at voltage v2.
>
> The design of this framework take into account all the above mentioned points.
> To summarize the basic design of DVFS framework:-
>
> 1. Have device opp tables for each device whose operating frequency can be
>    scaled. This is easy now due to the existance of hwmod layer which
>    allow storing of device specific info. The device opp tables contain
>    the opp pairs (frequency voltage tuples), the voltage domain pointer
>    to which the device belongs to, the device specific set_rate and
>    get_rate API's which will do the actual scaling of the device frequency
>    and retrieve the current device frequency.
> 2. Introduce use counting on a per VDD basis. This is to take care multiple
>    requests to scale a VDD. The VDD will be scaled to the maximum of the
>    voltages requested.
> 3. Keep track of all scalable devices belonging to a particular voltage
>    domain the voltage layer.
> 4. Generic API in the omap device layer which can be called by anybody
>    to scale a device opp. This API will take in the device pointer and
>    frequency to which the device needs to be scaled to. This API will
>    then internally find out the voltage domain to which the device
>    belongs to and the voltage to which the voltage domain needs to
>    be put to for the device to be scaled to the new frequency from
>    the device opp table. Then this API will call into the newly
>    introduced API in voltage layer (as mentioned in 2) to see if
>    there are other requests for the associated voltage domain to
>    be at a voltage higher than the current chosen one. If not this
>    API will go ahead and scale the voltage domain to the new voltage,
>    run through the list of all scalable devices belonging to this
>    voltage domain and scale them to the appropriate frequencies using
>    the set_rate pointer in the device opp table.s
>
> Work pending -
> 1. Handle inter VDD dependencies.
> 2. Add OMAP4 support.
>
> Contributors to conceptualization of the design include
> Benoit Cousson <b-cousson@ti.com>,
> Kevin Hilman <khilman@deeprootsystems.com>,
> Paul Wamsley <paul@pwsan.com>,
> Vishwanath Sripathy <vishwanath.bs@ti.com>
> Parthasarathy Basak <p-basak2@ti.com>
> Anand Sawant <sawant@ti.com>
>
> This patch series is primarily based of pm-sr branch of kevin's PM tree due to
> it's dependency on the newly introduced opp and voltage layer. On top of this
> branch I had to apply a few patches to test out dvfs using cpufreq framework.
> The following are the link to these additional patches.
> 	https://patchwork.kernel.org/patch/107876/

This patch does not apply directly to the current pm-sr branch, and also
had some review comments to be addressed.

> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=aa14cb9937e67c48f760c99a3c7fb3b2e7f5e623
> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=8f1298921d10789bb2f0a2d56cd3b92d844a1450
> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=10474ce3b07949d791b419aad433590e072e7159
> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=52fd40b873f8cd5aaea2d01d86ef35017c207eba
> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commit;h=57a2e45ff4a596a175aba27ae55a2b0d99adc3b5	

This looks like the current pm-cpufreq branch.  Did you just merge
pm-cpufreq or manually apply these?

Can you please make this available using a git tree so we can determine
exactly what was used to put this together?

Your series doesn't apply directly to pm-sr neither does the above patch
from patchwork, so I cannot currently apply this to anything.

> This series has been tested on OMAP3430 SDP for mpu and iva DVFS through
> cpu freq framework.

Just to clarify, you're testing this without SRF correct?  Based on the
above description, I assume you no longer have SRF code included, but I
just want to be sure.

Kevin

> Thara Gopinath (7):
>   OMAP: Introduce a user list for each voltage domain instance in the
>     voltage driver.
>   OMAP: Introduce API in the OPP layer to find the opp entry
>     corresponding to a voltage.
>   OMAP: Introduce voltage domain pointer and device specific set rate
>     and get rate in device opp structures.
>   OMAP: Voltage layer changes to support DVFS.
>   OMAP: Introduce device set_rate and get_rate.
>   OMAP3: Update OMAP3 opp tables to contain the voltage domain and
>     device set rate get rate info
>   OMAP3: Update cpufreq driver to use the new set_rate API
>
>  arch/arm/mach-omap2/cpufreq34xx.c             |  160 +++++++++++++++++++----
>  arch/arm/mach-omap2/voltage.c                 |  172 ++++++++++++++++++++++++-
>  arch/arm/plat-omap/cpu-omap.c                 |    5 +-
>  arch/arm/plat-omap/include/plat/omap_device.h |    2 +
>  arch/arm/plat-omap/include/plat/opp.h         |   39 ++++++-
>  arch/arm/plat-omap/include/plat/voltage.h     |    6 +-
>  arch/arm/plat-omap/omap_device.c              |   87 +++++++++++++
>  arch/arm/plat-omap/opp.c                      |   75 +++++++++--
>  8 files changed, 505 insertions(+), 41 deletions(-)

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

* Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-07-02 10:18     ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thara Gopinath
                         ` (2 preceding siblings ...)
  2010-08-02 12:10       ` Cousson, Benoit
@ 2010-08-04  0:32       ` Kevin Hilman
  2010-08-04  4:02         ` Gopinath, Thara
  3 siblings, 1 reply; 22+ messages in thread
From: Kevin Hilman @ 2010-08-04  0:32 UTC (permalink / raw)
  To: Thara Gopinath
  Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant, p-basak2

Thara Gopinath <thara@ti.com> writes:

> This patch extends the device opp structure to contain
> info about the voltage domain to which the device belongs to
> and to contain pointers to scale the operating rate of the
> device. This patch also adds an API in the opp layer that
> can be used by the voltage layer to get a list of all the
> scalable devices belonging to a particular voltage domain.
> This API is to be typically called only once by the voltage
> layer per voltage domain instance and the device list should
> be stored. This approach makes it easy during dvfs to scale
> all the devices associated with a voltage domain and then
> scale the voltage domain.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
>  arch/arm/plat-omap/include/plat/opp.h |   37 +++++++++++++++++++++++++-
>  arch/arm/plat-omap/opp.c              |   47 +++++++++++++++++++++++++-------
>  2 files changed, 72 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
> index 893731f..15e1e70 100644
> --- a/arch/arm/plat-omap/include/plat/opp.h
> +++ b/arch/arm/plat-omap/include/plat/opp.h
> @@ -16,6 +16,7 @@
>  
>  #include <linux/err.h>
>  #include <linux/cpufreq.h>
> +#include <linux/clk.h>
>  
>  #include <plat/common.h>
>  
> @@ -38,21 +39,45 @@
>   */
>  struct omap_opp_def {
>  	char *hwmod_name;
> +	char *vdd_name;
>  
>  	unsigned long freq;
>  	unsigned long u_volt;
>  
> +	int (*set_rate)(struct device *dev, unsigned long rate);
> +	unsigned long (*get_rate) (struct device *dev);
> +
>  	bool enabled;
>  };
>  
> +struct device_opp {
> +	struct list_head node;
> +	char *vdd_name;
> +
> +	struct omap_hwmod *oh;
> +	struct device *dev;
> +	struct omap_volt_domain *volt_domain;
> +
> +	struct list_head opp_list;
> +	u32 opp_count;
> +	u32 enabled_opp_count;
> +
> +	int (*set_rate)(struct device *dev, unsigned long rate);
> +	unsigned long (*get_rate) (struct device *dev);
> +};

I don't like moving the definition of this struct out.  This exposes the
implmentation details of the OPP layer that are subject to change.

A quick glance shows you need to access the volt_domain field and the
new function pointers.

The voltage domain should be part of the hwmod as suggested by Benoit,
and an API created to get the voltage domain from the hwmod.

For the get/set rate functions, maybe new OPP layer API should be
created access those functions.  opp_[get|set]_rate()?


>  /*
>   * Initialization wrapper used to define an OPP.
>   * To point at the end of a terminator of a list of OPPs,
>   * use OMAP_OPP_DEF(0, 0, 0)
>   */
> -#define OMAP_OPP_DEF(_hwmod_name, _enabled, _freq, _uv)	\
> +#define OMAP_OPP_DEF(_hwmod_name, _vdd_name, _set_rate, _get_rate, \
> +			_enabled, _freq, _uv)	\
>  {						\
>  	.hwmod_name	= _hwmod_name,		\
> +	.vdd_name	= _vdd_name,		\
> +	.set_rate	= _set_rate,		\
> +	.get_rate	= _get_rate,		\
>  	.enabled	= _enabled,		\
>  	.freq		= _freq,		\
>  	.u_volt		= _uv,			\
> @@ -77,6 +102,8 @@ struct omap_opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq);
>  
>  struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt);
>  
> +struct device_opp *opp_find_dev_opp(struct device *dev);
> +
>  int opp_add(const struct omap_opp_def *opp_def);
>  
>  int opp_enable(struct omap_opp *opp);
> @@ -89,6 +116,9 @@ u8 __deprecated opp_get_opp_id(struct omap_opp *opp);
>  
>  void opp_init_cpufreq_table(struct device *dev,
>  			    struct cpufreq_frequency_table **table);
> +
> +struct device **opp_init_voltage_params(struct omap_volt_domain *volt_domain,
> +		int *dev_count);
>  #else
>  static inline unsigned long opp_get_voltage(const struct omap_opp *opp)
>  {
> @@ -124,6 +154,11 @@ static inline struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl,
>  	return ERR_PTR(-EINVAL);
>  }
>  
> +static inline struct device_opp *opp_find_dev_opp(struct device *dev)
> +{
> +	return ERR_PTR(-EINVAL);
> +}
> +
>  static inline struct omap_opp *opp_add(struct omap_opp *oppl,
>  				       const struct omap_opp_def *opp_def)
>  {
> diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
> index 070ff5b..9bc53e8 100644
> --- a/arch/arm/plat-omap/opp.c
> +++ b/arch/arm/plat-omap/opp.c
> @@ -22,6 +22,7 @@
>  #include <plat/opp_twl_tps.h>
>  #include <plat/opp.h>
>  #include <plat/omap_device.h>
> +#include <plat/voltage.h>
>  
>  /**
>   * struct omap_opp - OMAP OPP description structure
> @@ -43,17 +44,6 @@ struct omap_opp {
>  	struct device_opp *dev_opp;  /* containing device_opp struct */
>  };
>  
> -struct device_opp {
> -	struct list_head node;
> -
> -	struct omap_hwmod *oh;
> -	struct device *dev;
> -
> -	struct list_head opp_list;
> -	u32 opp_count;
> -	u32 enabled_opp_count;
> -};
> -
>  static LIST_HEAD(dev_opp_list);
>  
>  /**
> @@ -330,6 +320,11 @@ struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt)
>  	return opp;
>  }
>  
> +struct device_opp *opp_find_dev_opp(struct device *dev)
> +{
> +	return find_device_opp(dev);
> +}
> +
>  /* wrapper to reuse converting opp_def to opp struct */
>  static void omap_opp_populate(struct omap_opp *opp,
>  			      const struct omap_opp_def *opp_def)
> @@ -385,6 +380,11 @@ int opp_add(const struct omap_opp_def *opp_def)
>  
>  		dev_opp->oh = oh;
>  		dev_opp->dev = &oh->od->pdev.dev;
> +		dev_opp->vdd_name = kzalloc(strlen(opp_def->vdd_name) + 1,
> +				GFP_KERNEL);
> +		strcpy(dev_opp->vdd_name, opp_def->vdd_name);

Since this is user-defined data/string, should probably have a max
strlen and use strncpy.

Kevin

> +		dev_opp->set_rate = opp_def->set_rate;
> +		dev_opp->get_rate = opp_def->get_rate;
>  		INIT_LIST_HEAD(&dev_opp->opp_list);
>  
>  		list_add(&dev_opp->node, &dev_opp_list);
> @@ -511,3 +511,28 @@ void opp_init_cpufreq_table(struct device *dev,
>  
>  	*table = &freq_table[0];
>  }
> +
> +struct device **opp_init_voltage_params(struct omap_volt_domain *volt_domain,
> +		int *dev_count)
> +{
> +	struct device_opp *dev_opp;
> +	struct device **dev_list;
> +	int count = 0, i = 0;
> +
> +	list_for_each_entry(dev_opp, &dev_opp_list, node) {
> +		if (!strcmp(dev_opp->vdd_name, volt_domain->name)) {
> +			dev_opp->volt_domain = volt_domain;
> +			count++;
> +		}
> +	}
> +
> +	dev_list = kzalloc(sizeof(struct device *) * count, GFP_KERNEL);
> +
> +	list_for_each_entry(dev_opp, &dev_opp_list, node) {
> +		if (dev_opp->volt_domain == volt_domain)
> +			dev_list[i++] = dev_opp->dev;
> +	}
> +
> +	*dev_count = count;
> +	return dev_list;
> +}

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

* RE: [RFC 0/7] OMAP: Basic DVFS framework
  2010-08-03 23:49 ` [RFC 0/7] OMAP: Basic DVFS framework Kevin Hilman
@ 2010-08-04  3:54   ` Gopinath, Thara
  0 siblings, 0 replies; 22+ messages in thread
From: Gopinath, Thara @ 2010-08-04  3:54 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant,
	Anand, Basak, Partha



>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Wednesday, August 04, 2010 5:20 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand;
>>Basak, Partha
>>Subject: Re: [RFC 0/7] OMAP: Basic DVFS framework
>>
>>Thara Gopinath <thara@ti.com> writes:
>>
>>> This patch series is RFC for support of Dynamic Voltage and
>>> Frequency Scaling (DVFS) for OMAP devices. DVFS is a technique that
>>> uses the optimal operating frequency and voltage to allow a task to be
>>> performed in the required amount of time.
>>> OMAP processors have voltage domains whose voltage can be scaled to
>>> various levels depending on which the operating frequencies of certain
>>> devices belonging to the domain will also need to be scaled. This voltage
>>> frequency tuple is known as Operating Performance Point (OPP). A device
>>> can have multiple OPP's. Also a voltage domain could be shared between
>>> multiple devices. Also there could be dependencies between various
>>> voltage domains for maintaining system performance like VDD<X>
>>> should be at voltage v1 when VDD<Y> is at voltage v2.
>>>
>>> The design of this framework take into account all the above mentioned points.
>>> To summarize the basic design of DVFS framework:-
>>>
>>> 1. Have device opp tables for each device whose operating frequency can be
>>>    scaled. This is easy now due to the existance of hwmod layer which
>>>    allow storing of device specific info. The device opp tables contain
>>>    the opp pairs (frequency voltage tuples), the voltage domain pointer
>>>    to which the device belongs to, the device specific set_rate and
>>>    get_rate API's which will do the actual scaling of the device frequency
>>>    and retrieve the current device frequency.
>>> 2. Introduce use counting on a per VDD basis. This is to take care multiple
>>>    requests to scale a VDD. The VDD will be scaled to the maximum of the
>>>    voltages requested.
>>> 3. Keep track of all scalable devices belonging to a particular voltage
>>>    domain the voltage layer.
>>> 4. Generic API in the omap device layer which can be called by anybody
>>>    to scale a device opp. This API will take in the device pointer and
>>>    frequency to which the device needs to be scaled to. This API will
>>>    then internally find out the voltage domain to which the device
>>>    belongs to and the voltage to which the voltage domain needs to
>>>    be put to for the device to be scaled to the new frequency from
>>>    the device opp table. Then this API will call into the newly
>>>    introduced API in voltage layer (as mentioned in 2) to see if
>>>    there are other requests for the associated voltage domain to
>>>    be at a voltage higher than the current chosen one. If not this
>>>    API will go ahead and scale the voltage domain to the new voltage,
>>>    run through the list of all scalable devices belonging to this
>>>    voltage domain and scale them to the appropriate frequencies using
>>>    the set_rate pointer in the device opp table.s
>>>
>>> Work pending -
>>> 1. Handle inter VDD dependencies.
>>> 2. Add OMAP4 support.
>>>
>>> Contributors to conceptualization of the design include
>>> Benoit Cousson <b-cousson@ti.com>,
>>> Kevin Hilman <khilman@deeprootsystems.com>,
>>> Paul Wamsley <paul@pwsan.com>,
>>> Vishwanath Sripathy <vishwanath.bs@ti.com>
>>> Parthasarathy Basak <p-basak2@ti.com>
>>> Anand Sawant <sawant@ti.com>
>>>
>>> This patch series is primarily based of pm-sr branch of kevin's PM tree due to
>>> it's dependency on the newly introduced opp and voltage layer. On top of this
>>> branch I had to apply a few patches to test out dvfs using cpufreq framework.
>>> The following are the link to these additional patches.
>>> 	https://patchwork.kernel.org/patch/107876/
>>
>>This patch does not apply directly to the current pm-sr branch, and also
>>had some review comments to be addressed.
>>
>>> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-
>>pm.git;a=commit;h=aa14cb9937e67c48f760c99a3c7fb3b2e7f5e623
>>> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-
>>pm.git;a=commit;h=8f1298921d10789bb2f0a2d56cd3b92d844a1450
>>> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-
>>pm.git;a=commit;h=10474ce3b07949d791b419aad433590e072e7159
>>> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-
>>pm.git;a=commit;h=52fd40b873f8cd5aaea2d01d86ef35017c207eba
>>> 	http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-
>>pm.git;a=commit;h=57a2e45ff4a596a175aba27ae55a2b0d99adc3b5
>>
>>This looks like the current pm-cpufreq branch.  Did you just merge
>>pm-cpufreq or manually apply these?

I had to apply the cpufreq patches manually. If I remember correct I posted this series on PM-SR
branch with the above mentioned patches applied manually. After this I migrated to latest
kernel.org kernel where I again applied some hwmod/device API's, opp layer, cpufreq layer
and voltage/sr series patches manually. I will be posting out a new version of voltage/sr layer patches against kernel.org shortly.
>>
>>Can you please make this available using a git tree so we can determine
>>exactly what was used to put this together?

As I said earlier currently I do have a tree against kernel.org where I have manually applied all the
required patches. This has OMAP4 related changes also. Currently I am working on posting out these patches to LO. I can surely try to make this tree available through a public git.

>>
>>Your series doesn't apply directly to pm-sr neither does the above patch
>>from patchwork, so I cannot currently apply this to anything.

Sorry for this. It did apply for me when I posted these patches. It has been a while now.
Maybe things have changed. I will try posting a fresh series pretty soon.

>>
>>> This series has been tested on OMAP3430 SDP for mpu and iva DVFS through
>>> cpu freq framework.
>>
>>Just to clarify, you're testing this without SRF correct?  Based on the
>>above description, I assume you no longer have SRF code included, but I
>>just want to be sure.

Yep this is true. SRF is removed.

Regards
Thara

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

* RE: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-08-02 12:10       ` Cousson, Benoit
@ 2010-08-04  4:01         ` Gopinath, Thara
  0 siblings, 0 replies; 22+ messages in thread
From: Gopinath, Thara @ 2010-08-04  4:01 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: linux-omap, khilman, paul, Sripathy, Vishwanath, Sawant, Anand,
	Basak, Partha



>>-----Original Message-----
>>From: Cousson, Benoit
>>Sent: Monday, August 02, 2010 5:41 PM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; khilman@deeprootsystems.com; paul@pwsan.com; Sripathy, Vishwanath;
>>Sawant, Anand; Basak, Partha
>>Subject: Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get
>>rate in device opp structures.
>>
>>Hi Thara,
>>
>>On 7/2/2010 12:18 PM, Gopinath, Thara wrote:
>>> This patch extends the device opp structure to contain
>>> info about the voltage domain to which the device belongs to
>>> and to contain pointers to scale the operating rate of the
>>> device. This patch also adds an API in the opp layer that
>>> can be used by the voltage layer to get a list of all the
>>> scalable devices belonging to a particular voltage domain.
>>> This API is to be typically called only once by the voltage
>>> layer per voltage domain instance and the device list should
>>> be stored. This approach makes it easy during dvfs to scale
>>> all the devices associated with a voltage domain and then
>>> scale the voltage domain.
>>>
>>> Signed-off-by: Thara Gopinath<thara@ti.com>
>>> ---
>>>   arch/arm/plat-omap/include/plat/opp.h |   37 +++++++++++++++++++++++++-
>>>   arch/arm/plat-omap/opp.c              |   47 +++++++++++++++++++++++++-------
>>>   2 files changed, 72 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
>>> index 893731f..15e1e70 100644
>>> --- a/arch/arm/plat-omap/include/plat/opp.h
>>> +++ b/arch/arm/plat-omap/include/plat/opp.h
>>> @@ -16,6 +16,7 @@
>>>
>>>   #include<linux/err.h>
>>>   #include<linux/cpufreq.h>
>>> +#include<linux/clk.h>
>>>
>>>   #include<plat/common.h>
>>>
>>> @@ -38,21 +39,45 @@
>>>    */
>>>   struct omap_opp_def {
>>>   	char *hwmod_name;
>>> +	char *vdd_name;
>>
>>vdd should be an attribute of hwmod. For one hwmod in a soc we will
>>always have the same vdd.
>>That will avoid to duplicate information and to have to populate that in
>>each OPP entry (cf patch 6).
I also do not like the duplication of info in the opp tables. I was not sure
about introducing this in the hwmod layer. I could surely do this for the
vdd name and voltage domain pointer.
>>
>>>
>>>   	unsigned long freq;
>>>   	unsigned long u_volt;
>>>
>>> +	int (*set_rate)(struct device *dev, unsigned long rate);
>>> +	unsigned long (*get_rate) (struct device *dev);
>>
>>We might already discussed that, but why should we store that per OPP?
>>Cannot we store that per device?

Paul had concerns regarding this. These are not h/w or h/w interface related info
in any manner. One good point is that even though these pointers are duplicated in
the init opp tables, during init the device opp tables are built and only one copy
is maintained. But I agree this does not look too very good.

Regards
Thara

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

* RE: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-08-04  0:32       ` Kevin Hilman
@ 2010-08-04  4:02         ` Gopinath, Thara
  2010-08-04 21:06           ` Kevin Hilman
  0 siblings, 1 reply; 22+ messages in thread
From: Gopinath, Thara @ 2010-08-04  4:02 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant,
	Anand, Basak, Partha



>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Wednesday, August 04, 2010 6:03 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand;
>>Basak, Partha
>>Subject: Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get
>>rate in device opp structures.
>>
>>Thara Gopinath <thara@ti.com> writes:
>>
>>> This patch extends the device opp structure to contain
>>> info about the voltage domain to which the device belongs to
>>> and to contain pointers to scale the operating rate of the
>>> device. This patch also adds an API in the opp layer that
>>> can be used by the voltage layer to get a list of all the
>>> scalable devices belonging to a particular voltage domain.
>>> This API is to be typically called only once by the voltage
>>> layer per voltage domain instance and the device list should
>>> be stored. This approach makes it easy during dvfs to scale
>>> all the devices associated with a voltage domain and then
>>> scale the voltage domain.
>>>
>>> Signed-off-by: Thara Gopinath <thara@ti.com>
>>> ---
>>>  arch/arm/plat-omap/include/plat/opp.h |   37 +++++++++++++++++++++++++-
>>>  arch/arm/plat-omap/opp.c              |   47 +++++++++++++++++++++++++-------
>>>  2 files changed, 72 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
>>> index 893731f..15e1e70 100644
>>> --- a/arch/arm/plat-omap/include/plat/opp.h
>>> +++ b/arch/arm/plat-omap/include/plat/opp.h
>>> @@ -16,6 +16,7 @@
>>>
>>>  #include <linux/err.h>
>>>  #include <linux/cpufreq.h>
>>> +#include <linux/clk.h>
>>>
>>>  #include <plat/common.h>
>>>
>>> @@ -38,21 +39,45 @@
>>>   */
>>>  struct omap_opp_def {
>>>  	char *hwmod_name;
>>> +	char *vdd_name;
>>>
>>>  	unsigned long freq;
>>>  	unsigned long u_volt;
>>>
>>> +	int (*set_rate)(struct device *dev, unsigned long rate);
>>> +	unsigned long (*get_rate) (struct device *dev);
>>> +
>>>  	bool enabled;
>>>  };
>>>
>>> +struct device_opp {
>>> +	struct list_head node;
>>> +	char *vdd_name;
>>> +
>>> +	struct omap_hwmod *oh;
>>> +	struct device *dev;
>>> +	struct omap_volt_domain *volt_domain;
>>> +
>>> +	struct list_head opp_list;
>>> +	u32 opp_count;
>>> +	u32 enabled_opp_count;
>>> +
>>> +	int (*set_rate)(struct device *dev, unsigned long rate);
>>> +	unsigned long (*get_rate) (struct device *dev);
>>> +};
>>
>>I don't like moving the definition of this struct out.  This exposes the
>>implmentation details of the OPP layer that are subject to change.
>>
>>A quick glance shows you need to access the volt_domain field and the
>>new function pointers.
>>
>>The voltage domain should be part of the hwmod as suggested by Benoit,
>>and an API created to get the voltage domain from the hwmod.
>>
>>For the get/set rate functions, maybe new OPP layer API should be
>>created access those functions.  opp_[get|set]_rate()?

Yes I could do this.

>>
>>
>>>  /*
>>>   * Initialization wrapper used to define an OPP.
>>>   * To point at the end of a terminator of a list of OPPs,
>>>   * use OMAP_OPP_DEF(0, 0, 0)
>>>   */
>>> -#define OMAP_OPP_DEF(_hwmod_name, _enabled, _freq, _uv)	\
>>> +#define OMAP_OPP_DEF(_hwmod_name, _vdd_name, _set_rate, _get_rate, \
>>> +			_enabled, _freq, _uv)	\
>>>  {						\
>>>  	.hwmod_name	= _hwmod_name,		\
>>> +	.vdd_name	= _vdd_name,		\
>>> +	.set_rate	= _set_rate,		\
>>> +	.get_rate	= _get_rate,		\
>>>  	.enabled	= _enabled,		\
>>>  	.freq		= _freq,		\
>>>  	.u_volt		= _uv,			\
>>> @@ -77,6 +102,8 @@ struct omap_opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq);
>>>
>>>  struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt);
>>>
>>> +struct device_opp *opp_find_dev_opp(struct device *dev);
>>> +
>>>  int opp_add(const struct omap_opp_def *opp_def);
>>>
>>>  int opp_enable(struct omap_opp *opp);
>>> @@ -89,6 +116,9 @@ u8 __deprecated opp_get_opp_id(struct omap_opp *opp);
>>>
>>>  void opp_init_cpufreq_table(struct device *dev,
>>>  			    struct cpufreq_frequency_table **table);
>>> +
>>> +struct device **opp_init_voltage_params(struct omap_volt_domain *volt_domain,
>>> +		int *dev_count);
>>>  #else
>>>  static inline unsigned long opp_get_voltage(const struct omap_opp *opp)
>>>  {
>>> @@ -124,6 +154,11 @@ static inline struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl,
>>>  	return ERR_PTR(-EINVAL);
>>>  }
>>>
>>> +static inline struct device_opp *opp_find_dev_opp(struct device *dev)
>>> +{
>>> +	return ERR_PTR(-EINVAL);
>>> +}
>>> +
>>>  static inline struct omap_opp *opp_add(struct omap_opp *oppl,
>>>  				       const struct omap_opp_def *opp_def)
>>>  {
>>> diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
>>> index 070ff5b..9bc53e8 100644
>>> --- a/arch/arm/plat-omap/opp.c
>>> +++ b/arch/arm/plat-omap/opp.c
>>> @@ -22,6 +22,7 @@
>>>  #include <plat/opp_twl_tps.h>
>>>  #include <plat/opp.h>
>>>  #include <plat/omap_device.h>
>>> +#include <plat/voltage.h>
>>>
>>>  /**
>>>   * struct omap_opp - OMAP OPP description structure
>>> @@ -43,17 +44,6 @@ struct omap_opp {
>>>  	struct device_opp *dev_opp;  /* containing device_opp struct */
>>>  };
>>>
>>> -struct device_opp {
>>> -	struct list_head node;
>>> -
>>> -	struct omap_hwmod *oh;
>>> -	struct device *dev;
>>> -
>>> -	struct list_head opp_list;
>>> -	u32 opp_count;
>>> -	u32 enabled_opp_count;
>>> -};
>>> -
>>>  static LIST_HEAD(dev_opp_list);
>>>
>>>  /**
>>> @@ -330,6 +320,11 @@ struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt)
>>>  	return opp;
>>>  }
>>>
>>> +struct device_opp *opp_find_dev_opp(struct device *dev)
>>> +{
>>> +	return find_device_opp(dev);
>>> +}
>>> +
>>>  /* wrapper to reuse converting opp_def to opp struct */
>>>  static void omap_opp_populate(struct omap_opp *opp,
>>>  			      const struct omap_opp_def *opp_def)
>>> @@ -385,6 +380,11 @@ int opp_add(const struct omap_opp_def *opp_def)
>>>
>>>  		dev_opp->oh = oh;
>>>  		dev_opp->dev = &oh->od->pdev.dev;
>>> +		dev_opp->vdd_name = kzalloc(strlen(opp_def->vdd_name) + 1,
>>> +				GFP_KERNEL);
>>> +		strcpy(dev_opp->vdd_name, opp_def->vdd_name);
>>
>>Since this is user-defined data/string, should probably have a max
>>strlen and use strncpy.

I did not get this. What is the problem with the strlen here ?

Regards
Thara

>>
>>Kevin
>>
>>> +		dev_opp->set_rate = opp_def->set_rate;
>>> +		dev_opp->get_rate = opp_def->get_rate;
>>>  		INIT_LIST_HEAD(&dev_opp->opp_list);
>>>
>>>  		list_add(&dev_opp->node, &dev_opp_list);
>>> @@ -511,3 +511,28 @@ void opp_init_cpufreq_table(struct device *dev,
>>>
>>>  	*table = &freq_table[0];
>>>  }
>>> +
>>> +struct device **opp_init_voltage_params(struct omap_volt_domain *volt_domain,
>>> +		int *dev_count)
>>> +{
>>> +	struct device_opp *dev_opp;
>>> +	struct device **dev_list;
>>> +	int count = 0, i = 0;
>>> +
>>> +	list_for_each_entry(dev_opp, &dev_opp_list, node) {
>>> +		if (!strcmp(dev_opp->vdd_name, volt_domain->name)) {
>>> +			dev_opp->volt_domain = volt_domain;
>>> +			count++;
>>> +		}
>>> +	}
>>> +
>>> +	dev_list = kzalloc(sizeof(struct device *) * count, GFP_KERNEL);
>>> +
>>> +	list_for_each_entry(dev_opp, &dev_opp_list, node) {
>>> +		if (dev_opp->volt_domain == volt_domain)
>>> +			dev_list[i++] = dev_opp->dev;
>>> +	}
>>> +
>>> +	*dev_count = count;
>>> +	return dev_list;
>>> +}

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

* Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-08-04  4:02         ` Gopinath, Thara
@ 2010-08-04 21:06           ` Kevin Hilman
  2010-08-05  5:48             ` Gopinath, Thara
  0 siblings, 1 reply; 22+ messages in thread
From: Kevin Hilman @ 2010-08-04 21:06 UTC (permalink / raw)
  To: Gopinath, Thara
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant,
	Anand, Basak, Partha

"Gopinath, Thara" <thara@ti.com> writes:

>>>> @@ -385,6 +380,11 @@ int opp_add(const struct omap_opp_def *opp_def)
>>>>
>>>>  		dev_opp->oh = oh;
>>>>  		dev_opp->dev = &oh->od->pdev.dev;
>>>> +		dev_opp->vdd_name = kzalloc(strlen(opp_def->vdd_name) + 1,
>>>> +				GFP_KERNEL);
>>>> +		strcpy(dev_opp->vdd_name, opp_def->vdd_name);
>>>
>>>Since this is user-defined data/string, should probably have a max
>>>strlen and use strncpy.
>
> I did not get this. What is the problem with the strlen here ?

It's more of a paranoia issue than a technical issue.  I don't like
blindly using strlen on strings that are user-configurable.  I guess,
since they're coming from the OPP table, they're not terribly
configurable, so it's probably not a big deal.

However, since opp_add() is already doing one kzalloc, I think it's
probably cleaner to just to make this field a fixed lenght and
then use strncpy():

#define VDD_NAME_LEN 8

struct device_opp {
       ...
       char vdd_name[VDD_NAME_LEN];
       ...
}

Kevin

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

* RE: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.
  2010-08-04 21:06           ` Kevin Hilman
@ 2010-08-05  5:48             ` Gopinath, Thara
  0 siblings, 0 replies; 22+ messages in thread
From: Gopinath, Thara @ 2010-08-05  5:48 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant,
	Anand, Basak, Partha



>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Thursday, August 05, 2010 2:36 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand;
>>Basak, Partha
>>Subject: Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get
>>rate in device opp structures.
>>
>>"Gopinath, Thara" <thara@ti.com> writes:
>>
>>>>>> @@ -385,6 +380,11 @@ int opp_add(const struct omap_opp_def *opp_def)
>>>>>>
>>>>>>  		dev_opp->oh = oh;
>>>>>>  		dev_opp->dev = &oh->od->pdev.dev;
>>>>>> +		dev_opp->vdd_name = kzalloc(strlen(opp_def->vdd_name) + 1,
>>>>>> +				GFP_KERNEL);
>>>>>> +		strcpy(dev_opp->vdd_name, opp_def->vdd_name);
>>>>>
>>>>>Since this is user-defined data/string, should probably have a max
>>>>>strlen and use strncpy.
>>>
>>> I did not get this. What is the problem with the strlen here ?
>>
>>It's more of a paranoia issue than a technical issue.  I don't like
>>blindly using strlen on strings that are user-configurable.  I guess,
>>since they're coming from the OPP table, they're not terribly
>>configurable, so it's probably not a big deal.
>>
>>However, since opp_add() is already doing one kzalloc, I think it's
>>probably cleaner to just to make this field a fixed lenght and
>>then use strncpy():
>>
>>#define VDD_NAME_LEN 8
>>
>>struct device_opp {
>>       ...
>>       char vdd_name[VDD_NAME_LEN];
>>       ...
>>}

Gotcha! Will incorporate in V2.

Regards
Thara

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

end of thread, other threads:[~2010-08-05  5:49 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-02 10:18 [RFC 0/7] OMAP: Basic DVFS framework Thara Gopinath
2010-07-02 10:18 ` [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
2010-07-02 10:18   ` [RFC 2/7] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage Thara Gopinath
2010-07-02 10:18     ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thara Gopinath
2010-07-02 10:18       ` [RFC 4/7] OMAP: Voltage layer changes to support DVFS Thara Gopinath
2010-07-02 10:18         ` [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer Thara Gopinath
2010-07-02 10:18           ` [RFC 6/7] OMAP3: Update OMAP3 opp tables to contain the voltage domain and device set rate get rate info Thara Gopinath
2010-07-02 10:18             ` [RFC 7/7] OMAP3: Update cpufreq driver to use the new set_rate API Thara Gopinath
2010-07-08  3:10               ` Pandita, Vikram
2010-07-08  3:11                 ` Gopinath, Thara
2010-07-02 11:52           ` [RFC 5/7] OMAP: Introduce set_rate and get_rate API in omap device layer Sripathy, Vishwanath
2010-07-12 14:48       ` [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures Thomas Petazzoni
2010-07-12 16:01         ` Paul Walmsley
2010-08-02 12:10       ` Cousson, Benoit
2010-08-04  4:01         ` Gopinath, Thara
2010-08-04  0:32       ` Kevin Hilman
2010-08-04  4:02         ` Gopinath, Thara
2010-08-04 21:06           ` Kevin Hilman
2010-08-05  5:48             ` Gopinath, Thara
2010-07-02 11:44   ` [RFC 1/7] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Sripathy, Vishwanath
2010-08-03 23:49 ` [RFC 0/7] OMAP: Basic DVFS framework Kevin Hilman
2010-08-04  3:54   ` Gopinath, Thara

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.