Currently device off does not have any counters / timers of its own and it is impossible to track the time spent in this state. In device off, MPU / CORE powerdomains enter OSWR, so normally the OSWR state times / counts are increased during device off. This patch adds a new field to the powerdomain struct for context loss register, which is checked during pwrdm_read_prev_func_pwrst to see if a device off type context loss has happened. If this is the case, the previous functional power state entered is shown as OFF and the corresponding debug counters / timers are incremented. This patch also adds a clear for the same register in the omap4_pwrdm_clear_all_prev_pwrst function. Signed-off-by: Tero Kristo <t-kristo@xxxxxx> --- arch/arm/mach-omap2/powerdomain.c | 4 +++ arch/arm/mach-omap2/powerdomain.h | 4 +++ arch/arm/mach-omap2/powerdomain44xx.c | 39 +++++++++++++++++++++++++++ arch/arm/mach-omap2/powerdomains44xx_data.c | 2 + 4 files changed, 49 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 2043f484..ac63f86 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -884,6 +884,10 @@ int pwrdm_read_prev_func_pwrst(struct powerdomain *pwrdm) int prev_pwrst = pwrdm_read_prev_pwrst(pwrdm); int prev_logic = pwrdm_read_prev_logic_pwrst(pwrdm); + if (arch_pwrdm && arch_pwrdm->pwrdm_lost_context_rff && + arch_pwrdm->pwrdm_lost_context_rff(pwrdm)) + return PWRDM_FUNC_PWRST_OFF; + return pwrdm_pwrst_to_func(pwrdm, prev_pwrst, prev_logic); } diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index a3dc859..0729d91 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -99,6 +99,7 @@ struct powerdomain; * @name: Powerdomain name * @voltdm: voltagedomain containing this powerdomain * @prcm_offs: the address offset from CM_BASE/PRM_BASE + * @context_offs: the address offset for the CONTEXT register * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs * @pwrsts: Possible powerdomain power states * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION @@ -123,6 +124,7 @@ struct powerdomain { struct voltagedomain *ptr; } voltdm; const s16 prcm_offs; + const s16 context_offs; const u8 pwrsts; const u8 pwrsts_logic_ret; const u8 flags; @@ -171,6 +173,7 @@ struct powerdomain { * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep * @pwrdm_wait_transition: Wait for a pd state transition to complete + * @pwrdm_lost_context_rff: Check if pd has lost RFF context (entered off) */ struct pwrdm_ops { int (*pwrdm_func_to_pwrst)(struct powerdomain *pwrdm, u8 func_pwrst); @@ -195,6 +198,7 @@ struct pwrdm_ops { int (*pwrdm_disable_hdwr_sar)(struct powerdomain *pwrdm); int (*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm); int (*pwrdm_wait_transition)(struct powerdomain *pwrdm); + bool (*pwrdm_lost_context_rff)(struct powerdomain *pwrdm); }; int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs); diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c index c63d580..562f78a 100644 --- a/arch/arm/mach-omap2/powerdomain44xx.c +++ b/arch/arm/mach-omap2/powerdomain44xx.c @@ -88,6 +88,14 @@ static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) OMAP4430_LASTPOWERSTATEENTERED_MASK, pwrdm->prcm_partition, pwrdm->prcm_offs, OMAP4_PM_PWSTST); + + if (pwrdm->context_offs) + omap4_prminst_write_inst_reg(OMAP4430_LOSTCONTEXT_DFF_MASK | + OMAP4430_LOSTCONTEXT_RFF_MASK, + pwrdm->prcm_partition, + pwrdm->prcm_offs, + pwrdm->context_offs); + return 0; } @@ -320,6 +328,36 @@ static int omap4_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) return 0; } +/** + * omap4_pwrdm_lost_context_rff - check if a pwrdm has lost it rff context + * @pwrdm: struct powerdomain * to check + * + * Checks if the powerdomain has lost its RFF context or not. Basically + * this means if the device has entered off or not. Returns true if the + * context has been lost, false otherwise. + */ +bool omap4_pwrdm_lost_context_rff(struct powerdomain *pwrdm) +{ + u32 val; + s16 inst, offset; + + if (!pwrdm) + return false; + + inst = pwrdm->prcm_offs; + offset = pwrdm->context_offs; + + if (!offset) + return false; + + val = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst, offset); + + if (val & OMAP4430_LOSTCONTEXT_RFF_MASK) + return true; + + return false; +} + struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_func_to_pwrst = omap2_pwrdm_func_to_pwrst, .pwrdm_func_to_logic_pwrst = omap2_pwrdm_func_to_logic_pwrst, @@ -342,4 +380,5 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_wait_transition = omap4_pwrdm_wait_transition, .pwrdm_enable_hdwr_sar = omap4_pwrdm_enable_hdwr_sar, .pwrdm_disable_hdwr_sar = omap4_pwrdm_disable_hdwr_sar, + .pwrdm_lost_context_rff = omap4_pwrdm_lost_context_rff, }; diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c index d8701ce..c4de02f 100644 --- a/arch/arm/mach-omap2/powerdomains44xx_data.c +++ b/arch/arm/mach-omap2/powerdomains44xx_data.c @@ -36,6 +36,7 @@ static struct powerdomain core_44xx_pwrdm = { .voltdm = { .name = "core" }, .prcm_offs = OMAP4430_PRM_CORE_INST, .prcm_partition = OMAP4430_PRM_PARTITION, + .context_offs = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET, .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 5, @@ -205,6 +206,7 @@ static struct powerdomain mpu_44xx_pwrdm = { .voltdm = { .name = "mpu" }, .prcm_offs = OMAP4430_PRM_MPU_INST, .prcm_partition = OMAP4430_PRM_PARTITION, + .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET, .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 3, -- 1.7.4.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