Hi!

Added Paul in Cc:.

On Thu, Jun 14, 2012 at 10:05 AM, Jean Pihet <jean.pi...@newoldbits.com> wrote:
> Hi Richard, all,
>
> On Tue, Jun 12, 2012 at 6:34 PM, Woodruff, Richard <r-woodru...@ti.com> wrote:
>> Hi Tony,
>>
>>> From: Tony Lindgren [mailto:t...@atomide.com]
>>> Sent: Friday, May 25, 2012 2:53 AM
>>
>> Thanks for quick input.  Apologies on slow ack of it.
>>
>>> Before we had these frameworks in place it was often hard to debug when
>>> something
>>> did not work for some omaps. Things would just not work or would stop
>>> working
>>> for some drivers with no ideas what was going on. So yeah, having these
>>> kind of
>>> frameworks in place has helped a lot to avoid breakage like you're
>>> describing
>>> above.
>>
>> Trees which had to hit the lowest power states for full customer boards all 
>> employed some form of abstraction of clock, power, voltage. The one today in 
>> mainline today is the most clean. Aspects around auto-generation are very 
>> good even if a bit big in size.
>>
>> Perhaps main grump I hear is the number of abstraction layers sometimes 
>> makes debugging difficult. It would be nice to find smart tricks for compile 
>> to prune away some.
>>
>> Still one can experience some of the mystery issues, as the PRCM connection 
>> to IP-device utilizes a protocol which the device side can mess up. If the 
>> device does not shut down its local function and associated clocks cleanly 
>> it will show 'stuck in transition' and this gates final global changes. In 
>> one of the closed implementation we would bug() drivers who did not shut 
>> down their internal clocks properly before allowing global clock release.  
>> Most of the issues seen in field are at drivers/peripheral-ip.
>>
>>
>>> For some external subsystems it might be possible to let the omap kernel
>>> manage
>>> powerdomains and other resource via remote proc interface, assuming these
>>> registers are ioremapped in the omap kernel side and not owned by the
>>> external
>>> subsystem. The messaging to do this would add some undesired latencies
>>> though,
>>> but maybe those would not be so critical for the external subsystems as
>>> they
>>> tend to be full on or completely off type accelerators.
>>
>> Humm. Maybe for some. Guess walking what is used and sorting might tell.
>>
>> The way some subsystems 'ideal' operation is described from designers 
>> implies tight control of timing and sequence for things like power state. A 
>> RPC doesn't feel like it fits with intent. However... practically speaking 
>> from 'full system view' RPC may fit sometimes. A subsystem exporting hooks 
>> to save 100uW using its optimal state set against other components running 
>> in 500mW range minimizes usefulness.
>>
>>> The other alternative of course is to implement similar frameworks for the
>>> external subsystems. Some of this might be possible to implement as simple
>>> macros with some type checks if it's subsystem specific. For doing it for
>>> all omap devices, macros were soon found not to be enough as the various
>>> bits all over need to be linked together for managing various resources.
>>
>> Agree.
>>
>> I don't know insides of all subsystems.  Though what I know or hear is kind 
>> of a mixed picture.
>>
>> OMAP has an ultra high level of integration. As such you might find 
>> something like DSP-Bios may provide a good hook but quick integration of a 
>> previously standalone single purpose piece does not have time to be 
>> readapted.
>>
>> The type checking question kind of grows out of this.  Linux might today 
>> offer a clean run-time api which is place where high wall should be built 
>> with type check.  But... the driver might not be able to function yet with 
>> the API alone given state of evolution of both ends.
>
> Regarding the API and type checking I think the following must be enforced:
> 1. proper type checking in the API, possibly by the compiler,
> 2. clean separation of an API into an internal part (used only by the
> framework implementation) and an external part (used by the callers of
> the API).
>
> About 1: using enum for the parameters did not help much AFACIT. The
> compiler cannot tell if the parameter from a variable is in the
> allowed range.
> Any thought?
>
> About 2: while introducing the functional power states I came across
> this problem. Ideally the current states macros (PWRDM_POWER_* and
> PWRSTS_*) shall be used by the internal code only in powerdomain*.[ch]
> while the callers (pm.c etc) shall use the new macros
> (PWRDM_FUNC_PWRST_*) and API (mainly pwrdm_*_func_* and
> omap_set_pwrdm_state).
>
> Here below is a patch extract (trimmed for brevity) to illustrate the problem.
FYI the full patch is at http://marc.info/?l=linux-omap&m=133968581305050&w=2

>
> From here is see a few possible options:
> 1. clearly separate the internal and external parts of the API in the
> header file using comments (as done in the patch below) or with a new
> #ifdef POWERDOMAIN_INTERNAL_API (ugly I know),
Some more details about that option: the internal values could be
prefixed by '__' or similar which kinds of highlights a bad API usage.

> 2. create a new internal only header file (powerdomain_internal.h) and
> include it only from powerdomain*.[ch],
> 3. move the external API to pm.h and keep the internal API in powerdomain.h
>
> Although I am using the func power states as an example I think this
> is a applicable to all PM frameworks APIs.
>
> What do you think?
Any thought?

> diff --git a/arch/arm/mach-omap2/powerdomain.h
> b/arch/arm/mach-omap2/powerdomain.h
> index bab84fc..0404f9f 100644
> --- a/arch/arm/mach-omap2/powerdomain.h
> +++ b/arch/arm/mach-omap2/powerdomain.h
> @@ -26,7 +23,51 @@
> -/* Powerdomain basic power states */
> +/***************************************************************
> + * External API
> + ***************************************************************/
> +
> +/* Powerdomain functional power states, used by the external API functions */
> +enum pwrdm_func_state {
> +       PWRDM_FUNC_PWRST_OFF            = 0x0,
> +       PWRDM_FUNC_PWRST_OSWR,
> +       PWRDM_FUNC_PWRST_CSWR,
> +       PWRDM_FUNC_PWRST_INACTIVE,
> +       PWRDM_FUNC_PWRST_ON,
> +       PWRDM_MAX_FUNC_PWRSTS           /* Last value, used as the max value 
> */
> +};
> +
> +struct clockdomain;
> +struct powerdomain;
> +
> ...
> +
> +int pwrdm_read_prev_func_pwrst(struct powerdomain *pwrdm);
> +int pwrdm_read_func_pwrst(struct powerdomain *pwrdm);
> +int pwrdm_read_next_func_pwrst(struct powerdomain *pwrdm);
> +extern int omap_set_pwrdm_state(struct powerdomain *pwrdm,
> +                               enum pwrdm_func_state func_pwrst);
> +
> +
> +/***************************************************************
> + * Internal code, only used in powerdomain*.[ch]
> + ***************************************************************/
> +
> +/* Powerdomain internal power states, internal use only */
>  #define PWRDM_POWER_OFF                0x0
>  #define PWRDM_POWER_RET                0x1
>  #define PWRDM_POWER_INACTIVE   0x2
> @@ -45,7 +86,6 @@
>  #define PWRSTS_RET_ON          (PWRSTS_RET | PWRSTS_ON)
>  #define PWRSTS_OFF_RET_ON      (PWRSTS_OFF_RET | PWRSTS_ON)
>
> -
>  /* Powerdomain flags */
>  #define PWRDM_HAS_HDWR_SAR     (1 << 0) /* hardware save-and-restore support 
> */
>  #define PWRDM_HAS_MPU_QUIRK    (1 << 1) /* MPU pwr domain has MEM bank 0 bits
>
>
>> Review question was pointing re-hitting of bugs for what could be argued 
>> 'ideal' internal framework api. How to fix up what is in use by real drivers 
>> or to add/fix external api so its useful should be roadmap.
>>
>> Regards,
>> Richard W.
>>
>
> Thanks for starting the discussion!
>
> Regards,
> Jean
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to