* [PATCHv5 0/8] ARM: OMAP4: core retention support @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel Hi, Changes compared to previous version: - Patch 6 now adds support for reading prev logic and mem states instead of tweaking the _update_logic_membank_counters function directly. - Some version of "[PATCH] OMAP2+: UART: Add mechanism to probe uart pins and configure rx wakeup" from Govindraj is needed, otherwise UART can't wake up the device from suspend. Tested with omap4460 GP panda + omap4430 EMU blaze devices. Patches also available here: tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git branch: mainline-3.4-omap4-ret-v5 -Tero ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 0/8] ARM: OMAP4: core retention support @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel Hi, Changes compared to previous version: - Patch 6 now adds support for reading prev logic and mem states instead of tweaking the _update_logic_membank_counters function directly. - Some version of "[PATCH] OMAP2+: UART: Add mechanism to probe uart pins and configure rx wakeup" from Govindraj is needed, otherwise UART can't wake up the device from suspend. Tested with omap4460 GP panda + omap4430 EMU blaze devices. Patches also available here: tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git branch: mainline-3.4-omap4-ret-v5 -Tero ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 1/8] ARM: OMAP4: suspend: Program all domains to retention 2012-05-14 10:03 ` Tero Kristo @ 2012-05-14 10:03 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> Remove the FIXME's in the suspend sequence since we now intend to support system level RET support. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Tero Kristo <t-kristo@ti.com> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> --- arch/arm/mach-omap2/pm44xx.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 8856253..31990d5 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -101,12 +101,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) if (!strncmp(pwrdm->name, "cpu", 3)) return 0; - /* - * FIXME: Remove this check when core retention is supported - * Only MPUSS power domain is added in the list. - */ - if (strcmp(pwrdm->name, "mpu_pwrdm")) - return 0; pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); if (!pwrst) -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 1/8] ARM: OMAP4: suspend: Program all domains to retention @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel From: Rajendra Nayak <rnayak@ti.com> Remove the FIXME's in the suspend sequence since we now intend to support system level RET support. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Tero Kristo <t-kristo@ti.com> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> --- arch/arm/mach-omap2/pm44xx.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 8856253..31990d5 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -101,12 +101,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) if (!strncmp(pwrdm->name, "cpu", 3)) return 0; - /* - * FIXME: Remove this check when core retention is supported - * Only MPUSS power domain is added in the list. - */ - if (strcmp(pwrdm->name, "mpu_pwrdm")) - return 0; pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); if (!pwrst) -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCHv5 1/8] ARM: OMAP4: suspend: Program all domains to retention 2012-05-14 10:03 ` Tero Kristo @ 2012-05-15 19:52 ` Kevin Hilman -1 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-15 19:52 UTC (permalink / raw) To: Tero Kristo; +Cc: linux-omap, paul, linux-arm-kernel, Rajendra Nayak Tero Kristo <t-kristo@ti.com> writes: > From: Rajendra Nayak <rnayak@ti.com> > > Remove the FIXME's in the suspend sequence since > we now intend to support system level RET support. minor: this should probably go at the end of the series, after retention is supported. Otherwise, ending up with only this patch applied (e.g. during a git bisect) will lead to a broken boot I suspect. Kevin > Signed-off-by: Rajendra Nayak <rnayak@ti.com> > Signed-off-by: Tero Kristo <t-kristo@ti.com> > Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> > --- > arch/arm/mach-omap2/pm44xx.c | 6 ------ > 1 files changed, 0 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > index 8856253..31990d5 100644 > --- a/arch/arm/mach-omap2/pm44xx.c > +++ b/arch/arm/mach-omap2/pm44xx.c > @@ -101,12 +101,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) > if (!strncmp(pwrdm->name, "cpu", 3)) > return 0; > > - /* > - * FIXME: Remove this check when core retention is supported > - * Only MPUSS power domain is added in the list. > - */ > - if (strcmp(pwrdm->name, "mpu_pwrdm")) > - return 0; > > pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); > if (!pwrst) ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 1/8] ARM: OMAP4: suspend: Program all domains to retention @ 2012-05-15 19:52 ` Kevin Hilman 0 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-15 19:52 UTC (permalink / raw) To: linux-arm-kernel Tero Kristo <t-kristo@ti.com> writes: > From: Rajendra Nayak <rnayak@ti.com> > > Remove the FIXME's in the suspend sequence since > we now intend to support system level RET support. minor: this should probably go at the end of the series, after retention is supported. Otherwise, ending up with only this patch applied (e.g. during a git bisect) will lead to a broken boot I suspect. Kevin > Signed-off-by: Rajendra Nayak <rnayak@ti.com> > Signed-off-by: Tero Kristo <t-kristo@ti.com> > Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> > --- > arch/arm/mach-omap2/pm44xx.c | 6 ------ > 1 files changed, 0 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > index 8856253..31990d5 100644 > --- a/arch/arm/mach-omap2/pm44xx.c > +++ b/arch/arm/mach-omap2/pm44xx.c > @@ -101,12 +101,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) > if (!strncmp(pwrdm->name, "cpu", 3)) > return 0; > > - /* > - * FIXME: Remove this check when core retention is supported > - * Only MPUSS power domain is added in the list. > - */ > - if (strcmp(pwrdm->name, "mpu_pwrdm")) > - return 0; > > pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); > if (!pwrst) ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 1/8] ARM: OMAP4: suspend: Program all domains to retention 2012-05-15 19:52 ` Kevin Hilman @ 2012-05-16 8:37 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-16 8:37 UTC (permalink / raw) To: Kevin Hilman; +Cc: paul, linux-omap, linux-arm-kernel, Rajendra Nayak On Tue, 2012-05-15 at 12:52 -0700, Kevin Hilman wrote: > Tero Kristo <t-kristo@ti.com> writes: > > > From: Rajendra Nayak <rnayak@ti.com> > > > > Remove the FIXME's in the suspend sequence since > > we now intend to support system level RET support. > > minor: this should probably go at the end of the series, after retention > is supported. Otherwise, ending up with only this patch applied > (e.g. during a git bisect) will lead to a broken boot I suspect. Ok, will move this to the end. -Tero > > Kevin > > > Signed-off-by: Rajendra Nayak <rnayak@ti.com> > > Signed-off-by: Tero Kristo <t-kristo@ti.com> > > Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> > > --- > > arch/arm/mach-omap2/pm44xx.c | 6 ------ > > 1 files changed, 0 insertions(+), 6 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > > index 8856253..31990d5 100644 > > --- a/arch/arm/mach-omap2/pm44xx.c > > +++ b/arch/arm/mach-omap2/pm44xx.c > > @@ -101,12 +101,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) > > if (!strncmp(pwrdm->name, "cpu", 3)) > > return 0; > > > > - /* > > - * FIXME: Remove this check when core retention is supported > > - * Only MPUSS power domain is added in the list. > > - */ > > - if (strcmp(pwrdm->name, "mpu_pwrdm")) > > - return 0; > > > > pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); > > if (!pwrst) ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 1/8] ARM: OMAP4: suspend: Program all domains to retention @ 2012-05-16 8:37 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-16 8:37 UTC (permalink / raw) To: linux-arm-kernel On Tue, 2012-05-15 at 12:52 -0700, Kevin Hilman wrote: > Tero Kristo <t-kristo@ti.com> writes: > > > From: Rajendra Nayak <rnayak@ti.com> > > > > Remove the FIXME's in the suspend sequence since > > we now intend to support system level RET support. > > minor: this should probably go at the end of the series, after retention > is supported. Otherwise, ending up with only this patch applied > (e.g. during a git bisect) will lead to a broken boot I suspect. Ok, will move this to the end. -Tero > > Kevin > > > Signed-off-by: Rajendra Nayak <rnayak@ti.com> > > Signed-off-by: Tero Kristo <t-kristo@ti.com> > > Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> > > --- > > arch/arm/mach-omap2/pm44xx.c | 6 ------ > > 1 files changed, 0 insertions(+), 6 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > > index 8856253..31990d5 100644 > > --- a/arch/arm/mach-omap2/pm44xx.c > > +++ b/arch/arm/mach-omap2/pm44xx.c > > @@ -101,12 +101,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) > > if (!strncmp(pwrdm->name, "cpu", 3)) > > return 0; > > > > - /* > > - * FIXME: Remove this check when core retention is supported > > - * Only MPUSS power domain is added in the list. > > - */ > > - if (strcmp(pwrdm->name, "mpu_pwrdm")) > > - return 0; > > > > pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); > > if (!pwrst) ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 2/8] TEMP: ARM: OMAP4: hwmod_data: Do not get DSP out of reset at boot time 2012-05-14 10:03 ` Tero Kristo @ 2012-05-14 10:03 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> With no driver handling DSP, if brought out of reset, it stays active and does not assert standby. This leads to IVAHD powerdomain not transitioning and hence preventing chip retention. This patch is no longer needed once Paul's powerdomain fixes are merged: http://marc.info/?l=linux-omap&m=133040749621183&w=2 Just provided for testing purposes. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 6abc757..fd305bc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1160,6 +1160,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = { .name = "dsp", .class = &omap44xx_dsp_hwmod_class, .clkdm_name = "tesla_clkdm", + .flags = HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_dsp_irqs, .rst_lines = omap44xx_dsp_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets), -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 2/8] TEMP: ARM: OMAP4: hwmod_data: Do not get DSP out of reset at boot time @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel From: Rajendra Nayak <rnayak@ti.com> With no driver handling DSP, if brought out of reset, it stays active and does not assert standby. This leads to IVAHD powerdomain not transitioning and hence preventing chip retention. This patch is no longer needed once Paul's powerdomain fixes are merged: http://marc.info/?l=linux-omap&m=133040749621183&w=2 Just provided for testing purposes. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 6abc757..fd305bc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1160,6 +1160,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = { .name = "dsp", .class = &omap44xx_dsp_hwmod_class, .clkdm_name = "tesla_clkdm", + .flags = HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_dsp_irqs, .rst_lines = omap44xx_dsp_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets), -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-14 10:03 ` Tero Kristo @ 2012-05-14 10:03 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Santosh Shilimkar From: Santosh Shilimkar <santosh.shilimkar@ti.com> GIC distributor control register has changed between CortexA9 r1pX and r2pX. The Control Register secure banked version is now composed of 2 bits: bit 0 == Secure Enable bit 1 == Non-Secure Enable The Non-Secure banked register has not changed. Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration will cause a problem to CPU0 Non-Secure SW. The workaround must be: 1) Before doing the CPU1 wakeup, CPU0 must disable the GIC distributor 2) CPU1 must re-enable the GIC distributor on it's wakeup path. With this procedure, the GIC configuration done between the CPU0 wakeup and CPU1 wakeup will not be lost but during this short windows, the CPU0 will not receive interrupts Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/common.h | 2 + arch/arm/mach-omap2/omap-headsmp.S | 36 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 ++++++- arch/arm/mach-omap2/omap-smp.c | 28 +++++++++++++++++++++- arch/arm/mach-omap2/omap4-common.c | 8 +++++- 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 57da7f4..48d1ebe 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -199,6 +199,7 @@ static inline void __iomem *omap4_get_scu_base(void) #endif extern void __init gic_init_irq(void); +extern void gic_dist_disable(void); extern void omap_smc1(u32 fn, u32 arg); extern void __iomem *omap4_get_sar_ram_base(void); extern void omap_do_wfi(void); @@ -206,6 +207,7 @@ extern void omap_do_wfi(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ extern void omap_secondary_startup(void); +extern void omap_secondary_startup_4460(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 503ac77..d602555 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -43,3 +43,39 @@ hold: ldr r12,=0x103 b secondary_startup ENDPROC(omap_secondary_startup) +ENTRY(omap_secondary_startup_4460) +hold_2: ldr r12,=0x103 + dsb + smc #0 @ read from AuxCoreBoot0 + mov r0, r0, lsr #9 + mrc p15, 0, r4, c0, c0, 5 + and r4, r4, #0x0f + cmp r0, r4 + bne hold_2 + + /* + * GIC distributor control register has changed between + * CortexA9 r1pX and r2pX. The Control Register secure + * banked version is now composed of 2 bits: + * bit 0 == Secure Enable + * bit 1 == Non-Secure Enable + * The Non-Secure banked register has not changed + * Because the ROM Code is based on the r1pX GIC, the CPU1 + * GIC restoration will cause a problem to CPU0 Non-Secure SW. + * The workaround must be: + * 1) Before doing the CPU1 wakeup, CPU0 must disable + * the GIC distributor + * 2) CPU1 must re-enable the GIC distributor on + * it's wakeup path. + */ + ldr r1, =0x48241000 + ldr r0, [r1] + orr r0, #1 + str r0, [r1] + + /* + * we've been released from the wait loop,secondary_stack + * should now contain the SVC stack for this core + */ + b secondary_startup +ENDPROC(omap_secondary_startup_4460) diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 13670aa..e02c082 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info { void __iomem *scu_sar_addr; void __iomem *wkup_sar_addr; void __iomem *l2x0_sar_addr; + void (*secondary_startup)(void); }; static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) { unsigned int cpu_state = 0; + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); if (omap_rev() == OMAP4430_REV_ES1_0) return -ENXIO; @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) clear_cpu_prev_pwrst(cpu); set_cpu_next_pwrst(cpu, power_state); - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); scu_pwrst_prepare(cpu, power_state); /* @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void) pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; + if (cpu_is_omap446x()) + pm_info->secondary_startup = omap_secondary_startup_4460; + else + pm_info->secondary_startup = omap_secondary_startup; + pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { pr_err("Lookup failed for CPU1 pwrdm\n"); diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index deffbf1..c3eb9e8 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -33,6 +33,7 @@ /* SCU base address */ static void __iomem *scu_base; +bool omap4_smp_romcode_errata; static DEFINE_SPINLOCK(boot_lock); @@ -104,6 +105,24 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * 4.3.4.2 Power States of CPU0 and CPU1 */ if (booted) { + /* + * GIC distributor control register has changed between + * CortexA9 r1pX and r2pX. The Control Register secure + * banked version is now composed of 2 bits: + * bit 0 == Secure Enable + * bit 1 == Non-Secure Enable + * The Non-Secure banked register has not changed + * Because the ROM Code is based on the r1pX GIC, the CPU1 + * GIC restoration will cause a problem to CPU0 Non-Secure SW. + * The workaround must be: + * 1) Before doing the CPU1 wakeup, CPU0 must disable + * the GIC distributor + * 2) CPU1 must re-enable the GIC distributor on + * it's wakeup path. + */ + if (omap4_smp_romcode_errata) + gic_dist_disable(); + clkdm_wakeup(cpu1_clkdm); clkdm_allow_idle(cpu1_clkdm); } else { @@ -124,13 +143,20 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init wakeup_secondary(void) { + void *startup_addr = omap_secondary_startup; + /* * Write the address of secondary startup routine into the * AuxCoreBoot1 where ROM code will jump and start executing * on secondary core once out of WFE * A barrier is added to ensure that write buffer is drained */ - omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); + if (cpu_is_omap446x()) { + startup_addr = omap_secondary_startup_4460; + omap4_smp_romcode_errata = true; + } + + omap_auxcoreboot_addr(virt_to_phys(startup_addr)); smp_wmb(); /* diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 70de277..cc6a915 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -38,6 +38,7 @@ static void __iomem *l2cache_base; #endif static void __iomem *sar_ram_base; +static void __iomem *gic_dist_base_addr; #ifdef CONFIG_OMAP4_ERRATA_I688 /* Used to implement memory barrier on DRAM path */ @@ -92,7 +93,6 @@ void __init omap_barriers_init(void) void __init gic_init_irq(void) { void __iomem *omap_irq_base; - void __iomem *gic_dist_base_addr; /* Static mapping, never released */ gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); @@ -107,6 +107,12 @@ void __init gic_init_irq(void) gic_init(0, 29, gic_dist_base_addr, omap_irq_base); } +void gic_dist_disable(void) +{ + if (gic_dist_base_addr) + __raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL); +} + #ifdef CONFIG_CACHE_L2X0 void __iomem *omap4_get_l2cache_base(void) -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel From: Santosh Shilimkar <santosh.shilimkar@ti.com> GIC distributor control register has changed between CortexA9 r1pX and r2pX. The Control Register secure banked version is now composed of 2 bits: bit 0 == Secure Enable bit 1 == Non-Secure Enable The Non-Secure banked register has not changed. Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration will cause a problem to CPU0 Non-Secure SW. The workaround must be: 1) Before doing the CPU1 wakeup, CPU0 must disable the GIC distributor 2) CPU1 must re-enable the GIC distributor on it's wakeup path. With this procedure, the GIC configuration done between the CPU0 wakeup and CPU1 wakeup will not be lost but during this short windows, the CPU0 will not receive interrupts Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/common.h | 2 + arch/arm/mach-omap2/omap-headsmp.S | 36 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 ++++++- arch/arm/mach-omap2/omap-smp.c | 28 +++++++++++++++++++++- arch/arm/mach-omap2/omap4-common.c | 8 +++++- 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 57da7f4..48d1ebe 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -199,6 +199,7 @@ static inline void __iomem *omap4_get_scu_base(void) #endif extern void __init gic_init_irq(void); +extern void gic_dist_disable(void); extern void omap_smc1(u32 fn, u32 arg); extern void __iomem *omap4_get_sar_ram_base(void); extern void omap_do_wfi(void); @@ -206,6 +207,7 @@ extern void omap_do_wfi(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ extern void omap_secondary_startup(void); +extern void omap_secondary_startup_4460(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 503ac77..d602555 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -43,3 +43,39 @@ hold: ldr r12,=0x103 b secondary_startup ENDPROC(omap_secondary_startup) +ENTRY(omap_secondary_startup_4460) +hold_2: ldr r12,=0x103 + dsb + smc #0 @ read from AuxCoreBoot0 + mov r0, r0, lsr #9 + mrc p15, 0, r4, c0, c0, 5 + and r4, r4, #0x0f + cmp r0, r4 + bne hold_2 + + /* + * GIC distributor control register has changed between + * CortexA9 r1pX and r2pX. The Control Register secure + * banked version is now composed of 2 bits: + * bit 0 == Secure Enable + * bit 1 == Non-Secure Enable + * The Non-Secure banked register has not changed + * Because the ROM Code is based on the r1pX GIC, the CPU1 + * GIC restoration will cause a problem to CPU0 Non-Secure SW. + * The workaround must be: + * 1) Before doing the CPU1 wakeup, CPU0 must disable + * the GIC distributor + * 2) CPU1 must re-enable the GIC distributor on + * it's wakeup path. + */ + ldr r1, =0x48241000 + ldr r0, [r1] + orr r0, #1 + str r0, [r1] + + /* + * we've been released from the wait loop,secondary_stack + * should now contain the SVC stack for this core + */ + b secondary_startup +ENDPROC(omap_secondary_startup_4460) diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 13670aa..e02c082 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info { void __iomem *scu_sar_addr; void __iomem *wkup_sar_addr; void __iomem *l2x0_sar_addr; + void (*secondary_startup)(void); }; static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) { unsigned int cpu_state = 0; + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); if (omap_rev() == OMAP4430_REV_ES1_0) return -ENXIO; @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) clear_cpu_prev_pwrst(cpu); set_cpu_next_pwrst(cpu, power_state); - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); scu_pwrst_prepare(cpu, power_state); /* @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void) pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; + if (cpu_is_omap446x()) + pm_info->secondary_startup = omap_secondary_startup_4460; + else + pm_info->secondary_startup = omap_secondary_startup; + pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { pr_err("Lookup failed for CPU1 pwrdm\n"); diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index deffbf1..c3eb9e8 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -33,6 +33,7 @@ /* SCU base address */ static void __iomem *scu_base; +bool omap4_smp_romcode_errata; static DEFINE_SPINLOCK(boot_lock); @@ -104,6 +105,24 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * 4.3.4.2 Power States of CPU0 and CPU1 */ if (booted) { + /* + * GIC distributor control register has changed between + * CortexA9 r1pX and r2pX. The Control Register secure + * banked version is now composed of 2 bits: + * bit 0 == Secure Enable + * bit 1 == Non-Secure Enable + * The Non-Secure banked register has not changed + * Because the ROM Code is based on the r1pX GIC, the CPU1 + * GIC restoration will cause a problem to CPU0 Non-Secure SW. + * The workaround must be: + * 1) Before doing the CPU1 wakeup, CPU0 must disable + * the GIC distributor + * 2) CPU1 must re-enable the GIC distributor on + * it's wakeup path. + */ + if (omap4_smp_romcode_errata) + gic_dist_disable(); + clkdm_wakeup(cpu1_clkdm); clkdm_allow_idle(cpu1_clkdm); } else { @@ -124,13 +143,20 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init wakeup_secondary(void) { + void *startup_addr = omap_secondary_startup; + /* * Write the address of secondary startup routine into the * AuxCoreBoot1 where ROM code will jump and start executing * on secondary core once out of WFE * A barrier is added to ensure that write buffer is drained */ - omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); + if (cpu_is_omap446x()) { + startup_addr = omap_secondary_startup_4460; + omap4_smp_romcode_errata = true; + } + + omap_auxcoreboot_addr(virt_to_phys(startup_addr)); smp_wmb(); /* diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 70de277..cc6a915 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -38,6 +38,7 @@ static void __iomem *l2cache_base; #endif static void __iomem *sar_ram_base; +static void __iomem *gic_dist_base_addr; #ifdef CONFIG_OMAP4_ERRATA_I688 /* Used to implement memory barrier on DRAM path */ @@ -92,7 +93,6 @@ void __init omap_barriers_init(void) void __init gic_init_irq(void) { void __iomem *omap_irq_base; - void __iomem *gic_dist_base_addr; /* Static mapping, never released */ gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); @@ -107,6 +107,12 @@ void __init gic_init_irq(void) gic_init(0, 29, gic_dist_base_addr, omap_irq_base); } +void gic_dist_disable(void) +{ + if (gic_dist_base_addr) + __raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL); +} + #ifdef CONFIG_CACHE_L2X0 void __iomem *omap4_get_l2cache_base(void) -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-14 10:03 ` Tero Kristo @ 2012-05-15 21:44 ` Kevin Hilman -1 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-15 21:44 UTC (permalink / raw) To: Tero Kristo, Santosh Shilimkar; +Cc: paul, linux-omap, linux-arm-kernel Santosh, Tero Kristo <t-kristo@ti.com> writes: > From: Santosh Shilimkar <santosh.shilimkar@ti.com> > > GIC distributor control register has changed between CortexA9 r1pX and > r2pX. The Control Register secure banked version is now composed of 2 > bits: > bit 0 == Secure Enable > bit 1 == Non-Secure Enable > The Non-Secure banked register has not changed. For those without the r1pX TRM handy, please include what this look like before (presumably 1 bit?) The changelog and in-code comments should both be enhanced. > Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration > will cause a problem to CPU0 Non-Secure SW. Please describe the problem, so we can better understand the specifics of the workaround. Also, is there an erratum number for this? > The workaround must be: > 1) Before doing the CPU1 wakeup, CPU0 must disable > the GIC distributor > 2) CPU1 must re-enable the GIC distributor on > it's wakeup path. Again, because the problem was not described, I am not entirely sure why the workaround "must" be this, and how it fixes the problem. Remember to put yourself in the shoes of a reviewer who has not been deeply involved in the code, so what seems obvious to you will not be obvious to the reviewer without having to study the code and dig in to the TRMs. > With this procedure, the GIC configuration done between the > CPU0 wakeup and CPU1 wakeup will not be lost but during this > short windows, the CPU0 will not receive interrupts Hmm, so I guess this means that CPU0 always has to wakeup first, even on GP devices? Also, the changelog doesn't describe what power states this affects, and whether it's an idle problem or just a supend problem. A quick glance at the code suggests that only suspend is being addressed by this patch. However, with the addition of coupled CPUidle (coming very soon now), won't we have this same problem in idle? IMO, this patch should address both. This workaround also assumes that you always want CPU1 to wakeup immediately after CPU0. I guess that will be the case for the coupled states that would be affected by this bug, but the changelog should describe that as well Some minor comments below... > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> > Signed-off-by: Tero Kristo <t-kristo@ti.com> > --- > arch/arm/mach-omap2/common.h | 2 + > arch/arm/mach-omap2/omap-headsmp.S | 36 +++++++++++++++++++++++++++++ > arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 ++++++- > arch/arm/mach-omap2/omap-smp.c | 28 +++++++++++++++++++++- > arch/arm/mach-omap2/omap4-common.c | 8 +++++- > 5 files changed, 80 insertions(+), 3 deletions(-) > > diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h > index 57da7f4..48d1ebe 100644 > --- a/arch/arm/mach-omap2/common.h > +++ b/arch/arm/mach-omap2/common.h > @@ -199,6 +199,7 @@ static inline void __iomem *omap4_get_scu_base(void) > #endif > > extern void __init gic_init_irq(void); > +extern void gic_dist_disable(void); > extern void omap_smc1(u32 fn, u32 arg); > extern void __iomem *omap4_get_sar_ram_base(void); > extern void omap_do_wfi(void); > @@ -206,6 +207,7 @@ extern void omap_do_wfi(void); > #ifdef CONFIG_SMP > /* Needed for secondary core boot */ > extern void omap_secondary_startup(void); > +extern void omap_secondary_startup_4460(void); > extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); > extern void omap_auxcoreboot_addr(u32 cpu_addr); > extern u32 omap_read_auxcoreboot0(void); > diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S > index 503ac77..d602555 100644 > --- a/arch/arm/mach-omap2/omap-headsmp.S > +++ b/arch/arm/mach-omap2/omap-headsmp.S > @@ -43,3 +43,39 @@ hold: ldr r12,=0x103 > b secondary_startup > ENDPROC(omap_secondary_startup) > > +ENTRY(omap_secondary_startup_4460) > +hold_2: ldr r12,=0x103 > + dsb > + smc #0 @ read from AuxCoreBoot0 > + mov r0, r0, lsr #9 > + mrc p15, 0, r4, c0, c0, 5 > + and r4, r4, #0x0f > + cmp r0, r4 > + bne hold_2 > + > + /* > + * GIC distributor control register has changed between > + * CortexA9 r1pX and r2pX. The Control Register secure > + * banked version is now composed of 2 bits: > + * bit 0 == Secure Enable > + * bit 1 == Non-Secure Enable > + * The Non-Secure banked register has not changed > + * Because the ROM Code is based on the r1pX GIC, the CPU1 > + * GIC restoration will cause a problem to CPU0 Non-Secure SW. > + * The workaround must be: > + * 1) Before doing the CPU1 wakeup, CPU0 must disable > + * the GIC distributor > + * 2) CPU1 must re-enable the GIC distributor on > + * it's wakeup path. > + */ > + ldr r1, =0x48241000 Why not OMAP44XX_GIC_DIST_BASE for readability sake? > + ldr r0, [r1] > + orr r0, #1 > + str r0, [r1] > + > + /* > + * we've been released from the wait loop,secondary_stack > + * should now contain the SVC stack for this core > + */ > + b secondary_startup > +ENDPROC(omap_secondary_startup_4460) > diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c > index 13670aa..e02c082 100644 > --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c > +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c > @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info { > void __iomem *scu_sar_addr; > void __iomem *wkup_sar_addr; > void __iomem *l2x0_sar_addr; > + void (*secondary_startup)(void); > }; > > static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); > @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) > int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) > { > unsigned int cpu_state = 0; > + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); > > if (omap_rev() == OMAP4430_REV_ES1_0) > return -ENXIO; > @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) > > clear_cpu_prev_pwrst(cpu); > set_cpu_next_pwrst(cpu, power_state); > - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); > + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); > scu_pwrst_prepare(cpu, power_state); > > /* > @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void) > pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; > pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; > pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; > + if (cpu_is_omap446x()) > + pm_info->secondary_startup = omap_secondary_startup_4460; > + else > + pm_info->secondary_startup = omap_secondary_startup; Does this exist on 4470 too? Using a PM erratum check here instead of cpu_is* would make this more scalable. Same comment for the cpu_is* check in wakeup_secondary() Then, where the erratum is defined, it should state clearly why this affects 446x and not before (presumably because 4430 has r1pX and 4460 has r2pX.) > pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); > if (!pm_info->pwrdm) { > pr_err("Lookup failed for CPU1 pwrdm\n"); > diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c > index deffbf1..c3eb9e8 100644 > --- a/arch/arm/mach-omap2/omap-smp.c > +++ b/arch/arm/mach-omap2/omap-smp.c > @@ -33,6 +33,7 @@ > > /* SCU base address */ > static void __iomem *scu_base; > +bool omap4_smp_romcode_errata; static? Kevin ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-15 21:44 ` Kevin Hilman 0 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-15 21:44 UTC (permalink / raw) To: linux-arm-kernel Santosh, Tero Kristo <t-kristo@ti.com> writes: > From: Santosh Shilimkar <santosh.shilimkar@ti.com> > > GIC distributor control register has changed between CortexA9 r1pX and > r2pX. The Control Register secure banked version is now composed of 2 > bits: > bit 0 == Secure Enable > bit 1 == Non-Secure Enable > The Non-Secure banked register has not changed. For those without the r1pX TRM handy, please include what this look like before (presumably 1 bit?) The changelog and in-code comments should both be enhanced. > Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration > will cause a problem to CPU0 Non-Secure SW. Please describe the problem, so we can better understand the specifics of the workaround. Also, is there an erratum number for this? > The workaround must be: > 1) Before doing the CPU1 wakeup, CPU0 must disable > the GIC distributor > 2) CPU1 must re-enable the GIC distributor on > it's wakeup path. Again, because the problem was not described, I am not entirely sure why the workaround "must" be this, and how it fixes the problem. Remember to put yourself in the shoes of a reviewer who has not been deeply involved in the code, so what seems obvious to you will not be obvious to the reviewer without having to study the code and dig in to the TRMs. > With this procedure, the GIC configuration done between the > CPU0 wakeup and CPU1 wakeup will not be lost but during this > short windows, the CPU0 will not receive interrupts Hmm, so I guess this means that CPU0 always has to wakeup first, even on GP devices? Also, the changelog doesn't describe what power states this affects, and whether it's an idle problem or just a supend problem. A quick glance at the code suggests that only suspend is being addressed by this patch. However, with the addition of coupled CPUidle (coming very soon now), won't we have this same problem in idle? IMO, this patch should address both. This workaround also assumes that you always want CPU1 to wakeup immediately after CPU0. I guess that will be the case for the coupled states that would be affected by this bug, but the changelog should describe that as well Some minor comments below... > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> > Signed-off-by: Tero Kristo <t-kristo@ti.com> > --- > arch/arm/mach-omap2/common.h | 2 + > arch/arm/mach-omap2/omap-headsmp.S | 36 +++++++++++++++++++++++++++++ > arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 ++++++- > arch/arm/mach-omap2/omap-smp.c | 28 +++++++++++++++++++++- > arch/arm/mach-omap2/omap4-common.c | 8 +++++- > 5 files changed, 80 insertions(+), 3 deletions(-) > > diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h > index 57da7f4..48d1ebe 100644 > --- a/arch/arm/mach-omap2/common.h > +++ b/arch/arm/mach-omap2/common.h > @@ -199,6 +199,7 @@ static inline void __iomem *omap4_get_scu_base(void) > #endif > > extern void __init gic_init_irq(void); > +extern void gic_dist_disable(void); > extern void omap_smc1(u32 fn, u32 arg); > extern void __iomem *omap4_get_sar_ram_base(void); > extern void omap_do_wfi(void); > @@ -206,6 +207,7 @@ extern void omap_do_wfi(void); > #ifdef CONFIG_SMP > /* Needed for secondary core boot */ > extern void omap_secondary_startup(void); > +extern void omap_secondary_startup_4460(void); > extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); > extern void omap_auxcoreboot_addr(u32 cpu_addr); > extern u32 omap_read_auxcoreboot0(void); > diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S > index 503ac77..d602555 100644 > --- a/arch/arm/mach-omap2/omap-headsmp.S > +++ b/arch/arm/mach-omap2/omap-headsmp.S > @@ -43,3 +43,39 @@ hold: ldr r12,=0x103 > b secondary_startup > ENDPROC(omap_secondary_startup) > > +ENTRY(omap_secondary_startup_4460) > +hold_2: ldr r12,=0x103 > + dsb > + smc #0 @ read from AuxCoreBoot0 > + mov r0, r0, lsr #9 > + mrc p15, 0, r4, c0, c0, 5 > + and r4, r4, #0x0f > + cmp r0, r4 > + bne hold_2 > + > + /* > + * GIC distributor control register has changed between > + * CortexA9 r1pX and r2pX. The Control Register secure > + * banked version is now composed of 2 bits: > + * bit 0 == Secure Enable > + * bit 1 == Non-Secure Enable > + * The Non-Secure banked register has not changed > + * Because the ROM Code is based on the r1pX GIC, the CPU1 > + * GIC restoration will cause a problem to CPU0 Non-Secure SW. > + * The workaround must be: > + * 1) Before doing the CPU1 wakeup, CPU0 must disable > + * the GIC distributor > + * 2) CPU1 must re-enable the GIC distributor on > + * it's wakeup path. > + */ > + ldr r1, =0x48241000 Why not OMAP44XX_GIC_DIST_BASE for readability sake? > + ldr r0, [r1] > + orr r0, #1 > + str r0, [r1] > + > + /* > + * we've been released from the wait loop,secondary_stack > + * should now contain the SVC stack for this core > + */ > + b secondary_startup > +ENDPROC(omap_secondary_startup_4460) > diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c > index 13670aa..e02c082 100644 > --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c > +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c > @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info { > void __iomem *scu_sar_addr; > void __iomem *wkup_sar_addr; > void __iomem *l2x0_sar_addr; > + void (*secondary_startup)(void); > }; > > static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); > @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) > int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) > { > unsigned int cpu_state = 0; > + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); > > if (omap_rev() == OMAP4430_REV_ES1_0) > return -ENXIO; > @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) > > clear_cpu_prev_pwrst(cpu); > set_cpu_next_pwrst(cpu, power_state); > - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); > + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); > scu_pwrst_prepare(cpu, power_state); > > /* > @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void) > pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; > pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; > pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; > + if (cpu_is_omap446x()) > + pm_info->secondary_startup = omap_secondary_startup_4460; > + else > + pm_info->secondary_startup = omap_secondary_startup; Does this exist on 4470 too? Using a PM erratum check here instead of cpu_is* would make this more scalable. Same comment for the cpu_is* check in wakeup_secondary() Then, where the erratum is defined, it should state clearly why this affects 446x and not before (presumably because 4430 has r1pX and 4460 has r2pX.) > pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); > if (!pm_info->pwrdm) { > pr_err("Lookup failed for CPU1 pwrdm\n"); > diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c > index deffbf1..c3eb9e8 100644 > --- a/arch/arm/mach-omap2/omap-smp.c > +++ b/arch/arm/mach-omap2/omap-smp.c > @@ -33,6 +33,7 @@ > > /* SCU base address */ > static void __iomem *scu_base; > +bool omap4_smp_romcode_errata; static? Kevin ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-15 21:44 ` Kevin Hilman @ 2012-05-16 8:54 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-16 8:54 UTC (permalink / raw) To: Kevin Hilman; +Cc: Santosh Shilimkar, linux-omap, paul, linux-arm-kernel On Tue, 2012-05-15 at 14:44 -0700, Kevin Hilman wrote: > Santosh, > > Tero Kristo <t-kristo@ti.com> writes: > > > From: Santosh Shilimkar <santosh.shilimkar@ti.com> > > > > GIC distributor control register has changed between CortexA9 r1pX and > > r2pX. The Control Register secure banked version is now composed of 2 > > bits: > > bit 0 == Secure Enable > > bit 1 == Non-Secure Enable > > The Non-Secure banked register has not changed. > > For those without the r1pX TRM handy, please include what this look like > before (presumably 1 bit?) The changelog and in-code comments should > both be enhanced. > > > Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration > > will cause a problem to CPU0 Non-Secure SW. > > Please describe the problem, so we can better understand the specifics > of the workaround. Santosh, can you provide a better changelog for this? > > Also, is there an erratum number for this? Nothing public. I don't think there are any public documents about ROM code, including erratas. > > > The workaround must be: > > 1) Before doing the CPU1 wakeup, CPU0 must disable > > the GIC distributor > > 2) CPU1 must re-enable the GIC distributor on > > it's wakeup path. > > Again, because the problem was not described, I am not entirely sure why > the workaround "must" be this, and how it fixes the problem. Remember > to put yourself in the shoes of a reviewer who has not been deeply > involved in the code, so what seems obvious to you will not be obvious > to the reviewer without having to study the code and dig in to the TRMs. > > > With this procedure, the GIC configuration done between the > > CPU0 wakeup and CPU1 wakeup will not be lost but during this > > short windows, the CPU0 will not receive interrupts > > Hmm, so I guess this means that CPU0 always has to wakeup first, even on GP > devices? Yes. > > Also, the changelog doesn't describe what power states this affects, and > whether it's an idle problem or just a supend problem. A quick glance > at the code suggests that only suspend is being addressed by this patch. > However, with the addition of coupled CPUidle (coming very soon now), > won't we have this same problem in idle? IMO, this patch should address > both. My understanding is that this happens if mpu_pwrdm goes off. Cpuidle support is not added to this patch as it does not exist yet. Probably shouldn't be that big fix. > > This workaround also assumes that you always want CPU1 to wakeup > immediately after CPU0. I guess that will be the case for the coupled > states that would be affected by this bug, but the changelog should > describe that as well Yes, this patch assumes both CPUs attempt to wake-up, thus cpu1 is stuck in the hold loop. The device-off set patch #17 addresses this issue and puts cpu1 back to idle immediately if no wake request is received from cpu0. That patch should be possible to move to this set if needed. > > Some minor comments below... > > > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> > > Signed-off-by: Tero Kristo <t-kristo@ti.com> > > --- > > arch/arm/mach-omap2/common.h | 2 + > > arch/arm/mach-omap2/omap-headsmp.S | 36 +++++++++++++++++++++++++++++ > > arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 ++++++- > > arch/arm/mach-omap2/omap-smp.c | 28 +++++++++++++++++++++- > > arch/arm/mach-omap2/omap4-common.c | 8 +++++- > > 5 files changed, 80 insertions(+), 3 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h > > index 57da7f4..48d1ebe 100644 > > --- a/arch/arm/mach-omap2/common.h > > +++ b/arch/arm/mach-omap2/common.h > > @@ -199,6 +199,7 @@ static inline void __iomem *omap4_get_scu_base(void) > > #endif > > > > extern void __init gic_init_irq(void); > > +extern void gic_dist_disable(void); > > extern void omap_smc1(u32 fn, u32 arg); > > extern void __iomem *omap4_get_sar_ram_base(void); > > extern void omap_do_wfi(void); > > @@ -206,6 +207,7 @@ extern void omap_do_wfi(void); > > #ifdef CONFIG_SMP > > /* Needed for secondary core boot */ > > extern void omap_secondary_startup(void); > > +extern void omap_secondary_startup_4460(void); > > extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); > > extern void omap_auxcoreboot_addr(u32 cpu_addr); > > extern u32 omap_read_auxcoreboot0(void); > > diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S > > index 503ac77..d602555 100644 > > --- a/arch/arm/mach-omap2/omap-headsmp.S > > +++ b/arch/arm/mach-omap2/omap-headsmp.S > > @@ -43,3 +43,39 @@ hold: ldr r12,=0x103 > > b secondary_startup > > ENDPROC(omap_secondary_startup) > > > > +ENTRY(omap_secondary_startup_4460) > > +hold_2: ldr r12,=0x103 > > + dsb > > + smc #0 @ read from AuxCoreBoot0 > > + mov r0, r0, lsr #9 > > + mrc p15, 0, r4, c0, c0, 5 > > + and r4, r4, #0x0f > > + cmp r0, r4 > > + bne hold_2 > > + > > + /* > > + * GIC distributor control register has changed between > > + * CortexA9 r1pX and r2pX. The Control Register secure > > + * banked version is now composed of 2 bits: > > + * bit 0 == Secure Enable > > + * bit 1 == Non-Secure Enable > > + * The Non-Secure banked register has not changed > > + * Because the ROM Code is based on the r1pX GIC, the CPU1 > > + * GIC restoration will cause a problem to CPU0 Non-Secure SW. > > + * The workaround must be: > > + * 1) Before doing the CPU1 wakeup, CPU0 must disable > > + * the GIC distributor > > + * 2) CPU1 must re-enable the GIC distributor on > > + * it's wakeup path. > > + */ > > + ldr r1, =0x48241000 > > Why not OMAP44XX_GIC_DIST_BASE for readability sake? Will change this. > > > + ldr r0, [r1] > > + orr r0, #1 > > + str r0, [r1] > > + > > + /* > > + * we've been released from the wait loop,secondary_stack > > + * should now contain the SVC stack for this core > > + */ > > + b secondary_startup > > +ENDPROC(omap_secondary_startup_4460) > > diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c > > index 13670aa..e02c082 100644 > > --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c > > +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c > > @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info { > > void __iomem *scu_sar_addr; > > void __iomem *wkup_sar_addr; > > void __iomem *l2x0_sar_addr; > > + void (*secondary_startup)(void); > > }; > > > > static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); > > @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) > > int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) > > { > > unsigned int cpu_state = 0; > > + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); > > > > if (omap_rev() == OMAP4430_REV_ES1_0) > > return -ENXIO; > > @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) > > > > clear_cpu_prev_pwrst(cpu); > > set_cpu_next_pwrst(cpu, power_state); > > - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); > > + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); > > scu_pwrst_prepare(cpu, power_state); > > > > /* > > @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void) > > pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; > > pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; > > pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; > > + if (cpu_is_omap446x()) > > + pm_info->secondary_startup = omap_secondary_startup_4460; > > + else > > + pm_info->secondary_startup = omap_secondary_startup; > > Does this exist on 4470 too? No, only valid for 4460. ROM code should be fixed on 4470 (haven't tested that though as I don't have access to 4470 devices.) > > Using a PM erratum check here instead of cpu_is* would make this more > scalable. > > Same comment for the cpu_is* check in wakeup_secondary() > > Then, where the erratum is defined, it should state clearly why this > affects 446x and not before (presumably because 4430 has r1pX and 4460 > has r2pX.) Yea, I can add errata flag for this. The errata support for omap4 PM is currently defined in the device off set, so I guess I need to pull that to this set. > > > pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); > > if (!pm_info->pwrdm) { > > pr_err("Lookup failed for CPU1 pwrdm\n"); > > diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c > > index deffbf1..c3eb9e8 100644 > > --- a/arch/arm/mach-omap2/omap-smp.c > > +++ b/arch/arm/mach-omap2/omap-smp.c > > @@ -33,6 +33,7 @@ > > > > /* SCU base address */ > > static void __iomem *scu_base; > > +bool omap4_smp_romcode_errata; > > static? Yes should be. -Tero ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-16 8:54 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-16 8:54 UTC (permalink / raw) To: linux-arm-kernel On Tue, 2012-05-15 at 14:44 -0700, Kevin Hilman wrote: > Santosh, > > Tero Kristo <t-kristo@ti.com> writes: > > > From: Santosh Shilimkar <santosh.shilimkar@ti.com> > > > > GIC distributor control register has changed between CortexA9 r1pX and > > r2pX. The Control Register secure banked version is now composed of 2 > > bits: > > bit 0 == Secure Enable > > bit 1 == Non-Secure Enable > > The Non-Secure banked register has not changed. > > For those without the r1pX TRM handy, please include what this look like > before (presumably 1 bit?) The changelog and in-code comments should > both be enhanced. > > > Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration > > will cause a problem to CPU0 Non-Secure SW. > > Please describe the problem, so we can better understand the specifics > of the workaround. Santosh, can you provide a better changelog for this? > > Also, is there an erratum number for this? Nothing public. I don't think there are any public documents about ROM code, including erratas. > > > The workaround must be: > > 1) Before doing the CPU1 wakeup, CPU0 must disable > > the GIC distributor > > 2) CPU1 must re-enable the GIC distributor on > > it's wakeup path. > > Again, because the problem was not described, I am not entirely sure why > the workaround "must" be this, and how it fixes the problem. Remember > to put yourself in the shoes of a reviewer who has not been deeply > involved in the code, so what seems obvious to you will not be obvious > to the reviewer without having to study the code and dig in to the TRMs. > > > With this procedure, the GIC configuration done between the > > CPU0 wakeup and CPU1 wakeup will not be lost but during this > > short windows, the CPU0 will not receive interrupts > > Hmm, so I guess this means that CPU0 always has to wakeup first, even on GP > devices? Yes. > > Also, the changelog doesn't describe what power states this affects, and > whether it's an idle problem or just a supend problem. A quick glance > at the code suggests that only suspend is being addressed by this patch. > However, with the addition of coupled CPUidle (coming very soon now), > won't we have this same problem in idle? IMO, this patch should address > both. My understanding is that this happens if mpu_pwrdm goes off. Cpuidle support is not added to this patch as it does not exist yet. Probably shouldn't be that big fix. > > This workaround also assumes that you always want CPU1 to wakeup > immediately after CPU0. I guess that will be the case for the coupled > states that would be affected by this bug, but the changelog should > describe that as well Yes, this patch assumes both CPUs attempt to wake-up, thus cpu1 is stuck in the hold loop. The device-off set patch #17 addresses this issue and puts cpu1 back to idle immediately if no wake request is received from cpu0. That patch should be possible to move to this set if needed. > > Some minor comments below... > > > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> > > Signed-off-by: Tero Kristo <t-kristo@ti.com> > > --- > > arch/arm/mach-omap2/common.h | 2 + > > arch/arm/mach-omap2/omap-headsmp.S | 36 +++++++++++++++++++++++++++++ > > arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 ++++++- > > arch/arm/mach-omap2/omap-smp.c | 28 +++++++++++++++++++++- > > arch/arm/mach-omap2/omap4-common.c | 8 +++++- > > 5 files changed, 80 insertions(+), 3 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h > > index 57da7f4..48d1ebe 100644 > > --- a/arch/arm/mach-omap2/common.h > > +++ b/arch/arm/mach-omap2/common.h > > @@ -199,6 +199,7 @@ static inline void __iomem *omap4_get_scu_base(void) > > #endif > > > > extern void __init gic_init_irq(void); > > +extern void gic_dist_disable(void); > > extern void omap_smc1(u32 fn, u32 arg); > > extern void __iomem *omap4_get_sar_ram_base(void); > > extern void omap_do_wfi(void); > > @@ -206,6 +207,7 @@ extern void omap_do_wfi(void); > > #ifdef CONFIG_SMP > > /* Needed for secondary core boot */ > > extern void omap_secondary_startup(void); > > +extern void omap_secondary_startup_4460(void); > > extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); > > extern void omap_auxcoreboot_addr(u32 cpu_addr); > > extern u32 omap_read_auxcoreboot0(void); > > diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S > > index 503ac77..d602555 100644 > > --- a/arch/arm/mach-omap2/omap-headsmp.S > > +++ b/arch/arm/mach-omap2/omap-headsmp.S > > @@ -43,3 +43,39 @@ hold: ldr r12,=0x103 > > b secondary_startup > > ENDPROC(omap_secondary_startup) > > > > +ENTRY(omap_secondary_startup_4460) > > +hold_2: ldr r12,=0x103 > > + dsb > > + smc #0 @ read from AuxCoreBoot0 > > + mov r0, r0, lsr #9 > > + mrc p15, 0, r4, c0, c0, 5 > > + and r4, r4, #0x0f > > + cmp r0, r4 > > + bne hold_2 > > + > > + /* > > + * GIC distributor control register has changed between > > + * CortexA9 r1pX and r2pX. The Control Register secure > > + * banked version is now composed of 2 bits: > > + * bit 0 == Secure Enable > > + * bit 1 == Non-Secure Enable > > + * The Non-Secure banked register has not changed > > + * Because the ROM Code is based on the r1pX GIC, the CPU1 > > + * GIC restoration will cause a problem to CPU0 Non-Secure SW. > > + * The workaround must be: > > + * 1) Before doing the CPU1 wakeup, CPU0 must disable > > + * the GIC distributor > > + * 2) CPU1 must re-enable the GIC distributor on > > + * it's wakeup path. > > + */ > > + ldr r1, =0x48241000 > > Why not OMAP44XX_GIC_DIST_BASE for readability sake? Will change this. > > > + ldr r0, [r1] > > + orr r0, #1 > > + str r0, [r1] > > + > > + /* > > + * we've been released from the wait loop,secondary_stack > > + * should now contain the SVC stack for this core > > + */ > > + b secondary_startup > > +ENDPROC(omap_secondary_startup_4460) > > diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c > > index 13670aa..e02c082 100644 > > --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c > > +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c > > @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info { > > void __iomem *scu_sar_addr; > > void __iomem *wkup_sar_addr; > > void __iomem *l2x0_sar_addr; > > + void (*secondary_startup)(void); > > }; > > > > static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); > > @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) > > int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) > > { > > unsigned int cpu_state = 0; > > + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); > > > > if (omap_rev() == OMAP4430_REV_ES1_0) > > return -ENXIO; > > @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) > > > > clear_cpu_prev_pwrst(cpu); > > set_cpu_next_pwrst(cpu, power_state); > > - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); > > + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); > > scu_pwrst_prepare(cpu, power_state); > > > > /* > > @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void) > > pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; > > pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; > > pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; > > + if (cpu_is_omap446x()) > > + pm_info->secondary_startup = omap_secondary_startup_4460; > > + else > > + pm_info->secondary_startup = omap_secondary_startup; > > Does this exist on 4470 too? No, only valid for 4460. ROM code should be fixed on 4470 (haven't tested that though as I don't have access to 4470 devices.) > > Using a PM erratum check here instead of cpu_is* would make this more > scalable. > > Same comment for the cpu_is* check in wakeup_secondary() > > Then, where the erratum is defined, it should state clearly why this > affects 446x and not before (presumably because 4430 has r1pX and 4460 > has r2pX.) Yea, I can add errata flag for this. The errata support for omap4 PM is currently defined in the device off set, so I guess I need to pull that to this set. > > > pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); > > if (!pm_info->pwrdm) { > > pr_err("Lookup failed for CPU1 pwrdm\n"); > > diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c > > index deffbf1..c3eb9e8 100644 > > --- a/arch/arm/mach-omap2/omap-smp.c > > +++ b/arch/arm/mach-omap2/omap-smp.c > > @@ -33,6 +33,7 @@ > > > > /* SCU base address */ > > static void __iomem *scu_base; > > +bool omap4_smp_romcode_errata; > > static? Yes should be. -Tero ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-15 21:44 ` Kevin Hilman @ 2012-05-16 9:16 ` Santosh Shilimkar -1 siblings, 0 replies; 56+ messages in thread From: Santosh Shilimkar @ 2012-05-16 9:16 UTC (permalink / raw) To: Kevin Hilman; +Cc: Tero Kristo, linux-omap, paul, linux-arm-kernel On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: > Santosh, > > Tero Kristo <t-kristo@ti.com> writes: > >> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >> >> GIC distributor control register has changed between CortexA9 r1pX and >> r2pX. The Control Register secure banked version is now composed of 2 >> bits: >> bit 0 == Secure Enable >> bit 1 == Non-Secure Enable >> The Non-Secure banked register has not changed. > > For those without the r1pX TRM handy, please include what this look like > before (presumably 1 bit?) The changelog and in-code comments should > both be enhanced. > You are right. There was only one bit previously which was used for secure/non-secure mode. So ROM over-writes the non-secure bit accidentally. >> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >> will cause a problem to CPU0 Non-Secure SW. > > Please describe the problem, so we can better understand the specifics > of the workaround. > > Also, is there an erratum number for this? > >> The workaround must be: >> 1) Before doing the CPU1 wakeup, CPU0 must disable >> the GIC distributor >> 2) CPU1 must re-enable the GIC distributor on >> it's wakeup path. > > Again, because the problem was not described, I am not entirely sure why > the workaround "must" be this, and how it fixes the problem. Remember > to put yourself in the shoes of a reviewer who has not been deeply > involved in the code, so what seems obvious to you will not be obvious > to the reviewer without having to study the code and dig in to the TRMs. > Agree and sorry for assuming that the TRM reference should be enough. >> With this procedure, the GIC configuration done between the >> CPU0 wakeup and CPU1 wakeup will not be lost but during this >> short windows, the CPU0 will not receive interrupts > > Hmm, so I guess this means that CPU0 always has to wakeup first, even on GP > devices? > Yes. Thats the case otherwise too, on all OMAP4 devices :-( > Also, the changelog doesn't describe what power states this affects, and > whether it's an idle problem or just a supend problem. A quick glance > at the code suggests that only suspend is being addressed by this patch. > However, with the addition of coupled CPUidle (coming very soon now), > won't we have this same problem in idle? IMO, this patch should address > both. > MPU OSWR and onwards states only. Will add that info in the changelog. > This workaround also assumes that you always want CPU1 to wakeup > immediately after CPU0. I guess that will be the case for the coupled > states that would be affected by this bug, but the changelog should > describe that as well > You are right. It does affect couple idle as well. The old idle code was relying on hotplug path and this fix is in that path which helps suspend as well as cpuidle with CPU1 hotplug in/out Actually this BUG is really nasty and the WA is worst. > Some minor comments below... > >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> >> Signed-off-by: Tero Kristo <t-kristo@ti.com> >> --- >> arch/arm/mach-omap2/common.h | 2 + >> arch/arm/mach-omap2/omap-headsmp.S | 36 +++++++++++++++++++++++++++++ >> arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 ++++++- >> arch/arm/mach-omap2/omap-smp.c | 28 +++++++++++++++++++++- >> arch/arm/mach-omap2/omap4-common.c | 8 +++++- >> 5 files changed, 80 insertions(+), 3 deletions(-) >> >> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h >> index 57da7f4..48d1ebe 100644 >> --- a/arch/arm/mach-omap2/common.h >> +++ b/arch/arm/mach-omap2/common.h >> @@ -199,6 +199,7 @@ static inline void __iomem *omap4_get_scu_base(void) >> #endif >> >> extern void __init gic_init_irq(void); >> +extern void gic_dist_disable(void); >> extern void omap_smc1(u32 fn, u32 arg); >> extern void __iomem *omap4_get_sar_ram_base(void); >> extern void omap_do_wfi(void); >> @@ -206,6 +207,7 @@ extern void omap_do_wfi(void); >> #ifdef CONFIG_SMP >> /* Needed for secondary core boot */ >> extern void omap_secondary_startup(void); >> +extern void omap_secondary_startup_4460(void); >> extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); >> extern void omap_auxcoreboot_addr(u32 cpu_addr); >> extern u32 omap_read_auxcoreboot0(void); >> diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S >> index 503ac77..d602555 100644 >> --- a/arch/arm/mach-omap2/omap-headsmp.S >> +++ b/arch/arm/mach-omap2/omap-headsmp.S >> @@ -43,3 +43,39 @@ hold: ldr r12,=0x103 >> b secondary_startup >> ENDPROC(omap_secondary_startup) >> >> +ENTRY(omap_secondary_startup_4460) >> +hold_2: ldr r12,=0x103 >> + dsb >> + smc #0 @ read from AuxCoreBoot0 >> + mov r0, r0, lsr #9 >> + mrc p15, 0, r4, c0, c0, 5 >> + and r4, r4, #0x0f >> + cmp r0, r4 >> + bne hold_2 >> + >> + /* >> + * GIC distributor control register has changed between >> + * CortexA9 r1pX and r2pX. The Control Register secure >> + * banked version is now composed of 2 bits: >> + * bit 0 == Secure Enable >> + * bit 1 == Non-Secure Enable >> + * The Non-Secure banked register has not changed >> + * Because the ROM Code is based on the r1pX GIC, the CPU1 >> + * GIC restoration will cause a problem to CPU0 Non-Secure SW. >> + * The workaround must be: >> + * 1) Before doing the CPU1 wakeup, CPU0 must disable >> + * the GIC distributor >> + * 2) CPU1 must re-enable the GIC distributor on >> + * it's wakeup path. >> + */ >> + ldr r1, =0x48241000 > > Why not OMAP44XX_GIC_DIST_BASE for readability sake? > Will fix that. >> + ldr r0, [r1] >> + orr r0, #1 >> + str r0, [r1] >> + >> + /* >> + * we've been released from the wait loop,secondary_stack >> + * should now contain the SVC stack for this core >> + */ >> + b secondary_startup >> +ENDPROC(omap_secondary_startup_4460) >> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c >> index 13670aa..e02c082 100644 >> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c >> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c >> @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info { >> void __iomem *scu_sar_addr; >> void __iomem *wkup_sar_addr; >> void __iomem *l2x0_sar_addr; >> + void (*secondary_startup)(void); >> }; >> >> static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); >> @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) >> int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) >> { >> unsigned int cpu_state = 0; >> + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); >> >> if (omap_rev() == OMAP4430_REV_ES1_0) >> return -ENXIO; >> @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) >> >> clear_cpu_prev_pwrst(cpu); >> set_cpu_next_pwrst(cpu, power_state); >> - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); >> + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); >> scu_pwrst_prepare(cpu, power_state); >> >> /* >> @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void) >> pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; >> pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; >> pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; >> + if (cpu_is_omap446x()) >> + pm_info->secondary_startup = omap_secondary_startup_4460; >> + else >> + pm_info->secondary_startup = omap_secondary_startup; > > Does this exist on 4470 too? > This OMAP4460 issue only. OMAP4470 ROM code BUG is fixed. > Using a PM erratum check here instead of cpu_is* would make this more > scalable. > > Same comment for the cpu_is* check in wakeup_secondary() > > Then, where the erratum is defined, it should state clearly why this > affects 446x and not before (presumably because 4430 has r1pX and 4460 > has r2pX.) > Ok Regards Santosh ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-16 9:16 ` Santosh Shilimkar 0 siblings, 0 replies; 56+ messages in thread From: Santosh Shilimkar @ 2012-05-16 9:16 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: > Santosh, > > Tero Kristo <t-kristo@ti.com> writes: > >> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >> >> GIC distributor control register has changed between CortexA9 r1pX and >> r2pX. The Control Register secure banked version is now composed of 2 >> bits: >> bit 0 == Secure Enable >> bit 1 == Non-Secure Enable >> The Non-Secure banked register has not changed. > > For those without the r1pX TRM handy, please include what this look like > before (presumably 1 bit?) The changelog and in-code comments should > both be enhanced. > You are right. There was only one bit previously which was used for secure/non-secure mode. So ROM over-writes the non-secure bit accidentally. >> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >> will cause a problem to CPU0 Non-Secure SW. > > Please describe the problem, so we can better understand the specifics > of the workaround. > > Also, is there an erratum number for this? > >> The workaround must be: >> 1) Before doing the CPU1 wakeup, CPU0 must disable >> the GIC distributor >> 2) CPU1 must re-enable the GIC distributor on >> it's wakeup path. > > Again, because the problem was not described, I am not entirely sure why > the workaround "must" be this, and how it fixes the problem. Remember > to put yourself in the shoes of a reviewer who has not been deeply > involved in the code, so what seems obvious to you will not be obvious > to the reviewer without having to study the code and dig in to the TRMs. > Agree and sorry for assuming that the TRM reference should be enough. >> With this procedure, the GIC configuration done between the >> CPU0 wakeup and CPU1 wakeup will not be lost but during this >> short windows, the CPU0 will not receive interrupts > > Hmm, so I guess this means that CPU0 always has to wakeup first, even on GP > devices? > Yes. Thats the case otherwise too, on all OMAP4 devices :-( > Also, the changelog doesn't describe what power states this affects, and > whether it's an idle problem or just a supend problem. A quick glance > at the code suggests that only suspend is being addressed by this patch. > However, with the addition of coupled CPUidle (coming very soon now), > won't we have this same problem in idle? IMO, this patch should address > both. > MPU OSWR and onwards states only. Will add that info in the changelog. > This workaround also assumes that you always want CPU1 to wakeup > immediately after CPU0. I guess that will be the case for the coupled > states that would be affected by this bug, but the changelog should > describe that as well > You are right. It does affect couple idle as well. The old idle code was relying on hotplug path and this fix is in that path which helps suspend as well as cpuidle with CPU1 hotplug in/out Actually this BUG is really nasty and the WA is worst. > Some minor comments below... > >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> >> Signed-off-by: Tero Kristo <t-kristo@ti.com> >> --- >> arch/arm/mach-omap2/common.h | 2 + >> arch/arm/mach-omap2/omap-headsmp.S | 36 +++++++++++++++++++++++++++++ >> arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 ++++++- >> arch/arm/mach-omap2/omap-smp.c | 28 +++++++++++++++++++++- >> arch/arm/mach-omap2/omap4-common.c | 8 +++++- >> 5 files changed, 80 insertions(+), 3 deletions(-) >> >> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h >> index 57da7f4..48d1ebe 100644 >> --- a/arch/arm/mach-omap2/common.h >> +++ b/arch/arm/mach-omap2/common.h >> @@ -199,6 +199,7 @@ static inline void __iomem *omap4_get_scu_base(void) >> #endif >> >> extern void __init gic_init_irq(void); >> +extern void gic_dist_disable(void); >> extern void omap_smc1(u32 fn, u32 arg); >> extern void __iomem *omap4_get_sar_ram_base(void); >> extern void omap_do_wfi(void); >> @@ -206,6 +207,7 @@ extern void omap_do_wfi(void); >> #ifdef CONFIG_SMP >> /* Needed for secondary core boot */ >> extern void omap_secondary_startup(void); >> +extern void omap_secondary_startup_4460(void); >> extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); >> extern void omap_auxcoreboot_addr(u32 cpu_addr); >> extern u32 omap_read_auxcoreboot0(void); >> diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S >> index 503ac77..d602555 100644 >> --- a/arch/arm/mach-omap2/omap-headsmp.S >> +++ b/arch/arm/mach-omap2/omap-headsmp.S >> @@ -43,3 +43,39 @@ hold: ldr r12,=0x103 >> b secondary_startup >> ENDPROC(omap_secondary_startup) >> >> +ENTRY(omap_secondary_startup_4460) >> +hold_2: ldr r12,=0x103 >> + dsb >> + smc #0 @ read from AuxCoreBoot0 >> + mov r0, r0, lsr #9 >> + mrc p15, 0, r4, c0, c0, 5 >> + and r4, r4, #0x0f >> + cmp r0, r4 >> + bne hold_2 >> + >> + /* >> + * GIC distributor control register has changed between >> + * CortexA9 r1pX and r2pX. The Control Register secure >> + * banked version is now composed of 2 bits: >> + * bit 0 == Secure Enable >> + * bit 1 == Non-Secure Enable >> + * The Non-Secure banked register has not changed >> + * Because the ROM Code is based on the r1pX GIC, the CPU1 >> + * GIC restoration will cause a problem to CPU0 Non-Secure SW. >> + * The workaround must be: >> + * 1) Before doing the CPU1 wakeup, CPU0 must disable >> + * the GIC distributor >> + * 2) CPU1 must re-enable the GIC distributor on >> + * it's wakeup path. >> + */ >> + ldr r1, =0x48241000 > > Why not OMAP44XX_GIC_DIST_BASE for readability sake? > Will fix that. >> + ldr r0, [r1] >> + orr r0, #1 >> + str r0, [r1] >> + >> + /* >> + * we've been released from the wait loop,secondary_stack >> + * should now contain the SVC stack for this core >> + */ >> + b secondary_startup >> +ENDPROC(omap_secondary_startup_4460) >> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c >> index 13670aa..e02c082 100644 >> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c >> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c >> @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info { >> void __iomem *scu_sar_addr; >> void __iomem *wkup_sar_addr; >> void __iomem *l2x0_sar_addr; >> + void (*secondary_startup)(void); >> }; >> >> static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); >> @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) >> int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) >> { >> unsigned int cpu_state = 0; >> + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); >> >> if (omap_rev() == OMAP4430_REV_ES1_0) >> return -ENXIO; >> @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) >> >> clear_cpu_prev_pwrst(cpu); >> set_cpu_next_pwrst(cpu, power_state); >> - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); >> + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); >> scu_pwrst_prepare(cpu, power_state); >> >> /* >> @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void) >> pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; >> pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; >> pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; >> + if (cpu_is_omap446x()) >> + pm_info->secondary_startup = omap_secondary_startup_4460; >> + else >> + pm_info->secondary_startup = omap_secondary_startup; > > Does this exist on 4470 too? > This OMAP4460 issue only. OMAP4470 ROM code BUG is fixed. > Using a PM erratum check here instead of cpu_is* would make this more > scalable. > > Same comment for the cpu_is* check in wakeup_secondary() > > Then, where the erratum is defined, it should state clearly why this > affects 446x and not before (presumably because 4430 has r1pX and 4460 > has r2pX.) > Ok Regards Santosh ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-16 9:16 ` Santosh Shilimkar @ 2012-05-16 12:23 ` Santosh Shilimkar -1 siblings, 0 replies; 56+ messages in thread From: Santosh Shilimkar @ 2012-05-16 12:23 UTC (permalink / raw) To: Kevin Hilman; +Cc: Tero Kristo, linux-omap, paul, linux-arm-kernel Kevin, On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: > On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >> Santosh, >> >> Tero Kristo <t-kristo@ti.com> writes: >> >>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>> >>> GIC distributor control register has changed between CortexA9 r1pX and >>> r2pX. The Control Register secure banked version is now composed of 2 >>> bits: >>> bit 0 == Secure Enable >>> bit 1 == Non-Secure Enable >>> The Non-Secure banked register has not changed. >> >> For those without the r1pX TRM handy, please include what this look like >> before (presumably 1 bit?) The changelog and in-code comments should >> both be enhanced. >> > You are right. There was only one bit previously which was used for > secure/non-secure mode. So ROM over-writes the non-secure bit > accidentally. > >>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>> will cause a problem to CPU0 Non-Secure SW. >> >> Please describe the problem, so we can better understand the specifics >> of the workaround. >> Below is the updated changelog. -------------- ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change With MPUSS programmed to OSWR(Open Switch retention), GIC context is lost. On the CPU wakeup paths, ROM code gets executed which will setup GIC secure configurations and restore the GIC context if it was saved based on SAR_BACKUP_STATUS. The ROM Code GIC distributor restoration is split in two parts: CPU specific register done by each CPU and common register done by only one CPU. If the GIC Distributor Control Register = 1, the second CPU will not do the common GIC restoration. GIC distributor control register has changed between CortexA9 r1pX and r2pX. The Control Register secure banked version is now composed of 2 bits vs only one bit before r1px: bit 0 == Secure Enable bit 1 == Non-Secure Enable Hence the value of Control register will be 3 and not 1 as the r1pX based ROM code expects. So he CPU1 on it's wakeup ROM code path, will go to the GIC initialization procedure and will so reset the full GIC and NS GIC distributor Enable bit will get cleared. Since the GIC distributor gets disabled in a live system, CPU1 will hang because the interrupts stop firing. Workaround for the issue: 1) Before doing the CPU1 wakeup, CPU0 must disable the GIC distributor and wait for it to be enabled. 2) CPU1 must re-enable the GIC distributor on it's wakeup path. With this procedure, the GIC configuration done between the CPU0 wakeup and CPU1 wakeup will not be lost but during this short windows, the CPU0 will not receive interrupts. The BUG is applicable to only OMAP4460(r2pX) devices. OMAP4470(r2Px), ROM code is fixed for this BUG. ---------------- Let me know if it clarifies the issue ? Regards Santosh ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-16 12:23 ` Santosh Shilimkar 0 siblings, 0 replies; 56+ messages in thread From: Santosh Shilimkar @ 2012-05-16 12:23 UTC (permalink / raw) To: linux-arm-kernel Kevin, On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: > On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >> Santosh, >> >> Tero Kristo <t-kristo@ti.com> writes: >> >>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>> >>> GIC distributor control register has changed between CortexA9 r1pX and >>> r2pX. The Control Register secure banked version is now composed of 2 >>> bits: >>> bit 0 == Secure Enable >>> bit 1 == Non-Secure Enable >>> The Non-Secure banked register has not changed. >> >> For those without the r1pX TRM handy, please include what this look like >> before (presumably 1 bit?) The changelog and in-code comments should >> both be enhanced. >> > You are right. There was only one bit previously which was used for > secure/non-secure mode. So ROM over-writes the non-secure bit > accidentally. > >>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>> will cause a problem to CPU0 Non-Secure SW. >> >> Please describe the problem, so we can better understand the specifics >> of the workaround. >> Below is the updated changelog. -------------- ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change With MPUSS programmed to OSWR(Open Switch retention), GIC context is lost. On the CPU wakeup paths, ROM code gets executed which will setup GIC secure configurations and restore the GIC context if it was saved based on SAR_BACKUP_STATUS. The ROM Code GIC distributor restoration is split in two parts: CPU specific register done by each CPU and common register done by only one CPU. If the GIC Distributor Control Register = 1, the second CPU will not do the common GIC restoration. GIC distributor control register has changed between CortexA9 r1pX and r2pX. The Control Register secure banked version is now composed of 2 bits vs only one bit before r1px: bit 0 == Secure Enable bit 1 == Non-Secure Enable Hence the value of Control register will be 3 and not 1 as the r1pX based ROM code expects. So he CPU1 on it's wakeup ROM code path, will go to the GIC initialization procedure and will so reset the full GIC and NS GIC distributor Enable bit will get cleared. Since the GIC distributor gets disabled in a live system, CPU1 will hang because the interrupts stop firing. Workaround for the issue: 1) Before doing the CPU1 wakeup, CPU0 must disable the GIC distributor and wait for it to be enabled. 2) CPU1 must re-enable the GIC distributor on it's wakeup path. With this procedure, the GIC configuration done between the CPU0 wakeup and CPU1 wakeup will not be lost but during this short windows, the CPU0 will not receive interrupts. The BUG is applicable to only OMAP4460(r2pX) devices. OMAP4470(r2Px), ROM code is fixed for this BUG. ---------------- Let me know if it clarifies the issue ? Regards Santosh ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-16 12:23 ` Santosh Shilimkar @ 2012-05-16 16:51 ` Kevin Hilman -1 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-16 16:51 UTC (permalink / raw) To: Santosh Shilimkar; +Cc: Tero Kristo, linux-omap, paul, linux-arm-kernel Santosh Shilimkar <santosh.shilimkar@ti.com> writes: > Kevin, > > On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: >> On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >>> Santosh, >>> >>> Tero Kristo <t-kristo@ti.com> writes: >>> >>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>>> >>>> GIC distributor control register has changed between CortexA9 r1pX and >>>> r2pX. The Control Register secure banked version is now composed of 2 >>>> bits: >>>> bit 0 == Secure Enable >>>> bit 1 == Non-Secure Enable >>>> The Non-Secure banked register has not changed. >>> >>> For those without the r1pX TRM handy, please include what this look like >>> before (presumably 1 bit?) The changelog and in-code comments should >>> both be enhanced. >>> >> You are right. There was only one bit previously which was used for >> secure/non-secure mode. So ROM over-writes the non-secure bit >> accidentally. >> >>>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>>> will cause a problem to CPU0 Non-Secure SW. >>> >>> Please describe the problem, so we can better understand the specifics >>> of the workaround. >>> > Below is the updated changelog. Much better, thanks. But it still took me several reads to fully understand. Maybe it's because the cold I have is stuffing up my head, so it takes me awhile to understand... Anyways, some minor comments to help clarify... Sorry to be so picky about changelogs, but this is a really nasty bug, and the workaround has some rather important side effects, so I want the description of the bug and the workaround to be well described. > -------------- > ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control > register change > > With MPUSS programmed to OSWR(Open Switch retention), GIC context is > lost. On the CPU wakeup paths, ROM code gets executed which will setup > GIC secure configurations and restore the GIC context if it was saved > based on SAR_BACKUP_STATUS. > > The ROM Code GIC distributor restoration is split in two parts: > CPU specific register done by each CPU and common register done by > only one CPU. If the GIC Distributor Control Register = 1, the > second CPU will not do the common GIC restoration. s/second CPU/second CPU to wake up/ > GIC distributor control register has changed between CortexA9 r1pX and > r2pX. The Control Register secure banked version is now composed of 2 > bits vs only one bit before r1px: before r1pX? > bit 0 == Secure Enable > bit 1 == Non-Secure Enable And what did this look like for r1pX? Presumably bit0 was non-secure enable? > Hence the value of Control register will be 3 and not 1 as the r1pX > based ROM code expects. Why will it be 3? Will it be 3 on GP devices? > So he CPU1 on it's wakeup ROM code path, will s/it's/its/ > go to the GIC initialization procedure and will so reset the full GIC > and NS GIC distributor Enable bit will get cleared. This is where it's confusing. On r2pX, NS enable bit is bit 1. It's not mentioned here, but I'm assuming that it's bit 0 on r1pX, right? (I can't seem to find an r1pX TRM) Since ROM code is r1pX-based, I would assume that it would continue to clear bit 0, which is only now the secure enable bit? Or, is it the case that ROM code clears all the bits? That should be described. > Since the GIC distributor gets disabled in a live system, CPU1 will > hang because the interrupts stop firing. > 1) Before doing the CPU1 wakeup, CPU0 must disable > the GIC distributor and wait for it to be enabled. what does 'disable GIC distributor' mean. secure? non-secure? both? > 2) CPU1 must re-enable the GIC distributor on > it's wakeup path. Describe why this works. e.g. because it cause ROM code to skip its broken restore path. > With this procedure, the GIC configuration done between the > CPU0 wakeup and CPU1 wakeup will not be lost but during this > short windows, the CPU0 will not receive interrupts. > > The BUG is applicable to only OMAP4460(r2pX) devices. > OMAP4470(r2Px), ROM code is fixed for this BUG. OMAP4470 (also r2pX) is not affected by this bug because ROM code has been fixed. Kevin > ---------------- > > Let me know if it clarifies the issue ? > > Regards > Santosh > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-16 16:51 ` Kevin Hilman 0 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-16 16:51 UTC (permalink / raw) To: linux-arm-kernel Santosh Shilimkar <santosh.shilimkar@ti.com> writes: > Kevin, > > On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: >> On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >>> Santosh, >>> >>> Tero Kristo <t-kristo@ti.com> writes: >>> >>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>>> >>>> GIC distributor control register has changed between CortexA9 r1pX and >>>> r2pX. The Control Register secure banked version is now composed of 2 >>>> bits: >>>> bit 0 == Secure Enable >>>> bit 1 == Non-Secure Enable >>>> The Non-Secure banked register has not changed. >>> >>> For those without the r1pX TRM handy, please include what this look like >>> before (presumably 1 bit?) The changelog and in-code comments should >>> both be enhanced. >>> >> You are right. There was only one bit previously which was used for >> secure/non-secure mode. So ROM over-writes the non-secure bit >> accidentally. >> >>>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>>> will cause a problem to CPU0 Non-Secure SW. >>> >>> Please describe the problem, so we can better understand the specifics >>> of the workaround. >>> > Below is the updated changelog. Much better, thanks. But it still took me several reads to fully understand. Maybe it's because the cold I have is stuffing up my head, so it takes me awhile to understand... Anyways, some minor comments to help clarify... Sorry to be so picky about changelogs, but this is a really nasty bug, and the workaround has some rather important side effects, so I want the description of the bug and the workaround to be well described. > -------------- > ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control > register change > > With MPUSS programmed to OSWR(Open Switch retention), GIC context is > lost. On the CPU wakeup paths, ROM code gets executed which will setup > GIC secure configurations and restore the GIC context if it was saved > based on SAR_BACKUP_STATUS. > > The ROM Code GIC distributor restoration is split in two parts: > CPU specific register done by each CPU and common register done by > only one CPU. If the GIC Distributor Control Register = 1, the > second CPU will not do the common GIC restoration. s/second CPU/second CPU to wake up/ > GIC distributor control register has changed between CortexA9 r1pX and > r2pX. The Control Register secure banked version is now composed of 2 > bits vs only one bit before r1px: before r1pX? > bit 0 == Secure Enable > bit 1 == Non-Secure Enable And what did this look like for r1pX? Presumably bit0 was non-secure enable? > Hence the value of Control register will be 3 and not 1 as the r1pX > based ROM code expects. Why will it be 3? Will it be 3 on GP devices? > So he CPU1 on it's wakeup ROM code path, will s/it's/its/ > go to the GIC initialization procedure and will so reset the full GIC > and NS GIC distributor Enable bit will get cleared. This is where it's confusing. On r2pX, NS enable bit is bit 1. It's not mentioned here, but I'm assuming that it's bit 0 on r1pX, right? (I can't seem to find an r1pX TRM) Since ROM code is r1pX-based, I would assume that it would continue to clear bit 0, which is only now the secure enable bit? Or, is it the case that ROM code clears all the bits? That should be described. > Since the GIC distributor gets disabled in a live system, CPU1 will > hang because the interrupts stop firing. > 1) Before doing the CPU1 wakeup, CPU0 must disable > the GIC distributor and wait for it to be enabled. what does 'disable GIC distributor' mean. secure? non-secure? both? > 2) CPU1 must re-enable the GIC distributor on > it's wakeup path. Describe why this works. e.g. because it cause ROM code to skip its broken restore path. > With this procedure, the GIC configuration done between the > CPU0 wakeup and CPU1 wakeup will not be lost but during this > short windows, the CPU0 will not receive interrupts. > > The BUG is applicable to only OMAP4460(r2pX) devices. > OMAP4470(r2Px), ROM code is fixed for this BUG. OMAP4470 (also r2pX) is not affected by this bug because ROM code has been fixed. Kevin > ---------------- > > Let me know if it clarifies the issue ? > > Regards > Santosh > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-16 16:51 ` Kevin Hilman @ 2012-05-17 6:46 ` Shilimkar, Santosh -1 siblings, 0 replies; 56+ messages in thread From: Shilimkar, Santosh @ 2012-05-17 6:46 UTC (permalink / raw) To: Kevin Hilman; +Cc: Tero Kristo, linux-omap, paul, linux-arm-kernel On Wed, May 16, 2012 at 10:21 PM, Kevin Hilman <khilman@ti.com> wrote: > Santosh Shilimkar <santosh.shilimkar@ti.com> writes: > >> Kevin, >> >> On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: >>> On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >>>> Santosh, >>>> >>>> Tero Kristo <t-kristo@ti.com> writes: >>>> >>>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>>>> >>>>> GIC distributor control register has changed between CortexA9 r1pX and >>>>> r2pX. The Control Register secure banked version is now composed of 2 >>>>> bits: >>>>> bit 0 == Secure Enable >>>>> bit 1 == Non-Secure Enable >>>>> The Non-Secure banked register has not changed. >>>> >>>> For those without the r1pX TRM handy, please include what this look like >>>> before (presumably 1 bit?) The changelog and in-code comments should >>>> both be enhanced. >>>> >>> You are right. There was only one bit previously which was used for >>> secure/non-secure mode. So ROM over-writes the non-secure bit >>> accidentally. >>> >>>>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>>>> will cause a problem to CPU0 Non-Secure SW. >>>> >>>> Please describe the problem, so we can better understand the specifics >>>> of the workaround. >>>> >> Below is the updated changelog. > > Much better, thanks. But it still took me several reads to fully > understand. Maybe it's because the cold I have is stuffing up my head, > so it takes me awhile to understand... Anyways, some minor comments to > help clarify... > > Sorry to be so picky about changelogs, but this is a really nasty bug, > and the workaround has some rather important side effects, so I want the > description of the bug and the workaround to be well described. > >> -------------- >> ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control >> register change >> >> With MPUSS programmed to OSWR(Open Switch retention), GIC context is >> lost. On the CPU wakeup paths, ROM code gets executed which will setup >> GIC secure configurations and restore the GIC context if it was saved >> based on SAR_BACKUP_STATUS. >> >> The ROM Code GIC distributor restoration is split in two parts: >> CPU specific register done by each CPU and common register done by >> only one CPU. If the GIC Distributor Control Register = 1, the >> second CPU will not do the common GIC restoration. > > s/second CPU/second CPU to wake up/ > ok >> GIC distributor control register has changed between CortexA9 r1pX and >> r2pX. The Control Register secure banked version is now composed of 2 >> bits vs only one bit before r1px: > > before r1pX? I mean r1px, r0px etc. > >> bit 0 == Secure Enable >> bit 1 == Non-Secure Enable > > And what did this look like for r1pX? Presumably bit0 was non-secure > enable? > Yes. Same bit is used. It's banked bit which has secure and non-secure view. >> Hence the value of Control register will be 3 and not 1 as the r1pX >> based ROM code expects. > > Why will it be 3? > > Will it be 3 on GP devices? > Yes. Because you have 2 bits. Since both bits will be set [ Bit 1 will be set by ROM code] and bit 0 will be set by Linux. >> So he CPU1 on it's wakeup ROM code path, will > > s/it's/its/ > ok >> go to the GIC initialization procedure and will so reset the full GIC >> and NS GIC distributor Enable bit will get cleared. > > This is where it's confusing. > Hmm. > On r2pX, NS enable bit is bit 1. It's not mentioned here, but I'm > assuming that it's bit 0 on r1pX, right? (I can't seem to find an r1pX > TRM) > Yes. As I mentioned earlier, will make that more clear. > Since ROM code is r1pX-based, I would assume that it would continue to > clear bit 0, which is only now the secure enable bit? > > Or, is it the case that ROM code clears all the bits? That should be described. > ROM code reads the register value and compares it with value == 1 " If the GIC Distributor Control Register = 1, the second CPU will not do the common GIC restoration" On r2Px, the value becomes 3 and entire ROM code logic goofs up and take wrong code path. >> Since the GIC distributor gets disabled in a live system, CPU1 will >> hang because the interrupts stop firing. >> 1) Before doing the CPU1 wakeup, CPU0 must disable >> the GIC distributor and wait for it to be enabled. > > what does 'disable GIC distributor' mean. secure? non-secure? both? > HLOS is a non-secure view so it can disable only non-secure bit. >> 2) CPU1 must re-enable the GIC distributor on >> it's wakeup path. > > Describe why this works. e.g. because it cause ROM code to skip its > broken restore path. > ROM code logic find the control register value 1 because bit 1 is cleared by non-secure SW during the check. >> With this procedure, the GIC configuration done between the >> CPU0 wakeup and CPU1 wakeup will not be lost but during this >> short windows, the CPU0 will not receive interrupts. >> >> The BUG is applicable to only OMAP4460(r2pX) devices. >> OMAP4470(r2Px), ROM code is fixed for this BUG. > > OMAP4470 (also r2pX) is not affected by this bug because ROM code has > been fixed. > Ok Regards Santosh -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-17 6:46 ` Shilimkar, Santosh 0 siblings, 0 replies; 56+ messages in thread From: Shilimkar, Santosh @ 2012-05-17 6:46 UTC (permalink / raw) To: linux-arm-kernel On Wed, May 16, 2012 at 10:21 PM, Kevin Hilman <khilman@ti.com> wrote: > Santosh Shilimkar <santosh.shilimkar@ti.com> writes: > >> Kevin, >> >> On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: >>> On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >>>> Santosh, >>>> >>>> Tero Kristo <t-kristo@ti.com> writes: >>>> >>>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>>>> >>>>> GIC distributor control register has changed between CortexA9 r1pX and >>>>> r2pX. The Control Register secure banked version is now composed of 2 >>>>> bits: >>>>> ? ? ?bit 0 == Secure Enable >>>>> ? ? ?bit 1 == Non-Secure Enable >>>>> The Non-Secure banked register has not changed. >>>> >>>> For those without the r1pX TRM handy, please include what this look like >>>> before (presumably 1 bit?) ?The changelog and in-code comments should >>>> both be enhanced. >>>> >>> You are right. There was only one bit previously which was used for >>> secure/non-secure mode. So ROM over-writes the non-secure bit >>> accidentally. >>> >>>>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>>>> will cause a problem to CPU0 Non-Secure SW. >>>> >>>> Please describe the problem, so we can better understand the specifics >>>> of the workaround. >>>> >> Below is the updated changelog. > > Much better, thanks. ?But it still took me several reads to fully > understand. ?Maybe it's because the cold I have is stuffing up my head, > so it takes me awhile to understand... ?Anyways, some minor comments to > help clarify... > > Sorry to be so picky about changelogs, but this is a really nasty bug, > and the workaround has some rather important side effects, so I want the > description of the bug and the workaround to be well described. > >> -------------- >> ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control >> register change >> >> With MPUSS programmed to OSWR(Open Switch retention), GIC context is >> lost. On the CPU wakeup paths, ROM code gets executed which will setup >> GIC secure configurations and restore the GIC context if it was saved >> based on SAR_BACKUP_STATUS. >> >> The ROM Code GIC distributor restoration is split in two parts: >> CPU specific register done by each CPU and common register done by >> only one CPU. If the GIC Distributor Control Register = 1, the >> second CPU will not do the common GIC restoration. > > s/second CPU/second CPU to wake up/ > ok >> GIC distributor control register has changed between CortexA9 r1pX and >> r2pX. The Control Register secure banked version is now composed of 2 >> bits vs only one bit before r1px: > > before r1pX? I mean r1px, r0px etc. > >> ? ? ?bit 0 == Secure Enable >> ? ? ?bit 1 == Non-Secure Enable > > And what did this look like for r1pX? ? ?Presumably bit0 was non-secure > enable? > Yes. Same bit is used. It's banked bit which has secure and non-secure view. >> Hence the value of Control register will be 3 and not 1 as the r1pX >> based ROM code expects. > > Why will it be 3? > > Will it be 3 on GP devices? > Yes. Because you have 2 bits. Since both bits will be set [ Bit 1 will be set by ROM code] and bit 0 will be set by Linux. >> So he CPU1 on it's wakeup ROM code path, will > > s/it's/its/ > ok >> go to the GIC initialization procedure and will so reset the full GIC >> and NS GIC distributor Enable bit will get cleared. > > This is where it's confusing. > Hmm. > On r2pX, NS enable bit is bit 1. ?It's not mentioned here, but I'm > assuming that it's bit 0 on r1pX, right? (I can't seem to find an r1pX > TRM) > Yes. As I mentioned earlier, will make that more clear. > Since ROM code is r1pX-based, I would assume that it would continue to > clear bit 0, which is only now the secure enable bit? > > Or, is it the case that ROM code clears all the bits? ?That should be described. > ROM code reads the register value and compares it with value == 1 " If the GIC Distributor Control Register = 1, the second CPU will not do the common GIC restoration" On r2Px, the value becomes 3 and entire ROM code logic goofs up and take wrong code path. >> Since the GIC distributor gets disabled in a live system, CPU1 will >> hang because the interrupts stop firing. >> ? ? ?1) Before doing the CPU1 wakeup, CPU0 must disable >> ? ? ? ? the GIC distributor and wait for it to be enabled. > > what does 'disable GIC distributor' mean. ?secure? non-secure? both? > HLOS is a non-secure view so it can disable only non-secure bit. >> ? ? ?2) CPU1 must re-enable the GIC distributor on >> ? ? ? ? it's wakeup path. > > Describe why this works. ?e.g. because it cause ROM code to skip its > broken restore path. > ROM code logic find the control register value 1 because bit 1 is cleared by non-secure SW during the check. >> With this procedure, the GIC configuration done between the >> CPU0 wakeup and CPU1 wakeup will not be lost but during this >> short windows, the CPU0 will not receive interrupts. >> >> The BUG is applicable to only OMAP4460(r2pX) devices. >> OMAP4470(r2Px), ROM code is fixed for this BUG. > > OMAP4470 (also r2pX) is not affected by this bug because ROM code has > been fixed. > Ok Regards Santosh ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-17 6:46 ` Shilimkar, Santosh @ 2012-05-17 17:15 ` Kevin Hilman -1 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-17 17:15 UTC (permalink / raw) To: Shilimkar, Santosh; +Cc: Tero Kristo, linux-omap, paul, linux-arm-kernel "Shilimkar, Santosh" <santosh.shilimkar@ti.com> writes: > On Wed, May 16, 2012 at 10:21 PM, Kevin Hilman <khilman@ti.com> wrote: >> Santosh Shilimkar <santosh.shilimkar@ti.com> writes: >> >>> Kevin, >>> >>> On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: >>>> On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >>>>> Santosh, >>>>> >>>>> Tero Kristo <t-kristo@ti.com> writes: >>>>> >>>>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>>>>> >>>>>> GIC distributor control register has changed between CortexA9 r1pX and >>>>>> r2pX. The Control Register secure banked version is now composed of 2 >>>>>> bits: >>>>>> bit 0 == Secure Enable >>>>>> bit 1 == Non-Secure Enable >>>>>> The Non-Secure banked register has not changed. >>>>> >>>>> For those without the r1pX TRM handy, please include what this look like >>>>> before (presumably 1 bit?) The changelog and in-code comments should >>>>> both be enhanced. >>>>> >>>> You are right. There was only one bit previously which was used for >>>> secure/non-secure mode. So ROM over-writes the non-secure bit >>>> accidentally. >>>> >>>>>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>>>>> will cause a problem to CPU0 Non-Secure SW. >>>>> >>>>> Please describe the problem, so we can better understand the specifics >>>>> of the workaround. >>>>> >>> Below is the updated changelog. >> >> Much better, thanks. But it still took me several reads to fully >> understand. Maybe it's because the cold I have is stuffing up my head, >> so it takes me awhile to understand... Anyways, some minor comments to >> help clarify... >> >> Sorry to be so picky about changelogs, but this is a really nasty bug, >> and the workaround has some rather important side effects, so I want the >> description of the bug and the workaround to be well described. >> >>> -------------- >>> ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control >>> register change >>> >>> With MPUSS programmed to OSWR(Open Switch retention), GIC context is >>> lost. On the CPU wakeup paths, ROM code gets executed which will setup >>> GIC secure configurations and restore the GIC context if it was saved >>> based on SAR_BACKUP_STATUS. >>> >>> The ROM Code GIC distributor restoration is split in two parts: >>> CPU specific register done by each CPU and common register done by >>> only one CPU. If the GIC Distributor Control Register = 1, the >>> second CPU will not do the common GIC restoration. >> >> s/second CPU/second CPU to wake up/ >> > ok >>> GIC distributor control register has changed between CortexA9 r1pX and >>> r2pX. The Control Register secure banked version is now composed of 2 >>> bits vs only one bit before r1px: >> >> before r1pX? > I mean r1px, r0px etc. >> >>> bit 0 == Secure Enable >>> bit 1 == Non-Secure Enable >> >> And what did this look like for r1pX? Presumably bit0 was non-secure >> enable? >> > Yes. Same bit is used. It's banked bit which has secure and non-secure view. > >>> Hence the value of Control register will be 3 and not 1 as the r1pX >>> based ROM code expects. >> >> Why will it be 3? >> >> Will it be 3 on GP devices? >> > Yes. Because you have 2 bits. Since both bits will be set [ Bit 1 will > be set by ROM code] > and bit 0 will be set by Linux. Why will the secure enable bit be set on GP devices? >>> So he CPU1 on it's wakeup ROM code path, will >> >> s/it's/its/ >> > ok >>> go to the GIC initialization procedure and will so reset the full GIC >>> and NS GIC distributor Enable bit will get cleared. >> >> This is where it's confusing. >> > Hmm. > >> On r2pX, NS enable bit is bit 1. It's not mentioned here, but I'm >> assuming that it's bit 0 on r1pX, right? (I can't seem to find an r1pX >> TRM) >> > Yes. As I mentioned earlier, will make that more clear. > >> Since ROM code is r1pX-based, I would assume that it would continue to >> clear bit 0, which is only now the secure enable bit? >> >> Or, is it the case that ROM code clears all the bits? That should be described. >> > ROM code reads the register value and compares it with value == 1 > " If the GIC Distributor Control Register = 1, the > second CPU will not do the common GIC restoration" > On r2Px, the value becomes 3 and entire ROM code logic goofs up > and take wrong code path. That part is clear. What's not at all clear is what the ROM code does *after* this. Does it clear both bits? or just bit 0? Since it's r1pX based, I would expect that it doesn't touch anything other than bit 0. >>> Since the GIC distributor gets disabled in a live system, CPU1 will >>> hang because the interrupts stop firing. >>> 1) Before doing the CPU1 wakeup, CPU0 must disable >>> the GIC distributor and wait for it to be enabled. >> >> what does 'disable GIC distributor' mean. secure? non-secure? both? >> > HLOS is a non-secure view so it can disable only non-secure bit. The changelog is not talking about the HLOS, it's talking about the ROM code, which presumably can set/clear both bits. >>> 2) CPU1 must re-enable the GIC distributor on >>> it's wakeup path. >> >> Describe why this works. e.g. because it cause ROM code to skip its >> broken restore path. >> > ROM code logic find the control register value 1 because bit 1 is > cleared by non-secure SW during the check. and because it finds the control regster value to be 1... Santosh, I do understand what is happening here. But I play dumb so that it will be described in great detail in the changelog so that when I forget (and you forget) we can go back to this and get a quick understanding of both the bug and the workaround. Since you are very deeply familiar with this bug, it's understandably hard to write this changelog since most things probably seem obvious to you. A suggestion would be to have a few colleagues that are not familiar with this bug read the changelog and try and describe it back to you. Kevin -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-17 17:15 ` Kevin Hilman 0 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-17 17:15 UTC (permalink / raw) To: linux-arm-kernel "Shilimkar, Santosh" <santosh.shilimkar@ti.com> writes: > On Wed, May 16, 2012 at 10:21 PM, Kevin Hilman <khilman@ti.com> wrote: >> Santosh Shilimkar <santosh.shilimkar@ti.com> writes: >> >>> Kevin, >>> >>> On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: >>>> On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >>>>> Santosh, >>>>> >>>>> Tero Kristo <t-kristo@ti.com> writes: >>>>> >>>>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>>>>> >>>>>> GIC distributor control register has changed between CortexA9 r1pX and >>>>>> r2pX. The Control Register secure banked version is now composed of 2 >>>>>> bits: >>>>>> ? ? ?bit 0 == Secure Enable >>>>>> ? ? ?bit 1 == Non-Secure Enable >>>>>> The Non-Secure banked register has not changed. >>>>> >>>>> For those without the r1pX TRM handy, please include what this look like >>>>> before (presumably 1 bit?) ?The changelog and in-code comments should >>>>> both be enhanced. >>>>> >>>> You are right. There was only one bit previously which was used for >>>> secure/non-secure mode. So ROM over-writes the non-secure bit >>>> accidentally. >>>> >>>>>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>>>>> will cause a problem to CPU0 Non-Secure SW. >>>>> >>>>> Please describe the problem, so we can better understand the specifics >>>>> of the workaround. >>>>> >>> Below is the updated changelog. >> >> Much better, thanks. ?But it still took me several reads to fully >> understand. ?Maybe it's because the cold I have is stuffing up my head, >> so it takes me awhile to understand... ?Anyways, some minor comments to >> help clarify... >> >> Sorry to be so picky about changelogs, but this is a really nasty bug, >> and the workaround has some rather important side effects, so I want the >> description of the bug and the workaround to be well described. >> >>> -------------- >>> ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control >>> register change >>> >>> With MPUSS programmed to OSWR(Open Switch retention), GIC context is >>> lost. On the CPU wakeup paths, ROM code gets executed which will setup >>> GIC secure configurations and restore the GIC context if it was saved >>> based on SAR_BACKUP_STATUS. >>> >>> The ROM Code GIC distributor restoration is split in two parts: >>> CPU specific register done by each CPU and common register done by >>> only one CPU. If the GIC Distributor Control Register = 1, the >>> second CPU will not do the common GIC restoration. >> >> s/second CPU/second CPU to wake up/ >> > ok >>> GIC distributor control register has changed between CortexA9 r1pX and >>> r2pX. The Control Register secure banked version is now composed of 2 >>> bits vs only one bit before r1px: >> >> before r1pX? > I mean r1px, r0px etc. >> >>> ? ? ?bit 0 == Secure Enable >>> ? ? ?bit 1 == Non-Secure Enable >> >> And what did this look like for r1pX? ? ?Presumably bit0 was non-secure >> enable? >> > Yes. Same bit is used. It's banked bit which has secure and non-secure view. > >>> Hence the value of Control register will be 3 and not 1 as the r1pX >>> based ROM code expects. >> >> Why will it be 3? >> >> Will it be 3 on GP devices? >> > Yes. Because you have 2 bits. Since both bits will be set [ Bit 1 will > be set by ROM code] > and bit 0 will be set by Linux. Why will the secure enable bit be set on GP devices? >>> So he CPU1 on it's wakeup ROM code path, will >> >> s/it's/its/ >> > ok >>> go to the GIC initialization procedure and will so reset the full GIC >>> and NS GIC distributor Enable bit will get cleared. >> >> This is where it's confusing. >> > Hmm. > >> On r2pX, NS enable bit is bit 1. ?It's not mentioned here, but I'm >> assuming that it's bit 0 on r1pX, right? (I can't seem to find an r1pX >> TRM) >> > Yes. As I mentioned earlier, will make that more clear. > >> Since ROM code is r1pX-based, I would assume that it would continue to >> clear bit 0, which is only now the secure enable bit? >> >> Or, is it the case that ROM code clears all the bits? ?That should be described. >> > ROM code reads the register value and compares it with value == 1 > " If the GIC Distributor Control Register = 1, the > second CPU will not do the common GIC restoration" > On r2Px, the value becomes 3 and entire ROM code logic goofs up > and take wrong code path. That part is clear. What's not at all clear is what the ROM code does *after* this. Does it clear both bits? or just bit 0? Since it's r1pX based, I would expect that it doesn't touch anything other than bit 0. >>> Since the GIC distributor gets disabled in a live system, CPU1 will >>> hang because the interrupts stop firing. >>> ? ? ?1) Before doing the CPU1 wakeup, CPU0 must disable >>> ? ? ? ? the GIC distributor and wait for it to be enabled. >> >> what does 'disable GIC distributor' mean. ?secure? non-secure? both? >> > HLOS is a non-secure view so it can disable only non-secure bit. The changelog is not talking about the HLOS, it's talking about the ROM code, which presumably can set/clear both bits. >>> ? ? ?2) CPU1 must re-enable the GIC distributor on >>> ? ? ? ? it's wakeup path. >> >> Describe why this works. ?e.g. because it cause ROM code to skip its >> broken restore path. >> > ROM code logic find the control register value 1 because bit 1 is > cleared by non-secure SW during the check. and because it finds the control regster value to be 1... Santosh, I do understand what is happening here. But I play dumb so that it will be described in great detail in the changelog so that when I forget (and you forget) we can go back to this and get a quick understanding of both the bug and the workaround. Since you are very deeply familiar with this bug, it's understandably hard to write this changelog since most things probably seem obvious to you. A suggestion would be to have a few colleagues that are not familiar with this bug read the changelog and try and describe it back to you. Kevin ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-17 17:15 ` Kevin Hilman @ 2012-05-18 6:05 ` Shilimkar, Santosh -1 siblings, 0 replies; 56+ messages in thread From: Shilimkar, Santosh @ 2012-05-18 6:05 UTC (permalink / raw) To: Kevin Hilman; +Cc: Tero Kristo, linux-omap, paul, linux-arm-kernel On Thu, May 17, 2012 at 10:45 PM, Kevin Hilman <khilman@ti.com> wrote: > "Shilimkar, Santosh" <santosh.shilimkar@ti.com> writes: > >> On Wed, May 16, 2012 at 10:21 PM, Kevin Hilman <khilman@ti.com> wrote: >>> Santosh Shilimkar <santosh.shilimkar@ti.com> writes: >>> >>>> Kevin, >>>> >>>> On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: >>>>> On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >>>>>> Santosh, >>>>>> >>>>>> Tero Kristo <t-kristo@ti.com> writes: >>>>>> >>>>>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>>>>>> >>>>>>> GIC distributor control register has changed between CortexA9 r1pX and >>>>>>> r2pX. The Control Register secure banked version is now composed of 2 >>>>>>> bits: >>>>>>> bit 0 == Secure Enable >>>>>>> bit 1 == Non-Secure Enable >>>>>>> The Non-Secure banked register has not changed. >>>>>> >>>>>> For those without the r1pX TRM handy, please include what this look like >>>>>> before (presumably 1 bit?) The changelog and in-code comments should >>>>>> both be enhanced. >>>>>> >>>>> You are right. There was only one bit previously which was used for >>>>> secure/non-secure mode. So ROM over-writes the non-secure bit >>>>> accidentally. >>>>> >>>>>>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>>>>>> will cause a problem to CPU0 Non-Secure SW. >>>>>> >>>>>> Please describe the problem, so we can better understand the specifics >>>>>> of the workaround. >>>>>> >>>> Below is the updated changelog. >>> >>> Much better, thanks. But it still took me several reads to fully >>> understand. Maybe it's because the cold I have is stuffing up my head, >>> so it takes me awhile to understand... Anyways, some minor comments to >>> help clarify... >>> >>> Sorry to be so picky about changelogs, but this is a really nasty bug, >>> and the workaround has some rather important side effects, so I want the >>> description of the bug and the workaround to be well described. >>> >>>> -------------- >>>> ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control >>>> register change >>>> >>>> With MPUSS programmed to OSWR(Open Switch retention), GIC context is >>>> lost. On the CPU wakeup paths, ROM code gets executed which will setup >>>> GIC secure configurations and restore the GIC context if it was saved >>>> based on SAR_BACKUP_STATUS. >>>> >>>> The ROM Code GIC distributor restoration is split in two parts: >>>> CPU specific register done by each CPU and common register done by >>>> only one CPU. If the GIC Distributor Control Register = 1, the >>>> second CPU will not do the common GIC restoration. >>> >>> s/second CPU/second CPU to wake up/ >>> >> ok >>>> GIC distributor control register has changed between CortexA9 r1pX and >>>> r2pX. The Control Register secure banked version is now composed of 2 >>>> bits vs only one bit before r1px: >>> >>> before r1pX? >> I mean r1px, r0px etc. >>> >>>> bit 0 == Secure Enable >>>> bit 1 == Non-Secure Enable >>> >>> And what did this look like for r1pX? Presumably bit0 was non-secure >>> enable? >>> >> Yes. Same bit is used. It's banked bit which has secure and non-secure view. >> >>>> Hence the value of Control register will be 3 and not 1 as the r1pX >>>> based ROM code expects. >>> >>> Why will it be 3? >>> >>> Will it be 3 on GP devices? >>> >> Yes. Because you have 2 bits. Since both bits will be set [ Bit 1 will >> be set by ROM code] >> and bit 0 will be set by Linux. > > Why will the secure enable bit be set on GP devices? > >>>> So he CPU1 on it's wakeup ROM code path, will >>> >>> s/it's/its/ >>> >> ok >>>> go to the GIC initialization procedure and will so reset the full GIC >>>> and NS GIC distributor Enable bit will get cleared. >>> >>> This is where it's confusing. >>> >> Hmm. >> >>> On r2pX, NS enable bit is bit 1. It's not mentioned here, but I'm >>> assuming that it's bit 0 on r1pX, right? (I can't seem to find an r1pX >>> TRM) >>> >> Yes. As I mentioned earlier, will make that more clear. >> >>> Since ROM code is r1pX-based, I would assume that it would continue to >>> clear bit 0, which is only now the secure enable bit? >>> >>> Or, is it the case that ROM code clears all the bits? That should be described. >>> >> ROM code reads the register value and compares it with value == 1 >> " If the GIC Distributor Control Register = 1, the >> second CPU will not do the common GIC restoration" >> On r2Px, the value becomes 3 and entire ROM code logic goofs up >> and take wrong code path. > > That part is clear. > > What's not at all clear is what the ROM code does *after* this. Does it > clear both bits? or just bit 0? Since it's r1pX based, I would expect > that it doesn't touch anything other than bit 0. > Actually since the condition of control register == 1 is not satisfied, It re-inits entire GIC thinking it's not configured at all. So everything will be cleared and including non-secure GIC dist. enable bit. >>>> Since the GIC distributor gets disabled in a live system, CPU1 will >>>> hang because the interrupts stop firing. >>>> 1) Before doing the CPU1 wakeup, CPU0 must disable >>>> the GIC distributor and wait for it to be enabled. >>> >>> what does 'disable GIC distributor' mean. secure? non-secure? both? >>> >> HLOS is a non-secure view so it can disable only non-secure bit. > > The changelog is not talking about the HLOS, it's talking about the ROM > code, which presumably can set/clear both bits. > >>>> 2) CPU1 must re-enable the GIC distributor on >>>> it's wakeup path. >>> >>> Describe why this works. e.g. because it cause ROM code to skip its >>> broken restore path. >>> >> ROM code logic find the control register value 1 because bit 1 is >> cleared by non-secure SW during the check. > > and because it finds the control regster value to be 1... > > Santosh, I do understand what is happening here. But I play dumb so > that it will be described in great detail in the changelog so that when > I forget (and you forget) we can go back to this and get a quick > understanding of both the bug and the workaround. > > Since you are very deeply familiar with this bug, it's understandably > hard to write this changelog since most things probably seem obvious to > you. A suggestion would be to have a few colleagues that are not > familiar with this bug read the changelog and try and describe it back > to you. > I agree with you. This is side effect of knowing some BUGs too much. I will work with Tero so that change log captures more details. Regards Santosh without any assumptions. -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-18 6:05 ` Shilimkar, Santosh 0 siblings, 0 replies; 56+ messages in thread From: Shilimkar, Santosh @ 2012-05-18 6:05 UTC (permalink / raw) To: linux-arm-kernel On Thu, May 17, 2012 at 10:45 PM, Kevin Hilman <khilman@ti.com> wrote: > "Shilimkar, Santosh" <santosh.shilimkar@ti.com> writes: > >> On Wed, May 16, 2012 at 10:21 PM, Kevin Hilman <khilman@ti.com> wrote: >>> Santosh Shilimkar <santosh.shilimkar@ti.com> writes: >>> >>>> Kevin, >>>> >>>> On Wednesday 16 May 2012 02:46 PM, Santosh Shilimkar wrote: >>>>> On Wednesday 16 May 2012 03:14 AM, Kevin Hilman wrote: >>>>>> Santosh, >>>>>> >>>>>> Tero Kristo <t-kristo@ti.com> writes: >>>>>> >>>>>>> From: Santosh Shilimkar <santosh.shilimkar@ti.com> >>>>>>> >>>>>>> GIC distributor control register has changed between CortexA9 r1pX and >>>>>>> r2pX. The Control Register secure banked version is now composed of 2 >>>>>>> bits: >>>>>>> ? ? ?bit 0 == Secure Enable >>>>>>> ? ? ?bit 1 == Non-Secure Enable >>>>>>> The Non-Secure banked register has not changed. >>>>>> >>>>>> For those without the r1pX TRM handy, please include what this look like >>>>>> before (presumably 1 bit?) ?The changelog and in-code comments should >>>>>> both be enhanced. >>>>>> >>>>> You are right. There was only one bit previously which was used for >>>>> secure/non-secure mode. So ROM over-writes the non-secure bit >>>>> accidentally. >>>>> >>>>>>> Since the ROM Code is based on the r1pX GIC, the CPU1 GIC restoration >>>>>>> will cause a problem to CPU0 Non-Secure SW. >>>>>> >>>>>> Please describe the problem, so we can better understand the specifics >>>>>> of the workaround. >>>>>> >>>> Below is the updated changelog. >>> >>> Much better, thanks. ?But it still took me several reads to fully >>> understand. ?Maybe it's because the cold I have is stuffing up my head, >>> so it takes me awhile to understand... ?Anyways, some minor comments to >>> help clarify... >>> >>> Sorry to be so picky about changelogs, but this is a really nasty bug, >>> and the workaround has some rather important side effects, so I want the >>> description of the bug and the workaround to be well described. >>> >>>> -------------- >>>> ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control >>>> register change >>>> >>>> With MPUSS programmed to OSWR(Open Switch retention), GIC context is >>>> lost. On the CPU wakeup paths, ROM code gets executed which will setup >>>> GIC secure configurations and restore the GIC context if it was saved >>>> based on SAR_BACKUP_STATUS. >>>> >>>> The ROM Code GIC distributor restoration is split in two parts: >>>> CPU specific register done by each CPU and common register done by >>>> only one CPU. If the GIC Distributor Control Register = 1, the >>>> second CPU will not do the common GIC restoration. >>> >>> s/second CPU/second CPU to wake up/ >>> >> ok >>>> GIC distributor control register has changed between CortexA9 r1pX and >>>> r2pX. The Control Register secure banked version is now composed of 2 >>>> bits vs only one bit before r1px: >>> >>> before r1pX? >> I mean r1px, r0px etc. >>> >>>> ? ? ?bit 0 == Secure Enable >>>> ? ? ?bit 1 == Non-Secure Enable >>> >>> And what did this look like for r1pX? ? ?Presumably bit0 was non-secure >>> enable? >>> >> Yes. Same bit is used. It's banked bit which has secure and non-secure view. >> >>>> Hence the value of Control register will be 3 and not 1 as the r1pX >>>> based ROM code expects. >>> >>> Why will it be 3? >>> >>> Will it be 3 on GP devices? >>> >> Yes. Because you have 2 bits. Since both bits will be set [ Bit 1 will >> be set by ROM code] >> and bit 0 will be set by Linux. > > Why will the secure enable bit be set on GP devices? > >>>> So he CPU1 on it's wakeup ROM code path, will >>> >>> s/it's/its/ >>> >> ok >>>> go to the GIC initialization procedure and will so reset the full GIC >>>> and NS GIC distributor Enable bit will get cleared. >>> >>> This is where it's confusing. >>> >> Hmm. >> >>> On r2pX, NS enable bit is bit 1. ?It's not mentioned here, but I'm >>> assuming that it's bit 0 on r1pX, right? (I can't seem to find an r1pX >>> TRM) >>> >> Yes. As I mentioned earlier, will make that more clear. >> >>> Since ROM code is r1pX-based, I would assume that it would continue to >>> clear bit 0, which is only now the secure enable bit? >>> >>> Or, is it the case that ROM code clears all the bits? ?That should be described. >>> >> ROM code reads the register value and compares it with value == 1 >> " If the GIC Distributor Control Register = 1, the >> second CPU will not do the common GIC restoration" >> On r2Px, the value becomes 3 and entire ROM code logic goofs up >> and take wrong code path. > > That part is clear. > > What's not at all clear is what the ROM code does *after* this. ?Does it > clear both bits? ?or just bit 0? ?Since it's r1pX based, I would expect > that it doesn't touch anything other than bit 0. > Actually since the condition of control register == 1 is not satisfied, It re-inits entire GIC thinking it's not configured at all. So everything will be cleared and including non-secure GIC dist. enable bit. >>>> Since the GIC distributor gets disabled in a live system, CPU1 will >>>> hang because the interrupts stop firing. >>>> ? ? ?1) Before doing the CPU1 wakeup, CPU0 must disable >>>> ? ? ? ? the GIC distributor and wait for it to be enabled. >>> >>> what does 'disable GIC distributor' mean. ?secure? non-secure? both? >>> >> HLOS is a non-secure view so it can disable only non-secure bit. > > The changelog is not talking about the HLOS, it's talking about the ROM > code, which presumably can set/clear both bits. > >>>> ? ? ?2) CPU1 must re-enable the GIC distributor on >>>> ? ? ? ? it's wakeup path. >>> >>> Describe why this works. ?e.g. because it cause ROM code to skip its >>> broken restore path. >>> >> ROM code logic find the control register value 1 because bit 1 is >> cleared by non-secure SW during the check. > > and because it finds the control regster value to be 1... > > Santosh, I do understand what is happening here. ?But I play dumb so > that it will be described in great detail in the changelog so that when > I forget (and you forget) we can go back to this and get a quick > understanding of both the bug and the workaround. > > Since you are very deeply familiar with this bug, it's understandably > hard to write this changelog since most things probably seem obvious to > you. ?A suggestion would be to have a few colleagues that are not > familiar with this bug read the changelog and try and describe it back > to you. > I agree with you. This is side effect of knowing some BUGs too much. I will work with Tero so that change log captures more details. Regards Santosh without any assumptions. ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-18 6:05 ` Shilimkar, Santosh @ 2012-05-18 14:13 ` Kevin Hilman -1 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-18 14:13 UTC (permalink / raw) To: Shilimkar, Santosh; +Cc: Tero Kristo, linux-omap, paul, linux-arm-kernel "Shilimkar, Santosh" <santosh.shilimkar@ti.com> writes: > On Thu, May 17, 2012 at 10:45 PM, Kevin Hilman <khilman@ti.com> wrote: [...] >> What's not at all clear is what the ROM code does *after* this. Does it >> clear both bits? or just bit 0? Since it's r1pX based, I would expect >> that it doesn't touch anything other than bit 0. >> > Actually since the condition of control register == 1 is not satisfied, > It re-inits entire GIC thinking it's not configured at all. So everything > will be cleared and including non-secure GIC dist. enable bit. Aha, that's the missing piece of the puzzle: The ROM code is clearing bits that are unused on r1pX (but used on r2pX). That is the root of this bug and needs more description. Thanks for clarifying. [...] >> Santosh, I do understand what is happening here. But I play dumb so >> that it will be described in great detail in the changelog so that when >> I forget (and you forget) we can go back to this and get a quick >> understanding of both the bug and the workaround. >> >> Since you are very deeply familiar with this bug, it's understandably >> hard to write this changelog since most things probably seem obvious to >> you. A suggestion would be to have a few colleagues that are not >> familiar with this bug read the changelog and try and describe it back >> to you. >> > I agree with you. This is side effect of knowing some BUGs too much. > I will work with Tero so that change log captures more details. Thanks. Maybe Jon Hunter can help review the changelog too. IMO, he is the reigning champion of thorough, descriptive and detailed changelogs. :) Kevin -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-18 14:13 ` Kevin Hilman 0 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-18 14:13 UTC (permalink / raw) To: linux-arm-kernel "Shilimkar, Santosh" <santosh.shilimkar@ti.com> writes: > On Thu, May 17, 2012 at 10:45 PM, Kevin Hilman <khilman@ti.com> wrote: [...] >> What's not at all clear is what the ROM code does *after* this. ?Does it >> clear both bits? ?or just bit 0? ?Since it's r1pX based, I would expect >> that it doesn't touch anything other than bit 0. >> > Actually since the condition of control register == 1 is not satisfied, > It re-inits entire GIC thinking it's not configured at all. So everything > will be cleared and including non-secure GIC dist. enable bit. Aha, that's the missing piece of the puzzle: The ROM code is clearing bits that are unused on r1pX (but used on r2pX). That is the root of this bug and needs more description. Thanks for clarifying. [...] >> Santosh, I do understand what is happening here. ?But I play dumb so >> that it will be described in great detail in the changelog so that when >> I forget (and you forget) we can go back to this and get a quick >> understanding of both the bug and the workaround. >> >> Since you are very deeply familiar with this bug, it's understandably >> hard to write this changelog since most things probably seem obvious to >> you. ?A suggestion would be to have a few colleagues that are not >> familiar with this bug read the changelog and try and describe it back >> to you. >> > I agree with you. This is side effect of knowing some BUGs too much. > I will work with Tero so that change log captures more details. Thanks. Maybe Jon Hunter can help review the changelog too. IMO, he is the reigning champion of thorough, descriptive and detailed changelogs. :) Kevin ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change 2012-05-14 10:03 ` Tero Kristo @ 2012-05-16 12:31 ` Santosh Shilimkar -1 siblings, 0 replies; 56+ messages in thread From: Santosh Shilimkar @ 2012-05-16 12:31 UTC (permalink / raw) To: Tero Kristo; +Cc: linux-omap, khilman, paul, linux-arm-kernel Tero, On Monday 14 May 2012 03:33 PM, Tero Kristo wrote: > From: Santosh Shilimkar <santosh.shilimkar@ti.com> > > GIC distributor control register has changed between CortexA9 r1pX and > r2pX. The Control Register secure banked version is now composed of 2 > bits: > bit 0 == Secure Enable > bit 1 == Non-Secure Enable [..] > diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c > index deffbf1..c3eb9e8 100644 > --- a/arch/arm/mach-omap2/omap-smp.c > +++ b/arch/arm/mach-omap2/omap-smp.c > @@ -33,6 +33,7 @@ > > /* SCU base address */ > static void __iomem *scu_base; > +bool omap4_smp_romcode_errata; > > static DEFINE_SPINLOCK(boot_lock); > > @@ -104,6 +105,24 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) > * 4.3.4.2 Power States of CPU0 and CPU1 > */ > if (booted) { > + /* > + * GIC distributor control register has changed between > + * CortexA9 r1pX and r2pX. The Control Register secure > + * banked version is now composed of 2 bits: > + * bit 0 == Secure Enable > + * bit 1 == Non-Secure Enable > + * The Non-Secure banked register has not changed > + * Because the ROM Code is based on the r1pX GIC, the CPU1 > + * GIC restoration will cause a problem to CPU0 Non-Secure SW. > + * The workaround must be: > + * 1) Before doing the CPU1 wakeup, CPU0 must disable > + * the GIC distributor > + * 2) CPU1 must re-enable the GIC distributor on > + * it's wakeup path. > + */ > + if (omap4_smp_romcode_errata) For safety, disable local IRQ here. local_irq_disable(); > + gic_dist_disable(); > + And CPU0 needs to wait here till CPU1 re-enables the distributor to avoid any random issues. The BUG is applicable for CPUIDLE as well with MPUSS OSWR state, but we can fix the idle in another patch to avoid dependency. Basically above 3 lines should also be part of idle code where we wakeup the CPU1 using force wakeup. Regards Santosh ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change @ 2012-05-16 12:31 ` Santosh Shilimkar 0 siblings, 0 replies; 56+ messages in thread From: Santosh Shilimkar @ 2012-05-16 12:31 UTC (permalink / raw) To: linux-arm-kernel Tero, On Monday 14 May 2012 03:33 PM, Tero Kristo wrote: > From: Santosh Shilimkar <santosh.shilimkar@ti.com> > > GIC distributor control register has changed between CortexA9 r1pX and > r2pX. The Control Register secure banked version is now composed of 2 > bits: > bit 0 == Secure Enable > bit 1 == Non-Secure Enable [..] > diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c > index deffbf1..c3eb9e8 100644 > --- a/arch/arm/mach-omap2/omap-smp.c > +++ b/arch/arm/mach-omap2/omap-smp.c > @@ -33,6 +33,7 @@ > > /* SCU base address */ > static void __iomem *scu_base; > +bool omap4_smp_romcode_errata; > > static DEFINE_SPINLOCK(boot_lock); > > @@ -104,6 +105,24 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) > * 4.3.4.2 Power States of CPU0 and CPU1 > */ > if (booted) { > + /* > + * GIC distributor control register has changed between > + * CortexA9 r1pX and r2pX. The Control Register secure > + * banked version is now composed of 2 bits: > + * bit 0 == Secure Enable > + * bit 1 == Non-Secure Enable > + * The Non-Secure banked register has not changed > + * Because the ROM Code is based on the r1pX GIC, the CPU1 > + * GIC restoration will cause a problem to CPU0 Non-Secure SW. > + * The workaround must be: > + * 1) Before doing the CPU1 wakeup, CPU0 must disable > + * the GIC distributor > + * 2) CPU1 must re-enable the GIC distributor on > + * it's wakeup path. > + */ > + if (omap4_smp_romcode_errata) For safety, disable local IRQ here. local_irq_disable(); > + gic_dist_disable(); > + And CPU0 needs to wait here till CPU1 re-enables the distributor to avoid any random issues. The BUG is applicable for CPUIDLE as well with MPUSS OSWR state, but we can fix the idle in another patch to avoid dependency. Basically above 3 lines should also be part of idle code where we wakeup the CPU1 using force wakeup. Regards Santosh ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 4/8] ARM: OMAP4: hwmod: flag hwmods/modules supporting module level context status 2012-05-14 10:03 ` Tero Kristo @ 2012-05-14 10:03 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> On OMAP4 most modules/hwmods support module level context status. On OMAP3 and earlier, we relyed on the power domain level context status. Identify all such modules using a 'HWMOD_CONTEXT_REG' flag, all such hwmods already have a valid 'context_offs' populated in .prcm structure. Signed-off-by: Rajendra Nayak <rnayak@ti.com> --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 104 ++++++++++++++++++++++---- arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 + 2 files changed, 91 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index fd305bc..16836ca 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -128,6 +128,7 @@ static struct omap_hwmod omap44xx_dmm_hwmod = { .name = "dmm", .class = &omap44xx_dmm_hwmod_class, .clkdm_name = "l3_emif_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET, @@ -184,6 +185,7 @@ static struct omap_hwmod omap44xx_emif_fw_hwmod = { .name = "emif_fw", .class = &omap44xx_emif_fw_hwmod_class, .clkdm_name = "l3_emif_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET, @@ -229,6 +231,7 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = { .name = "l3_instr", .class = &omap44xx_l3_hwmod_class, .clkdm_name = "l3_instr_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET, @@ -328,6 +331,7 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = { .name = "l3_main_1", .class = &omap44xx_l3_hwmod_class, .clkdm_name = "l3_1_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_l3_main_1_irqs, .prcm = { .omap4 = { @@ -430,6 +434,7 @@ static struct omap_hwmod omap44xx_l3_main_2_hwmod = { .name = "l3_main_2", .class = &omap44xx_l3_hwmod_class, .clkdm_name = "l3_2_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET, @@ -486,6 +491,7 @@ static struct omap_hwmod omap44xx_l3_main_3_hwmod = { .name = "l3_main_3", .class = &omap44xx_l3_hwmod_class, .clkdm_name = "l3_instr_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET, @@ -577,6 +583,7 @@ static struct omap_hwmod omap44xx_l4_cfg_hwmod = { .name = "l4_cfg", .class = &omap44xx_l4_hwmod_class, .clkdm_name = "l4_cfg_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET, @@ -605,6 +612,7 @@ static struct omap_hwmod omap44xx_l4_per_hwmod = { .name = "l4_per", .class = &omap44xx_l4_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET, @@ -633,6 +641,7 @@ static struct omap_hwmod omap44xx_l4_wkup_hwmod = { .name = "l4_wkup", .class = &omap44xx_l4_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET, @@ -807,6 +816,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = { .name = "aess", .class = &omap44xx_aess_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_aess_irqs, .sdma_reqs = omap44xx_aess_sdma_reqs, .main_clk = "aess_fck", @@ -898,7 +908,7 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = { .name = "counter_32k", .class = &omap44xx_counter_hwmod_class, .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, + .flags = HWMOD_CONTEXT_REG | HWMOD_SWSUP_SIDLE, .main_clk = "sys_32k_ck", .prcm = { .omap4 = { @@ -982,6 +992,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = { .name = "dma_system", .class = &omap44xx_dma_hwmod_class, .clkdm_name = "l3_dma_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dma_system_irqs, .main_clk = "l3_div_ck", .prcm = { @@ -1077,6 +1088,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = { .name = "dmic", .class = &omap44xx_dmic_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dmic_irqs, .sdma_reqs = omap44xx_dmic_sdma_reqs, .main_clk = "dmic_fck", @@ -1160,7 +1172,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = { .name = "dsp", .class = &omap44xx_dsp_hwmod_class, .clkdm_name = "tesla_clkdm", - .flags = HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_RESET | HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dsp_irqs, .rst_lines = omap44xx_dsp_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets), @@ -1252,7 +1264,8 @@ static struct omap_hwmod_opt_clk dss_opt_clks[] = { static struct omap_hwmod omap44xx_dss_hwmod = { .name = "dss_core", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .class = &omap44xx_dss_hwmod_class, .clkdm_name = "l3_dss_clkdm", .main_clk = "dss_dss_clk", @@ -1356,6 +1369,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = { .name = "dss_dispc", .class = &omap44xx_dispc_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dss_dispc_irqs, .sdma_reqs = omap44xx_dss_dispc_sdma_reqs, .main_clk = "dss_dss_clk", @@ -1453,6 +1467,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { .name = "dss_dsi1", .class = &omap44xx_dsi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dss_dsi1_irqs, .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs, .main_clk = "dss_dss_clk", @@ -1530,6 +1545,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { .name = "dss_dsi2", .class = &omap44xx_dsi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dss_dsi2_irqs, .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs, .main_clk = "dss_dss_clk", @@ -1627,6 +1643,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { .name = "dss_hdmi", .class = &omap44xx_hdmi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dss_hdmi_irqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .main_clk = "dss_48mhz_clk", @@ -1719,6 +1736,7 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { .name = "dss_rfbi", .class = &omap44xx_rfbi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs, .main_clk = "dss_dss_clk", .prcm = { @@ -1790,6 +1808,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { .name = "dss_venc", .class = &omap44xx_venc_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .main_clk = "dss_tv_clk", .prcm = { .omap4 = { @@ -1868,6 +1887,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = { .name = "gpio1", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_gpio1_irqs, .main_clk = "gpio1_ick", .prcm = { @@ -1922,7 +1942,8 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = { .name = "gpio2", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio2_irqs, .main_clk = "gpio2_ick", .prcm = { @@ -1977,7 +1998,8 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = { .name = "gpio3", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio3_irqs, .main_clk = "gpio3_ick", .prcm = { @@ -2032,7 +2054,8 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = { .name = "gpio4", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio4_irqs, .main_clk = "gpio4_ick", .prcm = { @@ -2087,7 +2110,8 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = { .name = "gpio5", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio5_irqs, .main_clk = "gpio5_ick", .prcm = { @@ -2142,7 +2166,8 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = { .name = "gpio6", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio6_irqs, .main_clk = "gpio6_ick", .prcm = { @@ -2223,6 +2248,7 @@ static struct omap_hwmod omap44xx_hsi_hwmod = { .name = "hsi", .class = &omap44xx_hsi_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_hsi_irqs, .main_clk = "hsi_fck", .prcm = { @@ -2306,7 +2332,8 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = { .name = "i2c1", .class = &omap44xx_i2c_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .flags = HWMOD_CONTEXT_REG | HWMOD_16BIT_REG | + HWMOD_SET_DEFAULT_CLOCKACT, .mpu_irqs = omap44xx_i2c1_irqs, .sdma_reqs = omap44xx_i2c1_sdma_reqs, .main_clk = "i2c1_fck", @@ -2362,7 +2389,8 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = { .name = "i2c2", .class = &omap44xx_i2c_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .flags = HWMOD_CONTEXT_REG | HWMOD_16BIT_REG | + HWMOD_SET_DEFAULT_CLOCKACT, .mpu_irqs = omap44xx_i2c2_irqs, .sdma_reqs = omap44xx_i2c2_sdma_reqs, .main_clk = "i2c2_fck", @@ -2418,7 +2446,8 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = { .name = "i2c3", .class = &omap44xx_i2c_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .flags = HWMOD_CONTEXT_REG | HWMOD_16BIT_REG | + HWMOD_SET_DEFAULT_CLOCKACT, .mpu_irqs = omap44xx_i2c3_irqs, .sdma_reqs = omap44xx_i2c3_sdma_reqs, .main_clk = "i2c3_fck", @@ -2474,7 +2503,8 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = { .name = "i2c4", .class = &omap44xx_i2c_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .flags = HWMOD_CONTEXT_REG | HWMOD_16BIT_REG | + HWMOD_SET_DEFAULT_CLOCKACT, .mpu_irqs = omap44xx_i2c4_irqs, .sdma_reqs = omap44xx_i2c4_sdma_reqs, .main_clk = "i2c4_fck", @@ -2569,6 +2599,7 @@ static struct omap_hwmod omap44xx_ipu_hwmod = { .name = "ipu", .class = &omap44xx_ipu_hwmod_class, .clkdm_name = "ducati_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_ipu_irqs, .rst_lines = omap44xx_ipu_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_resets), @@ -2667,6 +2698,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = { .name = "iss", .class = &omap44xx_iss_hwmod_class, .clkdm_name = "iss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_iss_irqs, .sdma_reqs = omap44xx_iss_sdma_reqs, .main_clk = "iss_fck", @@ -2778,6 +2810,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = { .name = "iva", .class = &omap44xx_iva_hwmod_class, .clkdm_name = "ivahd_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_iva_irqs, .rst_lines = omap44xx_iva_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), @@ -2852,6 +2885,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = { .name = "kbd", .class = &omap44xx_kbd_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_kbd_irqs, .main_clk = "kbd_fck", .prcm = { @@ -2919,6 +2953,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = { .name = "mailbox", .class = &omap44xx_mailbox_hwmod_class, .clkdm_name = "l4_cfg_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mailbox_irqs, .prcm = { .omap4 = { @@ -3015,6 +3050,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = { .name = "mcbsp1", .class = &omap44xx_mcbsp_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcbsp1_irqs, .sdma_reqs = omap44xx_mcbsp1_sdma_reqs, .main_clk = "mcbsp1_fck", @@ -3097,6 +3133,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = { .name = "mcbsp2", .class = &omap44xx_mcbsp_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcbsp2_irqs, .sdma_reqs = omap44xx_mcbsp2_sdma_reqs, .main_clk = "mcbsp2_fck", @@ -3179,6 +3216,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = { .name = "mcbsp3", .class = &omap44xx_mcbsp_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcbsp3_irqs, .sdma_reqs = omap44xx_mcbsp3_sdma_reqs, .main_clk = "mcbsp3_fck", @@ -3240,6 +3278,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = { .name = "mcbsp4", .class = &omap44xx_mcbsp_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcbsp4_irqs, .sdma_reqs = omap44xx_mcbsp4_sdma_reqs, .main_clk = "mcbsp4_fck", @@ -3336,6 +3375,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck", @@ -3423,6 +3463,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = { .name = "mcspi1", .class = &omap44xx_mcspi_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcspi1_irqs, .sdma_reqs = omap44xx_mcspi1_sdma_reqs, .main_clk = "mcspi1_fck", @@ -3485,6 +3526,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = { .name = "mcspi2", .class = &omap44xx_mcspi_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcspi2_irqs, .sdma_reqs = omap44xx_mcspi2_sdma_reqs, .main_clk = "mcspi2_fck", @@ -3547,6 +3589,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = { .name = "mcspi3", .class = &omap44xx_mcspi_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcspi3_irqs, .sdma_reqs = omap44xx_mcspi3_sdma_reqs, .main_clk = "mcspi3_fck", @@ -3607,6 +3650,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = { .name = "mcspi4", .class = &omap44xx_mcspi_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcspi4_irqs, .sdma_reqs = omap44xx_mcspi4_sdma_reqs, .main_clk = "mcspi4_fck", @@ -3693,6 +3737,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = { .name = "mmc1", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc1_irqs, .sdma_reqs = omap44xx_mmc1_sdma_reqs, .main_clk = "mmc1_fck", @@ -3754,6 +3799,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = { .name = "mmc2", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc2_irqs, .sdma_reqs = omap44xx_mmc2_sdma_reqs, .main_clk = "mmc2_fck", @@ -3810,6 +3856,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = { .name = "mmc3", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc3_irqs, .sdma_reqs = omap44xx_mmc3_sdma_reqs, .main_clk = "mmc3_fck", @@ -3864,6 +3911,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = { .name = "mmc4", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc4_irqs, .sdma_reqs = omap44xx_mmc4_sdma_reqs, @@ -3919,6 +3967,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = { .name = "mmc5", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc5_irqs, .sdma_reqs = omap44xx_mmc5_sdma_reqs, .main_clk = "mmc5_fck", @@ -3961,7 +4010,8 @@ static struct omap_hwmod omap44xx_mpu_hwmod = { .name = "mpu", .class = &omap44xx_mpu_hwmod_class, .clkdm_name = "mpuss_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_CONTEXT_REG | HWMOD_INIT_NO_IDLE | + HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_mpu_irqs, .main_clk = "dpll_mpu_m2_ck", .prcm = { @@ -4038,6 +4088,7 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { .name = "smartreflex_core", .class = &omap44xx_smartreflex_hwmod_class, .clkdm_name = "l4_ao_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_smartreflex_core_irqs, .main_clk = "smartreflex_core_fck", @@ -4091,6 +4142,7 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { .name = "smartreflex_iva", .class = &omap44xx_smartreflex_hwmod_class, .clkdm_name = "l4_ao_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_smartreflex_iva_irqs, .main_clk = "smartreflex_iva_fck", .prcm = { @@ -4143,6 +4195,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { .name = "smartreflex_mpu", .class = &omap44xx_smartreflex_hwmod_class, .clkdm_name = "l4_ao_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_smartreflex_mpu_irqs, .main_clk = "smartreflex_mpu_fck", .prcm = { @@ -4209,6 +4262,7 @@ static struct omap_hwmod omap44xx_spinlock_hwmod = { .name = "spinlock", .class = &omap44xx_spinlock_hwmod_class, .clkdm_name = "l4_cfg_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET, @@ -4301,6 +4355,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = { .name = "timer1", .class = &omap44xx_timer_1ms_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer1_irqs, .main_clk = "timer1_fck", .prcm = { @@ -4349,6 +4404,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = { .name = "timer2", .class = &omap44xx_timer_1ms_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer2_irqs, .main_clk = "timer2_fck", .prcm = { @@ -4397,6 +4453,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = { .name = "timer3", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer3_irqs, .main_clk = "timer3_fck", .prcm = { @@ -4445,6 +4502,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = { .name = "timer4", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer4_irqs, .main_clk = "timer4_fck", .prcm = { @@ -4512,6 +4570,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = { .name = "timer5", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer5_irqs, .main_clk = "timer5_fck", .prcm = { @@ -4579,6 +4638,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = { .name = "timer6", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer6_irqs, .main_clk = "timer6_fck", @@ -4647,6 +4707,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = { .name = "timer7", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer7_irqs, .main_clk = "timer7_fck", .prcm = { @@ -4714,6 +4775,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = { .name = "timer8", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer8_irqs, .main_clk = "timer8_fck", .prcm = { @@ -4762,6 +4824,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = { .name = "timer9", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer9_irqs, .main_clk = "timer9_fck", .prcm = { @@ -4810,6 +4873,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = { .name = "timer10", .class = &omap44xx_timer_1ms_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer10_irqs, .main_clk = "timer10_fck", .prcm = { @@ -4858,6 +4922,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = { .name = "timer11", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer11_irqs, .main_clk = "timer11_fck", .prcm = { @@ -4934,6 +4999,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = { .name = "uart1", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_uart1_irqs, .sdma_reqs = omap44xx_uart1_sdma_reqs, .main_clk = "uart1_fck", @@ -4988,6 +5054,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = { .name = "uart2", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_uart2_irqs, .sdma_reqs = omap44xx_uart2_sdma_reqs, .main_clk = "uart2_fck", @@ -5042,7 +5109,8 @@ static struct omap_hwmod omap44xx_uart3_hwmod = { .name = "uart3", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_CONTEXT_REG | HWMOD_INIT_NO_IDLE | + HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_uart3_irqs, .sdma_reqs = omap44xx_uart3_sdma_reqs, .main_clk = "uart3_fck", @@ -5097,6 +5165,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = { .name = "uart4", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_uart4_irqs, .sdma_reqs = omap44xx_uart4_sdma_reqs, .main_clk = "uart4_fck", @@ -5177,7 +5246,8 @@ static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = { .name = "usb_otg_hs", .class = &omap44xx_usb_otg_hs_hwmod_class, .clkdm_name = "l3_init_clkdm", - .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .flags = HWMOD_CONTEXT_REG | HWMOD_SWSUP_SIDLE | + HWMOD_SWSUP_MSTANDBY, .mpu_irqs = omap44xx_usb_otg_hs_irqs, .main_clk = "usb_otg_hs_ick", .prcm = { @@ -5252,6 +5322,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = { .name = "wd_timer2", .class = &omap44xx_wd_timer_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_wd_timer2_irqs, .main_clk = "wd_timer2_fck", .prcm = { @@ -5318,6 +5389,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = { .name = "wd_timer3", .class = &omap44xx_wd_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_wd_timer3_irqs, .main_clk = "wd_timer3_fck", .prcm = { @@ -5405,6 +5477,7 @@ static struct omap_hwmod omap44xx_usb_host_hs_hwmod = { .name = "usb_host_hs", .class = &omap44xx_usb_host_hs_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .main_clk = "usb_host_hs_fck", .prcm = { .omap4 = { @@ -5519,6 +5592,7 @@ static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = { .name = "usb_tll_hs", .class = &omap44xx_usb_tll_hs_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .main_clk = "usb_tll_hs_ick", .prcm = { .omap4 = { diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 3f26db4..f247dee 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -401,6 +401,7 @@ struct omap_hwmod_omap4_prcm { * in order to complete the reset. Optional clocks will be disabled * again after the reset. * HWMOD_16BIT_REG: Module has 16bit registers + * HWMOD_CONTEXT_REG: Module has a valid context register */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -411,6 +412,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_NO_IDLEST (1 << 6) #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) #define HWMOD_16BIT_REG (1 << 8) +#define HWMOD_CONTEXT_REG (1 << 9) /* * omap_hwmod._int_flags definitions -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 4/8] ARM: OMAP4: hwmod: flag hwmods/modules supporting module level context status @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel From: Rajendra Nayak <rnayak@ti.com> On OMAP4 most modules/hwmods support module level context status. On OMAP3 and earlier, we relyed on the power domain level context status. Identify all such modules using a 'HWMOD_CONTEXT_REG' flag, all such hwmods already have a valid 'context_offs' populated in .prcm structure. Signed-off-by: Rajendra Nayak <rnayak@ti.com> --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 104 ++++++++++++++++++++++---- arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 + 2 files changed, 91 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index fd305bc..16836ca 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -128,6 +128,7 @@ static struct omap_hwmod omap44xx_dmm_hwmod = { .name = "dmm", .class = &omap44xx_dmm_hwmod_class, .clkdm_name = "l3_emif_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET, @@ -184,6 +185,7 @@ static struct omap_hwmod omap44xx_emif_fw_hwmod = { .name = "emif_fw", .class = &omap44xx_emif_fw_hwmod_class, .clkdm_name = "l3_emif_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET, @@ -229,6 +231,7 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = { .name = "l3_instr", .class = &omap44xx_l3_hwmod_class, .clkdm_name = "l3_instr_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET, @@ -328,6 +331,7 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = { .name = "l3_main_1", .class = &omap44xx_l3_hwmod_class, .clkdm_name = "l3_1_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_l3_main_1_irqs, .prcm = { .omap4 = { @@ -430,6 +434,7 @@ static struct omap_hwmod omap44xx_l3_main_2_hwmod = { .name = "l3_main_2", .class = &omap44xx_l3_hwmod_class, .clkdm_name = "l3_2_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET, @@ -486,6 +491,7 @@ static struct omap_hwmod omap44xx_l3_main_3_hwmod = { .name = "l3_main_3", .class = &omap44xx_l3_hwmod_class, .clkdm_name = "l3_instr_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET, @@ -577,6 +583,7 @@ static struct omap_hwmod omap44xx_l4_cfg_hwmod = { .name = "l4_cfg", .class = &omap44xx_l4_hwmod_class, .clkdm_name = "l4_cfg_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET, @@ -605,6 +612,7 @@ static struct omap_hwmod omap44xx_l4_per_hwmod = { .name = "l4_per", .class = &omap44xx_l4_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET, @@ -633,6 +641,7 @@ static struct omap_hwmod omap44xx_l4_wkup_hwmod = { .name = "l4_wkup", .class = &omap44xx_l4_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET, @@ -807,6 +816,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = { .name = "aess", .class = &omap44xx_aess_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_aess_irqs, .sdma_reqs = omap44xx_aess_sdma_reqs, .main_clk = "aess_fck", @@ -898,7 +908,7 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = { .name = "counter_32k", .class = &omap44xx_counter_hwmod_class, .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, + .flags = HWMOD_CONTEXT_REG | HWMOD_SWSUP_SIDLE, .main_clk = "sys_32k_ck", .prcm = { .omap4 = { @@ -982,6 +992,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = { .name = "dma_system", .class = &omap44xx_dma_hwmod_class, .clkdm_name = "l3_dma_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dma_system_irqs, .main_clk = "l3_div_ck", .prcm = { @@ -1077,6 +1088,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = { .name = "dmic", .class = &omap44xx_dmic_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dmic_irqs, .sdma_reqs = omap44xx_dmic_sdma_reqs, .main_clk = "dmic_fck", @@ -1160,7 +1172,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = { .name = "dsp", .class = &omap44xx_dsp_hwmod_class, .clkdm_name = "tesla_clkdm", - .flags = HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_RESET | HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dsp_irqs, .rst_lines = omap44xx_dsp_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets), @@ -1252,7 +1264,8 @@ static struct omap_hwmod_opt_clk dss_opt_clks[] = { static struct omap_hwmod omap44xx_dss_hwmod = { .name = "dss_core", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .class = &omap44xx_dss_hwmod_class, .clkdm_name = "l3_dss_clkdm", .main_clk = "dss_dss_clk", @@ -1356,6 +1369,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = { .name = "dss_dispc", .class = &omap44xx_dispc_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dss_dispc_irqs, .sdma_reqs = omap44xx_dss_dispc_sdma_reqs, .main_clk = "dss_dss_clk", @@ -1453,6 +1467,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { .name = "dss_dsi1", .class = &omap44xx_dsi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dss_dsi1_irqs, .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs, .main_clk = "dss_dss_clk", @@ -1530,6 +1545,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { .name = "dss_dsi2", .class = &omap44xx_dsi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dss_dsi2_irqs, .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs, .main_clk = "dss_dss_clk", @@ -1627,6 +1643,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { .name = "dss_hdmi", .class = &omap44xx_hdmi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_dss_hdmi_irqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .main_clk = "dss_48mhz_clk", @@ -1719,6 +1736,7 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { .name = "dss_rfbi", .class = &omap44xx_rfbi_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs, .main_clk = "dss_dss_clk", .prcm = { @@ -1790,6 +1808,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { .name = "dss_venc", .class = &omap44xx_venc_hwmod_class, .clkdm_name = "l3_dss_clkdm", + .flags = HWMOD_CONTEXT_REG, .main_clk = "dss_tv_clk", .prcm = { .omap4 = { @@ -1868,6 +1887,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = { .name = "gpio1", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_gpio1_irqs, .main_clk = "gpio1_ick", .prcm = { @@ -1922,7 +1942,8 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = { .name = "gpio2", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio2_irqs, .main_clk = "gpio2_ick", .prcm = { @@ -1977,7 +1998,8 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = { .name = "gpio3", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio3_irqs, .main_clk = "gpio3_ick", .prcm = { @@ -2032,7 +2054,8 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = { .name = "gpio4", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio4_irqs, .main_clk = "gpio4_ick", .prcm = { @@ -2087,7 +2110,8 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = { .name = "gpio5", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio5_irqs, .main_clk = "gpio5_ick", .prcm = { @@ -2142,7 +2166,8 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = { .name = "gpio6", .class = &omap44xx_gpio_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .flags = HWMOD_CONTEXT_REG | + HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio6_irqs, .main_clk = "gpio6_ick", .prcm = { @@ -2223,6 +2248,7 @@ static struct omap_hwmod omap44xx_hsi_hwmod = { .name = "hsi", .class = &omap44xx_hsi_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_hsi_irqs, .main_clk = "hsi_fck", .prcm = { @@ -2306,7 +2332,8 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = { .name = "i2c1", .class = &omap44xx_i2c_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .flags = HWMOD_CONTEXT_REG | HWMOD_16BIT_REG | + HWMOD_SET_DEFAULT_CLOCKACT, .mpu_irqs = omap44xx_i2c1_irqs, .sdma_reqs = omap44xx_i2c1_sdma_reqs, .main_clk = "i2c1_fck", @@ -2362,7 +2389,8 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = { .name = "i2c2", .class = &omap44xx_i2c_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .flags = HWMOD_CONTEXT_REG | HWMOD_16BIT_REG | + HWMOD_SET_DEFAULT_CLOCKACT, .mpu_irqs = omap44xx_i2c2_irqs, .sdma_reqs = omap44xx_i2c2_sdma_reqs, .main_clk = "i2c2_fck", @@ -2418,7 +2446,8 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = { .name = "i2c3", .class = &omap44xx_i2c_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .flags = HWMOD_CONTEXT_REG | HWMOD_16BIT_REG | + HWMOD_SET_DEFAULT_CLOCKACT, .mpu_irqs = omap44xx_i2c3_irqs, .sdma_reqs = omap44xx_i2c3_sdma_reqs, .main_clk = "i2c3_fck", @@ -2474,7 +2503,8 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = { .name = "i2c4", .class = &omap44xx_i2c_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .flags = HWMOD_CONTEXT_REG | HWMOD_16BIT_REG | + HWMOD_SET_DEFAULT_CLOCKACT, .mpu_irqs = omap44xx_i2c4_irqs, .sdma_reqs = omap44xx_i2c4_sdma_reqs, .main_clk = "i2c4_fck", @@ -2569,6 +2599,7 @@ static struct omap_hwmod omap44xx_ipu_hwmod = { .name = "ipu", .class = &omap44xx_ipu_hwmod_class, .clkdm_name = "ducati_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_ipu_irqs, .rst_lines = omap44xx_ipu_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_resets), @@ -2667,6 +2698,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = { .name = "iss", .class = &omap44xx_iss_hwmod_class, .clkdm_name = "iss_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_iss_irqs, .sdma_reqs = omap44xx_iss_sdma_reqs, .main_clk = "iss_fck", @@ -2778,6 +2810,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = { .name = "iva", .class = &omap44xx_iva_hwmod_class, .clkdm_name = "ivahd_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_iva_irqs, .rst_lines = omap44xx_iva_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), @@ -2852,6 +2885,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = { .name = "kbd", .class = &omap44xx_kbd_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_kbd_irqs, .main_clk = "kbd_fck", .prcm = { @@ -2919,6 +2953,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = { .name = "mailbox", .class = &omap44xx_mailbox_hwmod_class, .clkdm_name = "l4_cfg_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mailbox_irqs, .prcm = { .omap4 = { @@ -3015,6 +3050,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = { .name = "mcbsp1", .class = &omap44xx_mcbsp_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcbsp1_irqs, .sdma_reqs = omap44xx_mcbsp1_sdma_reqs, .main_clk = "mcbsp1_fck", @@ -3097,6 +3133,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = { .name = "mcbsp2", .class = &omap44xx_mcbsp_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcbsp2_irqs, .sdma_reqs = omap44xx_mcbsp2_sdma_reqs, .main_clk = "mcbsp2_fck", @@ -3179,6 +3216,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = { .name = "mcbsp3", .class = &omap44xx_mcbsp_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcbsp3_irqs, .sdma_reqs = omap44xx_mcbsp3_sdma_reqs, .main_clk = "mcbsp3_fck", @@ -3240,6 +3278,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = { .name = "mcbsp4", .class = &omap44xx_mcbsp_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcbsp4_irqs, .sdma_reqs = omap44xx_mcbsp4_sdma_reqs, .main_clk = "mcbsp4_fck", @@ -3336,6 +3375,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck", @@ -3423,6 +3463,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = { .name = "mcspi1", .class = &omap44xx_mcspi_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcspi1_irqs, .sdma_reqs = omap44xx_mcspi1_sdma_reqs, .main_clk = "mcspi1_fck", @@ -3485,6 +3526,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = { .name = "mcspi2", .class = &omap44xx_mcspi_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcspi2_irqs, .sdma_reqs = omap44xx_mcspi2_sdma_reqs, .main_clk = "mcspi2_fck", @@ -3547,6 +3589,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = { .name = "mcspi3", .class = &omap44xx_mcspi_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcspi3_irqs, .sdma_reqs = omap44xx_mcspi3_sdma_reqs, .main_clk = "mcspi3_fck", @@ -3607,6 +3650,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = { .name = "mcspi4", .class = &omap44xx_mcspi_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mcspi4_irqs, .sdma_reqs = omap44xx_mcspi4_sdma_reqs, .main_clk = "mcspi4_fck", @@ -3693,6 +3737,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = { .name = "mmc1", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc1_irqs, .sdma_reqs = omap44xx_mmc1_sdma_reqs, .main_clk = "mmc1_fck", @@ -3754,6 +3799,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = { .name = "mmc2", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc2_irqs, .sdma_reqs = omap44xx_mmc2_sdma_reqs, .main_clk = "mmc2_fck", @@ -3810,6 +3856,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = { .name = "mmc3", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc3_irqs, .sdma_reqs = omap44xx_mmc3_sdma_reqs, .main_clk = "mmc3_fck", @@ -3864,6 +3911,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = { .name = "mmc4", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc4_irqs, .sdma_reqs = omap44xx_mmc4_sdma_reqs, @@ -3919,6 +3967,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = { .name = "mmc5", .class = &omap44xx_mmc_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_mmc5_irqs, .sdma_reqs = omap44xx_mmc5_sdma_reqs, .main_clk = "mmc5_fck", @@ -3961,7 +4010,8 @@ static struct omap_hwmod omap44xx_mpu_hwmod = { .name = "mpu", .class = &omap44xx_mpu_hwmod_class, .clkdm_name = "mpuss_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_CONTEXT_REG | HWMOD_INIT_NO_IDLE | + HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_mpu_irqs, .main_clk = "dpll_mpu_m2_ck", .prcm = { @@ -4038,6 +4088,7 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { .name = "smartreflex_core", .class = &omap44xx_smartreflex_hwmod_class, .clkdm_name = "l4_ao_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_smartreflex_core_irqs, .main_clk = "smartreflex_core_fck", @@ -4091,6 +4142,7 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { .name = "smartreflex_iva", .class = &omap44xx_smartreflex_hwmod_class, .clkdm_name = "l4_ao_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_smartreflex_iva_irqs, .main_clk = "smartreflex_iva_fck", .prcm = { @@ -4143,6 +4195,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { .name = "smartreflex_mpu", .class = &omap44xx_smartreflex_hwmod_class, .clkdm_name = "l4_ao_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_smartreflex_mpu_irqs, .main_clk = "smartreflex_mpu_fck", .prcm = { @@ -4209,6 +4262,7 @@ static struct omap_hwmod omap44xx_spinlock_hwmod = { .name = "spinlock", .class = &omap44xx_spinlock_hwmod_class, .clkdm_name = "l4_cfg_clkdm", + .flags = HWMOD_CONTEXT_REG, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET, @@ -4301,6 +4355,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = { .name = "timer1", .class = &omap44xx_timer_1ms_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer1_irqs, .main_clk = "timer1_fck", .prcm = { @@ -4349,6 +4404,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = { .name = "timer2", .class = &omap44xx_timer_1ms_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer2_irqs, .main_clk = "timer2_fck", .prcm = { @@ -4397,6 +4453,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = { .name = "timer3", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer3_irqs, .main_clk = "timer3_fck", .prcm = { @@ -4445,6 +4502,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = { .name = "timer4", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer4_irqs, .main_clk = "timer4_fck", .prcm = { @@ -4512,6 +4570,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = { .name = "timer5", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer5_irqs, .main_clk = "timer5_fck", .prcm = { @@ -4579,6 +4638,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = { .name = "timer6", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer6_irqs, .main_clk = "timer6_fck", @@ -4647,6 +4707,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = { .name = "timer7", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer7_irqs, .main_clk = "timer7_fck", .prcm = { @@ -4714,6 +4775,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = { .name = "timer8", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer8_irqs, .main_clk = "timer8_fck", .prcm = { @@ -4762,6 +4824,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = { .name = "timer9", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer9_irqs, .main_clk = "timer9_fck", .prcm = { @@ -4810,6 +4873,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = { .name = "timer10", .class = &omap44xx_timer_1ms_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer10_irqs, .main_clk = "timer10_fck", .prcm = { @@ -4858,6 +4922,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = { .name = "timer11", .class = &omap44xx_timer_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_timer11_irqs, .main_clk = "timer11_fck", .prcm = { @@ -4934,6 +4999,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = { .name = "uart1", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_uart1_irqs, .sdma_reqs = omap44xx_uart1_sdma_reqs, .main_clk = "uart1_fck", @@ -4988,6 +5054,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = { .name = "uart2", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_uart2_irqs, .sdma_reqs = omap44xx_uart2_sdma_reqs, .main_clk = "uart2_fck", @@ -5042,7 +5109,8 @@ static struct omap_hwmod omap44xx_uart3_hwmod = { .name = "uart3", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_CONTEXT_REG | HWMOD_INIT_NO_IDLE | + HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_uart3_irqs, .sdma_reqs = omap44xx_uart3_sdma_reqs, .main_clk = "uart3_fck", @@ -5097,6 +5165,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = { .name = "uart4", .class = &omap44xx_uart_hwmod_class, .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_uart4_irqs, .sdma_reqs = omap44xx_uart4_sdma_reqs, .main_clk = "uart4_fck", @@ -5177,7 +5246,8 @@ static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = { .name = "usb_otg_hs", .class = &omap44xx_usb_otg_hs_hwmod_class, .clkdm_name = "l3_init_clkdm", - .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .flags = HWMOD_CONTEXT_REG | HWMOD_SWSUP_SIDLE | + HWMOD_SWSUP_MSTANDBY, .mpu_irqs = omap44xx_usb_otg_hs_irqs, .main_clk = "usb_otg_hs_ick", .prcm = { @@ -5252,6 +5322,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = { .name = "wd_timer2", .class = &omap44xx_wd_timer_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_wd_timer2_irqs, .main_clk = "wd_timer2_fck", .prcm = { @@ -5318,6 +5389,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = { .name = "wd_timer3", .class = &omap44xx_wd_timer_hwmod_class, .clkdm_name = "abe_clkdm", + .flags = HWMOD_CONTEXT_REG, .mpu_irqs = omap44xx_wd_timer3_irqs, .main_clk = "wd_timer3_fck", .prcm = { @@ -5405,6 +5477,7 @@ static struct omap_hwmod omap44xx_usb_host_hs_hwmod = { .name = "usb_host_hs", .class = &omap44xx_usb_host_hs_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .main_clk = "usb_host_hs_fck", .prcm = { .omap4 = { @@ -5519,6 +5592,7 @@ static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = { .name = "usb_tll_hs", .class = &omap44xx_usb_tll_hs_hwmod_class, .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_CONTEXT_REG, .main_clk = "usb_tll_hs_ick", .prcm = { .omap4 = { diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 3f26db4..f247dee 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -401,6 +401,7 @@ struct omap_hwmod_omap4_prcm { * in order to complete the reset. Optional clocks will be disabled * again after the reset. * HWMOD_16BIT_REG: Module has 16bit registers + * HWMOD_CONTEXT_REG: Module has a valid context register */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -411,6 +412,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_NO_IDLEST (1 << 6) #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) #define HWMOD_16BIT_REG (1 << 8) +#define HWMOD_CONTEXT_REG (1 << 9) /* * omap_hwmod._int_flags definitions -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 5/8] ARM: OMAP: hwmod: Add support for per hwmod/module context lost count 2012-05-14 10:03 ` Tero Kristo @ 2012-05-14 10:03 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel, Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> OMAP4 has module specific context lost registers which makes it now possible to have module level context loss count, instead of relying on the powerdomain level context count. Add 2 private hwmod api's to update/clear the hwmod/module specific context lost counters/register. Update the module specific context_lost_counter and clear the hardware bits just after enabling the module. omap_hwmod_get_context_loss_count() now returns the hwmod context loss count them on platforms where they exist (OMAP4), else fall back on the pwrdm level counters for older platforms. Signed-off-by: Rajendra Nayak <rnayak@ti.com> [paul@pwsan.com: added function kerneldoc, fixed structure kerneldoc, rearranged structure to avoid memory waste, marked fns as OMAP4-specific, prevent fn entry on non-OMAP4 chips, reduced indentation, merged update and clear, merged patches] Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/omap_hwmod.c | 44 +++++++++++++++++++++++-- arch/arm/plat-omap/include/plat/omap_hwmod.h | 8 +++- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 8683d6f..601f5a5f 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1520,6 +1520,36 @@ static void _reconfigure_io_chain(void) } /** + * _omap4_update_context_lost - increment hwmod context loss counter if + * hwmod context was lost, and clear hardware context loss reg + * @oh: hwmod to check for context loss + * + * If the PRCM indicates that the hwmod @oh lost context, increment + * our in-memory context loss counter, and clear the RM_*_CONTEXT + * bits. No return value. + */ +static void _omap4_update_context_lost(struct omap_hwmod *oh) +{ + u32 r; + + if (!(oh->flags & HWMOD_CONTEXT_REG)) + return; + + r = omap4_prminst_read_inst_reg(oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.context_offs); + + if (!r) + return; + + oh->prcm.omap4.context_lost_counter++; + + omap4_prminst_write_inst_reg(r, oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.context_offs); +} + +/** * _enable - enable an omap_hwmod * @oh: struct omap_hwmod * * @@ -1599,6 +1629,8 @@ static int _enable(struct omap_hwmod *oh) _enable_clocks(oh); _enable_module(oh); + _omap4_update_context_lost(oh); + r = _wait_target_ready(oh); if (!r) { /* @@ -2724,17 +2756,21 @@ ohsps_unlock: * omap_hwmod_get_context_loss_count - get lost context count * @oh: struct omap_hwmod * * - * Query the powerdomain of of @oh to get the context loss - * count for this device. + * Returns the context loss count of associated @oh + * upon success, or zero if no context loss data is available. * - * Returns the context loss count of the powerdomain assocated with @oh - * upon success, or zero if no powerdomain exists for @oh. + * On OMAP4, this queries the per-hwmod context loss register, + * assuming one exists. If not, or on OMAP2/3, this queries the + * enclosing powerdomain context loss count. */ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh) { struct powerdomain *pwrdm; int ret = 0; + if (oh->flags & HWMOD_CONTEXT_REG) + return oh->prcm.omap4.context_lost_counter; + pwrdm = omap_hwmod_get_pwrdm(oh); if (pwrdm) ret = pwrdm_get_context_loss_count(pwrdm); diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index f247dee..8f5510b 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -364,9 +364,12 @@ struct omap_hwmod_omap2_prcm { /** * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data - * @clkctrl_reg: PRCM address of the clock control register - * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM + * @clkctrl_offs: offset of the PRCM clock control register + * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM + * @context_offs: offset of the RM_*_CONTEXT register * @submodule_wkdep_bit: bit shift of the WKDEP range + * @modulemode: allowable modulemodes + * @context_lost_counter: Count of module level context lost */ struct omap_hwmod_omap4_prcm { u16 clkctrl_offs; @@ -374,6 +377,7 @@ struct omap_hwmod_omap4_prcm { u16 context_offs; u8 submodule_wkdep_bit; u8 modulemode; + unsigned context_lost_counter; }; -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 5/8] ARM: OMAP: hwmod: Add support for per hwmod/module context lost count @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel From: Rajendra Nayak <rnayak@ti.com> OMAP4 has module specific context lost registers which makes it now possible to have module level context loss count, instead of relying on the powerdomain level context count. Add 2 private hwmod api's to update/clear the hwmod/module specific context lost counters/register. Update the module specific context_lost_counter and clear the hardware bits just after enabling the module. omap_hwmod_get_context_loss_count() now returns the hwmod context loss count them on platforms where they exist (OMAP4), else fall back on the pwrdm level counters for older platforms. Signed-off-by: Rajendra Nayak <rnayak@ti.com> [paul at pwsan.com: added function kerneldoc, fixed structure kerneldoc, rearranged structure to avoid memory waste, marked fns as OMAP4-specific, prevent fn entry on non-OMAP4 chips, reduced indentation, merged update and clear, merged patches] Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/omap_hwmod.c | 44 +++++++++++++++++++++++-- arch/arm/plat-omap/include/plat/omap_hwmod.h | 8 +++- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 8683d6f..601f5a5f 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1520,6 +1520,36 @@ static void _reconfigure_io_chain(void) } /** + * _omap4_update_context_lost - increment hwmod context loss counter if + * hwmod context was lost, and clear hardware context loss reg + * @oh: hwmod to check for context loss + * + * If the PRCM indicates that the hwmod @oh lost context, increment + * our in-memory context loss counter, and clear the RM_*_CONTEXT + * bits. No return value. + */ +static void _omap4_update_context_lost(struct omap_hwmod *oh) +{ + u32 r; + + if (!(oh->flags & HWMOD_CONTEXT_REG)) + return; + + r = omap4_prminst_read_inst_reg(oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.context_offs); + + if (!r) + return; + + oh->prcm.omap4.context_lost_counter++; + + omap4_prminst_write_inst_reg(r, oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.context_offs); +} + +/** * _enable - enable an omap_hwmod * @oh: struct omap_hwmod * * @@ -1599,6 +1629,8 @@ static int _enable(struct omap_hwmod *oh) _enable_clocks(oh); _enable_module(oh); + _omap4_update_context_lost(oh); + r = _wait_target_ready(oh); if (!r) { /* @@ -2724,17 +2756,21 @@ ohsps_unlock: * omap_hwmod_get_context_loss_count - get lost context count * @oh: struct omap_hwmod * * - * Query the powerdomain of of @oh to get the context loss - * count for this device. + * Returns the context loss count of associated @oh + * upon success, or zero if no context loss data is available. * - * Returns the context loss count of the powerdomain assocated with @oh - * upon success, or zero if no powerdomain exists for @oh. + * On OMAP4, this queries the per-hwmod context loss register, + * assuming one exists. If not, or on OMAP2/3, this queries the + * enclosing powerdomain context loss count. */ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh) { struct powerdomain *pwrdm; int ret = 0; + if (oh->flags & HWMOD_CONTEXT_REG) + return oh->prcm.omap4.context_lost_counter; + pwrdm = omap_hwmod_get_pwrdm(oh); if (pwrdm) ret = pwrdm_get_context_loss_count(pwrdm); diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index f247dee..8f5510b 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -364,9 +364,12 @@ struct omap_hwmod_omap2_prcm { /** * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data - * @clkctrl_reg: PRCM address of the clock control register - * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM + * @clkctrl_offs: offset of the PRCM clock control register + * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM + * @context_offs: offset of the RM_*_CONTEXT register * @submodule_wkdep_bit: bit shift of the WKDEP range + * @modulemode: allowable modulemodes + * @context_lost_counter: Count of module level context lost */ struct omap_hwmod_omap4_prcm { u16 clkctrl_offs; @@ -374,6 +377,7 @@ struct omap_hwmod_omap4_prcm { u16 context_offs; u8 submodule_wkdep_bit; u8 modulemode; + unsigned context_lost_counter; }; -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCHv5 5/8] ARM: OMAP: hwmod: Add support for per hwmod/module context lost count 2012-05-14 10:03 ` Tero Kristo @ 2012-05-29 19:32 ` Menon, Nishanth -1 siblings, 0 replies; 56+ messages in thread From: Menon, Nishanth @ 2012-05-29 19:32 UTC (permalink / raw) To: Tero Kristo; +Cc: linux-omap, khilman, paul, Rajendra Nayak, linux-arm-kernel On Mon, May 14, 2012 at 5:03 AM, Tero Kristo <t-kristo@ti.com> wrote: [...] > +/** > * _enable - enable an omap_hwmod > * @oh: struct omap_hwmod * > * > @@ -1599,6 +1629,8 @@ static int _enable(struct omap_hwmod *oh) > _enable_clocks(oh); > _enable_module(oh); > > + _omap4_update_context_lost(oh); > + > r = _wait_target_ready(oh); > if (!r) { > /* Dumb q: Since we monitor the count around _enable, how do we ensure that context loss counter is accurate around OFF and idle transitions for domains that could have been hwauto? it might be good to have limitations in the $commit_message if it is not targeted to do so. Regards, Nishanth Menon -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 5/8] ARM: OMAP: hwmod: Add support for per hwmod/module context lost count @ 2012-05-29 19:32 ` Menon, Nishanth 0 siblings, 0 replies; 56+ messages in thread From: Menon, Nishanth @ 2012-05-29 19:32 UTC (permalink / raw) To: linux-arm-kernel On Mon, May 14, 2012 at 5:03 AM, Tero Kristo <t-kristo@ti.com> wrote: [...] > +/** > ?* _enable - enable an omap_hwmod > ?* @oh: struct omap_hwmod * > ?* > @@ -1599,6 +1629,8 @@ static int _enable(struct omap_hwmod *oh) > ? ? ? ?_enable_clocks(oh); > ? ? ? ?_enable_module(oh); > > + ? ? ? _omap4_update_context_lost(oh); > + > ? ? ? ?r = _wait_target_ready(oh); > ? ? ? ?if (!r) { > ? ? ? ? ? ? ? ?/* Dumb q: Since we monitor the count around _enable, how do we ensure that context loss counter is accurate around OFF and idle transitions for domains that could have been hwauto? it might be good to have limitations in the $commit_message if it is not targeted to do so. Regards, Nishanth Menon ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 5/8] ARM: OMAP: hwmod: Add support for per hwmod/module context lost count 2012-05-29 19:32 ` Menon, Nishanth @ 2012-05-30 8:02 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-30 8:02 UTC (permalink / raw) To: Menon, Nishanth Cc: linux-omap, khilman, paul, Rajendra Nayak, linux-arm-kernel On Tue, 2012-05-29 at 14:32 -0500, Menon, Nishanth wrote: > On Mon, May 14, 2012 at 5:03 AM, Tero Kristo <t-kristo@ti.com> wrote: > [...] > > +/** > > * _enable - enable an omap_hwmod > > * @oh: struct omap_hwmod * > > * > > @@ -1599,6 +1629,8 @@ static int _enable(struct omap_hwmod *oh) > > _enable_clocks(oh); > > _enable_module(oh); > > > > + _omap4_update_context_lost(oh); > > + > > r = _wait_target_ready(oh); > > if (!r) { > > /* > > Dumb q: Since we monitor the count around _enable, how do we ensure > that context loss counter is accurate > around OFF and idle transitions for domains that could have been > hwauto? it might be good to have limitations > in the $commit_message if it is not targeted to do so. True, I can add a comment to the commit msg about this. -Tero ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 5/8] ARM: OMAP: hwmod: Add support for per hwmod/module context lost count @ 2012-05-30 8:02 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-30 8:02 UTC (permalink / raw) To: linux-arm-kernel On Tue, 2012-05-29 at 14:32 -0500, Menon, Nishanth wrote: > On Mon, May 14, 2012 at 5:03 AM, Tero Kristo <t-kristo@ti.com> wrote: > [...] > > +/** > > * _enable - enable an omap_hwmod > > * @oh: struct omap_hwmod * > > * > > @@ -1599,6 +1629,8 @@ static int _enable(struct omap_hwmod *oh) > > _enable_clocks(oh); > > _enable_module(oh); > > > > + _omap4_update_context_lost(oh); > > + > > r = _wait_target_ready(oh); > > if (!r) { > > /* > > Dumb q: Since we monitor the count around _enable, how do we ensure > that context loss counter is accurate > around OFF and idle transitions for domains that could have been > hwauto? it might be good to have limitations > in the $commit_message if it is not targeted to do so. True, I can add a comment to the commit msg about this. -Tero ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 6/8] ARM: OMAP4: pwrdm: add support for reading prev logic and mem states 2012-05-14 10:03 ` Tero Kristo @ 2012-05-14 10:03 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel On OMAP4, there is no support to read previous logic state or previous memory state achieved when a power domain transitions to RET. Instead there are module level context registers. In order to support the powerdomain level logic/mem_off_counters on OMAP4, instead use the previous power state achieved (RET) and the *programmed* logic/mem RET state to derive if a powerdomain lost logic or did not. If the powerdomain is programmed to enter RET state and lose logic in RET state, knowing that the powerdomain entered RET is good enough to derive that the logic was lost as well, in such cases. Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/powerdomain44xx.c | 32 ++++++++++++++++++++++++++++++++ 1 files changed, 32 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c index 601325b..ab00736 100644 --- a/arch/arm/mach-omap2/powerdomain44xx.c +++ b/arch/arm/mach-omap2/powerdomain44xx.c @@ -151,6 +151,21 @@ static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) return v; } +static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) +{ + int state; + + state = omap4_pwrdm_read_prev_pwrst(pwrdm); + + if (state == PWRDM_POWER_OFF) + return PWRDM_POWER_OFF; + + if (state != PWRDM_POWER_RET) + return PWRDM_POWER_ON; + + return omap4_pwrdm_read_logic_retst(pwrdm); +} + static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) { u32 m, v; @@ -179,6 +194,21 @@ static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) return v; } +static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + int state; + + state = omap4_pwrdm_read_prev_pwrst(pwrdm); + + if (state == PWRDM_POWER_OFF) + return PWRDM_POWER_OFF; + + if (state != PWRDM_POWER_RET) + return PWRDM_POWER_ON; + + return omap4_pwrdm_read_mem_retst(pwrdm, bank); +} + static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) { u32 c = 0; @@ -217,9 +247,11 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, + .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst, .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, + .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst, .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, .pwrdm_wait_transition = omap4_pwrdm_wait_transition, -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 6/8] ARM: OMAP4: pwrdm: add support for reading prev logic and mem states @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel On OMAP4, there is no support to read previous logic state or previous memory state achieved when a power domain transitions to RET. Instead there are module level context registers. In order to support the powerdomain level logic/mem_off_counters on OMAP4, instead use the previous power state achieved (RET) and the *programmed* logic/mem RET state to derive if a powerdomain lost logic or did not. If the powerdomain is programmed to enter RET state and lose logic in RET state, knowing that the powerdomain entered RET is good enough to derive that the logic was lost as well, in such cases. Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/powerdomain44xx.c | 32 ++++++++++++++++++++++++++++++++ 1 files changed, 32 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c index 601325b..ab00736 100644 --- a/arch/arm/mach-omap2/powerdomain44xx.c +++ b/arch/arm/mach-omap2/powerdomain44xx.c @@ -151,6 +151,21 @@ static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) return v; } +static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) +{ + int state; + + state = omap4_pwrdm_read_prev_pwrst(pwrdm); + + if (state == PWRDM_POWER_OFF) + return PWRDM_POWER_OFF; + + if (state != PWRDM_POWER_RET) + return PWRDM_POWER_ON; + + return omap4_pwrdm_read_logic_retst(pwrdm); +} + static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) { u32 m, v; @@ -179,6 +194,21 @@ static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) return v; } +static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + int state; + + state = omap4_pwrdm_read_prev_pwrst(pwrdm); + + if (state == PWRDM_POWER_OFF) + return PWRDM_POWER_OFF; + + if (state != PWRDM_POWER_RET) + return PWRDM_POWER_ON; + + return omap4_pwrdm_read_mem_retst(pwrdm, bank); +} + static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) { u32 c = 0; @@ -217,9 +247,11 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, + .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst, .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, + .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst, .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, .pwrdm_wait_transition = omap4_pwrdm_wait_transition, -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCHv5 6/8] ARM: OMAP4: pwrdm: add support for reading prev logic and mem states 2012-05-14 10:03 ` Tero Kristo @ 2012-05-15 22:36 ` Kevin Hilman -1 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-15 22:36 UTC (permalink / raw) To: Tero Kristo; +Cc: linux-omap, paul, linux-arm-kernel Tero Kristo <t-kristo@ti.com> writes: > On OMAP4, there is no support to read previous logic state > or previous memory state achieved when a power domain transitions > to RET. Instead there are module level context registers. > > In order to support the powerdomain level logic/mem_off_counters > on OMAP4, instead use the previous power state achieved (RET) and > the *programmed* logic/mem RET state to derive if a powerdomain lost > logic or did not. > > If the powerdomain is programmed to enter RET state and lose logic > in RET state, knowing that the powerdomain entered RET is good enough > to derive that the logic was lost as well, in such cases. > > Signed-off-by: Tero Kristo <t-kristo@ti.com> Looks OK, but these new functions need some kerneldoc to describe the decision making. Kevin > --- > arch/arm/mach-omap2/powerdomain44xx.c | 32 ++++++++++++++++++++++++++++++++ > 1 files changed, 32 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c > index 601325b..ab00736 100644 > --- a/arch/arm/mach-omap2/powerdomain44xx.c > +++ b/arch/arm/mach-omap2/powerdomain44xx.c > @@ -151,6 +151,21 @@ static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) > return v; > } > > +static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) > +{ > + int state; > + > + state = omap4_pwrdm_read_prev_pwrst(pwrdm); > + > + if (state == PWRDM_POWER_OFF) > + return PWRDM_POWER_OFF; > + > + if (state != PWRDM_POWER_RET) > + return PWRDM_POWER_ON; > + > + return omap4_pwrdm_read_logic_retst(pwrdm); > +} > + > static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) > { > u32 m, v; > @@ -179,6 +194,21 @@ static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) > return v; > } > > +static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) > +{ > + int state; > + > + state = omap4_pwrdm_read_prev_pwrst(pwrdm); > + > + if (state == PWRDM_POWER_OFF) > + return PWRDM_POWER_OFF; > + > + if (state != PWRDM_POWER_RET) > + return PWRDM_POWER_ON; > + > + return omap4_pwrdm_read_mem_retst(pwrdm, bank); > +} > + > static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) > { > u32 c = 0; > @@ -217,9 +247,11 @@ struct pwrdm_ops omap4_pwrdm_operations = { > .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, > .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, > .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, > + .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst, > .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, > .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, > .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, > + .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst, > .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, > .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, > .pwrdm_wait_transition = omap4_pwrdm_wait_transition, ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 6/8] ARM: OMAP4: pwrdm: add support for reading prev logic and mem states @ 2012-05-15 22:36 ` Kevin Hilman 0 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-15 22:36 UTC (permalink / raw) To: linux-arm-kernel Tero Kristo <t-kristo@ti.com> writes: > On OMAP4, there is no support to read previous logic state > or previous memory state achieved when a power domain transitions > to RET. Instead there are module level context registers. > > In order to support the powerdomain level logic/mem_off_counters > on OMAP4, instead use the previous power state achieved (RET) and > the *programmed* logic/mem RET state to derive if a powerdomain lost > logic or did not. > > If the powerdomain is programmed to enter RET state and lose logic > in RET state, knowing that the powerdomain entered RET is good enough > to derive that the logic was lost as well, in such cases. > > Signed-off-by: Tero Kristo <t-kristo@ti.com> Looks OK, but these new functions need some kerneldoc to describe the decision making. Kevin > --- > arch/arm/mach-omap2/powerdomain44xx.c | 32 ++++++++++++++++++++++++++++++++ > 1 files changed, 32 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c > index 601325b..ab00736 100644 > --- a/arch/arm/mach-omap2/powerdomain44xx.c > +++ b/arch/arm/mach-omap2/powerdomain44xx.c > @@ -151,6 +151,21 @@ static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) > return v; > } > > +static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) > +{ > + int state; > + > + state = omap4_pwrdm_read_prev_pwrst(pwrdm); > + > + if (state == PWRDM_POWER_OFF) > + return PWRDM_POWER_OFF; > + > + if (state != PWRDM_POWER_RET) > + return PWRDM_POWER_ON; > + > + return omap4_pwrdm_read_logic_retst(pwrdm); > +} > + > static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) > { > u32 m, v; > @@ -179,6 +194,21 @@ static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) > return v; > } > > +static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) > +{ > + int state; > + > + state = omap4_pwrdm_read_prev_pwrst(pwrdm); > + > + if (state == PWRDM_POWER_OFF) > + return PWRDM_POWER_OFF; > + > + if (state != PWRDM_POWER_RET) > + return PWRDM_POWER_ON; > + > + return omap4_pwrdm_read_mem_retst(pwrdm, bank); > +} > + > static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) > { > u32 c = 0; > @@ -217,9 +247,11 @@ struct pwrdm_ops omap4_pwrdm_operations = { > .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, > .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, > .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, > + .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst, > .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, > .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, > .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, > + .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst, > .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, > .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, > .pwrdm_wait_transition = omap4_pwrdm_wait_transition, ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 6/8] ARM: OMAP4: pwrdm: add support for reading prev logic and mem states 2012-05-15 22:36 ` Kevin Hilman @ 2012-05-16 8:55 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-16 8:55 UTC (permalink / raw) To: Kevin Hilman; +Cc: linux-omap, paul, linux-arm-kernel On Tue, 2012-05-15 at 15:36 -0700, Kevin Hilman wrote: > Tero Kristo <t-kristo@ti.com> writes: > > > On OMAP4, there is no support to read previous logic state > > or previous memory state achieved when a power domain transitions > > to RET. Instead there are module level context registers. > > > > In order to support the powerdomain level logic/mem_off_counters > > on OMAP4, instead use the previous power state achieved (RET) and > > the *programmed* logic/mem RET state to derive if a powerdomain lost > > logic or did not. > > > > If the powerdomain is programmed to enter RET state and lose logic > > in RET state, knowing that the powerdomain entered RET is good enough > > to derive that the logic was lost as well, in such cases. > > > > Signed-off-by: Tero Kristo <t-kristo@ti.com> > > Looks OK, but these new functions need some kerneldoc to describe the > decision making. Will add. -Tero > > Kevin > > > --- > > arch/arm/mach-omap2/powerdomain44xx.c | 32 ++++++++++++++++++++++++++++++++ > > 1 files changed, 32 insertions(+), 0 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c > > index 601325b..ab00736 100644 > > --- a/arch/arm/mach-omap2/powerdomain44xx.c > > +++ b/arch/arm/mach-omap2/powerdomain44xx.c > > @@ -151,6 +151,21 @@ static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) > > return v; > > } > > > > +static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) > > +{ > > + int state; > > + > > + state = omap4_pwrdm_read_prev_pwrst(pwrdm); > > + > > + if (state == PWRDM_POWER_OFF) > > + return PWRDM_POWER_OFF; > > + > > + if (state != PWRDM_POWER_RET) > > + return PWRDM_POWER_ON; > > + > > + return omap4_pwrdm_read_logic_retst(pwrdm); > > +} > > + > > static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) > > { > > u32 m, v; > > @@ -179,6 +194,21 @@ static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) > > return v; > > } > > > > +static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) > > +{ > > + int state; > > + > > + state = omap4_pwrdm_read_prev_pwrst(pwrdm); > > + > > + if (state == PWRDM_POWER_OFF) > > + return PWRDM_POWER_OFF; > > + > > + if (state != PWRDM_POWER_RET) > > + return PWRDM_POWER_ON; > > + > > + return omap4_pwrdm_read_mem_retst(pwrdm, bank); > > +} > > + > > static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) > > { > > u32 c = 0; > > @@ -217,9 +247,11 @@ struct pwrdm_ops omap4_pwrdm_operations = { > > .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, > > .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, > > .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, > > + .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst, > > .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, > > .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, > > .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, > > + .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst, > > .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, > > .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, > > .pwrdm_wait_transition = omap4_pwrdm_wait_transition, ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 6/8] ARM: OMAP4: pwrdm: add support for reading prev logic and mem states @ 2012-05-16 8:55 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-16 8:55 UTC (permalink / raw) To: linux-arm-kernel On Tue, 2012-05-15 at 15:36 -0700, Kevin Hilman wrote: > Tero Kristo <t-kristo@ti.com> writes: > > > On OMAP4, there is no support to read previous logic state > > or previous memory state achieved when a power domain transitions > > to RET. Instead there are module level context registers. > > > > In order to support the powerdomain level logic/mem_off_counters > > on OMAP4, instead use the previous power state achieved (RET) and > > the *programmed* logic/mem RET state to derive if a powerdomain lost > > logic or did not. > > > > If the powerdomain is programmed to enter RET state and lose logic > > in RET state, knowing that the powerdomain entered RET is good enough > > to derive that the logic was lost as well, in such cases. > > > > Signed-off-by: Tero Kristo <t-kristo@ti.com> > > Looks OK, but these new functions need some kerneldoc to describe the > decision making. Will add. -Tero > > Kevin > > > --- > > arch/arm/mach-omap2/powerdomain44xx.c | 32 ++++++++++++++++++++++++++++++++ > > 1 files changed, 32 insertions(+), 0 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c > > index 601325b..ab00736 100644 > > --- a/arch/arm/mach-omap2/powerdomain44xx.c > > +++ b/arch/arm/mach-omap2/powerdomain44xx.c > > @@ -151,6 +151,21 @@ static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) > > return v; > > } > > > > +static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) > > +{ > > + int state; > > + > > + state = omap4_pwrdm_read_prev_pwrst(pwrdm); > > + > > + if (state == PWRDM_POWER_OFF) > > + return PWRDM_POWER_OFF; > > + > > + if (state != PWRDM_POWER_RET) > > + return PWRDM_POWER_ON; > > + > > + return omap4_pwrdm_read_logic_retst(pwrdm); > > +} > > + > > static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) > > { > > u32 m, v; > > @@ -179,6 +194,21 @@ static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) > > return v; > > } > > > > +static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) > > +{ > > + int state; > > + > > + state = omap4_pwrdm_read_prev_pwrst(pwrdm); > > + > > + if (state == PWRDM_POWER_OFF) > > + return PWRDM_POWER_OFF; > > + > > + if (state != PWRDM_POWER_RET) > > + return PWRDM_POWER_ON; > > + > > + return omap4_pwrdm_read_mem_retst(pwrdm, bank); > > +} > > + > > static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) > > { > > u32 c = 0; > > @@ -217,9 +247,11 @@ struct pwrdm_ops omap4_pwrdm_operations = { > > .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, > > .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, > > .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, > > + .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst, > > .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, > > .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, > > .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, > > + .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst, > > .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, > > .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, > > .pwrdm_wait_transition = omap4_pwrdm_wait_transition, ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 7/8] ARM: OMAP4: PM: Add next_logic_state param to power_state 2012-05-14 10:03 ` Tero Kristo @ 2012-05-14 10:03 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel This will make it easier to handle next logic states for power domains during suspend. With this patch, the parameter is also programmed to retention for every powerdomain, thus all powerdomains enter CSWR state after this patch. Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/pm44xx.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 31990d5..cc85576 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -26,6 +26,7 @@ struct power_state { struct powerdomain *pwrdm; u32 next_state; + u32 next_logic_state; #ifdef CONFIG_SUSPEND u32 saved_state; u32 saved_logic_state; @@ -51,7 +52,7 @@ static int omap4_pm_suspend(void) /* Set targeted power domain states by suspend */ list_for_each_entry(pwrst, &pwrst_list, node) { omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); - pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF); + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); } /* @@ -108,6 +109,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) pwrst->pwrdm = pwrdm; pwrst->next_state = PWRDM_POWER_RET; + pwrst->next_logic_state = PWRDM_POWER_RET; list_add(&pwrst->node, &pwrst_list); return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 7/8] ARM: OMAP4: PM: Add next_logic_state param to power_state @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel This will make it easier to handle next logic states for power domains during suspend. With this patch, the parameter is also programmed to retention for every powerdomain, thus all powerdomains enter CSWR state after this patch. Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/pm44xx.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 31990d5..cc85576 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -26,6 +26,7 @@ struct power_state { struct powerdomain *pwrdm; u32 next_state; + u32 next_logic_state; #ifdef CONFIG_SUSPEND u32 saved_state; u32 saved_logic_state; @@ -51,7 +52,7 @@ static int omap4_pm_suspend(void) /* Set targeted power domain states by suspend */ list_for_each_entry(pwrst, &pwrst_list, node) { omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); - pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF); + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); } /* @@ -108,6 +109,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) pwrst->pwrdm = pwrdm; pwrst->next_state = PWRDM_POWER_RET; + pwrst->next_logic_state = PWRDM_POWER_RET; list_add(&pwrst->node, &pwrst_list); return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR 2012-05-14 10:03 ` Tero Kristo @ 2012-05-14 10:03 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-omap, khilman, paul; +Cc: linux-arm-kernel PM debug now contains a file that can be used to control OSWR support enable / disable on OMAP4. Also removed the off_mode_enable file for the same platform as it is unsupported. Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/pm-debug.c | 20 ++++++++++++++++---- arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm44xx.c | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 814bcd9..d9a8e42 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -39,6 +39,7 @@ #include "pm.h" u32 enable_off_mode; +static u32 enable_oswr_mode; #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> @@ -247,10 +248,13 @@ static int option_set(void *data, u64 val) omap_pm_enable_off_mode(); else omap_pm_disable_off_mode(); - if (cpu_is_omap34xx()) - omap3_pm_off_mode_enable(val); + + omap3_pm_off_mode_enable(val); } + if (option == &enable_oswr_mode) + omap4_pm_oswr_mode_enable(val); + return 0; } @@ -274,8 +278,16 @@ static int __init pm_dbg_init(void) pwrdm_for_each(pwrdms_setup, (void *)d); - (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, - &enable_off_mode, &pm_dbg_option_fops); + if (cpu_is_omap34xx()) + (void) debugfs_create_file("enable_off_mode", + S_IRUGO | S_IWUSR, d, &enable_off_mode, + &pm_dbg_option_fops); + + if (cpu_is_omap44xx()) + (void) debugfs_create_file("enable_oswr_mode", + S_IRUGO | S_IWUSR, d, &enable_oswr_mode, + &pm_dbg_option_fops); + pm_dbg_init_done = 1; return 0; diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 36fa90b..c36ab63 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -17,6 +17,7 @@ extern void *omap3_secure_ram_storage; extern void omap3_pm_off_mode_enable(int); +extern void omap4_pm_oswr_mode_enable(int); extern void omap_sram_idle(void); extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); extern int omap3_idle_init(void); diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index cc85576..07ac0d3 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -115,6 +115,22 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); } +void omap4_pm_oswr_mode_enable(int enable) +{ + u32 next_logic_state; + struct power_state *pwrst; + + if (enable) + next_logic_state = PWRDM_POWER_OFF; + else + next_logic_state = PWRDM_POWER_RET; + + list_for_each_entry(pwrst, &pwrst_list, node) { + pwrst->next_logic_state = next_logic_state; + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); + } +} + /** * omap_default_idle - OMAP4 default ilde routine.' * -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR @ 2012-05-14 10:03 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-14 10:03 UTC (permalink / raw) To: linux-arm-kernel PM debug now contains a file that can be used to control OSWR support enable / disable on OMAP4. Also removed the off_mode_enable file for the same platform as it is unsupported. Signed-off-by: Tero Kristo <t-kristo@ti.com> --- arch/arm/mach-omap2/pm-debug.c | 20 ++++++++++++++++---- arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm44xx.c | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 814bcd9..d9a8e42 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -39,6 +39,7 @@ #include "pm.h" u32 enable_off_mode; +static u32 enable_oswr_mode; #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> @@ -247,10 +248,13 @@ static int option_set(void *data, u64 val) omap_pm_enable_off_mode(); else omap_pm_disable_off_mode(); - if (cpu_is_omap34xx()) - omap3_pm_off_mode_enable(val); + + omap3_pm_off_mode_enable(val); } + if (option == &enable_oswr_mode) + omap4_pm_oswr_mode_enable(val); + return 0; } @@ -274,8 +278,16 @@ static int __init pm_dbg_init(void) pwrdm_for_each(pwrdms_setup, (void *)d); - (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, - &enable_off_mode, &pm_dbg_option_fops); + if (cpu_is_omap34xx()) + (void) debugfs_create_file("enable_off_mode", + S_IRUGO | S_IWUSR, d, &enable_off_mode, + &pm_dbg_option_fops); + + if (cpu_is_omap44xx()) + (void) debugfs_create_file("enable_oswr_mode", + S_IRUGO | S_IWUSR, d, &enable_oswr_mode, + &pm_dbg_option_fops); + pm_dbg_init_done = 1; return 0; diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 36fa90b..c36ab63 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -17,6 +17,7 @@ extern void *omap3_secure_ram_storage; extern void omap3_pm_off_mode_enable(int); +extern void omap4_pm_oswr_mode_enable(int); extern void omap_sram_idle(void); extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); extern int omap3_idle_init(void); diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index cc85576..07ac0d3 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -115,6 +115,22 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); } +void omap4_pm_oswr_mode_enable(int enable) +{ + u32 next_logic_state; + struct power_state *pwrst; + + if (enable) + next_logic_state = PWRDM_POWER_OFF; + else + next_logic_state = PWRDM_POWER_RET; + + list_for_each_entry(pwrst, &pwrst_list, node) { + pwrst->next_logic_state = next_logic_state; + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); + } +} + /** * omap_default_idle - OMAP4 default ilde routine.' * -- 1.7.4.1 ^ permalink raw reply related [flat|nested] 56+ messages in thread
* Re: [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR 2012-05-14 10:03 ` Tero Kristo @ 2012-05-15 22:41 ` Kevin Hilman -1 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-15 22:41 UTC (permalink / raw) To: Tero Kristo; +Cc: linux-omap, paul, linux-arm-kernel Tero Kristo <t-kristo@ti.com> writes: > PM debug now contains a file that can be used to control OSWR support > enable / disable on OMAP4. Also removed the off_mode_enable file for > the same platform as it is unsupported. > > Signed-off-by: Tero Kristo <t-kristo@ti.com> I'll gladly take a patch that makes enable_off_mode OMAP3-only, but I am not interested managing another new flag for OSWR. For OMAP4, this should just be the default, and any drivers that are broken just need to be fixed either by implementing context save/restore or by using constraints. Kevin > --- > arch/arm/mach-omap2/pm-debug.c | 20 ++++++++++++++++---- > arch/arm/mach-omap2/pm.h | 1 + > arch/arm/mach-omap2/pm44xx.c | 16 ++++++++++++++++ > 3 files changed, 33 insertions(+), 4 deletions(-) > > diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c > index 814bcd9..d9a8e42 100644 > --- a/arch/arm/mach-omap2/pm-debug.c > +++ b/arch/arm/mach-omap2/pm-debug.c > @@ -39,6 +39,7 @@ > #include "pm.h" > > u32 enable_off_mode; > +static u32 enable_oswr_mode; > > #ifdef CONFIG_DEBUG_FS > #include <linux/debugfs.h> > @@ -247,10 +248,13 @@ static int option_set(void *data, u64 val) > omap_pm_enable_off_mode(); > else > omap_pm_disable_off_mode(); > - if (cpu_is_omap34xx()) > - omap3_pm_off_mode_enable(val); > + > + omap3_pm_off_mode_enable(val); > } > > + if (option == &enable_oswr_mode) > + omap4_pm_oswr_mode_enable(val); > + > return 0; > } > > @@ -274,8 +278,16 @@ static int __init pm_dbg_init(void) > > pwrdm_for_each(pwrdms_setup, (void *)d); > > - (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, > - &enable_off_mode, &pm_dbg_option_fops); > + if (cpu_is_omap34xx()) > + (void) debugfs_create_file("enable_off_mode", > + S_IRUGO | S_IWUSR, d, &enable_off_mode, > + &pm_dbg_option_fops); > + > + if (cpu_is_omap44xx()) > + (void) debugfs_create_file("enable_oswr_mode", > + S_IRUGO | S_IWUSR, d, &enable_oswr_mode, > + &pm_dbg_option_fops); > + > pm_dbg_init_done = 1; > > return 0; > diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h > index 36fa90b..c36ab63 100644 > --- a/arch/arm/mach-omap2/pm.h > +++ b/arch/arm/mach-omap2/pm.h > @@ -17,6 +17,7 @@ > > extern void *omap3_secure_ram_storage; > extern void omap3_pm_off_mode_enable(int); > +extern void omap4_pm_oswr_mode_enable(int); > extern void omap_sram_idle(void); > extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); > extern int omap3_idle_init(void); > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > index cc85576..07ac0d3 100644 > --- a/arch/arm/mach-omap2/pm44xx.c > +++ b/arch/arm/mach-omap2/pm44xx.c > @@ -115,6 +115,22 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) > return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); > } > > +void omap4_pm_oswr_mode_enable(int enable) > +{ > + u32 next_logic_state; > + struct power_state *pwrst; > + > + if (enable) > + next_logic_state = PWRDM_POWER_OFF; > + else > + next_logic_state = PWRDM_POWER_RET; > + > + list_for_each_entry(pwrst, &pwrst_list, node) { > + pwrst->next_logic_state = next_logic_state; > + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); > + } > +} > + > /** > * omap_default_idle - OMAP4 default ilde routine.' > * ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR @ 2012-05-15 22:41 ` Kevin Hilman 0 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-15 22:41 UTC (permalink / raw) To: linux-arm-kernel Tero Kristo <t-kristo@ti.com> writes: > PM debug now contains a file that can be used to control OSWR support > enable / disable on OMAP4. Also removed the off_mode_enable file for > the same platform as it is unsupported. > > Signed-off-by: Tero Kristo <t-kristo@ti.com> I'll gladly take a patch that makes enable_off_mode OMAP3-only, but I am not interested managing another new flag for OSWR. For OMAP4, this should just be the default, and any drivers that are broken just need to be fixed either by implementing context save/restore or by using constraints. Kevin > --- > arch/arm/mach-omap2/pm-debug.c | 20 ++++++++++++++++---- > arch/arm/mach-omap2/pm.h | 1 + > arch/arm/mach-omap2/pm44xx.c | 16 ++++++++++++++++ > 3 files changed, 33 insertions(+), 4 deletions(-) > > diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c > index 814bcd9..d9a8e42 100644 > --- a/arch/arm/mach-omap2/pm-debug.c > +++ b/arch/arm/mach-omap2/pm-debug.c > @@ -39,6 +39,7 @@ > #include "pm.h" > > u32 enable_off_mode; > +static u32 enable_oswr_mode; > > #ifdef CONFIG_DEBUG_FS > #include <linux/debugfs.h> > @@ -247,10 +248,13 @@ static int option_set(void *data, u64 val) > omap_pm_enable_off_mode(); > else > omap_pm_disable_off_mode(); > - if (cpu_is_omap34xx()) > - omap3_pm_off_mode_enable(val); > + > + omap3_pm_off_mode_enable(val); > } > > + if (option == &enable_oswr_mode) > + omap4_pm_oswr_mode_enable(val); > + > return 0; > } > > @@ -274,8 +278,16 @@ static int __init pm_dbg_init(void) > > pwrdm_for_each(pwrdms_setup, (void *)d); > > - (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, > - &enable_off_mode, &pm_dbg_option_fops); > + if (cpu_is_omap34xx()) > + (void) debugfs_create_file("enable_off_mode", > + S_IRUGO | S_IWUSR, d, &enable_off_mode, > + &pm_dbg_option_fops); > + > + if (cpu_is_omap44xx()) > + (void) debugfs_create_file("enable_oswr_mode", > + S_IRUGO | S_IWUSR, d, &enable_oswr_mode, > + &pm_dbg_option_fops); > + > pm_dbg_init_done = 1; > > return 0; > diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h > index 36fa90b..c36ab63 100644 > --- a/arch/arm/mach-omap2/pm.h > +++ b/arch/arm/mach-omap2/pm.h > @@ -17,6 +17,7 @@ > > extern void *omap3_secure_ram_storage; > extern void omap3_pm_off_mode_enable(int); > +extern void omap4_pm_oswr_mode_enable(int); > extern void omap_sram_idle(void); > extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); > extern int omap3_idle_init(void); > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > index cc85576..07ac0d3 100644 > --- a/arch/arm/mach-omap2/pm44xx.c > +++ b/arch/arm/mach-omap2/pm44xx.c > @@ -115,6 +115,22 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) > return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); > } > > +void omap4_pm_oswr_mode_enable(int enable) > +{ > + u32 next_logic_state; > + struct power_state *pwrst; > + > + if (enable) > + next_logic_state = PWRDM_POWER_OFF; > + else > + next_logic_state = PWRDM_POWER_RET; > + > + list_for_each_entry(pwrst, &pwrst_list, node) { > + pwrst->next_logic_state = next_logic_state; > + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); > + } > +} > + > /** > * omap_default_idle - OMAP4 default ilde routine.' > * ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR 2012-05-15 22:41 ` Kevin Hilman @ 2012-05-16 9:10 ` Tero Kristo -1 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-16 9:10 UTC (permalink / raw) To: Kevin Hilman; +Cc: linux-omap, paul, linux-arm-kernel On Tue, 2012-05-15 at 15:41 -0700, Kevin Hilman wrote: > Tero Kristo <t-kristo@ti.com> writes: > > > PM debug now contains a file that can be used to control OSWR support > > enable / disable on OMAP4. Also removed the off_mode_enable file for > > the same platform as it is unsupported. > > > > Signed-off-by: Tero Kristo <t-kristo@ti.com> > > I'll gladly take a patch that makes enable_off_mode OMAP3-only, but I am > not interested managing another new flag for OSWR. > > For OMAP4, this should just be the default, and any drivers that are > broken just need to be fixed either by implementing context save/restore > or by using constraints. Well, it is not flag as such, as it is static variable internal to pm-debug.c. I could drop this, however it is extremely useful as a testing feature. Without this, it is difficult to test CSWR / OSWR. If you have taken a look at the device-off set, I am actually adding the flag back for omap4 there for enabling device off. If this flag is also dropped, the device will always just go to device off, in which case testing CSWR / OSWR becomes an issue again, and I don't think this is ideal. Speaking of enable_off_mode, it might be possible to change it also be static and remove all the references to it from code. Currently it is only used from cpuidle34xx.c. -Tero > > Kevin > > > --- > > arch/arm/mach-omap2/pm-debug.c | 20 ++++++++++++++++---- > > arch/arm/mach-omap2/pm.h | 1 + > > arch/arm/mach-omap2/pm44xx.c | 16 ++++++++++++++++ > > 3 files changed, 33 insertions(+), 4 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c > > index 814bcd9..d9a8e42 100644 > > --- a/arch/arm/mach-omap2/pm-debug.c > > +++ b/arch/arm/mach-omap2/pm-debug.c > > @@ -39,6 +39,7 @@ > > #include "pm.h" > > > > u32 enable_off_mode; > > +static u32 enable_oswr_mode; > > > > #ifdef CONFIG_DEBUG_FS > > #include <linux/debugfs.h> > > @@ -247,10 +248,13 @@ static int option_set(void *data, u64 val) > > omap_pm_enable_off_mode(); > > else > > omap_pm_disable_off_mode(); > > - if (cpu_is_omap34xx()) > > - omap3_pm_off_mode_enable(val); > > + > > + omap3_pm_off_mode_enable(val); > > } > > > > + if (option == &enable_oswr_mode) > > + omap4_pm_oswr_mode_enable(val); > > + > > return 0; > > } > > > > @@ -274,8 +278,16 @@ static int __init pm_dbg_init(void) > > > > pwrdm_for_each(pwrdms_setup, (void *)d); > > > > - (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, > > - &enable_off_mode, &pm_dbg_option_fops); > > + if (cpu_is_omap34xx()) > > + (void) debugfs_create_file("enable_off_mode", > > + S_IRUGO | S_IWUSR, d, &enable_off_mode, > > + &pm_dbg_option_fops); > > + > > + if (cpu_is_omap44xx()) > > + (void) debugfs_create_file("enable_oswr_mode", > > + S_IRUGO | S_IWUSR, d, &enable_oswr_mode, > > + &pm_dbg_option_fops); > > + > > pm_dbg_init_done = 1; > > > > return 0; > > diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h > > index 36fa90b..c36ab63 100644 > > --- a/arch/arm/mach-omap2/pm.h > > +++ b/arch/arm/mach-omap2/pm.h > > @@ -17,6 +17,7 @@ > > > > extern void *omap3_secure_ram_storage; > > extern void omap3_pm_off_mode_enable(int); > > +extern void omap4_pm_oswr_mode_enable(int); > > extern void omap_sram_idle(void); > > extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); > > extern int omap3_idle_init(void); > > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > > index cc85576..07ac0d3 100644 > > --- a/arch/arm/mach-omap2/pm44xx.c > > +++ b/arch/arm/mach-omap2/pm44xx.c > > @@ -115,6 +115,22 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) > > return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); > > } > > > > +void omap4_pm_oswr_mode_enable(int enable) > > +{ > > + u32 next_logic_state; > > + struct power_state *pwrst; > > + > > + if (enable) > > + next_logic_state = PWRDM_POWER_OFF; > > + else > > + next_logic_state = PWRDM_POWER_RET; > > + > > + list_for_each_entry(pwrst, &pwrst_list, node) { > > + pwrst->next_logic_state = next_logic_state; > > + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); > > + } > > +} > > + > > /** > > * omap_default_idle - OMAP4 default ilde routine.' > > * ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR @ 2012-05-16 9:10 ` Tero Kristo 0 siblings, 0 replies; 56+ messages in thread From: Tero Kristo @ 2012-05-16 9:10 UTC (permalink / raw) To: linux-arm-kernel On Tue, 2012-05-15 at 15:41 -0700, Kevin Hilman wrote: > Tero Kristo <t-kristo@ti.com> writes: > > > PM debug now contains a file that can be used to control OSWR support > > enable / disable on OMAP4. Also removed the off_mode_enable file for > > the same platform as it is unsupported. > > > > Signed-off-by: Tero Kristo <t-kristo@ti.com> > > I'll gladly take a patch that makes enable_off_mode OMAP3-only, but I am > not interested managing another new flag for OSWR. > > For OMAP4, this should just be the default, and any drivers that are > broken just need to be fixed either by implementing context save/restore > or by using constraints. Well, it is not flag as such, as it is static variable internal to pm-debug.c. I could drop this, however it is extremely useful as a testing feature. Without this, it is difficult to test CSWR / OSWR. If you have taken a look at the device-off set, I am actually adding the flag back for omap4 there for enabling device off. If this flag is also dropped, the device will always just go to device off, in which case testing CSWR / OSWR becomes an issue again, and I don't think this is ideal. Speaking of enable_off_mode, it might be possible to change it also be static and remove all the references to it from code. Currently it is only used from cpuidle34xx.c. -Tero > > Kevin > > > --- > > arch/arm/mach-omap2/pm-debug.c | 20 ++++++++++++++++---- > > arch/arm/mach-omap2/pm.h | 1 + > > arch/arm/mach-omap2/pm44xx.c | 16 ++++++++++++++++ > > 3 files changed, 33 insertions(+), 4 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c > > index 814bcd9..d9a8e42 100644 > > --- a/arch/arm/mach-omap2/pm-debug.c > > +++ b/arch/arm/mach-omap2/pm-debug.c > > @@ -39,6 +39,7 @@ > > #include "pm.h" > > > > u32 enable_off_mode; > > +static u32 enable_oswr_mode; > > > > #ifdef CONFIG_DEBUG_FS > > #include <linux/debugfs.h> > > @@ -247,10 +248,13 @@ static int option_set(void *data, u64 val) > > omap_pm_enable_off_mode(); > > else > > omap_pm_disable_off_mode(); > > - if (cpu_is_omap34xx()) > > - omap3_pm_off_mode_enable(val); > > + > > + omap3_pm_off_mode_enable(val); > > } > > > > + if (option == &enable_oswr_mode) > > + omap4_pm_oswr_mode_enable(val); > > + > > return 0; > > } > > > > @@ -274,8 +278,16 @@ static int __init pm_dbg_init(void) > > > > pwrdm_for_each(pwrdms_setup, (void *)d); > > > > - (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, > > - &enable_off_mode, &pm_dbg_option_fops); > > + if (cpu_is_omap34xx()) > > + (void) debugfs_create_file("enable_off_mode", > > + S_IRUGO | S_IWUSR, d, &enable_off_mode, > > + &pm_dbg_option_fops); > > + > > + if (cpu_is_omap44xx()) > > + (void) debugfs_create_file("enable_oswr_mode", > > + S_IRUGO | S_IWUSR, d, &enable_oswr_mode, > > + &pm_dbg_option_fops); > > + > > pm_dbg_init_done = 1; > > > > return 0; > > diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h > > index 36fa90b..c36ab63 100644 > > --- a/arch/arm/mach-omap2/pm.h > > +++ b/arch/arm/mach-omap2/pm.h > > @@ -17,6 +17,7 @@ > > > > extern void *omap3_secure_ram_storage; > > extern void omap3_pm_off_mode_enable(int); > > +extern void omap4_pm_oswr_mode_enable(int); > > extern void omap_sram_idle(void); > > extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); > > extern int omap3_idle_init(void); > > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > > index cc85576..07ac0d3 100644 > > --- a/arch/arm/mach-omap2/pm44xx.c > > +++ b/arch/arm/mach-omap2/pm44xx.c > > @@ -115,6 +115,22 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) > > return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); > > } > > > > +void omap4_pm_oswr_mode_enable(int enable) > > +{ > > + u32 next_logic_state; > > + struct power_state *pwrst; > > + > > + if (enable) > > + next_logic_state = PWRDM_POWER_OFF; > > + else > > + next_logic_state = PWRDM_POWER_RET; > > + > > + list_for_each_entry(pwrst, &pwrst_list, node) { > > + pwrst->next_logic_state = next_logic_state; > > + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); > > + } > > +} > > + > > /** > > * omap_default_idle - OMAP4 default ilde routine.' > > * ^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR 2012-05-16 9:10 ` Tero Kristo @ 2012-05-16 18:03 ` Kevin Hilman -1 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-16 18:03 UTC (permalink / raw) To: t-kristo; +Cc: linux-omap, paul, linux-arm-kernel Tero Kristo <t-kristo@ti.com> writes: > On Tue, 2012-05-15 at 15:41 -0700, Kevin Hilman wrote: >> Tero Kristo <t-kristo@ti.com> writes: >> >> > PM debug now contains a file that can be used to control OSWR support >> > enable / disable on OMAP4. Also removed the off_mode_enable file for >> > the same platform as it is unsupported. >> >> >> > Signed-off-by: Tero Kristo <t-kristo@ti.com> >> >> I'll gladly take a patch that makes enable_off_mode OMAP3-only, but I am >> not interested managing another new flag for OSWR. >> >> For OMAP4, this should just be the default, and any drivers that are >> broken just need to be fixed either by implementing context save/restore >> or by using constraints. > > Well, it is not flag as such, as it is static variable internal to > pm-debug.c. I could drop this, however it is extremely useful as a > testing feature. Without this, it is difficult to test CSWR / OSWR. I understand its usefulness for testing (and I will use it to test this series), but IMO it should live out of tree. Having this in tree makes it possible for drivers to be merged that don't support off-mode. I added this flag to OMAP3 as a short-term feature hoping that drivers would eventually be converted, and I was wrong. We still have drivers that don't support off-mode upstream. I don't want to make that mistake again. > If you have taken a look at the device-off set, I am actually adding > the flag back for omap4 there for enabling device off. If this flag is > also dropped, the device will always just go to device off, in which > case testing CSWR / OSWR becomes an issue again, and I don't think > this is ideal. > > Speaking of enable_off_mode, it might be possible to change it also be > static and remove all the references to it from code. Currently it is > only used from cpuidle34xx.c. I would prefer to get rid of all of these flags, and use the new sysfs controls[1] for CPUidle C-states to disable/enable certain C-states for debugging/testing. Kevin [1] Example shell snippet using new sysfs interface: # CPUidle: disable everything but C1 cd /sys/devices/system/cpu/cpu0/cpuidle for state in state[1-6]*; do if [ -e ${state} ]; then echo 1 > ${state}/disable fi done ^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR @ 2012-05-16 18:03 ` Kevin Hilman 0 siblings, 0 replies; 56+ messages in thread From: Kevin Hilman @ 2012-05-16 18:03 UTC (permalink / raw) To: linux-arm-kernel Tero Kristo <t-kristo@ti.com> writes: > On Tue, 2012-05-15 at 15:41 -0700, Kevin Hilman wrote: >> Tero Kristo <t-kristo@ti.com> writes: >> >> > PM debug now contains a file that can be used to control OSWR support >> > enable / disable on OMAP4. Also removed the off_mode_enable file for >> > the same platform as it is unsupported. >> >> >> > Signed-off-by: Tero Kristo <t-kristo@ti.com> >> >> I'll gladly take a patch that makes enable_off_mode OMAP3-only, but I am >> not interested managing another new flag for OSWR. >> >> For OMAP4, this should just be the default, and any drivers that are >> broken just need to be fixed either by implementing context save/restore >> or by using constraints. > > Well, it is not flag as such, as it is static variable internal to > pm-debug.c. I could drop this, however it is extremely useful as a > testing feature. Without this, it is difficult to test CSWR / OSWR. I understand its usefulness for testing (and I will use it to test this series), but IMO it should live out of tree. Having this in tree makes it possible for drivers to be merged that don't support off-mode. I added this flag to OMAP3 as a short-term feature hoping that drivers would eventually be converted, and I was wrong. We still have drivers that don't support off-mode upstream. I don't want to make that mistake again. > If you have taken a look at the device-off set, I am actually adding > the flag back for omap4 there for enabling device off. If this flag is > also dropped, the device will always just go to device off, in which > case testing CSWR / OSWR becomes an issue again, and I don't think > this is ideal. > > Speaking of enable_off_mode, it might be possible to change it also be > static and remove all the references to it from code. Currently it is > only used from cpuidle34xx.c. I would prefer to get rid of all of these flags, and use the new sysfs controls[1] for CPUidle C-states to disable/enable certain C-states for debugging/testing. Kevin [1] Example shell snippet using new sysfs interface: # CPUidle: disable everything but C1 cd /sys/devices/system/cpu/cpu0/cpuidle for state in state[1-6]*; do if [ -e ${state} ]; then echo 1 > ${state}/disable fi done ^ permalink raw reply [flat|nested] 56+ messages in thread
end of thread, other threads:[~2012-05-30 8:02 UTC | newest] Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-05-14 10:03 [PATCHv5 0/8] ARM: OMAP4: core retention support Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-14 10:03 ` [PATCHv5 1/8] ARM: OMAP4: suspend: Program all domains to retention Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-15 19:52 ` Kevin Hilman 2012-05-15 19:52 ` Kevin Hilman 2012-05-16 8:37 ` Tero Kristo 2012-05-16 8:37 ` Tero Kristo 2012-05-14 10:03 ` [PATCHv5 2/8] TEMP: ARM: OMAP4: hwmod_data: Do not get DSP out of reset at boot time Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-14 10:03 ` [PATCHv5 3/8] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX gic control register change Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-15 21:44 ` Kevin Hilman 2012-05-15 21:44 ` Kevin Hilman 2012-05-16 8:54 ` Tero Kristo 2012-05-16 8:54 ` Tero Kristo 2012-05-16 9:16 ` Santosh Shilimkar 2012-05-16 9:16 ` Santosh Shilimkar 2012-05-16 12:23 ` Santosh Shilimkar 2012-05-16 12:23 ` Santosh Shilimkar 2012-05-16 16:51 ` Kevin Hilman 2012-05-16 16:51 ` Kevin Hilman 2012-05-17 6:46 ` Shilimkar, Santosh 2012-05-17 6:46 ` Shilimkar, Santosh 2012-05-17 17:15 ` Kevin Hilman 2012-05-17 17:15 ` Kevin Hilman 2012-05-18 6:05 ` Shilimkar, Santosh 2012-05-18 6:05 ` Shilimkar, Santosh 2012-05-18 14:13 ` Kevin Hilman 2012-05-18 14:13 ` Kevin Hilman 2012-05-16 12:31 ` Santosh Shilimkar 2012-05-16 12:31 ` Santosh Shilimkar 2012-05-14 10:03 ` [PATCHv5 4/8] ARM: OMAP4: hwmod: flag hwmods/modules supporting module level context status Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-14 10:03 ` [PATCHv5 5/8] ARM: OMAP: hwmod: Add support for per hwmod/module context lost count Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-29 19:32 ` Menon, Nishanth 2012-05-29 19:32 ` Menon, Nishanth 2012-05-30 8:02 ` Tero Kristo 2012-05-30 8:02 ` Tero Kristo 2012-05-14 10:03 ` [PATCHv5 6/8] ARM: OMAP4: pwrdm: add support for reading prev logic and mem states Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-15 22:36 ` Kevin Hilman 2012-05-15 22:36 ` Kevin Hilman 2012-05-16 8:55 ` Tero Kristo 2012-05-16 8:55 ` Tero Kristo 2012-05-14 10:03 ` [PATCHv5 7/8] ARM: OMAP4: PM: Add next_logic_state param to power_state Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-14 10:03 ` [PATCHv5 8/8] ARM: OMAP4: PM: Added option for enabling OSWR Tero Kristo 2012-05-14 10:03 ` Tero Kristo 2012-05-15 22:41 ` Kevin Hilman 2012-05-15 22:41 ` Kevin Hilman 2012-05-16 9:10 ` Tero Kristo 2012-05-16 9:10 ` Tero Kristo 2012-05-16 18:03 ` Kevin Hilman 2012-05-16 18:03 ` Kevin Hilman
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.