Re: [PATCH 3/8] OMAP3 hwmod: Add automatic OCP_SYSCONFIG AUTOIDLE handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Nov 18, 2009 at 6:35 AM, Kevin Hilman
<khilman@xxxxxxxxxxxxxxxxxxx> wrote:
> From: Paul Walmsley <paul@xxxxxxxxx>
>
> This patch fills in the OCP_SYSCONFIG.AUTOIDLE handling in the OMAP
> hwmod code.
>
> After this patch, the hwmod code will set the module AUTOIDLE bit (generally
> <module>.OCP_SYSCONFIG.AUTOIDLE) to 1 by default upon enable, and 1 upon
> disable.

You wanted to say:  "0 upon disable", isn't it?

-vimal

> If the hwmod flag HWMOD_NO_AUTOIDLE is set, AUTOIDLE will be
> set to 0 upon enable.
>
> Enabling module autoidle should save some power.  The only reason to
> not set the OCP_SYSCONFIG.AUTOIDLE bit is if there is a bug in the
> module RTL, e.g., the MPUINTC block on OMAP3.
>
> Comments from Kevin Hilman <khilman@xxxxxxxxxxxxxxxxxxx> inspired this patch.
>
> Signed-off-by: Paul Walmsley <paul@xxxxxxxxx>
> Tested-by: Kevin Hilman <khilman@xxxxxxxxxxxxxxxxxxx>
> ---
>  arch/arm/mach-omap2/omap_hwmod.c             |   50 +++++++++++++++++++++++---
>  arch/arm/plat-omap/include/plat/omap_hwmod.h |    8 ++++-
>  2 files changed, 52 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 7d7b3b8..25d9484 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -210,6 +210,29 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
>  }
>
>  /**
> + * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v
> + * @oh: struct omap_hwmod *
> + * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
> + * @v: pointer to register contents to modify
> + *
> + * Update the module autoidle mode bit in @v to be @autoidle for the
> + * @oh hwmod.  Does not write to the hardware.  Returns -EINVAL upon
> + * error or 0 upon success.
> + */
> +static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
> +                               u32 *v)
> +{
> +       if (!oh->sysconfig ||
> +           !(oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE))
> +               return -EINVAL;
> +
> +       *v &= ~SYSC_AUTOIDLE_MASK;
> +       *v |= autoidle << SYSC_AUTOIDLE_SHIFT;
> +
> +       return 0;
> +}
> +
> +/**
>  * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
>  * @oh: struct omap_hwmod *
>  *
> @@ -560,7 +583,13 @@ static void _sysc_enable(struct omap_hwmod *oh)
>                _set_master_standbymode(oh, idlemode, &v);
>        }
>
> -       /* XXX OCP AUTOIDLE bit? */
> +       if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE) {
> +               idlemode = (oh->flags & HWMOD_NO_AUTOIDLE) ?
> +                       0 : 1;
> +               _set_module_autoidle(oh, idlemode, &v);
> +       }
> +
> +       /* XXX OCP ENAWAKEUP bit? */
>
>        if (oh->flags & HWMOD_SET_DEFAULT_CLOCKACT &&
>            oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)
> @@ -625,7 +654,8 @@ static void _sysc_shutdown(struct omap_hwmod *oh)
>        if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)
>                _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
>
> -       /* XXX clear OCP AUTOIDLE bit? */
> +       if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE)
> +               _set_module_autoidle(oh, 1, &v);
>
>        _write_sysconfig(v, oh);
>  }
> @@ -951,11 +981,21 @@ static int _setup(struct omap_hwmod *oh)
>
>        _enable(oh);
>
> -       if (!(oh->flags & HWMOD_INIT_NO_RESET))
> +       if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
>                _reset(oh);
>
> -       /* XXX OCP AUTOIDLE bit? */
> -       /* XXX OCP ENAWAKEUP bit? */
> +               /*
> +                * XXX Do the OCP_SYSCONFIG bits need to be
> +                * reprogrammed after a reset?  If not, then this can
> +                * be removed.  If it does, then probably the
> +                * _enable() function should be split to avoid the
> +                * rewrite of the OCP_SYSCONFIG register.
> +                */
> +               if (oh->sysconfig) {
> +                       _update_sysc_cache(oh);
> +                       _sysc_enable(oh);
> +               }
> +       }
>
>        if (!(oh->flags & HWMOD_INIT_NO_IDLE))
>                _idle(oh);
> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> index dbdd123..ec140b0 100644
> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> @@ -50,6 +50,8 @@ struct omap_device;
>  #define SYSC_ENAWAKEUP_MASK            (1 << SYSC_ENAWAKEUP_SHIFT)
>  #define SYSC_SOFTRESET_SHIFT           1
>  #define SYSC_SOFTRESET_MASK            (1 << SYSC_SOFTRESET_SHIFT)
> +#define SYSC_AUTOIDLE_SHIFT            0
> +#define SYSC_AUTOIDLE_MASK             (1 << SYSC_AUTOIDLE_SHIFT)
>
>  /* OCP SYSSTATUS bit shifts/masks */
>  #define SYSS_RESETDONE_SHIFT           0
> @@ -294,13 +296,17 @@ struct omap_hwmod_omap4_prcm {
>  *     SDRAM controller, etc.
>  * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
>  *     controller, etc.
> + * HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
> + *     when module is enabled, rather than the default, which is to
> + *     enable autoidle
>  * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
>  */
>  #define HWMOD_SWSUP_SIDLE                      (1 << 0)
>  #define HWMOD_SWSUP_MSTANDBY                   (1 << 1)
>  #define HWMOD_INIT_NO_RESET                    (1 << 2)
>  #define HWMOD_INIT_NO_IDLE                     (1 << 3)
> -#define HWMOD_SET_DEFAULT_CLOCKACT             (1 << 4)
> +#define HWMOD_NO_AUTOIDLE                      (1 << 4)
> +#define HWMOD_SET_DEFAULT_CLOCKACT             (1 << 5)
>
>  /*
>  * omap_hwmod._int_flags definitions
> --
> 1.6.5.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux