Message ID | alpine.DEB.2.00.1207040625090.6760@utopia.booyaka.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Paul, On 07/04/2012 02:48 PM, Paul Walmsley wrote: > Hi Benoît, > > On Fri, 15 Jun 2012, Cousson, Benoit wrote: > >> My point is simple, we should not add any new custom flag when all the >> information to detect such exception are already there in the current >> data and represent accurately what the HW is doing. > > This seems like the crux of the issue. We don't have sufficient > information to detect this exception in our current data, in my view. > The software additionally must know when it can rely on a clockdomain > remaining active when the MPU is active. Yes, indeed, but that will be accurate mostly for OMAP3. On OMAP4, *in theory* the dynamic dependency should always ensure that a clock domain will be accessible upon any initiator requests. In that case the notion of a domain active when the MPU is active become a little bit less accurate. Except when we have to force the static dep because of HW bugs workaround. In that case, we are in the same situation than OMAP3. > Ideally the hardcoded clockdomain sleep dependencies would be encoded, and > we could test the intersection of those and the software-programmable > clockdomain sleep dependencies. But such a change seems too complex for > the -rc cycle. So the updated patch below uses a clockdomain data flag > for this instead. Yep, I do agree that encoding that kind of information will require more thought and much more code. I have the feeling that some information about the IP idle behavior should help figuring out that module like counter_32k, GPIO or mailbox can be handled without real SW control. This intermediate approach is thus good for the moment. > From: Paul Walmsley <paul@pwsan.com> > Date: Wed, 4 Jul 2012 05:22:53 -0600 > Subject: [PATCH] ARM: OMAP2+: hwmod code/clockdomain data: fix 32K sync timer [...] > @@ -1208,8 +1219,13 @@ static void _idle_sysc(struct omap_hwmod *oh) > sf = oh->class->sysc->sysc_flags; > > if (sf & SYSC_HAS_SIDLEMODE) { > - idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? > - HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; > + /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ What do you mean here? Regards, Benoit
Hi Benoît On Wed, 4 Jul 2012, Benoit Cousson wrote: > > From: Paul Walmsley <paul@pwsan.com> > > Date: Wed, 4 Jul 2012 05:22:53 -0600 > > Subject: [PATCH] ARM: OMAP2+: hwmod code/clockdomain data: fix 32K sync timer > > [...] > > > @@ -1208,8 +1219,13 @@ static void _idle_sysc(struct omap_hwmod *oh) > > sf = oh->class->sysc->sysc_flags; > > > > if (sf & SYSC_HAS_SIDLEMODE) { > > - idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? > > - HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; > > + /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ > > What do you mean here? We're not programming IP block target idle modes to smart idle + wakeup on OMAP4. We're only programming them to smart idle :-( - Paul
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index f7b5860..6227e95 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -31,12 +31,16 @@ * * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this * clockdomain. (Currently, this applies to OMAP3 clockdomains only.) + * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is + * active whenever the MPU is active. True for interconnects and + * the WKUP clockdomains. */ #define CLKDM_CAN_FORCE_SLEEP (1 << 0) #define CLKDM_CAN_FORCE_WAKEUP (1 << 1) #define CLKDM_CAN_ENABLE_AUTO (1 << 2) #define CLKDM_CAN_DISABLE_AUTO (1 << 3) #define CLKDM_NO_AUTODEPS (1 << 4) +#define CLKDM_ACTIVE_WITH_MPU (1 << 5) #define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) #define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c index 839145e..4972219 100644 --- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c @@ -88,4 +88,5 @@ struct clockdomain wkup_common_clkdm = { .name = "wkup_clkdm", .pwrdm = { .name = "wkup_pwrdm" }, .dep_bit = OMAP_EN_WKUP_SHIFT, + .flags = CLKDM_ACTIVE_WITH_MPU, }; diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index c534258..6e93d49 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -1,7 +1,7 @@ /* * OMAP4 Clock domains framework * - * Copyright (C) 2009-2011 Texas Instruments, Inc. + * Copyright (C) 2009-2012 Texas Instruments, Inc. * Copyright (C) 2009-2011 Nokia Corporation * * Abhijit Pagare (abhijitpagare@ti.com) @@ -381,7 +381,7 @@ static struct clockdomain l4_wkup_44xx_clkdm = { .cm_inst = OMAP4430_PRM_WKUP_CM_INST, .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS, .dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT, - .flags = CLKDM_CAN_HWSUP, + .flags = CLKDM_CAN_HWSUP | CLKDM_ACTIVE_WITH_MPU, }; static struct clockdomain emu_sys_44xx_clkdm = { diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 7731936..f749546 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1124,15 +1124,18 @@ static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * - * If module is marked as SWSUP_SIDLE, force the module out of slave - * idle; otherwise, configure it for smart-idle. If module is marked - * as SWSUP_MSUSPEND, force the module out of master standby; - * otherwise, configure it for smart-standby. No return value. + * Ensure that the OCP_SYSCONFIG register for the IP block represented + * by @oh is set to indicate to the PRCM that the IP block is active. + * Usually this means placing the module into smart-idle mode and + * smart-standby, but if there is a bug in the automatic idle handling + * for the IP block, it may need to be placed into the force-idle or + * no-idle variants of these modes. No return value. */ static void _enable_sysc(struct omap_hwmod *oh) { u8 idlemode, sf; u32 v; + bool clkdm_act; if (!oh->class->sysc) return; @@ -1141,8 +1144,16 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags; if (sf & SYSC_HAS_SIDLEMODE) { - idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? - HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; + clkdm_act = ((oh->clkdm && + oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) || + (oh->_clk->clkdm && + oh->_clk->clkdm->flags & CLKDM_ACTIVE_WITH_MPU)); + if (clkdm_act && !(oh->class->sysc->idlemodes & + (SIDLE_SMART | SIDLE_SMART_WKUP))) + idlemode = HWMOD_IDLEMODE_FORCE; + else + idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? + HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; _set_slave_idlemode(oh, idlemode, &v); } @@ -1208,8 +1219,13 @@ static void _idle_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags; if (sf & SYSC_HAS_SIDLEMODE) { - idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? - HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; + /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ + if (oh->flags & HWMOD_SWSUP_SIDLE || + !(oh->class->sysc->idlemodes & + (SIDLE_SMART | SIDLE_SMART_WKUP))) + idlemode = HWMOD_IDLEMODE_FORCE; + else + idlemode = HWMOD_IDLEMODE_SMART; _set_slave_idlemode(oh, idlemode, &v); }