OMAP: Basic DVFS framework
Subsystems (9)
v2 cover OMAP: Basic DVFS framework
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 <[email protected]>,
Kevin Hilman <[email protected]>, Paul Wamsley <[email protected]>,
Vishwanath Sripathy <[email protected]> Parthasarathy Basak <[email protected]>
Anand Sawant <[email protected]>
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(-)
PATCH v2 1/14 OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
This patch introduces a user list of devices associated with each voltage domain instance. The user list is implemented using plist structure with priority node populated with the voltage values. This patch also adds an API which will take in a device and requested voltage as parameters, adds the info to the user list and returns back the maximum voltage requested by all the user devices. This can be used anytime to get the voltage that the voltage domain instance can be transitioned into.
--- arch/arm/mach-omap2/voltage.c | 101 ++++++++++++++++++++++++++++- arch/arm/plat-omap/include/plat/voltage.h | 7 ++ 2 files changed, 107 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/voltage.c +100 -1
@@ -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
arch/arm/plat-omap/include/plat/voltage.h +7 -0
@@ -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
Signature · 1 line
1.7.0.4
Re: [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
Quoted 10 lines · 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 <[email protected]>
[...]
Quoted 27 lines
arch/arm/mach-omap2/voltage.c +27
-0+/** +* 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__);
arch/arm/mach-omap2/voltage.c unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) · line 1215
Quoted 10 lines
arch/arm/mach-omap2/voltage.c +10
-0+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;
}arch/arm/mach-omap2/voltage.c unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) · line 1220
Quoted 5 lines
arch/arm/mach-omap2/voltage.c +5
-0+break ; + } + } + +if (!found) {
if (!user) {Quoted 5 lines
arch/arm/mach-omap2/voltage.c +5
-0+ 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);
arch/arm/mach-omap2/voltage.c unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) · line 1235
Quoted 10 lines
arch/arm/mach-omap2/voltage.c +10
-0+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 otherplist_last() so one of them must be wrong.
arch/arm/mach-omap2/voltage.c unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm) · line 1241
Quoted 6 lines
arch/arm/mach-omap2/voltage.c +6
-0+ *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
Re: [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
In reply to Thara GopinathThara Gopinath <[email protected]> writes:
[...]
arch/arm/mach-omap2/voltage.c struct vp_reg_val { · line 117
Quoted 11 lines
arch/arm/mach-omap2/voltage.c +4
-0+/** * 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
PATCH v2 2/14 OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage.
In reply to Thara GopinathThis patch adds an API in the opp layer to get the opp table entry corresponding to the voltage passed as the parameter.
--- drivers/base/power/opp.c | 28 ++++++++++++++++++++++++++++ include/linux/opp.h | 8 ++++++++ 2 files changed, 36 insertions(+), 0 deletions(-)
drivers/base/power/opp.c +28 -0
@@ -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
include/linux/opp.h +8 -0
@@ -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) {
Signature · 1 line
1.7.0.4
PATCH v2 3/14 OMAP: Introduce voltage domain information in the hwmod structures
In reply to Thara GopinathThis 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.
--- arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
arch/arm/plat-omap/include/plat/omap_hwmod.h +5 -0
@@ -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;
Signature · 1 line
1.7.0.4
PATCH v2 4/14 OMAP: Introduce API to register a device with a voltagedomain
In reply to Thara GopinathThis 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.
--- 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(-)
arch/arm/mach-omap2/voltage.c +45 -0
@@ -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.
arch/arm/plat-omap/include/plat/voltage.h +7 -0
@@ -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
arch/arm/plat-omap/omap_device.c +12 -0
@@ -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)
Signature · 1 line
1.7.0.4
Re: [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain
Quoted 8 lines · Thara Gopinath
This patch adds an API in the voltage layer that
can be used duringomap_device_buildto 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 <[email protected]>
[...]
arch/arm/mach-omap2/voltage.c int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev, · line 1254
Quoted 6 lines
/* Generic voltage init functions */
arch/arm/mach-omap2/voltage.c +1
-0@@ -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)
[...]
Quoted 13 lines
arch/arm/plat-omap/omap_device.c +1
-0@@ -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
arch/arm/plat-omap/omap_device.c struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, · line 457
Quoted 4 lines
arch/arm/plat-omap/omap_device.c +1
-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)
arch/arm/plat-omap/omap_device.c struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, · line 462
Quoted 5 lines
arch/arm/plat-omap/omap_device.c +5
-0+struct omap_hwmod *oh = hwmods[i]; +struct voltagedomain *voltdm; + +if (is_early_device) +continue ;
and drop this check
arch/arm/plat-omap/omap_device.c struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, · line 470
Quoted 7 lines
arch/arm/plat-omap/omap_device.c +4
-0+ voltdm =omap_voltage_domain_lookup (oh->vdd_name); +if (!omap_voltage_add_dev (voltdm, &od->pdev.dev)) + oh->voltdm = voltdm; + } }if (ret)
Kevin
RE: [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain
Quoted 27 lines
Quoted 27 lines
-----Original Message-----
From: Kevin Hilman [mailto:[email protected]]
Sent: Thursday, November 11, 2010 6:19 AM
To: Gopinath, Thara
Cc: [email protected]; [email protected]; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand
Subject: Re: [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomainQuoted 8 lines · Thara Gopinath
This patch adds an API in the voltage layer that
can be used duringomap_device_buildto 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 <[email protected]>[...]
Review int omap_voltage_add_request(struct voltagedomain
Quoted 2 lines
/* Generic voltage init functions */
(quoted diff) +0
-0@@ -1240,6 +1251,40 @@ int omap_voltage_add_request(struct voltagedomain*voltdm, struct device *dev,
Quoted 7 lines
Quoted 7 lines
arch/arm/mach-omap2/voltage.c int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev, · line 1254
Quoted 4 lines
arch/arm/mach-omap2/voltage.c +1
-0return 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.
Quoted 27 lines
Quoted 27 lines
[...]
arch/arm/plat-
Quoted 1 line
arch/arm/plat- renamed from arch/arm/plat-omap/omap_device.c +0
-0
omap/omap_device.carch/arm/plat-omap/omap_device.c struct omap_device *omap_device_build_ss(const char
Quoted 12 lines
index abe933c..7c902a6 100644
arch/arm/plat-omap/omap_device.c +1
-0@@ -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, intpdev_id,arch/arm/plat-omap/omap_device.c struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, · line 457
Quoted 4 lines
arch/arm/plat-omap/omap_device.c +1
-0for (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)
Quoted 7 lines
Quoted 7 lines
arch/arm/plat-omap/omap_device.c struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, · line 462
Quoted 5 lines
arch/arm/plat-omap/omap_device.c +5
-0+struct omap_hwmod *oh = hwmods[i]; +struct voltagedomain *voltdm; + +if (is_early_device) +continue ;and drop this check
Ok
Quoted 11 lines
Quoted 11 lines
arch/arm/plat-omap/omap_device.c struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, · line 470
Quoted 9 lines
arch/arm/plat-omap/omap_device.c +4
-0+ voltdm =omap_voltage_domain_lookup (oh->vdd_name); +if (!omap_voltage_add_dev (voltdm, &od->pdev.dev)) + oh->voltdm = voltdm; + } }if (ret)Kevin
PATCH v2 5/14 OMAP: Introduce device specific set rate and get rate in omap_device structure
In reply to Thara GopinathThis 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.
--- 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(-)
arch/arm/plat-omap/include/plat/omap_device.h +9 -0
@@ -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 */
arch/arm/plat-omap/omap_device.c +49 -0
55 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Re: [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure
Quoted 32 lines · Thara Gopinath
This patch extends the
omap_devicestructure 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 namelyomap_device_set_ratethat can be called to set a new operating rate for a device,omap_device_get_ratethat can be called to retrieve the operating frequency for a device andomap_device_populate_rate_fnsto populte the device specificset_rateandget_rateAPI's. Theomap_device_set_rateandomap_device_get_ratedoes some routine error checks and finally calls into the device specificset_rateandget_rateAPIs populated throughomap_device_populate_rate_fns.Signed-off-by Thara Gopinath <[email protected]>--- 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(-)arch/arm/plat-omap/include/plat/omap_device.h +2
-0@@ -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
arch/arm/plat-omap/include/plat/omap_device.h struct omap_device { · line 73
Quoted 5 lines
arch/arm/plat-omap/include/plat/omap_device.h +2
-0@@ -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.
arch/arm/plat-omap/include/plat/omap_device.h void __iomem *omap_device_get_rt_va(struct omap_device *od); · line 118
Quoted 12 lines
arch/arm/plat-omap/include/plat/omap_device.h +5
-0u32 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()
Quoted 7 lines
arch/arm/plat-omap/include/plat/omap_device.h +0
-0/* Other */ arch/arm/plat-omap/omap_device.c +0
-0
arch/arm/plat-omap/omap_device.c int omap_device_enable_clocks(struct omap_device *od) · line 793
Quoted 9 lines
arch/arm/plat-omap/omap_device.c +6
-0@@ -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.
Quoted 7 lines
arch/arm/plat-omap/omap_device.c +7
-0+ od =_find_by_pdev (pdev); + +if (!od->set_rate) { +dev_err (dev,"%s: No set_rate API for scaling device\n" , + __func__); +return -ENODATA ; + }
arch/arm/plat-omap/omap_device.c int omap_device_enable_clocks(struct omap_device *od) · line 810
Quoted 10 lines
arch/arm/plat-omap/omap_device.c +10
-0+ +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)
Quoted 10 lines
arch/arm/plat-omap/omap_device.c +10
-0+ 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);
arch/arm/plat-omap/omap_device.c int omap_device_enable_clocks(struct omap_device *od) · line 830
Quoted 10 lines
arch/arm/plat-omap/omap_device.c +10
-0+} + +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)
arch/arm/plat-omap/omap_device.c int omap_device_enable_clocks(struct omap_device *od) · line 839
Quoted 9 lines
arch/arm/plat-omap/omap_device.c +6
-0+ 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
RE: [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure
Quoted 46 lines
Quoted 46 lines
-----Original Message-----
From: Kevin Hilman [mailto:[email protected]]
Sent: Friday, November 12, 2010 4:29 AM
To: Gopinath, Thara
Cc: [email protected]; [email protected]; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand
Subject: Re: [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate inomap_devicestructureQuoted 12 lines · Thara Gopinath
This patch extends the
omap_devicestructure 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 namelyomap_device_set_ratethat can be called to set a new operating rate for a device,omap_device_get_ratethat can be called to retrieve the operating frequency for a device andomap_device_populate_rate_fnsto populte the device specificset_rateandget_rateAPI's. Theomap_device_set_rateandomap_device_get_ratedoes some routine error checks and finally calls into the device specificset_rateandget_rateAPIs populated throughomap_device_populate_rate_fns.Quoted 4 lines
Signed-off-by Thara Gopinath <[email protected]>--- arch/arm/plat-omap/include/plat/omap_device.h | 9 +++++ arch/arm/plat-omap/omap_device.c | 49+++++++++++++++++++++++++
arch/arm/plat-
Quoted 3 lines
2 files changed, 58 insertions(+), 0 deletions(-)arch/arm/plat- renamed from arch/arm/plat-omap/include/plat/omap_device.h +0
-0
omap/include/plat/omap_device.harch/arm/plat-omap/include/plat/omap_device.h extern struct device omap_device_parent; · line 56
Quoted 11 lines
index 28e2d1a..2a37345 100644
arch/arm/plat-omap/include/plat/omap_device.h +2
-0@@ -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
Quoted 9 lines
Quoted 9 lines
arch/arm/plat-omap/include/plat/omap_device.h struct omap_device { · line 73
Quoted 7 lines
arch/arm/plat-omap/include/plat/omap_device.h +2
-0* @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
Quoted 6 lines
Quoted 6 lines
arch/arm/plat-omap/include/plat/omap_device.h void __iomem *omap_device_get_rt_va(struct omap_device
Quoted 5 lines
arch/arm/plat-omap/include/plat/omap_device.h +0
-0u32 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);
Quoted 10 lines
Quoted 10 lines
arch/arm/plat-omap/include/plat/omap_device.h void __iomem *omap_device_get_rt_va(struct omap_device *od); · line 118
Quoted 8 lines
arch/arm/plat-omap/include/plat/omap_device.h +5
-0int 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.
Quoted 21 lines
Quoted 21 lines
arch/arm/plat-
Quoted 4 lines
arch/arm/plat-omap/include/plat/omap_device.h +0
-0/* Other */ arch/arm/plat- renamed from arch/arm/plat-omap/omap_device.c +0
-0
omap/omap_device.carch/arm/plat-omap/omap_device.c int omap_device_enable_clocks(struct omap_device *od) · line 793
Quoted 13 lines
index 7c902a6..ffe06eb 100644
arch/arm/plat-omap/omap_device.c +6
-0@@ -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)
Quoted 1 line
Quoted 1 line
This helper is already defined in
platform_device.h.
Ok
Quoted 35 lines
Quoted 35 lines
Quoted 8 lines
arch/arm/plat-omap/omap_device.c +7
-0+ od =_find_by_pdev (pdev); + +if (!od->set_rate) { +dev_err (dev,"%s: No set_rate API for scaling device\n" , + __func__); +return -ENODATA ; + }arch/arm/plat-omap/omap_device.c int omap_device_enable_clocks(struct omap_device *od) · line 810
Quoted 10 lines
arch/arm/plat-omap/omap_device.c +10
-0+ +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)Quoted 14 lines
arch/arm/plat-omap/omap_device.c +14
-0+ 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),
Quoted 8 lines
Quoted 8 lines
arch/arm/plat-omap/omap_device.c int omap_device_enable_clocks(struct omap_device *od) · line 830
Quoted 6 lines
arch/arm/plat-omap/omap_device.c +6
-0+ 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
Quoted 12 lines
Quoted 12 lines
arch/arm/plat-omap/omap_device.c int omap_device_enable_clocks(struct omap_device *od) · line 839
Quoted 10 lines
arch/arm/plat-omap/omap_device.c +6
-0+ 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
PATCH v2 6/14 OMAP: Voltage layer changes to support DVFS.
In reply to Thara GopinathThis 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.
--- arch/arm/mach-omap2/voltage.c | 72 +++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/voltage.h | 7 +++ 2 files changed, 79 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/voltage.c +72 -0
@@ -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 )
arch/arm/plat-omap/include/plat/voltage.h +7 -0
@@ -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
Signature · 1 line
1.7.0.4
Re: [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS.
Quoted 76 lines · 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 <[email protected]>--- arch/arm/mach-omap2/voltage.c | 72 +++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/voltage.h | 7 +++ 2 files changed, 79 insertions(+), 0 deletions(-)arch/arm/mach-omap2/voltage.c +47
-0@@ -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)) {
arch/arm/mach-omap2/voltage.c struct voltagedomain *omap_voltage_domain_lookup(char *name) · line 1737
Quoted 10 lines
arch/arm/mach-omap2/voltage.c +10
-0+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
Quoted 43 lines
arch/arm/mach-omap2/voltage.c +15
-0+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 )arch/arm/plat-omap/include/plat/voltage.h +7
-0@@ -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
RE: [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS.
Quoted 104 lines
Quoted 104 lines
-----Original Message-----
From: Kevin Hilman [mailto:[email protected]]
Sent: Friday, November 12, 2010 5:04 AM
To: Gopinath, Thara
Cc: [email protected]; [email protected]; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand
Subject: Re: [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS.Quoted 8 lines · 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 <[email protected]>--- arch/arm/mach-omap2/voltage.c | 72+++++++++++++++++++++++++++++
arch/arm/mach-omap2/voltage.c struct voltagedomain
Quoted 20 lines
arch/arm/plat-omap/include/plat/voltage.h | 7 +++ 2 files changed, 79 insertions(+), 0 deletions(-)arch/arm/mach-omap2/voltage.c +2
-0@@ -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)
Quoted 48 lines
arch/arm/mach-omap2/voltage.c +45
-0}/** +* 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)) {arch/arm/mach-omap2/voltage.c struct voltagedomain *omap_voltage_domain_lookup(char *name) · line 1737
Quoted 10 lines
arch/arm/mach-omap2/voltage.c +10
-0+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
Quoted 2 lines
Quoted 2 lines
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
PATCH v2 7/14 OMAP: Introduce dependent voltage domain support.
In reply to Thara GopinathThere 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.
--- arch/arm/mach-omap2/voltage.c | 122 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 122 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/voltage.c +122 -0
@@ -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 ; }
Signature · 1 line
1.7.0.4
Re: [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support.
Quoted 10 lines · 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 <[email protected]>
This patch introduces recursive locking (found by lockdep)
[...]
Quoted 12 lines
/**
*omap_voltage_get_nom_volt()- Gets the current non-auto-compensated voltagearch/arm/mach-omap2/voltage.c +2
-0@@ -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__);
arch/arm/mach-omap2/voltage.c int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt) · line 1818
Quoted 2 lines
arch/arm/mach-omap2/voltage.c +0
-0@@ -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()
arch/arm/mach-omap2/voltage.c int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt) · line 1825
Quoted 6 lines
arch/arm/mach-omap2/voltage.c +5
-0+/* 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.
Quoted 10 lines
arch/arm/mach-omap2/voltage.c +5
-0+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) {
arch/arm/mach-omap2/voltage.c int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt) · line 1872
Quoted 8 lines
arch/arm/mach-omap2/voltage.c +3
-0@@ -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)PATCH v2 8/14 OMAP: Introduce device scale
In reply to Thara GopinathThis patch adds omap_device_scale API which can be used to generic device rate scaling.
--- 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(-)
arch/arm/plat-omap/include/plat/omap_device.h +2 -1
@@ -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 *
arch/arm/plat-omap/omap_device.c +78 -0
90 lines not on this page · raw message
Signature · 1 line
1.7.0.4
PATCH v2 9/14 OMAP: Disable smartreflex across DVFS
In reply to Thara GopinathThis 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.
--- arch/arm/mach-omap2/voltage.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/voltage.c +7 -0
@@ -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);
Signature · 1 line
1.7.0.4
PATCH v2 10/14 OMAP3: Introduce custom set rate and get rate APIs for scalable devices
In reply to Thara GopinathThis 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
--- arch/arm/mach-omap2/pm.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 110 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm.c +110 -0
@@ -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); + + } }/*
Signature · 1 line
1.7.0.4
PATCH v2 11/14 OMAP3: Update cpufreq driver to use the new set_rate API
In reply to Thara GopinathThis patch updates the cpufreq driver to use the device set rate API to scale the mpu frequency for OMAP3.
--- arch/arm/plat-omap/cpu-omap.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
arch/arm/plat-omap/cpu-omap.c +2 -1
@@ -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; }
Signature · 1 line
1.7.0.4
PATCH v2 12/14 OMAP3: Introduce voltage domain info in the hwmod structures.
In reply to Thara GopinathThis patch adds voltage domain info in the relevant device hwmod structures so as to enable OMAP3 DVFS support.
--- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +3 -0
@@ -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 )
Signature · 1 line
1.7.0.4
PATCH v2 13/14 OMAP3: Add voltage dependency table for VDD1.
In reply to Thara GopinathIn 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.
--- arch/arm/mach-omap2/voltage.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/voltage.c +19 -0
@@ -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 ;
Signature · 1 line
1.7.0.4
RE: [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.
Thara,
Quoted 35 lines
-----Original Message-----
From: Gopinath, Thara
Sent: Friday, October 29, 2010 9:08 PM
To: [email protected]
Cc: [email protected]; [email protected]; 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 <[email protected]>--- arch/arm/mach-omap2/voltage.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)arch/arm/mach- renamed from arch/arm/mach-omap2/voltage.c +0
-0
omap2/voltage.c
index 6f85f75..241fac5 100644arch/arm/mach-omap2/voltage.c +6
-0@@ -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},
arch/arm/mach-omap2/voltage.c static struct omap_volt_data · line 370
Quoted 10 lines
arch/arm/mach-omap2/voltage.c +10
-0+ {.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
Quoted 20 lines
arch/arm/mach-omap2/voltage.c +1
-0+/* By default VPFORCEUPDATE is the chosen method of voltage scaling */
static boolvoltscale_vpforceupdate= true;arch/arm/mach-omap2/voltage.c +2
-0@@ -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);arch/arm/mach-omap2/voltage.c +0
-0} vdd->vp_reg.tranxdone_status =
OMAP3430_VP1_TRANXDONE_ST_MASK;
--
1.7.0.4
RE: [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.
Quoted 53 lines
Quoted 53 lines
-----Original Message-----
From: [email protected] [mailto:linux-omap- [email protected]] On Behalf Of Sripathy, Vishwanath
Sent: Wednesday, December 01, 2010 9:01 PM
To: [email protected]
Cc: [email protected]; [email protected]
Subject: RE: [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.Thara,
Quoted 41 lines
-----Original Message-----
From: Gopinath, Thara
Sent: Friday, October 29, 2010 9:08 PM
To: [email protected]
Cc: [email protected]; [email protected]; 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 <[email protected]>--- arch/arm/mach-omap2/voltage.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)arch/arm/mach- renamed from arch/arm/mach-omap2/voltage.c +0
-0
omap2/voltage.c
index 6f85f75..241fac5 100644arch/arm/mach-omap2/voltage.c +12
-0@@ -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[] = { + {
Quoted 8 lines
Quoted 8 lines
arch/arm/mach-omap2/voltage.c static struct omap_volt_data omap44xx_vdd_core_volt_data[] = { · line 368
Quoted 4 lines
arch/arm/mach-omap2/voltage.c +4
-0+ .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
Quoted 26 lines
Quoted 26 lines
Vishwa
Quoted 17 lines
arch/arm/mach-omap2/voltage.c +1
-0+/* By default VPFORCEUPDATE is the chosen method of voltage scaling */
static boolvoltscale_vpforceupdate= true;arch/arm/mach-omap2/voltage.c +2
-0@@ -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);arch/arm/mach-omap2/voltage.c +0
-0} vdd->vp_reg.tranxdone_status =Quoted 3 lines
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1.
In reply to Thara GopinathThara,
Quoted 35 lines
-----Original Message-----
From: Gopinath, Thara
Sent: Friday, October 29, 2010 9:08 PM
To: [email protected]
Cc: [email protected]; [email protected]; 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 <[email protected]>--- arch/arm/mach-omap2/voltage.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)arch/arm/mach- renamed from arch/arm/mach-omap2/voltage.c +0
-0
omap2/voltage.c
index 6f85f75..241fac5 100644arch/arm/mach-omap2/voltage.c +6
-0@@ -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},
arch/arm/mach-omap2/voltage.c static struct omap_volt_data · line 370
Quoted 10 lines
arch/arm/mach-omap2/voltage.c +10
-0+ {.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
Quoted 20 lines
arch/arm/mach-omap2/voltage.c +1
-0+/* By default VPFORCEUPDATE is the chosen method of voltage scaling */
static boolvoltscale_vpforceupdate= true;arch/arm/mach-omap2/voltage.c +2
-0@@ -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);arch/arm/mach-omap2/voltage.c +0
-0} vdd->vp_reg.tranxdone_status =
OMAP3430_VP1_TRANXDONE_ST_MASK;
--
1.7.0.4
PATCH v2 14/14 OMAP2PLUS: Enable various options in defconfig
In reply to Thara GopinathThis patch enables Smartreflex and Cpu Freq in the omap2plus defconfig.
--- arch/arm/configs/omap2plus_defconfig | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/configs/omap2plus_defconfig +4 -0
@@ -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
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerRe: [PATCH v2 14/14] OMAP2PLUS: Enable various options in defconfig
Quoted 13 lines · Thara Gopinath
This patch enables Smartreflex and Cpu Freq in the omap2plus defconfig.
Signed-off-by Thara Gopinath <[email protected]>--- arch/arm/configs/omap2plus_defconfig | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)arch/arm/configs/omap2plus_defconfig +0
-0
arch/arm/configs/omap2plus_defconfig CONFIG_CRC_T10DIF=y · line 297
Quoted 7 lines
arch/arm/configs/omap2plus_defconfig +4
-0@@ -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