Prev: [OOPS] apbuart.c: Two problems related to grlib_apbuart_configure()
Next: Resierfs random corruptions (probably related to cryptsetup or LVM)
From: Mark Brown on 10 May 2010 10:10 On Mon, May 10, 2010 at 07:16:06PM +0530, Deepak Sikri wrote: > In our System on chip we have several power domains. As such there is no > generic framework for the Power Domains in linux , and I find huge potential > in the software to control the domains and exploit the power management > capabilities. > There is one very small model that I could think of, something on the lines > of clock framework. Might be worth looking at what the OMAP and SH Mobile CPUs are doing here, they have existing handling for power domains. Off-SoC the regulator API should already cope with a lot of this stuff. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Sundar on 16 May 2010 07:20 Hi All, The regulator framework documentation already refers to the concept of power domains and I think the framework *can* be extended more to support on-SoC power domains as well. I have been working with the regulator framework for on-chip power domains too and.... >2. Maintain a list of the different power domains present. >3. The devices in a specific power domain, as per the requirements would get the power >domain... >4. Typically a usage count of zero for any power domai.. >5. The same could be mapped on to the PM framework.. >6. The model could further be build upon to check any dependency in the power domains the above requirements can be leveraged through the current regulator framework itself. However, for working with power domains within the framework, I feel that, - support must be added to allow additional domain-specific states like retention, idle etc. - controlling operating points for regulators, unlike setting optimal modes. - controlling regulator modes via constraints enforced by clients and managing transition to various states through the client requests and pushing the client states up to the parent regulator. >7. The advantages of the framework could be leveraged in the CPU idle time, by switching >off the Power domains with zero usage counts. Yes. A simple platform specific list of all regulators ( and power domains ) can be easily used in the CPUIdle driver for determining low power states. Further, enforcing run time PM can club together any peripheral's power sources in terms of external regulators, on-chip domains ( and clock sources possibly). i have a very primitive implementation for adding operating points and constraints into the framework and currently i am able to control regulator aka domain states based on various child domains and contraints. However, with more inputs, I think we can make the regulator framework easily manage power sources, whether on-chip domains or external conventional regulators... Waiting for opinions and views, Regards, Sundar Mon, May 10, 2010 at 7:35 PM, Mark Brown <broonie(a)opensource.wolfsonmicro.com> wrote: > On Mon, May 10, 2010 at 07:16:06PM +0530, Deepak Sikri wrote: > >> In our System on chip we have several power domains. As such there is no >> generic framework for the Power Domains in linux , and I find huge potential >> in the software to control the domains and exploit the power management >> capabilities. > >> There is one very small model that I could think of, something on the lines >> of clock framework. > > Might be worth looking at what the OMAP and SH Mobile CPUs are doing > here, they have existing handling for power domains. �Off-SoC the > regulator API should already cope with a lot of this stuff. > _______________________________________________ > linux-pm mailing list > linux-pm(a)lists.linux-foundation.org > https://lists.linux-foundation.org/mailman/listinfo/linux-pm > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Mark Brown on 16 May 2010 23:20 On Sun, May 16, 2010 at 04:43:52PM +0530, Sundar wrote: Please don't top post, it breaks the thread of discussion. > However, for working with power domains within the framework, I feel that, > - support must be added to allow additional domain-specific states > like retention, idle etc. I'm really not convinced that this is a good idea. Generally I suspect the implementations of these concepts that I've seen would introduce layering violations if done via the regulator API - from what I've seen the power domains can end up knowing rather more about the things that are being powered than is healthy for the regulator API and... > - controlling operating points for regulators, unlike setting optimal modes. > - controlling regulator modes via constraints enforced by clients and > managing transition to various states through the client requests and > pushing the client states up to the parent regulator. ....knowing a lot about the specifics of the internal structures of the device you're trying to model. Cross talk with the clock API also seems fairly common here. I do think it's likely that you'll want something that looks like the regulator API at the edges, but that a separate implementation that avoids having to shoehorn through the abstractions of the regulator API for the on-chip work seems much more sensible (and is what OMAP and SH are already doing). This is fairly similar to the relationship between the clock and regulator APIs - they look a lot alike, especially from a user point of view, but they are separate because there are enough differences in what they are trying to represent to make it sensible to keep them apart. However, if you have patches it's probably easier to talk about those than architecture astronauting; perhaps your implementation avoids my concerns. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Sundar R Iyer on 17 May 2010 12:40 On Mon, 2010-05-17 at 18:23 +0200, Sundar wrote: > P.S : Let me post out the patch set following on. Sorry to change the email-ID; didnt want to would break patch readability. The implementation follows: The regulator framework states that any source which supplies power to a peripheral can be modeled as a regulator. However, in new SoCs where peripherals apart from being powered through the conventional regulators, peripherals are also powered through on-chip domains. These on-chip domains control enabling/disabling and also controlling the output to the peripheral as full mode or idle mode (retention). These power sources don.t allow control of parameters like DRMS, current, voltage etc. Also, in such designs, often individual domains are clubbed under a unified domain. In such a case, smaller domains need to communicate to the parent domain in case of a constraining request from its peripheral(s). Domain ABC |---Periph Domain A, (100OPP/50OPP), to run at 100OPP, parent to run at 100OPP |---Periph Domain B, (100OPP), to run at 100OPP, parent to run at 100OPP |---Periph Domain C, (100OPP/50OPP), to run at 100OPP, parent to run at 100OPP Thus, for ideal power saving modes, the Domain ABC can be turned to a lower OPP if - Periph B is not running - Periph A/C are running at 50OPP only. This patch set adds a function for controlling the OPPs, not touching the existing voltage/mode functions, as they are needed in their own way for conventional regulators. Sundar R Iyer (1): regulators : Regulator Operating Points --- drivers/regulator/core.c | 79 ++++++++++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 27 ++++++++++++ include/linux/regulator/driver.h | 5 ++ include/linux/regulator/machine.h | 6 +++ 4 files changed, 117 insertions(+), 0 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c old mode 100644 new mode 100755 index 2248087..7c6c5af --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1898,6 +1898,85 @@ out: } EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); +/* locks held by regulator_set_operating_point() */ +static int _regulator_set_operating_point(struct regulator_dev *rdev, + unsigned int opp) +{ + int ret, regulator_curr_opp = 0; + + if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_OPP)) { + printk(KERN_ERR "%s: operation not allowed for %s\n", + __func__, rdev->desc->name); + return -EPERM; + } + + /* sanity checks */ + if (!rdev->desc->ops->set_operating_point) { + return -EINVAL; + } + + if (rdev->desc->ops->get_operating_point) + regulator_curr_opp = rdev->desc->ops->get_operating_point(rdev); + + /* we have no issues with upgrading the opp */ + if (opp == REGULATOR_OPERATINGPOINT_FULL) { + if (rdev->constraints->opp_constraint_count < 1) { + if (rdev->supply) + ret = _regulator_set_operating_point(rdev->supply, opp); + ret = rdev->desc->ops->set_operating_point(rdev, opp); + } + rdev->constraints->opp_constraint_count++; + } + + if (opp == REGULATOR_OPERATINGPOINT_IDLE) { + rdev->constraints->opp_constraint_count--; + /* if there r no constraints */ + if (rdev->constraints->opp_constraint_count == 0) { + if (rdev->supply) + ret = _regulator_set_operating_point(rdev->supply, opp); + + ret = rdev->desc->ops->set_operating_point(rdev, opp); + } + } + + return ret; +} + +/** + * regulator_set_operating_point - set regulator operating point + * @regulator: regulator source + * @opp: operating point to set + * + * sets the operating point for a regulator. + * this is not to be confused the regulator modes. For smart regulators + * that can run at varied operating points, clients can request simply + * operating points rather than notional load values. + * + * For eg, an on-chip regulator source for a peripheral like multimedia can + * - run at a full operating point for a full 1020p, + * - run at half the operating point for something like QVGA. + * + * All on-chip power domains can be modelled as regulators, and their controls + * through this function. + * + * Returns the new regulator operating point or error. + */ +int regulator_set_operating_point(struct regulator *regulator, unsigned int opp) +{ + struct regulator_dev *rdev = regulator->rdev; + int ret; + + mutex_lock(&rdev->mutex); + ret = _regulator_set_operating_point(rdev, opp); + mutex_unlock(&rdev->mutex); + + return ret; + +} +EXPORT_SYMBOL_GPL(regulator_set_operating_point); + + + /** * regulator_register_notifier - register regulator event notifier * @regulator: regulator source diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h old mode 100644 new mode 100755 index ebd7472..680ec30 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -82,6 +82,30 @@ #define REGULATOR_MODE_STANDBY 0x8 /* + * Regulator operating points + * + * Fast, switchable supplies for peripherals which are controlled + * via on-chip power domains are different from normal regulators + * which control voltages, current, drms etc. For such power domain + * supplies aka regulators, all that can be controlled is the operating + * point, OPP. Such regulators can be either on with full voltage, or + * partially on at retention/normal voltages (specific to SoC settings) + * + * these flags can be used to model "power domains" on SoCs in the main + * regulator framework + * + * Also, for such power domains, turning on/off can be handled through + * the regulator enable/disable calls + * + * FULL Regulator runs at the full output + * HALF Regulator runs at the half output + * + * these OPPs can be OR'ed together to make a mask of valid regulator OPPs + */ +#define REGULATOR_OPERATINGPOINT_FULL 0x1 +#define REGULATOR_OPERATINGPOINT_IDLE 0x2 + +/* * Regulator notifier events. * * UNDER_VOLTAGE Regulator output is under voltage. @@ -160,6 +184,9 @@ int regulator_get_current_limit(struct regulator *regulator); int regulator_set_mode(struct regulator *regulator, unsigned int mode); unsigned int regulator_get_mode(struct regulator *regulator); + +int regulator_set_operating_point(struct regulator *regulator, unsigned int opp); + int regulator_set_optimum_mode(struct regulator *regulator, int load_uA); /* regulator notifier block */ diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h old mode 100644 new mode 100755 index 592cd7c..e5be16b --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -122,6 +122,11 @@ struct regulator_ops { /* set regulator suspend operating mode (defined in regulator.h) */ int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode); + + /* set regulator operating point */ + int (*set_operating_point) (struct regulator_dev *, int opp); + int (*get_operating_point) (struct regulator_dev *); + }; /* diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h old mode 100644 new mode 100755 index e298028..185a5d5 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -39,6 +39,7 @@ struct regulator; #define REGULATOR_CHANGE_MODE 0x4 #define REGULATOR_CHANGE_STATUS 0x8 #define REGULATOR_CHANGE_DRMS 0x10 +#define REGULATOR_CHANGE_OPP 0x20 /** * struct regulator_state - regulator state during low power system states @@ -109,6 +110,9 @@ struct regulation_constraints { /* valid operations for regulator on this machine */ unsigned int valid_ops_mask; + /* valid operating point ranges for this regulator */ + unsigned int valid_opp_mask; + /* regulator input voltage - only if supply is another regulator */ int input_uV; @@ -125,6 +129,8 @@ struct regulation_constraints { unsigned always_on:1; /* regulator never off when system is on */ unsigned boot_on:1; /* bootloader/firmware enabled regulator */ unsigned apply_uV:1; /* apply uV constraint if min == max */ + unsigned int opp_constraint_count; /* clients enforcing a constraint */ + }; /** -- 1.7.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
From: Mark Brown on 17 May 2010 13:10
On Mon, 2010-05-17 at 22:05 +0530, Sundar R Iyer wrote: > +/* locks held by regulator_set_operating_point() */ > +static int _regulator_set_operating_point(struct regulator_dev *rdev, > + unsigned int opp) > +{ > + int ret, regulator_curr_opp = 0; > + > + if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_OPP)) { > + printk(KERN_ERR "%s: operation not allowed for %s\n", > + __func__, rdev->desc->name); > + return -EPERM; > + } > + > + /* sanity checks */ > + if (!rdev->desc->ops->set_operating_point) { > + return -EINVAL; > + } > + > + if (rdev->desc->ops->get_operating_point) > + regulator_curr_opp = rdev->desc->ops->get_operating_point(rdev); > + > + /* we have no issues with upgrading the opp */ > + if (opp == REGULATOR_OPERATINGPOINT_FULL) { > + if (rdev->constraints->opp_constraint_count < 1) { > + if (rdev->supply) > + ret = _regulator_set_operating_point(rdev->supply, opp); > + ret = rdev->desc->ops->set_operating_point(rdev, opp); > + } > + rdev->constraints->opp_constraint_count++; > + } This implementation is assuming that the implementation in hardware only has two levels, and that the decision to go to the higher level is done by a simple or of requests for the full level from the consumers. I'm not convinced that this will be true in general, or that it's always going to be true that the different power domains are all isolated from each other. There doesn't seem to be any immediate reason why hardware won't ever implement more than two modes, and I'm not convinced that the straight or of requests will always be sufficient to determine the operating mode for the entire power domain. For example, I can see hardware requiring that if more than a given number of blocks are enabled at any level a higher operating point is selected. Are you sure that this interface is sufficiently general to work with all hardware, not just your own? How does this map on to the OMAP or SH hardware, for example? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ |