* [PATCH v2 00/14] OMAP: Basic DVFS framework
@ 2010-10-29 15:38 Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
` (13 more replies)
0 siblings, 14 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch series introduces support 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 tables.
5. Handle inter VDD dependecies.
Work pending -
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 lo-master and is dependent on
the cpufreq patches in Kevin's PM tree and the Voltage layer and
Smartreflex sereis posted by me to the list. These patches can be viewed
at
http://dev.omapzoom.org/?p=thara/omap-dvfs.git;a=summary
head - pm-dvfs
This series has been tested on OMAP3430 SDP for mpu, iva and
core DVFS through cpu freq framework.
Thara Gopinath (14):
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 information in the hwmod structures
OMAP: Introduce API to register a device with a voltagedomain
OMAP: Introduce device specific set rate and get rate in omap_device
structure
OMAP: Voltage layer changes to support DVFS.
OMAP: Introduce dependent voltage domain support.
OMAP: Introduce device scale
OMAP: Disable smartreflex across DVFS
OMAP3: Introduce custom set rate and get rate APIs for scalable
devices
OMAP3: Update cpufreq driver to use the new set_rate API
OMAP3: Introduce voltage domain info in the hwmod structures.
OMAP3: Add voltage dependency table for VDD1.
OMAP2PLUS: Enable various options in defconfig
arch/arm/configs/omap2plus_defconfig | 4 +
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 3 +
arch/arm/mach-omap2/pm.c | 110 ++++++++
arch/arm/mach-omap2/voltage.c | 366 ++++++++++++++++++++++++-
arch/arm/plat-omap/cpu-omap.c | 3 +-
arch/arm/plat-omap/include/plat/omap_device.h | 12 +-
arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 +
arch/arm/plat-omap/include/plat/voltage.h | 21 ++
arch/arm/plat-omap/omap_device.c | 139 ++++++++++
drivers/base/power/opp.c | 28 ++
include/linux/opp.h | 8 +
11 files changed, 696 insertions(+), 3 deletions(-)
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-11-11 23:53 ` Kevin Hilman
2010-11-12 0:07 ` Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 02/14] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage Thara Gopinath
` (12 subsequent siblings)
13 siblings, 2 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, 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 | 101 ++++++++++++++++++++++++++++-
arch/arm/plat-omap/include/plat/voltage.h | 7 ++
2 files changed, 107 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 45b0958..f0ecc30 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -24,6 +24,9 @@
#include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/plist.h>
+#include <linux/slab.h>
#include <plat/common.h>
#include <plat/voltage.h>
@@ -85,6 +88,20 @@ struct vp_reg_val {
};
/**
+ * struct 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
@@ -95,9 +112,13 @@ struct vp_reg_val {
* vp registers
* @voltdm : pointer to the voltage domain structure
* @debug_dir : debug directory for this voltage domain.
+ * @user_lock : the lock to be used by the plist user_list
+ * @user_list : the list head maintaining the various users.
+ * @scaling_mutex : the dvfs muutex.
+ * of this vdd with the voltage requested by each user.
* @volt_data_count : number of distinct voltages supported by this vdd.
* @nominal_volt : nominal voltage for this vdd.
- * @curr_volt : current voltage for this vdd;
+ * @curr_volt : current voltage for this vdd.
* cmdval_reg : voltage controller cmdval register.
* @vdd_sr_reg : the smartreflex register associated with this VDD.
*/
@@ -107,6 +128,9 @@ struct omap_vdd_info{
struct vp_reg_val vp_reg;
struct voltagedomain voltdm;
struct dentry *debug_dir;
+ spinlock_t user_lock;
+ struct plist_head user_list;
+ struct mutex scaling_mutex;
int volt_data_count;
u32 nominal_volt;
u32 curr_volt;
@@ -591,6 +615,12 @@ static void __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
vdd->vp_reg.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT;
vdd->vp_reg.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT;
vdd->vp_reg.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT;
+
+ /* Init the plist */
+ spin_lock_init(&vdd->user_lock);
+ plist_head_init(&vdd->user_list, &vdd->user_lock);
+ /* Init the DVFS mutex */
+ mutex_init(&vdd->scaling_mutex);
}
/* OMAP4 specific voltage init functions */
@@ -715,6 +745,12 @@ static void __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
vdd->vp_reg.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT;
vdd->vp_reg.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT;
vdd->vp_reg.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT;
+
+ /* Init the plist */
+ spin_lock_init(&vdd->user_lock);
+ plist_head_init(&vdd->user_list, &vdd->user_lock);
+ /* Init the DVFS mutex */
+ mutex_init(&vdd->scaling_mutex);
}
/* Generic voltage init functions */
@@ -1140,6 +1176,69 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
return volt_pmic_info.vsel_to_uv(curr_vsel);
}
+/**
+ * omap_voltage_add_request() - 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_voltage_add_request(struct voltagedomain *voltdm, 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 (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ mutex_lock(&vdd->scaling_mutex);
+
+ 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__, voltdm->name);
+ mutex_unlock(&vdd->scaling_mutex);
+ return -ENOMEM;
+ }
+ user->dev = dev;
+ } else {
+ plist_del(&user->node, &vdd->user_list);
+ }
+
+ plist_node_init(&user->node, *volt);
+ plist_add(&user->node, &vdd->user_list);
+ node = plist_last(&vdd->user_list);
+ *volt = user->volt = node->prio;
+
+ mutex_unlock(&vdd->scaling_mutex);
+
+ return 0;
+}
/**
* omap_vp_enable() - API to enable a particular VP
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 812266e..c226b6d 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -150,11 +150,18 @@ bool omap_voltage_override_params(struct voltagedomain *voltdm);
void omap_voltage_register_pmic(struct omap_volt_pmic_info *pmic_info);
void omap_voltage_init_vc(struct omap_volt_vc_data *setup_vc);
void omap_change_voltscale_method(int voltscale_method);
+int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
+ unsigned long *volt);
#else
static inline void omap_voltage_register_pmic
(struct omap_volt_pmic_info *pmic_info) {}
static inline void omap_voltage_init_vc(struct omap_volt_vc_data *setup_vc) {}
static inline void omap_change_voltscale_method(int voltscale_method) {}
+static inline int omap_voltage_add_request(struct voltagedomain *voltdm,
+ struct device *dev, unsigned long *volt)
+{
+ return -EINVAL;
+}
#endif
#endif
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 02/14] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage.
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 03/14] OMAP: Introduce voltage domain information in the hwmod structures Thara Gopinath
` (11 subsequent siblings)
13 siblings, 0 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, 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>
---
drivers/base/power/opp.c | 28 ++++++++++++++++++++++++++++
include/linux/opp.h | 8 ++++++++
2 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index 2bb9b4c..60b4478 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -354,6 +354,34 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
}
/**
+ * 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 opp *opp_find_voltage(struct device *dev, unsigned long volt)
+{
+ struct device_opp *dev_opp;
+ struct opp *temp_opp, *opp = ERR_PTR(-ENODEV);
+
+ dev_opp = find_device_opp(dev);
+ if (IS_ERR(dev_opp))
+ return opp;
+
+ list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) {
+ if (temp_opp->available && temp_opp->u_volt == volt) {
+ opp = temp_opp;
+ break;
+ }
+ }
+
+ return opp;
+}
+
+/**
* opp_add() - Add an OPP table from a table definitions
* @dev: device for which we do this operation
* @freq: Frequency in Hz for this OPP
diff --git a/include/linux/opp.h b/include/linux/opp.h
index 5449945..4977d5c 100644
--- a/include/linux/opp.h
+++ b/include/linux/opp.h
@@ -34,6 +34,8 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq);
struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq);
+struct opp *opp_find_voltage(struct device *dev, unsigned long volt);
+
int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt);
int opp_enable(struct device *dev, unsigned long freq);
@@ -74,6 +76,12 @@ static inline struct opp *opp_find_freq_ceil(struct device *dev,
return ERR_PTR(-EINVAL);
}
+static inline struct opp *opp_find_voltage(struct device *dev,
+ unsigned long volt)
+{
+ return ERR_PTR(-EINVAL);
+}
+
static inline int opp_add(struct device *dev, unsigned long freq,
unsigned long u_volt)
{
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 03/14] OMAP: Introduce voltage domain information in the hwmod structures
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 02/14] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain Thara Gopinath
` (10 subsequent siblings)
13 siblings, 0 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch extends the device hwmod structure to contain
info about the voltage domain to which the device belongs to.
This is needed to support a device based DVFS where the
device knows which voltage domain it belongs to.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 7eaa8ed..9567aee 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -34,6 +34,7 @@
#include <linux/ioport.h>
#include <linux/mutex.h>
#include <plat/cpu.h>
+#include <plat/voltage.h>
struct omap_device;
@@ -436,6 +437,8 @@ struct omap_hwmod_class {
* @main_clk: main clock: OMAP clock name
* @_clk: pointer to the main struct clk (filled in at runtime)
* @opt_clks: other device clocks that drivers can request (0..*)
+ * @vdd_name: voltage domain name
+ * @voltdm: pointer to voltage domain (filled in at runtime)
* @masters: ptr to array of OCP ifs that this hwmod can initiate on
* @slaves: ptr to array of OCP ifs that this hwmod can respond on
* @dev_attr: arbitrary device attributes that can be passed to the driver
@@ -479,6 +482,8 @@ struct omap_hwmod {
const char *main_clk;
struct clk *_clk;
struct omap_hwmod_opt_clk *opt_clks;
+ char *vdd_name;
+ struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
void *dev_attr;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (2 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 03/14] OMAP: Introduce voltage domain information in the hwmod structures Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-11-11 0:49 ` Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure Thara Gopinath
` (9 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch adds an API in the voltage layer that
can be used during omap_device_build to register the built
device with the voltage domain. This API is to be typically called
only once per device during the device registeration. 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/mach-omap2/voltage.c | 45 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/voltage.h | 7 ++++
arch/arm/plat-omap/omap_device.c | 12 ++++++++
3 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index f0ecc30..6c2e4ef 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -101,6 +101,11 @@ struct omap_vdd_user_list {
u32 volt;
};
+struct omap_vdd_dev_list {
+ struct device *dev;
+ struct list_head node;
+};
+
/**
* omap_vdd_info - Per Voltage Domain info
*
@@ -116,6 +121,7 @@ struct omap_vdd_user_list {
* @user_list : the list head maintaining the various users.
* @scaling_mutex : the dvfs muutex.
* of this vdd with the voltage requested by each user.
+ * @dev_list : list of devices bwlonging to this voltage domain.
* @volt_data_count : number of distinct voltages supported by this vdd.
* @nominal_volt : nominal voltage for this vdd.
* @curr_volt : current voltage for this vdd.
@@ -131,6 +137,7 @@ struct omap_vdd_info{
spinlock_t user_lock;
struct plist_head user_list;
struct mutex scaling_mutex;
+ struct list_head dev_list;
int volt_data_count;
u32 nominal_volt;
u32 curr_volt;
@@ -621,6 +628,8 @@ static void __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
plist_head_init(&vdd->user_list, &vdd->user_lock);
/* Init the DVFS mutex */
mutex_init(&vdd->scaling_mutex);
+ /* Init the device list */
+ INIT_LIST_HEAD(&vdd->dev_list);
}
/* OMAP4 specific voltage init functions */
@@ -751,6 +760,8 @@ static void __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
plist_head_init(&vdd->user_list, &vdd->user_lock);
/* Init the DVFS mutex */
mutex_init(&vdd->scaling_mutex);
+ /* Init the device list */
+ INIT_LIST_HEAD(&vdd->dev_list);
}
/* Generic voltage init functions */
@@ -1240,6 +1251,40 @@ int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
return 0;
}
+int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev)
+{
+ struct omap_vdd_info *vdd;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ list_for_each_entry(temp_dev, &vdd->dev_list, node) {
+ if (temp_dev->dev == dev) {
+ dev_warn(dev, "%s: Device already added to vdee_%s\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+ }
+
+ temp_dev = kzalloc(sizeof(struct omap_vdd_dev_list), GFP_KERNEL);
+ if (!temp_dev) {
+ dev_err(dev, "%s: Unable to creat a new device for vdd_%s\n",
+ __func__, voltdm->name);
+ return -ENOMEM;
+ }
+
+ temp_dev->dev = dev;
+
+ list_add(&temp_dev->node, &vdd->dev_list);
+
+ return 0;
+}
+
/**
* omap_vp_enable() - API to enable a particular VP
* @voltdm: 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 c226b6d..dc64a9a 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -152,6 +152,7 @@ void omap_voltage_init_vc(struct omap_volt_vc_data *setup_vc);
void omap_change_voltscale_method(int voltscale_method);
int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
unsigned long *volt);
+int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev);
#else
static inline void omap_voltage_register_pmic
(struct omap_volt_pmic_info *pmic_info) {}
@@ -162,6 +163,12 @@ static inline int omap_voltage_add_request(struct voltagedomain *voltdm,
{
return -EINVAL;
}
+
+static inline int omap_voltage_add_dev(struct voltagedomain *voltdm,
+ struct device *dev)
+{
+ return -EINVAL;
+}
#endif
#endif
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index abe933c..7c902a6 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -86,6 +86,7 @@
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
+#include <plat/voltage.h>
/* These parameters are passed to _omap_device_{de,}activate() */
#define USE_WAKEUP_LAT 0
@@ -453,6 +454,17 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
for (i = 0; i < oh_cnt; i++) {
hwmods[i]->od = od;
_add_optional_clock_alias(od, hwmods[i]);
+ if (hwmods[i]->vdd_name) {
+ struct omap_hwmod *oh = hwmods[i];
+ struct voltagedomain *voltdm;
+
+ if (is_early_device)
+ continue;
+
+ voltdm = omap_voltage_domain_lookup(oh->vdd_name);
+ if (!omap_voltage_add_dev(voltdm, &od->pdev.dev))
+ oh->voltdm = voltdm;
+ }
}
if (ret)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (3 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-11-11 22:59 ` Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS Thara Gopinath
` (8 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch extends the omap_device structure to contain
pointers to scale the operating rate of the
device and to retrieve the operating rate of the device.
This patch also adds the three new APIs in the omap device layer
namely omap_device_set_rate that can be called to set a new operating
rate for a device, omap_device_get_rate that can be called to retrieve
the operating frequency for a device and omap_device_populate_rate_fns
to populte the device specific set_rate and get_rate API's.
The omap_device_set_rate and omap_device_get_rate does some routine error
checks and finally calls into the device specific set_rate
and get_rate APIs populated through omap_device_populate_rate_fns.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/plat-omap/include/plat/omap_device.h | 9 +++++
arch/arm/plat-omap/omap_device.c | 49 +++++++++++++++++++++++++
2 files changed, 58 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 28e2d1a..2a37345 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -50,6 +50,8 @@ extern struct device omap_device_parent;
* @hwmods: (one .. many per omap_device)
* @hwmods_cnt: ARRAY_SIZE() of @hwmods
* @pm_lats: ptr to an omap_device_pm_latency table
+ * @set_rate: fn ptr to change the operating rate.
+ * @get_rate: fn ptr to retrieve the current operating rate.
* @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
* @pm_lat_level: array index of the last odpl entry executed - -1 if never
* @dev_wakeup_lat: dev wakeup latency in nanoseconds
@@ -67,6 +69,8 @@ struct omap_device {
struct platform_device pdev;
struct omap_hwmod **hwmods;
struct omap_device_pm_latency *pm_lats;
+ int (*set_rate)(struct device *dev, unsigned long rate);
+ unsigned long (*get_rate) (struct device *dev);
u32 dev_wakeup_lat;
u32 _dev_wakeup_lat_limit;
u8 pm_lats_cnt;
@@ -107,6 +111,11 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od);
int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit);
struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
+int omap_device_set_rate(struct device *dev, unsigned long freq);
+unsigned long omap_device_get_rate(struct device *dev);
+void omap_device_populate_rate_fns(struct device *dev,
+ int (*set_rate)(struct device *dev, unsigned long rate),
+ unsigned long (*get_rate) (struct device *dev));
/* Other */
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 7c902a6..ffe06eb 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -785,6 +785,55 @@ int omap_device_enable_clocks(struct omap_device *od)
return 0;
}
+int omap_device_set_rate(struct device *dev, unsigned long freq)
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+ if (!od->set_rate) {
+ dev_err(dev, "%s: No set_rate API for scaling device\n",
+ __func__);
+ return -ENODATA;
+ }
+
+ return od->set_rate(dev, freq);
+}
+
+unsigned long omap_device_get_rate(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+
+ if (!od->get_rate) {
+ dev_err(dev, "%s: No get rate API for the device\n",
+ __func__);
+ return 0;
+ }
+
+ return od->get_rate(dev);
+}
+
+void omap_device_populate_rate_fns(struct device *dev,
+ int (*set_rate)(struct device *dev, unsigned long rate),
+ unsigned long (*get_rate) (struct device *dev))
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+ od->set_rate = set_rate;
+ od->get_rate = get_rate;
+}
+
struct device omap_device_parent = {
.init_name = "omap",
.parent = &platform_bus,
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS.
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (4 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-11-11 23:34 ` Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support Thara Gopinath
` (7 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch 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.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 72 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/voltage.h | 7 +++
2 files changed, 79 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 6c2e4ef..458f8c1 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -27,9 +27,11 @@
#include <linux/spinlock.h>
#include <linux/plist.h>
#include <linux/slab.h>
+#include <linux/opp.h>
#include <plat/common.h>
#include <plat/voltage.h>
+#include <plat/omap_device.h>
#include "prm-regbits-34xx.h"
#include "prm44xx.h"
@@ -1678,6 +1680,76 @@ struct voltagedomain *omap_voltage_domain_lookup(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 voltagedomain *voltdm, unsigned long volt)
+{
+ unsigned long curr_volt;
+ int is_volt_scaled = 0;
+ struct omap_vdd_info *vdd;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ mutex_lock(&vdd->scaling_mutex);
+
+ curr_volt = omap_voltage_get_nom_volt(voltdm);
+
+ if (curr_volt == volt) {
+ is_volt_scaled = 1;
+ } else if (curr_volt < volt) {
+ omap_voltage_scale_vdd(voltdm, volt);
+ is_volt_scaled = 1;
+ }
+
+ list_for_each_entry(temp_dev, &vdd->dev_list, node) {
+ struct device *dev;
+ struct opp *opp;
+ unsigned long freq;
+
+ dev = temp_dev->dev;
+
+ opp = opp_find_voltage(dev, volt);
+ if (IS_ERR(opp)) {
+ dev_err(dev, "%s: Unable to find OPP for"
+ "volt%ld\n", __func__, volt);
+ continue;
+ }
+
+ freq = opp_get_freq(opp);
+
+ if (freq == omap_device_get_rate(dev)) {
+ dev_warn(dev, "%s: Already at the requested"
+ "rate %ld\n", __func__, freq);
+ continue;
+ }
+
+ omap_device_set_rate(dev, freq);
+ }
+
+ if (!is_volt_scaled)
+ omap_voltage_scale_vdd(voltdm, volt);
+
+ mutex_unlock(&vdd->scaling_mutex);
+
+ 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 dc64a9a..54d50e2 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -153,6 +153,7 @@ void omap_change_voltscale_method(int voltscale_method);
int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
unsigned long *volt);
int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev);
+int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt);
#else
static inline void omap_voltage_register_pmic
(struct omap_volt_pmic_info *pmic_info) {}
@@ -169,6 +170,12 @@ static inline int omap_voltage_add_dev(struct voltagedomain *voltdm,
{
return -EINVAL;
}
+
+static inline int omap_voltage_scale(struct voltagedomain *voltdm,
+ unsigned long volt)
+{
+ return -EINVAL;
+}
#endif
#endif
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support.
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (5 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-11-11 17:06 ` Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 08/14] OMAP: Introduce device scale Thara Gopinath
` (6 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
There could be dependencies between various voltage domains for
maintaining system performance or hardware limitation reasons
like VDD<X> should be at voltage v1 when VDD<Y> is at voltage v2.
This patch introduce dependent vdd information structures in the
voltage layer which can be used to populate these dependencies
for a voltage domain. This patch also adds support to scale
the dependent vdd and the scalable devices belonging to it
during the scaling of a main vdd through omap_voltage_scale.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 122 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 458f8c1..67748b0 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -90,6 +90,36 @@ struct vp_reg_val {
};
/**
+ * omap_vdd_dep_volt - Table containing the parent vdd voltage and the
+ * dependent vdd voltage corresponding to it.
+ *
+ * @main_vdd_volt : The main vdd voltage
+ * @dep_vdd_volt : The voltage at which the dependent vdd should be
+ * when the main vdd is at <main_vdd_volt> voltage
+ */
+struct omap_vdd_dep_volt {
+ u32 main_vdd_volt;
+ u32 dep_vdd_volt;
+};
+
+/**
+ * omap_vdd_dep_info - Dependent vdd info
+ *
+ * @name : Dependent vdd name
+ * @voltdm : Dependent vdd pointer
+ * @dep_table : Table containing the dependent vdd voltage
+ * corresponding to every main vdd voltage.
+ * @cur_dep_volt : The voltage to which dependent vdd should be put
+ * to for the current main vdd voltage.
+ */
+struct omap_vdd_dep_info{
+ char *name;
+ struct voltagedomain *voltdm;
+ struct omap_vdd_dep_volt *dep_table;
+ unsigned long cur_dep_volt;
+};
+
+/**
* struct omap_vdd_user_list - The per vdd user list
*
* @dev: The device asking for the vdd to be set at a particular
@@ -135,12 +165,14 @@ struct omap_vdd_info{
struct vp_reg_offs vp_offs;
struct vp_reg_val vp_reg;
struct voltagedomain voltdm;
+ struct omap_vdd_dep_info *dep_vdd_info;
struct dentry *debug_dir;
spinlock_t user_lock;
struct plist_head user_list;
struct mutex scaling_mutex;
struct list_head dev_list;
int volt_data_count;
+ int nr_dep_vdd;
u32 nominal_volt;
u32 curr_volt;
u8 cmdval_reg;
@@ -1139,6 +1171,80 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
return 0;
}
+static int calc_dep_vdd_volt(struct device *dev,
+ struct omap_vdd_info *main_vdd, unsigned long main_volt)
+{
+ struct omap_vdd_dep_info *dep_vdds;
+ int i, ret = 0;
+
+ if (!main_vdd->dep_vdd_info) {
+ pr_debug("%s: No dependent VDD's for vdd_%s\n",
+ __func__, main_vdd->voltdm.name);
+ return 0;
+ }
+
+ dep_vdds = main_vdd->dep_vdd_info;
+
+ for (i = 0; i < main_vdd->nr_dep_vdd; i++) {
+ struct omap_vdd_dep_volt *volt_table = dep_vdds[i].dep_table;
+ int nr_volt = 0;
+ unsigned long dep_volt = 0, act_volt = 0;
+
+ while (volt_table[nr_volt].main_vdd_volt != 0) {
+ if (volt_table[nr_volt].main_vdd_volt == main_volt) {
+ dep_volt = volt_table[nr_volt].dep_vdd_volt;
+ break;
+ }
+ nr_volt++;
+ }
+ if (!dep_volt) {
+ pr_warning("%s: Not able to find a matching volt for"
+ "vdd_%s corresponding to vdd_%s %ld volt\n",
+ __func__, dep_vdds[i].name,
+ main_vdd->voltdm.name, main_volt);
+ ret = -EINVAL;
+ continue;
+ }
+
+ if (!dep_vdds[i].voltdm)
+ dep_vdds[i].voltdm =
+ omap_voltage_domain_lookup(dep_vdds[i].name);
+
+ act_volt = dep_volt;
+
+ /* See if dep_volt is possible for the vdd*/
+ ret = omap_voltage_add_request(dep_vdds[i].voltdm, dev,
+ &act_volt);
+
+ /*
+ * Currently we do not bother if the dep volt and act volt are
+ * different. We could add a check if needed.
+ */
+ dep_vdds[i].cur_dep_volt = act_volt;
+ }
+
+ return ret;
+}
+
+static int scale_dep_vdd(struct omap_vdd_info *main_vdd)
+{
+ struct omap_vdd_dep_info *dep_vdds;
+ int i;
+
+ if (!main_vdd->dep_vdd_info) {
+ pr_debug("%s: No dependent VDD's for vdd_%s\n",
+ __func__, main_vdd->voltdm.name);
+ return 0;
+ }
+
+ dep_vdds = main_vdd->dep_vdd_info;
+
+ for (i = 0; i < main_vdd->nr_dep_vdd; i++)
+ omap_voltage_scale(dep_vdds[i].voltdm,
+ dep_vdds[i].cur_dep_volt);
+ return 0;
+}
+
/* Public functions */
/**
* omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
@@ -1697,6 +1803,8 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
int is_volt_scaled = 0;
struct omap_vdd_info *vdd;
struct omap_vdd_dev_list *temp_dev;
+ struct plist_node *node;
+ struct omap_vdd_user_list *user;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
@@ -1709,6 +1817,17 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
curr_volt = omap_voltage_get_nom_volt(voltdm);
+ /* Find the device requesting the voltage scaling */
+ node = plist_first(&vdd->user_list);
+ user = container_of(node, struct omap_vdd_user_list, node);
+
+ /* calculate the voltages for dependent vdd's */
+ if (calc_dep_vdd_volt(user->dev, vdd, volt)) {
+ pr_warning("%s: Error in calculating dependent vdd voltages"
+ "for vdd_%s\n", __func__, voltdm->name);
+ return -EINVAL;
+ }
+
if (curr_volt == volt) {
is_volt_scaled = 1;
} else if (curr_volt < volt) {
@@ -1746,6 +1865,9 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
mutex_unlock(&vdd->scaling_mutex);
+ /* Scale dependent vdds */
+ scale_dep_vdd(vdd);
+
return 0;
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 08/14] OMAP: Introduce device scale
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (6 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 09/14] OMAP: Disable smartreflex across DVFS Thara Gopinath
` (5 subsequent siblings)
13 siblings, 0 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch adds omap_device_scale API 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 | 3 +-
arch/arm/plat-omap/omap_device.c | 78 +++++++++++++++++++++++++
2 files changed, 80 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 2a37345..daafb5a 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -116,6 +116,8 @@ unsigned long omap_device_get_rate(struct device *dev);
void omap_device_populate_rate_fns(struct device *dev,
int (*set_rate)(struct device *dev, unsigned long rate),
unsigned long (*get_rate) (struct device *dev));
+int omap_device_scale(struct device *req_dev, struct device *dev,
+ unsigned long rate);
/* Other */
@@ -125,7 +127,6 @@ 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);
-
/*
* 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 ffe06eb..a273230 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -83,6 +83,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/opp.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
@@ -834,6 +835,83 @@ void omap_device_populate_rate_fns(struct device *dev,
od->get_rate = get_rate;
}
+/**
+ * omap_device_scale() - Set a new rate at which the device is to operate
+ * @req_dev: pointer to the device requesting the scaling.
+ * @dev: pointer to the device that is to be scaled
+ * @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_scale(struct device *req_dev, struct device *dev,
+ unsigned long rate)
+{
+ struct opp *opp;
+ unsigned long volt, freq, min_freq, max_freq;
+ struct voltagedomain *voltdm;
+ struct platform_device *pdev;
+ struct omap_device *od;
+ int ret;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+ /*
+ * Figure out if the desired frquency lies between the
+ * maximum and minimum possible for the particular device
+ */
+ min_freq = 0;
+ if (IS_ERR(opp_find_freq_ceil(dev, &min_freq))) {
+ dev_err(dev, "%s: Unable to find lowest opp\n", __func__);
+ return -ENODEV;
+ }
+
+ max_freq = ULONG_MAX;
+ if (IS_ERR(opp_find_freq_floor(dev, &max_freq))) {
+ dev_err(dev, "%s: Unable to find highest opp\n", __func__);
+ return -ENODEV;
+ }
+
+ if (rate < min_freq)
+ freq = min_freq;
+ else if (rate > max_freq)
+ freq = max_freq;
+ else
+ 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;
+ }
+
+ /* 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.
+ */
+ voltdm = od->hwmods[0]->voltdm;
+ ret = omap_voltage_add_request(voltdm, req_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(voltdm, volt);
+}
+EXPORT_SYMBOL(omap_device_scale);
+
struct device omap_device_parent = {
.init_name = "omap",
.parent = &platform_bus,
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 09/14] OMAP: Disable smartreflex across DVFS
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (7 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 08/14] OMAP: Introduce device scale Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 10/14] OMAP3: Introduce custom set rate and get rate APIs for scalable devices Thara Gopinath
` (4 subsequent siblings)
13 siblings, 0 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch disables smartreflex for a particular voltage
domain when the the voltage domain and the devices belonging
to it is being scaled and re-enables it back once the scaling
is done.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 67748b0..6f85f75 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -32,6 +32,7 @@
#include <plat/common.h>
#include <plat/voltage.h>
#include <plat/omap_device.h>
+#include <plat/smartreflex.h>
#include "prm-regbits-34xx.h"
#include "prm44xx.h"
@@ -1828,6 +1829,9 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
return -EINVAL;
}
+ /* Disable smartreflex module across voltage and frequency scaling */
+ omap_sr_disable(voltdm);
+
if (curr_volt == volt) {
is_volt_scaled = 1;
} else if (curr_volt < volt) {
@@ -1865,6 +1869,9 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
mutex_unlock(&vdd->scaling_mutex);
+ /* Enable Smartreflex module */
+ omap_sr_enable(voltdm);
+
/* Scale dependent vdds */
scale_dep_vdd(vdd);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 10/14] OMAP3: Introduce custom set rate and get rate APIs for scalable devices
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (8 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 09/14] OMAP: Disable smartreflex across DVFS Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 11/14] OMAP3: Update cpufreq driver to use the new set_rate API Thara Gopinath
` (3 subsequent siblings)
13 siblings, 0 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
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
APIs for OMAP3 mpu, iva and l3_main devices. This patch also
calls into omap_device_populate_rate_fns during system init to register
various set_rate and get_rate APIs with the omap device layer
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/pm.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 110 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 0651667..0fa7fca 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -14,6 +14,7 @@
#include <linux/io.h>
#include <linux/err.h>
#include <linux/opp.h>
+#include <linux/delay.h>
#include <plat/omap-pm.h>
#include <plat/omap_device.h>
@@ -23,6 +24,8 @@
#include <plat/clockdomain.h>
#include <plat/voltage.h>
+#include "cm-regbits-34xx.h"
+#include "prm.h"
#include "pm.h"
static struct omap_device_pm_latency *pm_lats;
@@ -32,6 +35,8 @@ static struct device *iva_dev;
static struct device *l3_dev;
static struct device *dsp_dev;
+static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
+
struct device *omap2_get_mpuss_device(void)
{
WARN_ON_ONCE(!mpu_dev);
@@ -57,6 +62,26 @@ struct device *omap4_get_dsp_device(void)
}
EXPORT_SYMBOL(omap4_get_dsp_device);
+static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
+{
+ unsigned long new_jiffy_l, new_jiffy_h;
+
+ /*
+ * Recalculate loops_per_jiffy. We do it this way to
+ * avoid math overflow on 32-bit machines. Maybe we
+ * should make this architecture dependent? If you have
+ * a better way of doing this, please replace!
+ *
+ * new = old * mult / div
+ */
+ new_jiffy_h = ref / div;
+ new_jiffy_l = (ref % div) / 100;
+ new_jiffy_h *= mult;
+ new_jiffy_l = new_jiffy_l * mult / div;
+
+ return new_jiffy_h + new_jiffy_l * 100;
+}
+
/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
static int _init_omap_device(char *name, struct device **new_dev)
{
@@ -78,6 +103,74 @@ static int _init_omap_device(char *name, struct device **new_dev)
return 0;
}
+static unsigned long omap3_mpu_get_rate(struct device *dev)
+{
+ return dpll1_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
+ 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 int omap3_iva_set_rate(struct device *dev, unsigned long 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_l3_set_rate(struct device *dev, unsigned long rate)
+{
+ int l3_div;
+
+ 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;
+}
+
/*
* Build omap_devices for processors and bus.
*/
@@ -91,6 +184,23 @@ static void omap2_init_processor_devices(void)
} else {
_init_omap_device("l3_main", &l3_dev);
}
+
+ if (cpu_is_omap34xx()) {
+ dpll1_clk = clk_get(NULL, "dpll1_ck");
+ dpll2_clk = clk_get(NULL, "dpll2_ck");
+ dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
+
+ if (mpu_dev)
+ omap_device_populate_rate_fns(mpu_dev,
+ omap3_mpu_set_rate, omap3_mpu_get_rate);
+ if (iva_dev)
+ omap_device_populate_rate_fns(iva_dev,
+ omap3_iva_set_rate, omap3_iva_get_rate);
+ if (l3_dev)
+ omap_device_populate_rate_fns(l3_dev,
+ omap3_l3_set_rate, omap3_l3_get_rate);
+
+ }
}
/*
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 11/14] OMAP3: Update cpufreq driver to use the new set_rate API
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (9 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 10/14] OMAP3: Introduce custom set rate and get rate APIs for scalable devices Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 12/14] OMAP3: Introduce voltage domain info in the hwmod structures Thara Gopinath
` (2 subsequent siblings)
13 siblings, 0 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, 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 | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 671e4b9..d9d5bdb 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -31,6 +31,7 @@
#include <plat/clock.h>
#include <plat/common.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>
@@ -118,7 +119,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_scale(mpu_dev, mpu_dev, freq);
#endif
return ret;
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 12/14] OMAP3: Introduce voltage domain info in the hwmod structures.
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (10 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 11/14] OMAP3: Update cpufreq driver to use the new set_rate API Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1 Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 14/14] OMAP2PLUS: Enable various options in defconfig Thara Gopinath
13 siblings, 0 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch adds voltage domain info in the relevant
device hwmod structures so as to enable OMAP3 DVFS
support.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index a6fbb6f..f73d4b7 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -86,6 +86,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
static struct omap_hwmod omap3xxx_l3_main_hwmod = {
.name = "l3_main",
.class = &l3_hwmod_class,
+ .vdd_name = "core",
.masters = omap3xxx_l3_main_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
.slaves = omap3xxx_l3_main_slaves,
@@ -376,6 +377,7 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
.name = "mpu",
.class = &mpu_hwmod_class,
.main_clk = "arm_fck",
+ .vdd_name = "mpu",
.masters = omap3xxx_mpu_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_mpu_masters),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -404,6 +406,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = {
static struct omap_hwmod omap3xxx_iva_hwmod = {
.name = "iva",
.class = &iva_hwmod_class,
+ .vdd_name = "mpu",
.masters = omap3xxx_iva_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (11 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 12/14] OMAP3: Introduce voltage domain info in the hwmod structures Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-12-01 15:31 ` Vishwanath Sripathy
2010-12-01 15:32 ` Vishwanath Sripathy
2010-10-29 15:38 ` [PATCH v2 14/14] OMAP2PLUS: Enable various options in defconfig Thara Gopinath
13 siblings, 2 replies; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
In OMAP3, for perfomrance reasons when VDD1 is at voltage above
1.075V, VDD2 should be at 1.15V for perfomrance reasons. This
patch introduce this cross VDD dependency for OMAP3 VDD1.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/voltage.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 6f85f75..241fac5 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -350,6 +350,23 @@ static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
{.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
};
+/* OMAP 3430 MPU Core VDD dependency table */
+static struct omap_vdd_dep_volt omap34xx_vdd1_vdd2_data[] = {
+ {.main_vdd_volt = 975000, .dep_vdd_volt = 1050000},
+ {.main_vdd_volt = 1075000, .dep_vdd_volt = 1050000},
+ {.main_vdd_volt = 1200000, .dep_vdd_volt = 1150000},
+ {.main_vdd_volt = 1270000, .dep_vdd_volt = 1150000},
+ {.main_vdd_volt = 1350000, .dep_vdd_volt = 1150000},
+ {.main_vdd_volt = 0, .dep_vdd_volt = 0},
+};
+
+static struct omap_vdd_dep_info omap34xx_vdd1_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap34xx_vdd1_vdd2_data,
+ },
+};
+
/* By default VPFORCEUPDATE is the chosen method of voltage scaling */
static bool voltscale_vpforceupdate = true;
@@ -574,6 +591,8 @@ static void __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
vdd->volt_data = omap34xx_vdd1_volt_data;
vdd->volt_data_count =
ARRAY_SIZE(omap34xx_vdd1_volt_data);
+ vdd->dep_vdd_info = omap34xx_vdd1_dep_info;
+ vdd->nr_dep_vdd = ARRAY_SIZE(omap34xx_vdd1_dep_info);
}
vdd->vp_reg.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 14/14] OMAP2PLUS: Enable various options in defconfig
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
` (12 preceding siblings ...)
2010-10-29 15:38 ` [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1 Thara Gopinath
@ 2010-10-29 15:38 ` Thara Gopinath
2010-11-08 19:24 ` Tony Lindgren
13 siblings, 1 reply; 28+ messages in thread
From: Thara Gopinath @ 2010-10-29 15:38 UTC (permalink / raw)
To: linux-omap
Cc: paul, khilman, b-cousson, vishwanath.bs, sawant, Thara Gopinath
This patch enables Smartreflex and Cpu Freq in the
omap2plus defconfig.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/configs/omap2plus_defconfig | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index ccedde1..b7888ae 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -291,3 +291,7 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
CONFIG_LIBCRC32C=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_OMAP_SMARTREFLEX=y
+CONFIG_OMAP_SMARTREFLEX_CLASS3=y
--
1.7.0.4
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v2 14/14] OMAP2PLUS: Enable various options in defconfig
2010-10-29 15:38 ` [PATCH v2 14/14] OMAP2PLUS: Enable various options in defconfig Thara Gopinath
@ 2010-11-08 19:24 ` Tony Lindgren
0 siblings, 0 replies; 28+ messages in thread
From: Tony Lindgren @ 2010-11-08 19:24 UTC (permalink / raw)
To: Thara Gopinath
Cc: linux-omap, paul, khilman, b-cousson, vishwanath.bs, sawant
* Thara Gopinath <thara@ti.com> [101029 08:30]:
> This patch enables Smartreflex and Cpu Freq in the
> omap2plus defconfig.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
> arch/arm/configs/omap2plus_defconfig | 4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
> index ccedde1..b7888ae 100644
> --- a/arch/arm/configs/omap2plus_defconfig
> +++ b/arch/arm/configs/omap2plus_defconfig
> @@ -291,3 +291,7 @@ CONFIG_CRC_T10DIF=y
> CONFIG_CRC_ITU_T=y
> CONFIG_CRC7=y
> CONFIG_LIBCRC32C=y
> +CONFIG_CPU_FREQ=y
> +CONFIG_CPU_FREQ_GOV_USERSPACE=y
> +CONFIG_OMAP_SMARTREFLEX=y
> +CONFIG_OMAP_SMARTREFLEX_CLASS3=y
Has this been tested to run reliably for several days and on which
hardware?
The reason I'm asking is that AFAIK smartreflex has not been enabled
for any production device so far.
Regards,
Tony
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain
2010-10-29 15:38 ` [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain Thara Gopinath
@ 2010-11-11 0:49 ` Kevin Hilman
2010-11-15 11:09 ` Gopinath, Thara
0 siblings, 1 reply; 28+ messages in thread
From: Kevin Hilman @ 2010-11-11 0:49 UTC (permalink / raw)
To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant
Thara Gopinath <thara@ti.com> writes:
> This patch adds an API in the voltage layer that
> can be used during omap_device_build to register the built
> device with the voltage domain. This API is to be typically called
> only once per device during the device registeration. 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>
[...]
> /* Generic voltage init functions */
> @@ -1240,6 +1251,40 @@ int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
> return 0;
> }
>
> +int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev)
minor nit: I prefer this be a 'register' function,
e.g. omap_voltage_register (or _register_dev)
[...]
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index abe933c..7c902a6 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -86,6 +86,7 @@
>
> #include <plat/omap_device.h>
> #include <plat/omap_hwmod.h>
> +#include <plat/voltage.h>
>
> /* These parameters are passed to _omap_device_{de,}activate() */
> #define USE_WAKEUP_LAT 0
> @@ -453,6 +454,17 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
> for (i = 0; i < oh_cnt; i++) {
> hwmods[i]->od = od;
> _add_optional_clock_alias(od, hwmods[i]);
> + if (hwmods[i]->vdd_name) {
Use:
if (!is_early_device && hwmods[i]->vdd_name)
> + struct omap_hwmod *oh = hwmods[i];
> + struct voltagedomain *voltdm;
> +
> + if (is_early_device)
> + continue;
and drop this check
> + voltdm = omap_voltage_domain_lookup(oh->vdd_name);
> + if (!omap_voltage_add_dev(voltdm, &od->pdev.dev))
> + oh->voltdm = voltdm;
> + }
> }
>
> if (ret)
Kevin
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support.
2010-10-29 15:38 ` [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support Thara Gopinath
@ 2010-11-11 17:06 ` Kevin Hilman
0 siblings, 0 replies; 28+ messages in thread
From: Kevin Hilman @ 2010-11-11 17:06 UTC (permalink / raw)
To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant
Thara Gopinath <thara@ti.com> writes:
> There could be dependencies between various voltage domains for
> maintaining system performance or hardware limitation reasons
> like VDD<X> should be at voltage v1 when VDD<Y> is at voltage v2.
> This patch introduce dependent vdd information structures in the
> voltage layer which can be used to populate these dependencies
> for a voltage domain. This patch also adds support to scale
> the dependent vdd and the scalable devices belonging to it
> during the scaling of a main vdd through omap_voltage_scale.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
This patch introduces recursive locking (found by lockdep)
[...]
> /**
> * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
> @@ -1697,6 +1803,8 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
> int is_volt_scaled = 0;
> struct omap_vdd_info *vdd;
> struct omap_vdd_dev_list *temp_dev;
> + struct plist_node *node;
> + struct omap_vdd_user_list *user;
>
> if (!voltdm || IS_ERR(voltdm)) {
> pr_warning("%s: VDD specified does not exist!\n", __func__);
> @@ -1709,6 +1817,17 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
>
> curr_volt = omap_voltage_get_nom_volt(voltdm);
Just above here, there is an existing mutex_lock()
> + /* Find the device requesting the voltage scaling */
> + node = plist_first(&vdd->user_list);
> + user = container_of(node, struct omap_vdd_user_list, node);
>
> + /* calculate the voltages for dependent vdd's */
> + if (calc_dep_vdd_volt(user->dev, vdd, volt)) {
This function can call omap_voltage_add_request() which will also try to
take the same mutex.
> + pr_warning("%s: Error in calculating dependent vdd voltages"
> + "for vdd_%s\n", __func__, voltdm->name);
> + return -EINVAL;
> + }
> +
>
> if (curr_volt == volt) {
> is_volt_scaled = 1;
> } else if (curr_volt < volt) {
> @@ -1746,6 +1865,9 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
>
> mutex_unlock(&vdd->scaling_mutex);
>
> + /* Scale dependent vdds */
> + scale_dep_vdd(vdd);
> +
> return 0;
> }
Here is the details reported by lockdep.
Kevin
[ 2.314270] SmartReflex Class3 initialized
[ 2.318634] omap_device: smartreflex.1: new worst case activate latency 0: 30517
[ 2.363861] clock: disabling unused clocks to save power
[ 2.372070]
[ 2.372070] =============================================
[ 2.379272] [ INFO: possible recursive locking detected ]
[ 2.384918] 2.6.36-pm-default-09076-g6ad1eb9 #2
[ 2.389648] ---------------------------------------------
[ 2.395294] swapper/1 is trying to acquire lock:
[ 2.400115] (&vdd->scaling_mutex){+.+.+.}, at: [<c025b138>] omap_voltage_add_request+0x48/0x1a0
[ 2.409362]
[ 2.409362] but task is already holding lock:
[ 2.415466] (&vdd->scaling_mutex){+.+.+.}, at: [<c025b2d0>] omap_voltage_scale+0x40/0x26c
[ 2.424133]
[ 2.424133] other info that might help us debug this:
[ 2.430938] 3 locks held by swapper/1:
[ 2.434875] #0: (sysdev_drivers_lock){+.+.+.}, at: [<c047d87c>] sysdev_driver_register+0x60/0x114
[ 2.444366] #1: (&per_cpu(cpu_policy_rwsem, cpu)){+.+.+.}, at: [<c0512bb0>] lock_policy_rwsem_write+0x40/0x94
[ 2.454956] #2: (&vdd->scaling_mutex){+.+.+.}, at: [<c025b2d0>] omap_voltage_scale+0x40/0x26c
[ 2.464080]
[ 2.464111] stack backtrace:
[ 2.468688] [<c024d4a0>] (unwind_backtrace+0x0/0xe4) from [<c02b670c>] (__lock_acquire+0xdc8/0x1758)
[ 2.478271] [<c02b670c>] (__lock_acquire+0xdc8/0x1758) from [<c02b7170>] (lock_acquire+0xd4/0xf8)
[ 2.487548] [<c02b7170>] (lock_acquire+0xd4/0xf8) from [<c05e4de8>] (mutex_lock_nested+0x54/0x320)
[ 2.496948] [<c05e4de8>] (mutex_lock_nested+0x54/0x320) from [<c025b138>] (omap_voltage_add_request+0x48/0x1a0)
[ 2.507476] [<c025b138>] (omap_voltage_add_request+0x48/0x1a0) from [<c025b388>] (omap_voltage_scale+0xf8/0x26c)
[ 2.518127] [<c025b388>] (omap_voltage_scale+0xf8/0x26c) from [<c0267918>] (omap_device_scale+0x108/0x12c)
[ 2.528228] [<c0267918>] (omap_device_scale+0x108/0x12c) from [<c026a754>] (omap_target+0x58/0x60)
[ 2.537628] [<c026a754>] (omap_target+0x58/0x60) from [<c0512b5c>] (__cpufreq_driver_target+0x4c/0x60)
[ 2.547363] [<c0512b5c>] (__cpufreq_driver_target+0x4c/0x60) from [<c05151c8>] (cpufreq_governor_performance+0x20/0x28)
[ 2.558654] [<c05151c8>] (cpufreq_governor_performance+0x20/0x28) from [<c0512d28>] (__cpufreq_governor+0xd8/0x12c)
[ 2.569549] [<c0512d28>] (__cpufreq_governor+0xd8/0x12c) from [<c0512eb4>] (__cpufreq_set_policy+0x114/0x15c)
[ 2.579925] [<c0512eb4>] (__cpufreq_set_policy+0x114/0x15c) from [<c0514288>] (cpufreq_add_dev_interface+0x268/0x2b4)
[ 2.591033] [<c0514288>] (cpufreq_add_dev_interface+0x268/0x2b4) from [<c0514790>] (cpufreq_add_dev+0x4bc/0x528)
[ 2.601684] [<c0514790>] (cpufreq_add_dev+0x4bc/0x528) from [<c047d8c8>] (sysdev_driver_register+0xac/0x114)
[ 2.611968] [<c047d8c8>] (sysdev_driver_register+0xac/0x114) from [<c051380c>] (cpufreq_register_driver+0x8c/0x16c)
[ 2.622924] [<c051380c>] (cpufreq_register_driver+0x8c/0x16c) from [<c0246578>] (do_one_initcall+0xcc/0x1a4)
[ 2.633209] [<c0246578>] (do_one_initcall+0xcc/0x1a4) from [<c00088e0>] (kernel_init+0x148/0x210)
[ 2.642486] [<c00088e0>] (kernel_init+0x148/0x210) from [<c0247cb8>] (kernel_thread_exit+0x0/0x8)
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure
2010-10-29 15:38 ` [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure Thara Gopinath
@ 2010-11-11 22:59 ` Kevin Hilman
2010-11-15 11:14 ` Gopinath, Thara
0 siblings, 1 reply; 28+ messages in thread
From: Kevin Hilman @ 2010-11-11 22:59 UTC (permalink / raw)
To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant
Thara Gopinath <thara@ti.com> writes:
> This patch extends the omap_device structure to contain
> pointers to scale the operating rate of the
> device and to retrieve the operating rate of the device.
> This patch also adds the three new APIs in the omap device layer
> namely omap_device_set_rate that can be called to set a new operating
> rate for a device, omap_device_get_rate that can be called to retrieve
> the operating frequency for a device and omap_device_populate_rate_fns
> to populte the device specific set_rate and get_rate API's.
> The omap_device_set_rate and omap_device_get_rate does some routine error
> checks and finally calls into the device specific set_rate
> and get_rate APIs populated through omap_device_populate_rate_fns.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
> arch/arm/plat-omap/include/plat/omap_device.h | 9 +++++
> arch/arm/plat-omap/omap_device.c | 49 +++++++++++++++++++++++++
> 2 files changed, 58 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 28e2d1a..2a37345 100644
> --- a/arch/arm/plat-omap/include/plat/omap_device.h
> +++ b/arch/arm/plat-omap/include/plat/omap_device.h
> @@ -50,6 +50,8 @@ extern struct device omap_device_parent;
> * @hwmods: (one .. many per omap_device)
> * @hwmods_cnt: ARRAY_SIZE() of @hwmods
> * @pm_lats: ptr to an omap_device_pm_latency table
> + * @set_rate: fn ptr to change the operating rate.
> + * @get_rate: fn ptr to retrieve the current operating rate.
> * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
> * @pm_lat_level: array index of the last odpl entry executed - -1 if never
> * @dev_wakeup_lat: dev wakeup latency in nanoseconds
> @@ -67,6 +69,8 @@ struct omap_device {
> struct platform_device pdev;
> struct omap_hwmod **hwmods;
> struct omap_device_pm_latency *pm_lats;
> + int (*set_rate)(struct device *dev, unsigned long rate);
> + unsigned long (*get_rate) (struct device *dev);
minor nit, but I prefer the function pointers at the end.
> u32 dev_wakeup_lat;
> u32 _dev_wakeup_lat_limit;
> u8 pm_lats_cnt;
> @@ -107,6 +111,11 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od);
> int omap_device_align_pm_lat(struct platform_device *pdev,
> u32 new_wakeup_lat_limit);
> struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
> +int omap_device_set_rate(struct device *dev, unsigned long freq);
> +unsigned long omap_device_get_rate(struct device *dev);
> +void omap_device_populate_rate_fns(struct device *dev,
> + int (*set_rate)(struct device *dev, unsigned long rate),
> + unsigned long (*get_rate) (struct device *dev));
how about omap_device_register_callbacks()
> /* Other */
>
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index 7c902a6..ffe06eb 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -785,6 +785,55 @@ int omap_device_enable_clocks(struct omap_device *od)
> return 0;
> }
>
> +int omap_device_set_rate(struct device *dev, unsigned long freq)
> +{
> + struct platform_device *pdev;
> + struct omap_device *od;
> +
> + pdev = container_of(dev, struct platform_device, dev);
pdev = to_platform_device(dev)
This helper is already defined in platform_device.h.
> + od = _find_by_pdev(pdev);
> +
> + if (!od->set_rate) {
> + dev_err(dev, "%s: No set_rate API for scaling device\n",
> + __func__);
> + return -ENODATA;
> + }
> +
> + return od->set_rate(dev, freq);
> +}
> +
> +unsigned long omap_device_get_rate(struct device *dev)
> +{
> + struct platform_device *pdev;
> + struct omap_device *od;
> +
> + pdev = container_of(dev, struct platform_device, dev);
pdev = to_platform_device(dev)
> + od = _find_by_pdev(pdev);
> +
> +
> + if (!od->get_rate) {
> + dev_err(dev, "%s: No get rate API for the device\n",
> + __func__);
> + return 0;
> + }
> +
> + return od->get_rate(dev);
> +}
> +
> +void omap_device_populate_rate_fns(struct device *dev,
> + int (*set_rate)(struct device *dev, unsigned long rate),
> + unsigned long (*get_rate) (struct device *dev))
> +{
> + struct platform_device *pdev;
> + struct omap_device *od;
> +
> + pdev = container_of(dev, struct platform_device, dev);
pdev = to_platform_device(dev)
> + od = _find_by_pdev(pdev);
> +
> + od->set_rate = set_rate;
> + od->get_rate = get_rate;
> +}
> +
> struct device omap_device_parent = {
> .init_name = "omap",
> .parent = &platform_bus,
Kevin
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS.
2010-10-29 15:38 ` [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS Thara Gopinath
@ 2010-11-11 23:34 ` Kevin Hilman
2010-11-15 14:12 ` Gopinath, Thara
0 siblings, 1 reply; 28+ messages in thread
From: Kevin Hilman @ 2010-11-11 23:34 UTC (permalink / raw)
To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant
Thara Gopinath <thara@ti.com> writes:
> This patch 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.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
> arch/arm/mach-omap2/voltage.c | 72 +++++++++++++++++++++++++++++
> arch/arm/plat-omap/include/plat/voltage.h | 7 +++
> 2 files changed, 79 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index 6c2e4ef..458f8c1 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -27,9 +27,11 @@
> #include <linux/spinlock.h>
> #include <linux/plist.h>
> #include <linux/slab.h>
> +#include <linux/opp.h>
>
> #include <plat/common.h>
> #include <plat/voltage.h>
> +#include <plat/omap_device.h>
>
> #include "prm-regbits-34xx.h"
> #include "prm44xx.h"
> @@ -1678,6 +1680,76 @@ struct voltagedomain *omap_voltage_domain_lookup(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 voltagedomain *voltdm, unsigned long volt)
> +{
> + unsigned long curr_volt;
> + int is_volt_scaled = 0;
> + struct omap_vdd_info *vdd;
> + struct omap_vdd_dev_list *temp_dev;
> +
> + if (!voltdm || IS_ERR(voltdm)) {
> + pr_warning("%s: VDD specified does not exist!\n", __func__);
> + return -EINVAL;
> + }
> +
> + vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
> +
> + mutex_lock(&vdd->scaling_mutex);
> +
> + curr_volt = omap_voltage_get_nom_volt(voltdm);
> +
> + if (curr_volt == volt) {
> + is_volt_scaled = 1;
> + } else if (curr_volt < volt) {
> + omap_voltage_scale_vdd(voltdm, volt);
> + is_volt_scaled = 1;
> + }
> +
> + list_for_each_entry(temp_dev, &vdd->dev_list, node) {
> + struct device *dev;
> + struct opp *opp;
> + unsigned long freq;
> +
> + dev = temp_dev->dev;
> +
> + opp = opp_find_voltage(dev, volt);
> + if (IS_ERR(opp)) {
> + dev_err(dev, "%s: Unable to find OPP for"
> + "volt%ld\n", __func__, volt);
> + continue;
> + }
> +
> + freq = opp_get_freq(opp);
> +
> + if (freq == omap_device_get_rate(dev)) {
> + dev_warn(dev, "%s: Already at the requested"
> + "rate %ld\n", __func__, freq);
Does this need to be a warning? This happens relatively often and is normal.
This should probably just be removed in favor of
if (freq != omap_device_get_rate(dev))
omap_device_set_rate(dev, freq);
Kevin
> + continue;
> + }
> +
> + omap_device_set_rate(dev, freq);
> + }
> +
> + if (!is_volt_scaled)
> + omap_voltage_scale_vdd(voltdm, volt);
> +
> + mutex_unlock(&vdd->scaling_mutex);
> +
> + 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 dc64a9a..54d50e2 100644
> --- a/arch/arm/plat-omap/include/plat/voltage.h
> +++ b/arch/arm/plat-omap/include/plat/voltage.h
> @@ -153,6 +153,7 @@ void omap_change_voltscale_method(int voltscale_method);
> int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
> unsigned long *volt);
> int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev);
> +int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt);
> #else
> static inline void omap_voltage_register_pmic
> (struct omap_volt_pmic_info *pmic_info) {}
> @@ -169,6 +170,12 @@ static inline int omap_voltage_add_dev(struct voltagedomain *voltdm,
> {
> return -EINVAL;
> }
> +
> +static inline int omap_voltage_scale(struct voltagedomain *voltdm,
> + unsigned long volt)
> +{
> + return -EINVAL;
> +}
> #endif
>
> #endif
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
2010-10-29 15:38 ` [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
@ 2010-11-11 23:53 ` Kevin Hilman
2010-11-12 0:07 ` Kevin Hilman
1 sibling, 0 replies; 28+ messages in thread
From: Kevin Hilman @ 2010-11-11 23:53 UTC (permalink / raw)
To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant
Thara Gopinath <thara@ti.com> writes:
> 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>
[...]
> +/**
> + * omap_voltage_add_request() - 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_voltage_add_request(struct voltagedomain *voltdm, 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 (!voltdm || IS_ERR(voltdm)) {
> + pr_warning("%s: VDD specified does not exist!\n", __func__);
> + return -EINVAL;
> + }
> +
> + vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
> +
> + mutex_lock(&vdd->scaling_mutex);
> +
> + plist_for_each_entry(user, &vdd->user_list, node) {
> + if (user->dev == dev) {
> + found = 1;
please drop the use of 'found' here. This can be solved using
a tmp iterator instead:
struct omap_vdd_user_list *tmp_user, *user = NULL;
plist_for_each_entry(tmp_user, &vdd->user_list, node)
if (tmp_user->dev == dev) {
user = tmp_user;
break;
}
> + break;
> + }
> + }
> +
> + if (!found) {
if (!user) {
> + 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__, voltdm->name);
> + mutex_unlock(&vdd->scaling_mutex);
> + return -ENOMEM;
> + }
> + user->dev = dev;
> + } else {
> + plist_del(&user->node, &vdd->user_list);
> + }
> +
> + plist_node_init(&user->node, *volt);
> + plist_add(&user->node, &vdd->user_list);
> + node = plist_last(&vdd->user_list);
The use of plist_last() doesn't seem right here. Won't plist_last()
return the node with the lowest voltage?, but this function is meant to
return the highest requested voltage.
I guess it currently works because it's only been tested with a single
requested voltage, so first and last are the same thing, but if I
understand the intent of the code correctly, I think it is broken if
ever there is more than one requester.
In [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support,
plist_first() is used to get the currently requesting node, so that is
what caused the confusion. One side is using plist_first(), the other
plist_last() so one of them must be wrong.
> + *volt = user->volt = node->prio;
> +
> + mutex_unlock(&vdd->scaling_mutex);
> +
> + return 0;
> +}
The above problems make me think that the 'request' and the 'get' part
of the above function should actually be separated out into two separate
functions. One to add the request voltage, and another to query the
current max request.
The query function could then be used in patch 07/14 instead of using
plist directly. That would clear up some of the confusion.
Kevin
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
2010-10-29 15:38 ` [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
2010-11-11 23:53 ` Kevin Hilman
@ 2010-11-12 0:07 ` Kevin Hilman
1 sibling, 0 replies; 28+ messages in thread
From: Kevin Hilman @ 2010-11-12 0:07 UTC (permalink / raw)
To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant
Thara Gopinath <thara@ti.com> writes:
[...]
> +/**
> * omap_vdd_info - Per Voltage Domain info
> *
> * @volt_data : voltage table having the distinct voltages supported
> @@ -95,9 +112,13 @@ struct vp_reg_val {
> * vp registers
> * @voltdm : pointer to the voltage domain structure
> * @debug_dir : debug directory for this voltage domain.
> + * @user_lock : the lock to be used by the plist user_list
> + * @user_list : the list head maintaining the various users.
> + * @scaling_mutex : the dvfs muutex.
^^^^^^
hmmmm... muutex, that must be a Finnish mutex. ;)
Kevin
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain
2010-11-11 0:49 ` Kevin Hilman
@ 2010-11-15 11:09 ` Gopinath, Thara
0 siblings, 0 replies; 28+ messages in thread
From: Gopinath, Thara @ 2010-11-15 11:09 UTC (permalink / raw)
To: Kevin Hilman
Cc: linux-omap@vger.kernel.org, paul@pwsan.com, Cousson, Benoit,
Sripathy, Vishwanath, Sawant, Anand
>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Thursday, November 11, 2010 6:19 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy,
>>Vishwanath; Sawant, Anand
>>Subject: Re: [PATCH v2 04/14] OMAP: Introduce API to register a device with a
>>voltagedomain
>>
>>Thara Gopinath <thara@ti.com> writes:
>>
>>> This patch adds an API in the voltage layer that
>>> can be used during omap_device_build to register the built
>>> device with the voltage domain. This API is to be typically called
>>> only once per device during the device registeration. 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>
>>
>>[...]
>>
>>> /* Generic voltage init functions */
>>> @@ -1240,6 +1251,40 @@ int omap_voltage_add_request(struct voltagedomain
>>*voltdm, struct device *dev,
>>> return 0;
>>> }
>>>
>>> +int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev)
>>
>>minor nit: I prefer this be a 'register' function,
>>e.g. omap_voltage_register (or _register_dev)
_register_dev. Will rename.
>>
>>[...]
>>
>>> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-
>>omap/omap_device.c
>>> index abe933c..7c902a6 100644
>>> --- a/arch/arm/plat-omap/omap_device.c
>>> +++ b/arch/arm/plat-omap/omap_device.c
>>> @@ -86,6 +86,7 @@
>>>
>>> #include <plat/omap_device.h>
>>> #include <plat/omap_hwmod.h>
>>> +#include <plat/voltage.h>
>>>
>>> /* These parameters are passed to _omap_device_{de,}activate() */
>>> #define USE_WAKEUP_LAT 0
>>> @@ -453,6 +454,17 @@ struct omap_device *omap_device_build_ss(const char
>>*pdev_name, int pdev_id,
>>> for (i = 0; i < oh_cnt; i++) {
>>> hwmods[i]->od = od;
>>> _add_optional_clock_alias(od, hwmods[i]);
>>> + if (hwmods[i]->vdd_name) {
>>
>>Use:
>>
>> if (!is_early_device && hwmods[i]->vdd_name)
>>
>>> + struct omap_hwmod *oh = hwmods[i];
>>> + struct voltagedomain *voltdm;
>>> +
>>> + if (is_early_device)
>>> + continue;
>>
>>and drop this check
Ok
>>
>>
>>> + voltdm = omap_voltage_domain_lookup(oh->vdd_name);
>>> + if (!omap_voltage_add_dev(voltdm, &od->pdev.dev))
>>> + oh->voltdm = voltdm;
>>> + }
>>> }
>>>
>>> if (ret)
>>
>>Kevin
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure
2010-11-11 22:59 ` Kevin Hilman
@ 2010-11-15 11:14 ` Gopinath, Thara
0 siblings, 0 replies; 28+ messages in thread
From: Gopinath, Thara @ 2010-11-15 11:14 UTC (permalink / raw)
To: Kevin Hilman
Cc: linux-omap@vger.kernel.org, paul@pwsan.com, Cousson, Benoit,
Sripathy, Vishwanath, Sawant, Anand
>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Friday, November 12, 2010 4:29 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy,
>>Vishwanath; Sawant, Anand
>>Subject: Re: [PATCH v2 05/14] OMAP: Introduce device specific set rate and
>>get rate in omap_device structure
>>
>>Thara Gopinath <thara@ti.com> writes:
>>
>>> This patch extends the omap_device structure to contain
>>> pointers to scale the operating rate of the
>>> device and to retrieve the operating rate of the device.
>>> This patch also adds the three new APIs in the omap device layer
>>> namely omap_device_set_rate that can be called to set a new operating
>>> rate for a device, omap_device_get_rate that can be called to retrieve
>>> the operating frequency for a device and omap_device_populate_rate_fns
>>> to populte the device specific set_rate and get_rate API's.
>>> The omap_device_set_rate and omap_device_get_rate does some routine error
>>> checks and finally calls into the device specific set_rate
>>> and get_rate APIs populated through omap_device_populate_rate_fns.
>>>
>>> Signed-off-by: Thara Gopinath <thara@ti.com>
>>> ---
>>> arch/arm/plat-omap/include/plat/omap_device.h | 9 +++++
>>> arch/arm/plat-omap/omap_device.c | 49
>>+++++++++++++++++++++++++
>>> 2 files changed, 58 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 28e2d1a..2a37345 100644
>>> --- a/arch/arm/plat-omap/include/plat/omap_device.h
>>> +++ b/arch/arm/plat-omap/include/plat/omap_device.h
>>> @@ -50,6 +50,8 @@ extern struct device omap_device_parent;
>>> * @hwmods: (one .. many per omap_device)
>>> * @hwmods_cnt: ARRAY_SIZE() of @hwmods
>>> * @pm_lats: ptr to an omap_device_pm_latency table
>>> + * @set_rate: fn ptr to change the operating rate.
>>> + * @get_rate: fn ptr to retrieve the current operating rate.
>>> * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
>>> * @pm_lat_level: array index of the last odpl entry executed - -1 if
>>never
>>> * @dev_wakeup_lat: dev wakeup latency in nanoseconds
>>> @@ -67,6 +69,8 @@ struct omap_device {
>>> struct platform_device pdev;
>>> struct omap_hwmod **hwmods;
>>> struct omap_device_pm_latency *pm_lats;
>>> + int (*set_rate)(struct device *dev, unsigned long rate);
>>> + unsigned long (*get_rate) (struct device *dev);
>>
>>minor nit, but I prefer the function pointers at the end.
Ok
>>
>>> u32 dev_wakeup_lat;
>>> u32 _dev_wakeup_lat_limit;
>>> u8 pm_lats_cnt;
>>> @@ -107,6 +111,11 @@ void __iomem *omap_device_get_rt_va(struct omap_device
>>*od);
>>> int omap_device_align_pm_lat(struct platform_device *pdev,
>>> u32 new_wakeup_lat_limit);
>>> struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
>>> +int omap_device_set_rate(struct device *dev, unsigned long freq);
>>> +unsigned long omap_device_get_rate(struct device *dev);
>>> +void omap_device_populate_rate_fns(struct device *dev,
>>> + int (*set_rate)(struct device *dev, unsigned long rate),
>>> + unsigned long (*get_rate) (struct device *dev));
>>
>>how about omap_device_register_callbacks()
I am ok. But then the name will not specify what kind of
callbacks.
>>
>>> /* Other */
>>>
>>> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-
>>omap/omap_device.c
>>> index 7c902a6..ffe06eb 100644
>>> --- a/arch/arm/plat-omap/omap_device.c
>>> +++ b/arch/arm/plat-omap/omap_device.c
>>> @@ -785,6 +785,55 @@ int omap_device_enable_clocks(struct omap_device *od)
>>> return 0;
>>> }
>>>
>>> +int omap_device_set_rate(struct device *dev, unsigned long freq)
>>> +{
>>> + struct platform_device *pdev;
>>> + struct omap_device *od;
>>> +
>>> + pdev = container_of(dev, struct platform_device, dev);
>>
>> pdev = to_platform_device(dev)
>>
>>This helper is already defined in platform_device.h.
Ok
>>
>>> + od = _find_by_pdev(pdev);
>>> +
>>> + if (!od->set_rate) {
>>> + dev_err(dev, "%s: No set_rate API for scaling device\n",
>>> + __func__);
>>> + return -ENODATA;
>>> + }
>>> +
>>> + return od->set_rate(dev, freq);
>>> +}
>>> +
>>> +unsigned long omap_device_get_rate(struct device *dev)
>>> +{
>>> + struct platform_device *pdev;
>>> + struct omap_device *od;
>>> +
>>> + pdev = container_of(dev, struct platform_device, dev);
>>
>> pdev = to_platform_device(dev)
>>
>>> + od = _find_by_pdev(pdev);
>>> +
>>> +
>>> + if (!od->get_rate) {
>>> + dev_err(dev, "%s: No get rate API for the device\n",
>>> + __func__);
>>> + return 0;
>>> + }
>>> +
>>> + return od->get_rate(dev);
>>> +}
>>> +
>>> +void omap_device_populate_rate_fns(struct device *dev,
>>> + int (*set_rate)(struct device *dev, unsigned long rate),
>>> + unsigned long (*get_rate) (struct device *dev))
>>> +{
>>> + struct platform_device *pdev;
>>> + struct omap_device *od;
>>> +
>>> + pdev = container_of(dev, struct platform_device, dev);
>>
>> pdev = to_platform_device(dev)
Ok
>>
>>> + od = _find_by_pdev(pdev);
>>> +
>>> + od->set_rate = set_rate;
>>> + od->get_rate = get_rate;
>>> +}
>>> +
>>> struct device omap_device_parent = {
>>> .init_name = "omap",
>>> .parent = &platform_bus,
>>
>>Kevin
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS.
2010-11-11 23:34 ` Kevin Hilman
@ 2010-11-15 14:12 ` Gopinath, Thara
0 siblings, 0 replies; 28+ messages in thread
From: Gopinath, Thara @ 2010-11-15 14:12 UTC (permalink / raw)
To: Kevin Hilman
Cc: linux-omap@vger.kernel.org, paul@pwsan.com, Cousson, Benoit,
Sripathy, Vishwanath, Sawant, Anand
>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Friday, November 12, 2010 5:04 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy,
>>Vishwanath; Sawant, Anand
>>Subject: Re: [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS.
>>
>>Thara Gopinath <thara@ti.com> writes:
>>
>>> This patch 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.
>>>
>>> Signed-off-by: Thara Gopinath <thara@ti.com>
>>> ---
>>> arch/arm/mach-omap2/voltage.c | 72
>>+++++++++++++++++++++++++++++
>>> arch/arm/plat-omap/include/plat/voltage.h | 7 +++
>>> 2 files changed, 79 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
>>> index 6c2e4ef..458f8c1 100644
>>> --- a/arch/arm/mach-omap2/voltage.c
>>> +++ b/arch/arm/mach-omap2/voltage.c
>>> @@ -27,9 +27,11 @@
>>> #include <linux/spinlock.h>
>>> #include <linux/plist.h>
>>> #include <linux/slab.h>
>>> +#include <linux/opp.h>
>>>
>>> #include <plat/common.h>
>>> #include <plat/voltage.h>
>>> +#include <plat/omap_device.h>
>>>
>>> #include "prm-regbits-34xx.h"
>>> #include "prm44xx.h"
>>> @@ -1678,6 +1680,76 @@ struct voltagedomain
>>*omap_voltage_domain_lookup(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 voltagedomain *voltdm, unsigned long volt)
>>> +{
>>> + unsigned long curr_volt;
>>> + int is_volt_scaled = 0;
>>> + struct omap_vdd_info *vdd;
>>> + struct omap_vdd_dev_list *temp_dev;
>>> +
>>> + if (!voltdm || IS_ERR(voltdm)) {
>>> + pr_warning("%s: VDD specified does not exist!\n", __func__);
>>> + return -EINVAL;
>>> + }
>>> +
>>> + vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
>>> +
>>> + mutex_lock(&vdd->scaling_mutex);
>>> +
>>> + curr_volt = omap_voltage_get_nom_volt(voltdm);
>>> +
>>> + if (curr_volt == volt) {
>>> + is_volt_scaled = 1;
>>> + } else if (curr_volt < volt) {
>>> + omap_voltage_scale_vdd(voltdm, volt);
>>> + is_volt_scaled = 1;
>>> + }
>>> +
>>> + list_for_each_entry(temp_dev, &vdd->dev_list, node) {
>>> + struct device *dev;
>>> + struct opp *opp;
>>> + unsigned long freq;
>>> +
>>> + dev = temp_dev->dev;
>>> +
>>> + opp = opp_find_voltage(dev, volt);
>>> + if (IS_ERR(opp)) {
>>> + dev_err(dev, "%s: Unable to find OPP for"
>>> + "volt%ld\n", __func__, volt);
>>> + continue;
>>> + }
>>> +
>>> + freq = opp_get_freq(opp);
>>> +
>>> + if (freq == omap_device_get_rate(dev)) {
>>> + dev_warn(dev, "%s: Already at the requested"
>>> + "rate %ld\n", __func__, freq);
>>
>>Does this need to be a warning? This happens relatively often and is normal.
>>This should probably just be removed in favor of
>>
>> if (freq != omap_device_get_rate(dev))
>> omap_device_set_rate(dev, freq);
Yes. There are other warnings also in the dvfs code
which could be removed. Will remove them all in the next
version
Regards
Thara
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.
2010-10-29 15:38 ` [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1 Thara Gopinath
@ 2010-12-01 15:31 ` Vishwanath Sripathy
2010-12-01 15:32 ` Gopinath, Thara
2010-12-01 15:32 ` Vishwanath Sripathy
1 sibling, 1 reply; 28+ messages in thread
From: Vishwanath Sripathy @ 2010-12-01 15:31 UTC (permalink / raw)
To: linux-omap; +Cc: paul, khilman
Thara,
> -----Original Message-----
> From: Gopinath, Thara
> Sent: Friday, October 29, 2010 9:08 PM
> To: linux-omap@vger.kernel.org
> Cc: paul@pwsan.com; khilman@deeprootsystems.com; Cousson, Benoit;
> Sripathy, Vishwanath; Sawant, Anand; Gopinath, Thara
> Subject: [PATCH v2 13/14] OMAP3: Add voltage dependency table for
> VDD1.
>
> In OMAP3, for perfomrance reasons when VDD1 is at voltage above
> 1.075V, VDD2 should be at 1.15V for perfomrance reasons. This
> patch introduce this cross VDD dependency for OMAP3 VDD1.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
> arch/arm/mach-omap2/voltage.c | 19 +++++++++++++++++++
> 1 files changed, 19 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-
> omap2/voltage.c
> index 6f85f75..241fac5 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -350,6 +350,23 @@ static struct omap_volt_data
> omap44xx_vdd_core_volt_data[] = {
> {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain =
> 0x16},
> };
>
> +/* OMAP 3430 MPU Core VDD dependency table */
> +static struct omap_vdd_dep_volt omap34xx_vdd1_vdd2_data[] = {
> + {.main_vdd_volt = 975000, .dep_vdd_volt = 1050000},
> + {.main_vdd_volt = 1075000, .dep_vdd_volt = 1050000},
> + {.main_vdd_volt = 1200000, .dep_vdd_volt = 1150000},
> + {.main_vdd_volt = 1270000, .dep_vdd_volt = 1150000},
> + {.main_vdd_volt = 1350000, .dep_vdd_volt = 1150000},
> + {.main_vdd_volt = 0, .dep_vdd_volt = 0},
> +};
> +
> +static struct omap_vdd_dep_info omap34xx_vdd1_dep_info[] = {
> + {
> + .name = "core",
> + .dep_table = omap34xx_vdd1_vdd2_data,
> + },
> +};
Dependency table for 3630 is missing. Pls add the same.
Also voltage values for 3630 does not match those on OPP table. Pls align
them.
Vishwa
> +
> /* By default VPFORCEUPDATE is the chosen method of voltage scaling
> */
> static bool voltscale_vpforceupdate = true;
>
> @@ -574,6 +591,8 @@ static void __init
> omap3_vdd_data_configure(struct omap_vdd_info *vdd)
> vdd->volt_data = omap34xx_vdd1_volt_data;
> vdd->volt_data_count =
>
> ARRAY_SIZE(omap34xx_vdd1_volt_data);
> + vdd->dep_vdd_info = omap34xx_vdd1_dep_info;
> + vdd->nr_dep_vdd =
> ARRAY_SIZE(omap34xx_vdd1_dep_info);
> }
>
> vdd->vp_reg.tranxdone_status =
> OMAP3430_VP1_TRANXDONE_ST_MASK;
> --
> 1.7.0.4
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.
2010-10-29 15:38 ` [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1 Thara Gopinath
2010-12-01 15:31 ` Vishwanath Sripathy
@ 2010-12-01 15:32 ` Vishwanath Sripathy
1 sibling, 0 replies; 28+ messages in thread
From: Vishwanath Sripathy @ 2010-12-01 15:32 UTC (permalink / raw)
To: linux-omap; +Cc: paul, khilman
Thara,
> -----Original Message-----
> From: Gopinath, Thara
> Sent: Friday, October 29, 2010 9:08 PM
> To: linux-omap@vger.kernel.org
> Cc: paul@pwsan.com; khilman@deeprootsystems.com; Cousson, Benoit;
> Sripathy, Vishwanath; Sawant, Anand; Gopinath, Thara
> Subject: [PATCH v2 13/14] OMAP3: Add voltage dependency table for
> VDD1.
>
> In OMAP3, for perfomrance reasons when VDD1 is at voltage above
> 1.075V, VDD2 should be at 1.15V for perfomrance reasons. This
> patch introduce this cross VDD dependency for OMAP3 VDD1.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
> arch/arm/mach-omap2/voltage.c | 19 +++++++++++++++++++
> 1 files changed, 19 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-
> omap2/voltage.c
> index 6f85f75..241fac5 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -350,6 +350,23 @@ static struct omap_volt_data
> omap44xx_vdd_core_volt_data[] = {
> {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain =
> 0x16},
> };
>
> +/* OMAP 3430 MPU Core VDD dependency table */
> +static struct omap_vdd_dep_volt omap34xx_vdd1_vdd2_data[] = {
> + {.main_vdd_volt = 975000, .dep_vdd_volt = 1050000},
> + {.main_vdd_volt = 1075000, .dep_vdd_volt = 1050000},
> + {.main_vdd_volt = 1200000, .dep_vdd_volt = 1150000},
> + {.main_vdd_volt = 1270000, .dep_vdd_volt = 1150000},
> + {.main_vdd_volt = 1350000, .dep_vdd_volt = 1150000},
> + {.main_vdd_volt = 0, .dep_vdd_volt = 0},
> +};
> +
> +static struct omap_vdd_dep_info omap34xx_vdd1_dep_info[] = {
> + {
> + .name = "core",
> + .dep_table = omap34xx_vdd1_vdd2_data,
> + },
> +};
Dependency table for 3630 is missing. Pls add the same.
Also voltage values for 3630 does not match those on OPP table. Pls align
them.
Vishwa
> +
> /* By default VPFORCEUPDATE is the chosen method of voltage scaling
> */
> static bool voltscale_vpforceupdate = true;
>
> @@ -574,6 +591,8 @@ static void __init
> omap3_vdd_data_configure(struct omap_vdd_info *vdd)
> vdd->volt_data = omap34xx_vdd1_volt_data;
> vdd->volt_data_count =
>
> ARRAY_SIZE(omap34xx_vdd1_volt_data);
> + vdd->dep_vdd_info = omap34xx_vdd1_dep_info;
> + vdd->nr_dep_vdd =
> ARRAY_SIZE(omap34xx_vdd1_dep_info);
> }
>
> vdd->vp_reg.tranxdone_status =
> OMAP3430_VP1_TRANXDONE_ST_MASK;
> --
> 1.7.0.4
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.
2010-12-01 15:31 ` Vishwanath Sripathy
@ 2010-12-01 15:32 ` Gopinath, Thara
0 siblings, 0 replies; 28+ messages in thread
From: Gopinath, Thara @ 2010-12-01 15:32 UTC (permalink / raw)
To: Sripathy, Vishwanath, linux-omap@vger.kernel.org
Cc: paul@pwsan.com, khilman@deeprootsystems.com
>>-----Original Message-----
>>From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
>>owner@vger.kernel.org] On Behalf Of Sripathy, Vishwanath
>>Sent: Wednesday, December 01, 2010 9:01 PM
>>To: linux-omap@vger.kernel.org
>>Cc: paul@pwsan.com; khilman@deeprootsystems.com
>>Subject: RE: [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.
>>
>>Thara,
>>
>>> -----Original Message-----
>>> From: Gopinath, Thara
>>> Sent: Friday, October 29, 2010 9:08 PM
>>> To: linux-omap@vger.kernel.org
>>> Cc: paul@pwsan.com; khilman@deeprootsystems.com; Cousson, Benoit;
>>> Sripathy, Vishwanath; Sawant, Anand; Gopinath, Thara
>>> Subject: [PATCH v2 13/14] OMAP3: Add voltage dependency table for
>>> VDD1.
>>>
>>> In OMAP3, for perfomrance reasons when VDD1 is at voltage above
>>> 1.075V, VDD2 should be at 1.15V for perfomrance reasons. This
>>> patch introduce this cross VDD dependency for OMAP3 VDD1.
>>>
>>> Signed-off-by: Thara Gopinath <thara@ti.com>
>>> ---
>>> arch/arm/mach-omap2/voltage.c | 19 +++++++++++++++++++
>>> 1 files changed, 19 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-
>>> omap2/voltage.c
>>> index 6f85f75..241fac5 100644
>>> --- a/arch/arm/mach-omap2/voltage.c
>>> +++ b/arch/arm/mach-omap2/voltage.c
>>> @@ -350,6 +350,23 @@ static struct omap_volt_data
>>> omap44xx_vdd_core_volt_data[] = {
>>> {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain =
>>> 0x16},
>>> };
>>>
>>> +/* OMAP 3430 MPU Core VDD dependency table */
>>> +static struct omap_vdd_dep_volt omap34xx_vdd1_vdd2_data[] = {
>>> + {.main_vdd_volt = 975000, .dep_vdd_volt = 1050000},
>>> + {.main_vdd_volt = 1075000, .dep_vdd_volt = 1050000},
>>> + {.main_vdd_volt = 1200000, .dep_vdd_volt = 1150000},
>>> + {.main_vdd_volt = 1270000, .dep_vdd_volt = 1150000},
>>> + {.main_vdd_volt = 1350000, .dep_vdd_volt = 1150000},
>>> + {.main_vdd_volt = 0, .dep_vdd_volt = 0},
>>> +};
>>> +
>>> +static struct omap_vdd_dep_info omap34xx_vdd1_dep_info[] = {
>>> + {
>>> + .name = "core",
>>> + .dep_table = omap34xx_vdd1_vdd2_data,
>>> + },
>>> +};
>>
>>Dependency table for 3630 is missing. Pls add the same.
>>Also voltage values for 3630 does not match those on OPP table. Pls align
>>them.
I think you have already given these comments on the list. Any ways I am incorporating them.
Regards
Thara
>>
>>Vishwa
>>> +
>>> /* By default VPFORCEUPDATE is the chosen method of voltage scaling
>>> */
>>> static bool voltscale_vpforceupdate = true;
>>>
>>> @@ -574,6 +591,8 @@ static void __init
>>> omap3_vdd_data_configure(struct omap_vdd_info *vdd)
>>> vdd->volt_data = omap34xx_vdd1_volt_data;
>>> vdd->volt_data_count =
>>>
>>> ARRAY_SIZE(omap34xx_vdd1_volt_data);
>>> + vdd->dep_vdd_info = omap34xx_vdd1_dep_info;
>>> + vdd->nr_dep_vdd =
>>> ARRAY_SIZE(omap34xx_vdd1_dep_info);
>>> }
>>>
>>> vdd->vp_reg.tranxdone_status =
>>> OMAP3430_VP1_TRANXDONE_ST_MASK;
>>> --
>>> 1.7.0.4
>>--
>>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] 28+ messages in thread
end of thread, other threads:[~2010-12-01 15:33 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
2010-11-11 23:53 ` Kevin Hilman
2010-11-12 0:07 ` Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 02/14] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 03/14] OMAP: Introduce voltage domain information in the hwmod structures Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain Thara Gopinath
2010-11-11 0:49 ` Kevin Hilman
2010-11-15 11:09 ` Gopinath, Thara
2010-10-29 15:38 ` [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure Thara Gopinath
2010-11-11 22:59 ` Kevin Hilman
2010-11-15 11:14 ` Gopinath, Thara
2010-10-29 15:38 ` [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS Thara Gopinath
2010-11-11 23:34 ` Kevin Hilman
2010-11-15 14:12 ` Gopinath, Thara
2010-10-29 15:38 ` [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support Thara Gopinath
2010-11-11 17:06 ` Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 08/14] OMAP: Introduce device scale Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 09/14] OMAP: Disable smartreflex across DVFS Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 10/14] OMAP3: Introduce custom set rate and get rate APIs for scalable devices Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 11/14] OMAP3: Update cpufreq driver to use the new set_rate API Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 12/14] OMAP3: Introduce voltage domain info in the hwmod structures Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1 Thara Gopinath
2010-12-01 15:31 ` Vishwanath Sripathy
2010-12-01 15:32 ` Gopinath, Thara
2010-12-01 15:32 ` Vishwanath Sripathy
2010-10-29 15:38 ` [PATCH v2 14/14] OMAP2PLUS: Enable various options in defconfig Thara Gopinath
2010-11-08 19:24 ` Tony Lindgren
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).