Tero Kristo writes:
> From: Tero Kristo
>
> pwrdm_can_idle(pwrdm) will check if the specified powerdomain can enter
> idle. This is done by checking all clockdomains under the powerdomain
> if they can idle also.
>
> omap2_clkdm_can_idle(clkdm) will check if the specified clockdomain can
> enter idle. This checks the functional clocks and idle status bits of the
> domain according to following rules:
> 1) functional clock check
> * get FCLK register content
> * ignore all clocks defined in idle_def.fclk_ignore
> * if any active functional clocks remain, domain can't idle
> 2) idle status check
> * get IDLEST register content
> * inverse it (any non-idle blocks are now as 1)
> * mask against idle_def.idlest_mask
> * if any bits remain high, domain can't idle
>
> These calls can be used e.g. inside cpuidle to decide which power states
> core and mpu should enter during idle, as there are certain dependencies
> between wakeup capabilities and reset logic.
>
> Signed-off-by: Tero Kristo
I'm OK with this version.
Paul?
Kevin
> ---
> arch/arm/mach-omap2/clockdomain.c | 32
> arch/arm/mach-omap2/clockdomains.h| 106
> +
> arch/arm/mach-omap2/powerdomain.c | 20 +
> arch/arm/plat-omap/include/plat/clockdomain.h | 17
> arch/arm/plat-omap/include/plat/powerdomain.h |1 +
> 5 files changed, 176 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/clockdomain.c
> b/arch/arm/mach-omap2/clockdomain.c
> index a38a615..9ebff51 100644
> --- a/arch/arm/mach-omap2/clockdomain.c
> +++ b/arch/arm/mach-omap2/clockdomain.c
> @@ -867,6 +867,38 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
> return 0;
> }
>
> +
> +/**
> + * omap2_clkdm_can_idle - check if clockdomain has any active clocks or not
> + * @clkdm: struct clockdomain *
> + *
> + * Checks if the clockdomain has any active clock or not, i.e. whether it
> + * can enter idle. Returns -EINVAL if clkdm is NULL; 0 if unable to idle;
> + * 1 if can idle.
> + */
> +int omap2_clkdm_can_idle(struct clockdomain *clkdm)
> +{
> + int i;
> +
> + if (!clkdm)
> + return -EINVAL;
> +
> + for (i = 0; i < clkdm->clk_reg_num; i++) {
> + u32 idlest, fclk;
> +
> + fclk = cm_read_mod_reg(clkdm->pwrdm.ptr->prcm_offs,
> + CM_FCLKEN + 4 * i);
> + if (fclk & ~clkdm->idle_def[i].fclk_ignore)
> + return 0;
> +
> + idlest = cm_read_mod_reg(clkdm->pwrdm.ptr->prcm_offs,
> + CM_IDLEST + 4 * i);
> + if (~idlest & clkdm->idle_def[i].idlest_mask)
> + return 0;
> + }
> + return 1;
> +}
> +
> /**
> * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
> * @clkdm: struct clockdomain *
> diff --git a/arch/arm/mach-omap2/clockdomains.h
> b/arch/arm/mach-omap2/clockdomains.h
> index 8fc19ff..5e29de8 100644
> --- a/arch/arm/mach-omap2/clockdomains.h
> +++ b/arch/arm/mach-omap2/clockdomains.h
> @@ -663,6 +663,12 @@ static struct clockdomain iva2_clkdm = {
> .wkdep_srcs = iva2_wkdeps,
> .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
> .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
> + .clk_reg_num= 1,
> + .idle_def = {
> + [0] = {
> + .idlest_mask = OMAP3430_ST_IVA2,
> + },
> + },
> };
>
> static struct clockdomain gfx_3430es1_clkdm = {
> @@ -686,6 +692,12 @@ static struct clockdomain sgx_clkdm = {
> .sleepdep_srcs = gfx_sgx_sleepdeps,
> .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
> .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
> + .clk_reg_num= 1,
> + .idle_def = {
> + [0] = {
> + .idlest_mask = OMAP3430ES2_ST_SGX_SHIFT,
> + },
> + },
> };
>
> /*
> @@ -717,6 +729,57 @@ static struct clockdomain core_l3_3xxx_clkdm = {
> .dep_bit= OMAP3430_EN_CORE_SHIFT,
> .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
> .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
> + .clk_reg_num= 3,
> + .idle_def = {
> + [0] = {
> + /* UARTs are controlled by idle loop so ignore */
> + .fclk_ignore = OMAP3430_EN_UART2 |
> + OMAP3430_EN_UART1,
> + /*
> + * Reason for IDLEST ignores:
> + * - SDRC and OMAPCTRL controlled by HW
> + * - HSOTGUSB_IDLE bit is autoidled by HW
> + * - MAILBOX is controlled by HW
> + */
> + .idlest_mask =
> + OMAP3430ES2_ST_MMC3_MASK |
> + OMAP3430_ST_ICR_MASK |
> + OMAP3430_ST_AES2_MASK |
> + OMA