ARM: OMAP4 device off support
Subsystems (8)
cover ARM: OMAP4 device off support
Hi,
First version for this work. Applies on top of mainline + iochain set + OMAP4 core retention set. Working tree available here:
tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-off
Tested on omap4430 EMU blaze + omap4460 GP panda boards.
Some drivers have issues with device off, most notably MMC, as it breaks device off on blaze device after 1 entry to device off mode:
[ 208.906921] omap_i2c omap_i2c.1: XRDY IRQ while no data to send [ 209.905639] omap_i2c omap_i2c.1: controller timed out [ 209.905792] twl: i2c_read failed to transfer all messages [ 209.905792] omap_hsmmc omap_hsmmc.1: could not set regulator OCR (-110) [ 212.296203] mmc0: error -110 during resume (card was removed?) [ 212.562164] PM: resume of devices complete after 3656.007 msecs [ 212.660125] Restarting tasks ... done. # # echo mem > /sys/power/state [ 220.376892] PM: Syncing filesystems ... done. [ 220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done. [ 220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don e. [ 220.439605] Suspending console(s) (use no_console_suspend to debug) [ 220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110 [ 220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110 [ 220.454711] PM: Some devices failed to suspend [ 220.718261] PM: resume of devices complete after 263.539 msecs [ 220.743988] Restarting tasks ... done.
Attempting to disable MMC from config prevented boot completely for me, so this issue is likely to stay until someone fixes the MMC driver. Panda device works fine though, although the wakeup from device off is slow due to problems with some other drivers (most likely I2C.)
Off mode is disabled by default, it can be enabled by either calling omap4_pm_enable_off_mode(1) from board files or alternatively writing to a debugfs node from userspace:
echo 1 > /debug/pm_debug/enable_off_mode
Device off entry can be tracked through the debugfs also, it increases the core_pwrdm OFF state counter / timer, as this is an invalid state for the chip normally (core enters OSWR in device off.) Not sure if this a good way to do this but comments are welcome.
-Tero
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.
--- arch/arm/mach-omap2/cm44xx.h | 5 + arch/arm/mach-omap2/dpll44xx.c | 271 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 276 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/cm44xx.h +5 -0
@@ -23,4 +23,9 @@#define OMAP4_CM_CLKSTCTRL 0x0000#define OMAP4_CM_STATICDEP 0x0004 +#ifndef __ASSEMBLER__ +extern void omap4_dpll_prepare_off (void ); +extern void omap4_dpll_resume_off (void ); +#endif +#endif
arch/arm/mach-omap2/dpll44xx.c +271 -0
286 lines not on this page · raw message
Signature · 1 line
1.7.4.1
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Hi Tero,
On 04/20/2012 04:33 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
arch/arm/mach-omap2/dpll44xx.c +5
-0+/** +* omap4_dpll_print_reg - dump out a single DPLL register value +* @dpll_reg: register to dump +* @name: name of the register +* @tuple: content of the register
arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 316
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+* +* Helper dump function to print out a DPLL register value in case +* of restore failures. +*/ +static void omap4_dpll_print_reg (struct omap4_dpll_regs *dpll_reg,char *name, +struct dpll_reg *tuple) +{ +if (tuple->offset) +pr_warn ("%s - Address offset = 0x%08x, value=0x%08x\n" , name, + tuple->offset, tuple->val);
Minor nit-pick here ...
1. Offset is 16-bits and so we can just have "offset = 0x%04x"
2. Consider dropping "Address" from "Address offset"
3. Can we be consistent in our spaces for "offset = " and "value="?
Quoted 19 lines
arch/arm/mach-omap2/dpll44xx.c +19
-0+} + +/* +* omap4_dpll_dump_regs - dump out DPLL registers +* @dpll_reg: DPLL to dump +* +* Dump out the contents of the registers for a DPLL. Called if a +* restore for DPLL fails to lock. +*/ +static void omap4_dpll_dump_regs (struct omap4_dpll_regs *dpll_reg) +{ +pr_warn ("%s: Unable to lock dpll %s[part=%x inst=%x]:\n" , + __func__, dpll_reg->name, dpll_reg->mod_partition, + dpll_reg->mod_inst); +omap4_dpll_print_reg (dpll_reg,"clksel" , &dpll_reg->clksel); +omap4_dpll_print_reg (dpll_reg,"div_m2" , &dpll_reg->div_m2); +omap4_dpll_print_reg (dpll_reg,"div_m3" , &dpll_reg->div_m3); +omap4_dpll_print_reg (dpll_reg,"div_m4" , &dpll_reg->div_m4); +omap4_dpll_print_reg (dpll_reg,"div_m5" , &dpll_reg->div_m5);
arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 345
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+omap4_dpll_print_reg (dpll_reg,"div_m6" , &dpll_reg->div_m6); +omap4_dpll_print_reg (dpll_reg,"div_m7" , &dpll_reg->div_m7); +omap4_dpll_print_reg (dpll_reg,"clkdcoldo" , &dpll_reg->clkdcoldo); +omap4_dpll_print_reg (dpll_reg,"clkmode" , &dpll_reg->clkmode); +omap4_dpll_print_reg (dpll_reg,"autoidle" , &dpll_reg->autoidle); +if (dpll_reg->idlest.offset) +pr_warn ("idlest - Address offset = 0x%08x, before val=0x%08x" +" after = 0x%08x\n" , dpll_reg->idlest.offset, + dpll_reg->idlest.val, +omap4_dpll_read_reg (dpll_reg, &dpll_reg->idlest));
Nit-pick ...
1. Same comments as above
2. Consider dropping "Address offset" altogether here as we print "idlest" the offset should be implied.
3. Also can we be consistent in our naming of "before val and "after"? For example, "val before =" and "val now = ".
Cheers
Jon
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 60 lines · Jon Hunter
Hi Tero,
On 04/20/2012 04:33 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
arch/arm/mach-omap2/dpll44xx.c +5
-0+/** +* omap4_dpll_print_reg - dump out a single DPLL register value +* @dpll_reg: register to dump +* @name: name of the register +* @tuple: content of the register arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 316
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+* +* Helper dump function to print out a DPLL register value in case +* of restore failures. +*/ +static void omap4_dpll_print_reg (struct omap4_dpll_regs *dpll_reg,char *name, +struct dpll_reg *tuple) +{ +if (tuple->offset) +pr_warn ("%s - Address offset = 0x%08x, value=0x%08x\n" , name, + tuple->offset, tuple->val);Minor nit-pick here ...
1. Offset is 16-bits and so we can just have "offset = 0x%04x"
2. Consider dropping "Address" from "Address offset"
3. Can we be consistent in our spaces for "offset = " and "value="?Quoted 19 lines
arch/arm/mach-omap2/dpll44xx.c +19
-0+} + +/* +* omap4_dpll_dump_regs - dump out DPLL registers +* @dpll_reg: DPLL to dump +* +* Dump out the contents of the registers for a DPLL. Called if a +* restore for DPLL fails to lock. +*/ +static void omap4_dpll_dump_regs (struct omap4_dpll_regs *dpll_reg) +{ +pr_warn ("%s: Unable to lock dpll %s[part=%x inst=%x]:\n" , + __func__, dpll_reg->name, dpll_reg->mod_partition, + dpll_reg->mod_inst); +omap4_dpll_print_reg (dpll_reg,"clksel" , &dpll_reg->clksel); +omap4_dpll_print_reg (dpll_reg,"div_m2" , &dpll_reg->div_m2); +omap4_dpll_print_reg (dpll_reg,"div_m3" , &dpll_reg->div_m3); +omap4_dpll_print_reg (dpll_reg,"div_m4" , &dpll_reg->div_m4); +omap4_dpll_print_reg (dpll_reg,"div_m5" , &dpll_reg->div_m5);arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 345
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+omap4_dpll_print_reg (dpll_reg,"div_m6" , &dpll_reg->div_m6); +omap4_dpll_print_reg (dpll_reg,"div_m7" , &dpll_reg->div_m7); +omap4_dpll_print_reg (dpll_reg,"clkdcoldo" , &dpll_reg->clkdcoldo); +omap4_dpll_print_reg (dpll_reg,"clkmode" , &dpll_reg->clkmode); +omap4_dpll_print_reg (dpll_reg,"autoidle" , &dpll_reg->autoidle); +if (dpll_reg->idlest.offset) +pr_warn ("idlest - Address offset = 0x%08x, before val=0x%08x" +" after = 0x%08x\n" , dpll_reg->idlest.offset, + dpll_reg->idlest.val, +omap4_dpll_read_reg (dpll_reg, &dpll_reg->idlest));Nit-pick ...
Quoted 5 lines
1. Same comments as above
2. Consider dropping "Address offset" altogether here as we print "idlest" the offset should be implied.
3. Also can we be consistent in our naming of "before val and "after"? For example, "val before =" and "val now = ".
Okay, I'll modify both prints slightly. Question though, do we want these prints in the kernel in the first place? At least Tony has been frowning upon register dumps in the kernel and this falls into that category. What we could do is just to print the warning but drop the register dumps out.
-Tero
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Hi Tero,
Quoted 67 lines · Tero Kristo
Quoted 60 lines · Jon Hunter
Hi Tero,
On 04/20/2012 04:33 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
arch/arm/mach-omap2/dpll44xx.c +5
-0+/** +* omap4_dpll_print_reg - dump out a single DPLL register value +* @dpll_reg: register to dump +* @name: name of the register +* @tuple: content of the register arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 316
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+* +* Helper dump function to print out a DPLL register value in case +* of restore failures. +*/ +static void omap4_dpll_print_reg (struct omap4_dpll_regs *dpll_reg,char *name, +struct dpll_reg *tuple) +{ +if (tuple->offset) +pr_warn ("%s - Address offset = 0x%08x, value=0x%08x\n" , name, + tuple->offset, tuple->val);Minor nit-pick here ...
1. Offset is 16-bits and so we can just have "offset = 0x%04x"
2. Consider dropping "Address" from "Address offset"
3. Can we be consistent in our spaces for "offset = " and "value="?Quoted 19 lines
arch/arm/mach-omap2/dpll44xx.c +19
-0+} + +/* +* omap4_dpll_dump_regs - dump out DPLL registers +* @dpll_reg: DPLL to dump +* +* Dump out the contents of the registers for a DPLL. Called if a +* restore for DPLL fails to lock. +*/ +static void omap4_dpll_dump_regs (struct omap4_dpll_regs *dpll_reg) +{ +pr_warn ("%s: Unable to lock dpll %s[part=%x inst=%x]:\n" , + __func__, dpll_reg->name, dpll_reg->mod_partition, + dpll_reg->mod_inst); +omap4_dpll_print_reg (dpll_reg,"clksel" , &dpll_reg->clksel); +omap4_dpll_print_reg (dpll_reg,"div_m2" , &dpll_reg->div_m2); +omap4_dpll_print_reg (dpll_reg,"div_m3" , &dpll_reg->div_m3); +omap4_dpll_print_reg (dpll_reg,"div_m4" , &dpll_reg->div_m4); +omap4_dpll_print_reg (dpll_reg,"div_m5" , &dpll_reg->div_m5);arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 345
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+omap4_dpll_print_reg (dpll_reg,"div_m6" , &dpll_reg->div_m6); +omap4_dpll_print_reg (dpll_reg,"div_m7" , &dpll_reg->div_m7); +omap4_dpll_print_reg (dpll_reg,"clkdcoldo" , &dpll_reg->clkdcoldo); +omap4_dpll_print_reg (dpll_reg,"clkmode" , &dpll_reg->clkmode); +omap4_dpll_print_reg (dpll_reg,"autoidle" , &dpll_reg->autoidle); +if (dpll_reg->idlest.offset) +pr_warn ("idlest - Address offset = 0x%08x, before val=0x%08x" +" after = 0x%08x\n" , dpll_reg->idlest.offset, + dpll_reg->idlest.val, +omap4_dpll_read_reg (dpll_reg, &dpll_reg->idlest));Nit-pick ...
Quoted 5 lines
1. Same comments as above
2. Consider dropping "Address offset" altogether here as we print "idlest" the offset should be implied.
3. Also can we be consistent in our naming of "before val and "after"? For example, "val before =" and "val now = ".
Quoted 5 lines
Okay, I'll modify both prints slightly. Question though, do we want these prints in the kernel in the first place? At least Tony has been frowning upon register dumps in the kernel and this falls into that category. What we could do is just to print the warning but drop the register dumps out.
Thanks. Good question. If we are not seeing failures often, and I would hope not, probably ok to remove. However, I will let Tony comment here ...
Cheers
Jon
Tony Lindgren
maintainerPATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 70 lines · Jon Hunter
Hi Tero,
Quoted 67 lines · Tero Kristo
Quoted 65 lines · Jon Hunter
Hi Tero,
On 04/20/2012 04:33 AM, Tero Kristo wrote:
[...]
Quoted 5 lines
arch/arm/mach-omap2/dpll44xx.c +5
-0+/** +* omap4_dpll_print_reg - dump out a single DPLL register value +* @dpll_reg: register to dump +* @name: name of the register +* @tuple: content of the register arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 316
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+* +* Helper dump function to print out a DPLL register value in case +* of restore failures. +*/ +static void omap4_dpll_print_reg (struct omap4_dpll_regs *dpll_reg,char *name, +struct dpll_reg *tuple) +{ +if (tuple->offset) +pr_warn ("%s - Address offset = 0x%08x, value=0x%08x\n" , name, + tuple->offset, tuple->val);Minor nit-pick here ...
1. Offset is 16-bits and so we can just have "offset = 0x%04x"
2. Consider dropping "Address" from "Address offset"
3. Can we be consistent in our spaces for "offset = " and "value="?Quoted 19 lines
arch/arm/mach-omap2/dpll44xx.c +19
-0+} + +/* +* omap4_dpll_dump_regs - dump out DPLL registers +* @dpll_reg: DPLL to dump +* +* Dump out the contents of the registers for a DPLL. Called if a +* restore for DPLL fails to lock. +*/ +static void omap4_dpll_dump_regs (struct omap4_dpll_regs *dpll_reg) +{ +pr_warn ("%s: Unable to lock dpll %s[part=%x inst=%x]:\n" , + __func__, dpll_reg->name, dpll_reg->mod_partition, + dpll_reg->mod_inst); +omap4_dpll_print_reg (dpll_reg,"clksel" , &dpll_reg->clksel); +omap4_dpll_print_reg (dpll_reg,"div_m2" , &dpll_reg->div_m2); +omap4_dpll_print_reg (dpll_reg,"div_m3" , &dpll_reg->div_m3); +omap4_dpll_print_reg (dpll_reg,"div_m4" , &dpll_reg->div_m4); +omap4_dpll_print_reg (dpll_reg,"div_m5" , &dpll_reg->div_m5);arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 345
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+omap4_dpll_print_reg (dpll_reg,"div_m6" , &dpll_reg->div_m6); +omap4_dpll_print_reg (dpll_reg,"div_m7" , &dpll_reg->div_m7); +omap4_dpll_print_reg (dpll_reg,"clkdcoldo" , &dpll_reg->clkdcoldo); +omap4_dpll_print_reg (dpll_reg,"clkmode" , &dpll_reg->clkmode); +omap4_dpll_print_reg (dpll_reg,"autoidle" , &dpll_reg->autoidle); +if (dpll_reg->idlest.offset) +pr_warn ("idlest - Address offset = 0x%08x, before val=0x%08x" +" after = 0x%08x\n" , dpll_reg->idlest.offset, + dpll_reg->idlest.val, +omap4_dpll_read_reg (dpll_reg, &dpll_reg->idlest));Nit-pick ...
1. Same comments as above
2. Consider dropping "Address offset" altogether here as we print "idlest" the offset should be implied.
3. Also can we be consistent in our naming of "before val and "after"? For example, "val before =" and "val now = ".
Quoted 8 lines
Quoted 5 lines
Okay, I'll modify both prints slightly. Question though, do we want these prints in the kernel in the first place? At least Tony has been frowning upon register dumps in the kernel and this falls into that category. What we could do is just to print the warning but drop the register dumps out.
Thanks. Good question. If we are not seeing failures often, and I would hope not, probably ok to remove. However, I will let Tony comment here ...
Well if the register dumps really help trace the issue and don't happen continuously I'm fine with them.
Tony
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
In reply to Tero KristoHi Tero,
Quoted 7 lines · Tero
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.
Most of the registers being saved and restored in the various patches look to be contiguous. So, instead of a long list of these contiguous registers how about having a generic API for backup and restore of the registers contents based on the memory address range?
Most of the registers which require save and restore are either part of PRM, CM or Control. The PRM or CM instance could be passed as the base and the save/restore API could work around that.
One downside is that there are some read-only registers in between but I don't see any simple way of avoiding save and restore of those. BTW, as per the TRM that I have, this patch is also doing save and restore of some read-only registers.
Quoted 307 lines
[nm at ti.com: minor cleanups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/cm44xx.h | 5 + arch/arm/mach-omap2/dpll44xx.c | 271 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 276 insertions(+), 0 deletions(-)arch/arm/mach-omap2/cm44xx.h +5
-0@@ -23,4 +23,9 @@#define OMAP4_CM_CLKSTCTRL 0x0000#define OMAP4_CM_STATICDEP 0x0004 +#ifndef __ASSEMBLER__ +extern void omap4_dpll_prepare_off (void ); +extern void omap4_dpll_resume_off (void ); +#endif +#endif arch/arm/mach-omap2/dpll44xx.c +261
-0@@ -14,6 +14,7 @@#include <linux/clk.h> #include <linux/io.h> #include <linux/bitops.h> +#include <linux/delay.h> #include <plat/cpu.h> #include <plat/clock.h> @@ -21,6 +22,96 @@#include "clock.h" #include "clock44xx.h" #include "cm-regbits-44xx.h" +#include "cm1_44xx.h" +#include "cm2_44xx.h" +#include "prcm44xx.h" +#include "cminst44xx.h" +#include "cm44xx.h" + +#define MAX_DPLL_WAIT_TRIES 1000000 + +struct dpll_reg { +u16 offset; +u32 val; +}; + +struct omap4_dpll_regs { +char *name; +u32 mod_partition; +u32 mod_inst; +struct dpll_reg clkmode; +struct dpll_reg autoidle; +struct dpll_reg idlest; +struct dpll_reg clksel; +struct dpll_reg div_m2; +struct dpll_reg div_m3; +struct dpll_reg div_m4; +struct dpll_reg div_m5; +struct dpll_reg div_m6; +struct dpll_reg div_m7; +struct dpll_reg clkdcoldo; +}; + +static struct omap4_dpll_regs dpll_regs[] = { +/* MPU DPLL */ + { .name ="mpu" , + .mod_partition =OMAP4430_CM1_PARTITION , + .mod_inst =OMAP4430_CM1_CKGEN_INST , + .clkmode = {.offset =OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET }, + .autoidle = {.offset =OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET }, + .idlest = {.offset =OMAP4_CM_IDLEST_DPLL_MPU_OFFSET }, + .clksel = {.offset =OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET }, + .div_m2 = {.offset =OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET }, + }, +/* IVA DPLL */ + { .name ="iva" , + .mod_partition =OMAP4430_CM1_PARTITION , + .mod_inst =OMAP4430_CM1_CKGEN_INST , + .clkmode = {.offset =OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET }, + .autoidle = {.offset =OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET }, + .idlest = {.offset =OMAP4_CM_IDLEST_DPLL_IVA_OFFSET }, + .clksel = {.offset =OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET }, + .div_m4 = {.offset =OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET }, + .div_m5 = {.offset =OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET }, + }, +/* ABE DPLL */ + { .name ="abe" , + .mod_partition =OMAP4430_CM1_PARTITION , + .mod_inst =OMAP4430_CM1_CKGEN_INST , + .clkmode = {.offset =OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET }, + .autoidle = {.offset =OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET }, + .idlest = {.offset =OMAP4_CM_IDLEST_DPLL_ABE_OFFSET }, + .clksel = {.offset =OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET }, + .div_m2 = {.offset =OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET }, + .div_m3 = {.offset =OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET }, + }, +/* USB DPLL */ + { .name ="usb" , + .mod_partition =OMAP4430_CM2_PARTITION , + .mod_inst =OMAP4430_CM2_CKGEN_INST , + .clkmode = {.offset =OMAP4_CM_CLKMODE_DPLL_USB_OFFSET }, + .autoidle = {.offset =OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET }, + .idlest = {.offset =OMAP4_CM_IDLEST_DPLL_USB_OFFSET }, + .clksel = {.offset =OMAP4_CM_CLKSEL_DPLL_USB_OFFSET }, + .div_m2 = {.offset =OMAP4_CM_DIV_M2_DPLL_USB_OFFSET }, + .clkdcoldo = {.offset =OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET }, + }, +/* PER DPLL */ + { .name ="per" , + .mod_partition =OMAP4430_CM2_PARTITION , + .mod_inst =OMAP4430_CM2_CKGEN_INST , + .clkmode = {.offset =OMAP4_CM_CLKMODE_DPLL_PER_OFFSET }, + .autoidle = {.offset =OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET }, + .idlest = {.offset =OMAP4_CM_IDLEST_DPLL_PER_OFFSET }, + .clksel = {.offset =OMAP4_CM_CLKSEL_DPLL_PER_OFFSET }, + .div_m2 = {.offset =OMAP4_CM_DIV_M2_DPLL_PER_OFFSET }, + .div_m3 = {.offset =OMAP4_CM_DIV_M3_DPLL_PER_OFFSET }, + .div_m4 = {.offset =OMAP4_CM_DIV_M4_DPLL_PER_OFFSET }, + .div_m5 = {.offset =OMAP4_CM_DIV_M5_DPLL_PER_OFFSET }, + .div_m6 = {.offset =OMAP4_CM_DIV_M6_DPLL_PER_OFFSET }, + .div_m7 = {.offset =OMAP4_CM_DIV_M7_DPLL_PER_OFFSET }, + }, +};/* Supported only on OMAP4 */ int omap4_dpllmx_gatectrl_read (struct clk *clk)@@ -151,3 +242,183 @@ long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)return clk->dpll_data->last_rounded_rate; } + +/** +* omap4_dpll_read_reg - reads DPLL register value +* @dpll_reg: DPLL register to read +* +* Reads the value of a single DPLL register. +*/ +static inline u32 omap4_dpll_read_reg (struct omap4_dpll_regs *dpll_reg, +struct dpll_reg *tuple) +{ +if (tuple->offset) +return omap4_cminst_read_inst_reg (dpll_reg->mod_partition, + dpll_reg->mod_inst, + tuple->offset); +return 0 ; +} + +/** +* omap4_dpll_store_reg - stores DPLL register value to memory location +* @dpll_reg: DPLL register to save +* @tuple: save address +* +* Saves a single DPLL register content to memory location defined by +* @tuple before entering device off mode. +*/ +static inline void omap4_dpll_store_reg (struct omap4_dpll_regs *dpll_reg, +struct dpll_reg *tuple) +{ + tuple->val =omap4_dpll_read_reg (dpll_reg, tuple); +} + +/** +* omap4_dpll_prepare_off - stores DPLL settings before off mode +* +* Saves all DPLL register settings. This must be called before +* entering device off. +*/ +void omap4_dpll_prepare_off (void ) +{ +u32 i; +struct omap4_dpll_regs *dpll_reg = dpll_regs; + +for (i =0 ; i <ARRAY_SIZE (dpll_regs); i++, dpll_reg++) { +omap4_dpll_store_reg (dpll_reg, &dpll_reg->clkmode); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->autoidle); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->clksel); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->div_m2); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->div_m3); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->div_m4); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->div_m5); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->div_m6); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->div_m7); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->clkdcoldo); +omap4_dpll_store_reg (dpll_reg, &dpll_reg->idlest); + } +} + +/** +* omap4_dpll_print_reg - dump out a single DPLL register value +* @dpll_reg: register to dump +* @name: name of the register +* @tuple: content of the register +* +* Helper dump function to print out a DPLL register value in case +* of restore failures. +*/ +static void omap4_dpll_print_reg (struct omap4_dpll_regs *dpll_reg,char *name, +struct dpll_reg *tuple) +{ +if (tuple->offset) +pr_warn ("%s - Address offset = 0x%08x, value=0x%08x\n" , name, + tuple->offset, tuple->val); +} + +/* +* omap4_dpll_dump_regs - dump out DPLL registers +* @dpll_reg: DPLL to dump +* +* Dump out the contents of the registers for a DPLL. Called if a +* restore for DPLL fails to lock. +*/ +static void omap4_dpll_dump_regs (struct omap4_dpll_regs *dpll_reg) +{ +pr_warn ("%s: Unable to lock dpll %s[part=%x inst=%x]:\n" , + __func__, dpll_reg->name, dpll_reg->mod_partition, + dpll_reg->mod_inst); +omap4_dpll_print_reg (dpll_reg,"clksel" , &dpll_reg->clksel); +omap4_dpll_print_reg (dpll_reg,"div_m2" , &dpll_reg->div_m2); +omap4_dpll_print_reg (dpll_reg,"div_m3" , &dpll_reg->div_m3); +omap4_dpll_print_reg (dpll_reg,"div_m4" , &dpll_reg->div_m4); +omap4_dpll_print_reg (dpll_reg,"div_m5" , &dpll_reg->div_m5); +omap4_dpll_print_reg (dpll_reg,"div_m6" , &dpll_reg->div_m6); +omap4_dpll_print_reg (dpll_reg,"div_m7" , &dpll_reg->div_m7); +omap4_dpll_print_reg (dpll_reg,"clkdcoldo" , &dpll_reg->clkdcoldo); +omap4_dpll_print_reg (dpll_reg,"clkmode" , &dpll_reg->clkmode); +omap4_dpll_print_reg (dpll_reg,"autoidle" , &dpll_reg->autoidle); +if (dpll_reg->idlest.offset) +pr_warn ("idlest - Address offset = 0x%08x, before val=0x%08x" +" after = 0x%08x\n" , dpll_reg->idlest.offset, + dpll_reg->idlest.val, +omap4_dpll_read_reg (dpll_reg, &dpll_reg->idlest)); +} + +/** +* omap4_wait_dpll_lock - wait for a DPLL lock +* @dpll_reg: DPLL to wait for +* +* Waits for a DPLL lock after restore. +*/ +static void omap4_wait_dpll_lock (struct omap4_dpll_regs *dpll_reg) +{ +int j =0 ; +u32 status; + +/* Return if we dont need to lock. */ +if ((dpll_reg->clkmode.val &OMAP4430_DPLL_EN_MASK ) != +DPLL_LOCKED <<OMAP4430_DPLL_EN_SHIFT ) +return ; + +while (1 ) { + status = (omap4_dpll_read_reg (dpll_reg, &dpll_reg->idlest) + &OMAP4430_ST_DPLL_CLK_MASK ) + >>OMAP4430_ST_DPLL_CLK_SHIFT ; +if (status ==0x1 ) +break ; +if (j ==MAX_DPLL_WAIT_TRIES ) { +/* If we are unable to lock, warn and move on.. */ +omap4_dpll_dump_regs (dpll_reg); +break ; + } + j++; +udelay (1 ); + } +} + +/** +* omap4_dpll_restore_reg - restores a single register for a DPLL +* @dpll_reg: DPLL to restore +* @tuple: register value to restore +* +* Restores a single register for a DPLL. +*/ +static inline void omap4_dpll_restore_reg (struct omap4_dpll_regs *dpll_reg, +struct dpll_reg *tuple) +{ +if (tuple->offset) +omap4_cminst_write_inst_reg (tuple->val, dpll_reg->mod_partition, + dpll_reg->mod_inst, tuple->offset); +} + +/** +* omap4_dpll_resume_off - restore DPLL settings after device off +* +* Restores all DPLL settings. Must be called after wakeup from device +* off. +*/ +void omap4_dpll_resume_off (void ) +{ +u32 i; +struct omap4_dpll_regs *dpll_reg = dpll_regs; + +for (i =0 ; i <ARRAY_SIZE (dpll_regs); i++, dpll_reg++) { +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->clksel); +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->div_m2); +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->div_m3); +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->div_m4); +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->div_m5); +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->div_m6); +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->div_m7); +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->clkdcoldo);
arch/arm/mach-omap2/dpll44xx.c long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate) · line 424
Quoted 10 lines
arch/arm/mach-omap2/dpll44xx.c +10
-0+ +/* Restore clkmode after the above registers are restored */ +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->clkmode); + +omap4_wait_dpll_lock (dpll_reg); + +/* Restore autoidle settings after the dpll is locked */ +omap4_dpll_restore_reg (dpll_reg, &dpll_reg->autoidle); + } +}
If this function is placed in SRAM and PER PLL restored just after MPU won't the exit latency be further optimized?
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 16 lines · Vaibhav
Hi Tero,
Quoted 7 lines · Tero
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.Most of the registers being saved and restored in the various patches look to be contiguous. So, instead of a long list of these contiguous registers how about having a generic API for backup and restore of the registers contents based on the memory address range?
Quoted 9 lines
Most of the registers which require save and restore are either part of PRM, CM or Control. The PRM or CM instance could be passed as the base and the save/restore API could work around that.
One downside is that there are some read-only registers in between but I don't see any simple way of avoiding save and restore of those. BTW, as per the TRM that I have, this patch is also doing save and restore of some read-only registers.
You should never write to read-only registers since the behavior is undefined.
[...]
Quoted 19 lines
Quoted 19 lines
(quoted diff) +19
-0+void omap4_dpll_resume_off(void) +{ + ? ? u32 i; + ? ? struct omap4_dpll_regs *dpll_reg = dpll_regs; + + ? ? for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) { + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo); + + ? ? ? ? ? ? /* Restore clkmode after the above registers are restored */ + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode); + + ? ? ? ? ? ? omap4_wait_dpll_lock(dpll_reg);
Quoted 9 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ + ? ? ? ? ? ? /* Restore autoidle settings after the dpll is locked */ + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle); + ? ? } +}If this function is placed in SRAM and PER PLL restored just after MPU won't the exit latency be further optimized?
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 21 lines · Santosh
Quoted 20 lines · Vaibhav
Hi Tero,
Quoted 7 lines · Tero
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.Most of the registers being saved and restored in the various patches look to be contiguous. So, instead of a long list of these contiguous registers how about having a generic API for backup and restore of the registers contents based on the memory address range?
Most of the registers which require save and restore are either part of PRM, CM or Control. The PRM or CM instance could be passed as the base and the save/restore API could work around that.
Quoted 7 lines
Quoted 5 lines
One downside is that there are some read-only registers in between but I don't see any simple way of avoiding save and restore of those. BTW, as per the TRM that I have, this patch is also doing save and restore of some read-only registers.
You should never write to read-only registers since the behavior is undefined.
I was afraid of that. If all the read-only registers were clubbed together a lot of code could have been removed. Looking more closely at the TRM I guess we can't really ask design folks to club those read-only registers in the future. So scratch this.
Quoted 30 lines
[...]
Quoted 19 lines
Quoted 19 lines
(quoted diff) +19
-0+void omap4_dpll_resume_off(void) +{ + ? ? u32 i; + ? ? struct omap4_dpll_regs *dpll_reg = dpll_regs; + + ? ? for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) { + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo); + + ? ? ? ? ? ? /* Restore clkmode after the above registers are restored */ + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode); + + ? ? ? ? ? ? omap4_wait_dpll_lock(dpll_reg);Quoted 9 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ + ? ? ? ? ? ? /* Restore autoidle settings after the dpll is locked */ + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle); + ? ? } +}If this function is placed in SRAM and PER PLL restored just after MPU won't the exit latency be further optimized?
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.
I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 7 lines · Vaibhav
Quoted 6 lines · Santosh
Quoted 5 lines · Vaibhav
Hi Tero,
Quoted 2 lines · Tero
From: Rajendra Nayak <[email protected]>
[...]
Quoted 30 lines
Quoted 30 lines
[...]
Quoted 28 lines
Quoted 14 lines
(quoted diff) +14
-0+void omap4_dpll_resume_off(void) +{ + ? ? u32 i; + ? ? struct omap4_dpll_regs *dpll_reg = dpll_regs; + + ? ? for (i = 0; i < ARRAY_SIZE(dpll_regs); i++, dpll_reg++) { + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clksel); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m2); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m3); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m4); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m5); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m6); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->div_m7); + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkdcoldo);Review
Quoted 10 lines
(quoted diff) +10
-0+ + ? ? ? ? ? ? /* Restore clkmode after the above registers are restored */ + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->clkmode); + + ? ? ? ? ? ? omap4_wait_dpll_lock(dpll_reg); + + ? ? ? ? ? ? /* Restore autoidle settings after the dpll is locked */ + ? ? ? ? ? ? omap4_dpll_restore_reg(dpll_reg, &dpll_reg->autoidle); + ? ? } +}If this function is placed in SRAM and PER PLL restored just after MPU won't the exit latency be further optimized?
Quoted 8 lines
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.
You don't have to do any real measurements at least on OMAP. OCMC RAM is interfaced over L4 and MPU has to cross two interconnect bridges to reach to SRAM. DDR is more of direct path and much faster.
Regards
Santosh
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.
Quoted 7 lines
Quoted 3 lines
I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.You don't have to do any real measurements at least on OMAP. OCMC RAM is interfaced over L4 and MPU has to cross two interconnect bridges to reach to SRAM. DDR is more of direct path and much faster.
Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4. Maybe there's a extra low latency path for DDR that I am missing.
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 11 lines · Vaibhav
On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]Quoted 8 lines
Quoted 8 lines
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.
Quoted 6 lines
Quoted 4 lines
You don't have to do any real measurements at least on OMAP. OCMC RAM is interfaced over L4 and MPU has to cross two interconnect bridges to reach to SRAM. DDR is more of direct path and much faster.
Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Nope. It's on L4 and it is same for all OMAPs including OMAP5
Quoted 1 line
Maybe there's a extra low latency path for DDR that I am missing.
Even OMAP3 DDR is faster than OCMC RAM.
Regards
Santosh
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 17 lines · Santosh
Quoted 16 lines · Vaibhav
On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]Quoted 12 lines
Quoted 8 lines
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.You don't have to do any real measurements at least on OMAP. OCMC RAM is interfaced over L4 and MPU has to cross two interconnect bridges to reach to SRAM. DDR is more of direct path and much faster.
Quoted 6 lines
Quoted 1 line
Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Nope. It's on L4 and it is same for all OMAPs including OMAP5
Quoted 1 line
Maybe there's a extra low latency path for DDR that I am missing.
Even OMAP3 DDR is faster than OCMC RAM.
Ok. I guess I need to come up with some data for AM33x then. Thanks for the clarification.
Regards,
Vaibhav
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
In reply to Bedia, VaibhavQuoted 13 lines · Vaibhav
On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]Quoted 9 lines
Quoted 9 lines
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.
Quoted 8 lines
Quoted 4 lines
You don't have to do any real measurements at least on OMAP. OCMC RAM is interfaced over L4 and MPU has to cross two interconnect bridges to reach to SRAM. DDR is more of direct path and much faster.
Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Maybe there's a extra low latency path for DDR that I am missing.
have you folks considered the possibility that SRAM may be reprogrammed by Security code to almost nothing if PA/PPA size needs to be increased? it would be rather dumb not to support HS devices on which real products are made, no? rule of thumb has been to avoid usage of SRAM as it constraints security folks as well (yep, I know they should share code with all of us etc.. but they have a different sets of challenges that may deny them such luxury).
Regards,
Nishanth Menon
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 22 lines · Nishanth
Quoted 13 lines · Vaibhav
On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]Quoted 9 lines
Quoted 9 lines
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.Quoted 8 lines
Quoted 4 lines
You don't have to do any real measurements at least on OMAP. OCMC RAM is interfaced over L4 and MPU has to cross two interconnect bridges to reach to SRAM. DDR is more of direct path and much faster.
Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Maybe there's a extra low latency path for DDR that I am missing.
Quoted 8 lines
have you folks considered the possibility that SRAM may be reprogrammed by Security code to almost nothing if PA/PPA size needs to be increased? it would be rather dumb not to support HS devices on which real products are made, no? rule of thumb has been to avoid usage of SRAM as it constraints security folks as well (yep, I know they should share code with all of us etc.. but they have a different sets of challenges that may deny them such luxury).
Even I would like to avoid the usage of MPUSS SRAM for this very reason. But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 32 lines · Vaibhav
Quoted 22 lines · Nishanth
Quoted 13 lines · Vaibhav
On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]Quoted 9 lines
Quoted 9 lines
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.Quoted 8 lines
Quoted 4 lines
You don't have to do any real measurements at least on OMAP. OCMC RAM is interfaced over L4 and MPU has to cross two interconnect bridges to reach to SRAM. DDR is more of direct path and much faster.
Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Maybe there's a extra low latency path for DDR that I am missing.Quoted 8 lines
have you folks considered the possibility that SRAM may be reprogrammed by Security code to almost nothing if PA/PPA size needs to be increased? it would be rather dumb not to support HS devices on which real products are made, no? rule of thumb has been to avoid usage of SRAM as it constraints security folks as well (yep, I know they should share code with all of us etc.. but they have a different sets of challenges that may deny them such luxury).
Quoted 2 lines
Even I would like to avoid the usage of MPUSS SRAM for this very reason. But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).
On OMAP, even OCMC RAM can be used by security middle-ware apart from reserved SRAM
for HS/EMU devices.
That's what Nishant meant.
Regards
Santosh
PATCH 1/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 33 lines · Santosh
Quoted 32 lines · Vaibhav
Quoted 30 lines · Nishanth
Quoted 13 lines · Vaibhav
On Wed, May 02, 2012 at 16:30:26, Shilimkar, Santosh wrote:
[...]Quoted 9 lines
Quoted 9 lines
Quoted 4 lines
How ?
SRAM is sower memory than DDR so I don't see how it will reduce latency.I am just guessing if that's indeed the case ;)
Haven't done any measurements to really check if that's indeed the case though.Quoted 8 lines
Quoted 4 lines
You don't have to do any real measurements at least on OMAP. OCMC RAM is interfaced over L4 and MPU has to cross two interconnect bridges to reach to SRAM. DDR is more of direct path and much faster.
Hmm, I was under the impression that OCMC RAM was on L3, at least for OMAP4.
Maybe there's a extra low latency path for DDR that I am missing.have you folks considered the possibility that SRAM may be reprogrammed by Security code to almost nothing if PA/PPA size needs to be increased? it would be rather dumb not to support HS devices on which real products are made, no? rule of thumb has been to avoid usage of SRAM as it constraints security folks as well (yep, I know they should share code with all of us etc.. but they have a different sets of challenges that may deny them such luxury).
Quoted 8 lines
Quoted 2 lines
Even I would like to avoid the usage of MPUSS SRAM for this very reason. But AFAIK the whole PPA stuff isn't applicable for OCMC RAM (not SRAM inside MPUSS).
On OMAP, even OCMC RAM can be used by security middle-ware apart from reserved SRAM
for HS/EMU devices.
That's what Nishant meant.
Oh ok. I wasn't aware of this aspect.
Thanks,
Vaibhav
PATCH 2/19 ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
In reply to Tero KristoFrom: Rajendra Nayak <[email protected]>
Restore all CM1/2 module registers as they are lost in OFF mode.
--- arch/arm/mach-omap2/cm44xx.c | 322 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/cm44xx.h | 2 + 2 files changed, 324 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/cm44xx.c +322 -0
@@ -21,8 +21,11 @@#include "iomap.h" #include "common.h" #include "cm.h" +#include "cm44xx.h" #include "cm1_44xx.h" #include "cm2_44xx.h" +#include "cminst44xx.h" +#include "prcm44xx.h" #include "cm-regbits-44xx.h" /* CM1 hardware module low-level functions */
@@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) {__raw_writel (val,OMAP44XX_CM2_REGADDR (inst, reg)); } + +#define MAX_CM_REGISTERS 51 + +struct omap4_cm_reg { +u16 offset; +u32 val; +}; + +struct omap4_cm_regs { +u32 mod_off; +u32 no_reg; +struct omap4_cm_reg reg[MAX_CM_REGISTERS ]; +}; + +static struct omap4_cm_regs cm1_regs[] = { +/* OMAP4430_CM1_OCP_SOCKET_MOD */ + { .mod_off =OMAP4430_CM1_OCP_SOCKET_INST , .no_reg =1 , + {{.offset =OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM1_CKGEN_MOD */ + { .mod_off =OMAP4430_CM1_CKGEN_INST , .no_reg =4 , + {{.offset =OMAP4_CM_CLKSEL_CORE_OFFSET }, + {.offset =OMAP4_CM_CLKSEL_ABE_OFFSET }, + {.offset =OMAP4_CM_DLL_CTRL_OFFSET }, + {.offset =OMAP4_CM_DYN_DEP_PRESCAL_OFFSET } }, + }, +/* OMAP4430_CM1_MPU_MOD */ + { .mod_off =OMAP4430_CM1_MPU_INST , .no_reg =4 , + {{.offset =OMAP4_CM_MPU_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_MPU_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_MPU_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM1_TESLA_MOD */ + { .mod_off =OMAP4430_CM1_TESLA_INST , .no_reg =4 , + {{.offset =OMAP4_CM_TESLA_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_TESLA_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_TESLA_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM1_ABE_MOD */ + { .mod_off =OMAP4430_CM1_ABE_INST , .no_reg =15 , + {{.offset =OMAP4_CM1_ABE_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET } }, + }, +}; + +static struct omap4_cm_regs cm2_regs[] = { +/* OMAP4430_CM2_OCP_SOCKET_MOD */ + {.mod_off =OMAP4430_CM2_OCP_SOCKET_INST , .no_reg =1 , + {{.offset =OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_CKGEN_MOD */ + {.mod_off =OMAP4430_CM2_CKGEN_INST , .no_reg =12 , + {{.offset =OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET }, + {.offset =OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET }, + {.offset =OMAP4_CM_SCALE_FCLK_OFFSET }, + {.offset =OMAP4_CM_CORE_DVFS_PERF1_OFFSET }, + {.offset =OMAP4_CM_CORE_DVFS_PERF2_OFFSET }, + {.offset =OMAP4_CM_CORE_DVFS_PERF3_OFFSET }, + {.offset =OMAP4_CM_CORE_DVFS_PERF4_OFFSET }, + {.offset =OMAP4_CM_CORE_DVFS_CURRENT_OFFSET }, + {.offset =OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET }, + {.offset =OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET }, + {.offset =OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET }, + {.offset =OMAP4_CM_IVA_DVFS_CURRENT_OFFSET } }, + }, +/* OMAP4430_CM2_ALWAYS_ON_MOD */ + {.mod_off =OMAP4430_CM2_ALWAYS_ON_INST , .no_reg =6 , + {{.offset =OMAP4_CM_ALWON_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_CORE_MOD */ + {.mod_off =OMAP4430_CM2_CORE_INST , .no_reg =41 , + {{.offset =OMAP4_CM_L3_1_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_L3_1_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3_2_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_L3_2_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_DUCATI_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_SDMA_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_SDMA_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_SDMA_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_D2D_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_D2D_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_D2D_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_D2D_MODEM_ICR_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_IVAHD_MOD */ + {.mod_off =OMAP4430_CM2_IVAHD_INST , .no_reg =5 , + {{.offset =OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_IVAHD_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_CAM_MOD */ + {.mod_off =OMAP4430_CM2_CAM_INST , .no_reg =5 , + {{.offset =OMAP4_CM_CAM_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_CAM_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_CAM_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_DSS_MOD */ + {.mod_off =OMAP4430_CM2_DSS_INST , .no_reg =5 , + {{.offset =OMAP4_CM_DSS_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_DSS_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_DSS_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_GFX_MOD */ + {.mod_off =OMAP4430_CM2_GFX_INST , .no_reg =4 , + {{.offset =OMAP4_CM_GFX_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_GFX_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_GFX_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_L3INIT_MOD */ + {.mod_off =OMAP4430_CM2_L3INIT_INST , .no_reg =20 , + {{.offset =OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_L4PER_MOD */ + {.mod_off =OMAP4430_CM2_L4PER_INST , .no_reg =51 , + {{.offset =OMAP4_CM_L4PER_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_L4SEC_STATICDEP_OFFSET }, + {.offset =OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET }, + {.offset =OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET }, + {.offset =OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET } }, + }, +/* OMAP4430_CM2_CEFUSE_MOD */ + {.mod_off =OMAP4430_CM2_CEFUSE_INST , .no_reg =2 , + {{.offset =OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET }, + {.offset =OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET } }, + }, +}; + +static void omap4_cm1_prepare_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm1_regs; + +for (i =0 ; i <ARRAY_SIZE (cm1_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { + cm_reg->reg[j].val = +omap4_cminst_read_inst_reg (OMAP4430_CM1_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +static void omap4_cm2_prepare_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm2_regs; + +for (i =0 ; i <ARRAY_SIZE (cm2_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { + cm_reg->reg[j].val = +omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +static void omap4_cm1_resume_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm1_regs; + +for (i =0 ; i <ARRAY_SIZE (cm1_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { +omap4_cminst_write_inst_reg (cm_reg->reg[j].val, +OMAP4430_CM1_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +static void omap4_cm2_resume_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm2_regs; + +for (i =0 ; i <ARRAY_SIZE (cm2_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { +omap4_cminst_write_inst_reg (cm_reg->reg[j].val, +OMAP4430_CM2_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +void omap4_cm_prepare_off (void ) +{ +omap4_cm1_prepare_off (); +omap4_cm2_prepare_off (); +} + +void omap4_cm_resume_off (void ) +{ +omap4_cm1_resume_off (); +omap4_cm2_resume_off (); +}
arch/arm/mach-omap2/cm44xx.h +2 -0
@@ -24,6 +24,8 @@#define OMAP4_CM_STATICDEP 0x0004#ifndef __ASSEMBLER__ +extern void omap4_cm_prepare_off (void ); +extern void omap4_cm_resume_off (void );extern void omap4_dpll_prepare_off (void );extern void omap4_dpll_resume_off (void );#endif
Signature · 1 line
1.7.4.1
PATCH 2/19 ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
Quoted 3 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
Restore all CM1/2 module registers as they are lost in OFF mode.
Except they are still lost since nobody calls these new functions (in this patch.) :)
For ease of review, it's preferred to add the *users* of new code in the same patch as the new code.
Quoted 32 lines
[nm at ti.com: minor clean ups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Axel Haslam <[email protected]>Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/cm44xx.c | 322 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/cm44xx.h | 2 + 2 files changed, 324 insertions(+), 0 deletions(-)arch/arm/mach-omap2/cm44xx.c +4
-0@@ -21,8 +21,11 @@#include "iomap.h" #include "common.h" #include "cm.h" +#include "cm44xx.h" #include "cm1_44xx.h" #include "cm2_44xx.h" +#include "cminst44xx.h" +#include "prcm44xx.h" #include "cm-regbits-44xx.h" /* CM1 hardware module low-level functions */ @@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) {__raw_writel (val,OMAP44XX_CM2_REGADDR (inst, reg)); } +
arch/arm/mach-omap2/cm44xx.c void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) · line 66
Quoted 10 lines
arch/arm/mach-omap2/cm44xx.c +10
-0+#define MAX_CM_REGISTERS 51 + +struct omap4_cm_reg { +u16 offset; +u32 val; +}; + +struct omap4_cm_regs { +u32 mod_off; +u32 no_reg;
minor: do these need to be u32?
arch/arm/mach-omap2/cm44xx.c void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) · line 73
Quoted 7 lines
arch/arm/mach-omap2/cm44xx.c +7
-0+struct omap4_cm_reg reg[MAX_CM_REGISTERS ]; +}; + +static struct omap4_cm_regs cm1_regs[] = { +/* OMAP4430_CM1_OCP_SOCKET_MOD */ + { .mod_off =OMAP4430_CM1_OCP_SOCKET_INST , .no_reg =1 , + {{.offset =OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET } },
For readability sake, I'd prefer to see this line indented. And why the extra space before the final '}'}
Quoted 1 line
arch/arm/mach-omap2/cm44xx.c +1
-0+ },
[...]
Quoted 49 lines
arch/arm/mach-omap2/cm44xx.c +48
-0+static void omap4_cm1_prepare_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm1_regs; + +for (i =0 ; i <ARRAY_SIZE (cm1_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { + cm_reg->reg[j].val = +omap4_cminst_read_inst_reg (OMAP4430_CM1_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +static void omap4_cm2_prepare_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm2_regs; + +for (i =0 ; i <ARRAY_SIZE (cm2_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { + cm_reg->reg[j].val = +omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} +static void omap4_cm1_resume_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm1_regs; + +for (i =0 ; i <ARRAY_SIZE (cm1_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { +omap4_cminst_write_inst_reg (cm_reg->reg[j].val, +OMAP4430_CM1_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +static void omap4_cm2_resume_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm2_regs;
arch/arm/mach-omap2/cm44xx.c void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) · line 362
Quoted 10 lines
arch/arm/mach-omap2/cm44xx.c +10
-0+ +for (i =0 ; i <ARRAY_SIZE (cm2_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { +omap4_cminst_write_inst_reg (cm_reg->reg[j].val, +OMAP4430_CM2_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +}
Notice the two prpare functions (and resume functions) are basically identical, except for the partition.
How about adding a .partition field to the struct so there can be a single function}
Kevin
PATCH 2/19 ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
Quoted 11 lines · Kevin Hilman
Quoted 3 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
Restore all CM1/2 module registers as they are lost in OFF mode.
Except they are still lost since nobody calls these new functions (in this patch.) :)
For ease of review, it's preferred to add the *users* of new code in the same patch as the new code.
I'll fix this for the next version. I think this same comment applies to patch #3 also.
Quoted 37 lines
Quoted 37 lines
[nm at ti.com: minor clean ups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Axel Haslam <[email protected]>Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/cm44xx.c | 322 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/cm44xx.h | 2 + 2 files changed, 324 insertions(+), 0 deletions(-)arch/arm/mach-omap2/cm44xx.c +8
-0@@ -21,8 +21,11 @@#include "iomap.h" #include "common.h" #include "cm.h" +#include "cm44xx.h" #include "cm1_44xx.h" #include "cm2_44xx.h" +#include "cminst44xx.h" +#include "prcm44xx.h" #include "cm-regbits-44xx.h" /* CM1 hardware module low-level functions */ @@ -50,3 +53,322 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) {__raw_writel (val,OMAP44XX_CM2_REGADDR (inst, reg)); } + +#define MAX_CM_REGISTERS 51 + +struct omap4_cm_reg { +u16 offset;
Quoted 8 lines
arch/arm/mach-omap2/cm44xx.c void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) · line 66
Quoted 6 lines
arch/arm/mach-omap2/cm44xx.c +6
-0+u32 val; +}; + +struct omap4_cm_regs { +u32 mod_off; +u32 no_reg;minor: do these need to be u32?
u16 should be good enough to save space I guess, I'll try changing this and see what happens.
Quoted 11 lines
arch/arm/mach-omap2/cm44xx.c void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) · line 73
Quoted 8 lines
arch/arm/mach-omap2/cm44xx.c +7
-0+struct omap4_cm_reg reg[MAX_CM_REGISTERS ]; +}; + +static struct omap4_cm_regs cm1_regs[] = { +/* OMAP4430_CM1_OCP_SOCKET_MOD */ + { .mod_off =OMAP4430_CM1_OCP_SOCKET_INST , .no_reg =1 , + {{.offset =OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET } },For readability sake, I'd prefer to see this line indented. And why the extra space before the final '}'}
These tables are horrible, would be better to get rid of them completely but I guess that is not possible... I'll look at the indentation.
Quoted 68 lines
Quoted 2 lines
arch/arm/mach-omap2/cm44xx.c +1
-0+ },[...]
Quoted 49 lines
arch/arm/mach-omap2/cm44xx.c +48
-0+static void omap4_cm1_prepare_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm1_regs; + +for (i =0 ; i <ARRAY_SIZE (cm1_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { + cm_reg->reg[j].val = +omap4_cminst_read_inst_reg (OMAP4430_CM1_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +static void omap4_cm2_prepare_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm2_regs; + +for (i =0 ; i <ARRAY_SIZE (cm2_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { + cm_reg->reg[j].val = +omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} +static void omap4_cm1_resume_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm1_regs; + +for (i =0 ; i <ARRAY_SIZE (cm1_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { +omap4_cminst_write_inst_reg (cm_reg->reg[j].val, +OMAP4430_CM1_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +static void omap4_cm2_resume_off (void ) +{ +u32 i, j; +struct omap4_cm_regs *cm_reg = cm2_regs;arch/arm/mach-omap2/cm44xx.c void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) · line 362
Quoted 10 lines
arch/arm/mach-omap2/cm44xx.c +10
-0+ +for (i =0 ; i <ARRAY_SIZE (cm2_regs); i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { +omap4_cminst_write_inst_reg (cm_reg->reg[j].val, +OMAP4430_CM2_PARTITION , + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +}Notice the two prpare functions (and resume functions) are basically identical, except for the partition.
Quoted 2 lines
How about adding a .partition field to the struct so there can be a single function}
Yea, should be possible. I'll fix this for next rev.
-Tero
PATCH 3/19 ARM: OMAP4: PM: powerdomain: Add HWSAR flag to L3INIT
In reply to Tero KristoFrom: Santosh Shilimkar <[email protected]>
L3INIT powerdomain has USB HOST and USB TLL modules which support hardware save-and-restore (HW SAR) mechanism.
This patch updates the L3INIT power domain to mark them as capable of doing H/w save and restore and provides functions to do them explicitly.
Note: Eventually, these custom function implementation will be abstracted and might be done in hwmod or in other layer.
--- arch/arm/mach-omap2/powerdomain44xx.c | 41 +++++++++++++++++++++++++++ arch/arm/mach-omap2/powerdomains44xx_data.c | 2 +- 2 files changed, 42 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/powerdomain44xx.c +41 -0
@@ -23,6 +23,10 @@#include "prm44xx.h" #include "prminst44xx.h" #include "prm-regbits-44xx.h" +#include "cm-regbits-44xx.h" +#include "prcm44xx.h" +#include "cm2_44xx.h" +#include "cminst44xx.h" static int omap4_pwrdm_set_next_pwrst (struct powerdomain *pwrdm,u8 pwrst) {
@@ -208,6 +212,41 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)return 0 ; } +static int omap4_pwrdm_enable_hdwr_sar (struct powerdomain *pwrdm) +{ +/* +* FIXME: This should be fixed right way by moving it into HWMOD +* or clock framework since sar control is moved to module level +*/ +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +1 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ); +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +1 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ); +return 0 ; +} + +static int omap4_pwrdm_disable_hdwr_sar (struct powerdomain *pwrdm) +{ +/* +* FIXME: This should be fixed right way by moving it into HWMOD +* or clock framework since sar control is moved to module level +*/ +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +0 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ); +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +0 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ); + +return 0 ; +} +struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
@@ -223,4 +262,6 @@ struct pwrdm_ops omap4_pwrdm_operations = { .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, + .pwrdm_enable_hdwr_sar = omap4_pwrdm_enable_hdwr_sar, + .pwrdm_disable_hdwr_sar = omap4_pwrdm_disable_hdwr_sar, };
arch/arm/mach-omap2/powerdomains44xx_data.c +1 -1
@@ -276,7 +276,7 @@ static struct powerdomain l3init_44xx_pwrdm = { .pwrsts_mem_on = { [0] = PWRSTS_ON, /* l3init_bank1 */ }, - .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE | PWRDM_HAS_HDWR_SAR, };/* l4per_44xx_pwrdm: Target peripherals power domain */
Signature · 1 line
1.7.4.1
PATCH 4/19 ARM: OMAP4: Add SAR ROM base address
In reply to Tero KristoAdded in preparation for device off mode. SAR ROM contains the mapping from SAR RAM to IO registers, and this will eventually be parsed during init time to do the reverse before device off.
--- arch/arm/plat-omap/include/plat/omap44xx.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
arch/arm/plat-omap/include/plat/omap44xx.h +1 -0
@@ -46,6 +46,7 @@#define OMAP44XX_MCPDM_BASE 0x40132000#define OMAP44XX_MCPDM_L3_BASE 0x49032000#define OMAP44XX_SAR_RAM_BASE 0x4a326000 +#define OMAP44XX_SAR_ROM_BASE 0x4a05e000#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
Signature · 1 line
1.7.4.1
PATCH 5/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
In reply to Tero KristoFrom: Santosh Shilimkar <[email protected]>
The SAR RAM is maintained during Device OFF mode. The register layout is fixed in SAR ROM. SAR is split into 4 banks with different privilege accesses based on device type
---------------------------------------------------------------
Access mode Bank Address Range
---------------------------------------------------------------
HS/GP : Public 1 0x4A32_6000 - 0x4A32_6FFF (4kB)
HS/GP : Public 2 0x4A32_7000 - 0x4A32_73FF (1kB)
HS/EMU : Secured
GP : Public 3 0x4A32_8000 - 0x4A32_87FF (2kB)
HS/GP :Secure
write once. 4 0x4A32_9000 - 0x4A32_93FF (1kB)
---------------------------------------------------------------
The save process is done entirely by software and restore is done by hardware using the auto-restore feature. The restore feature is enabled by default and cannot be disabled. The software must save the data to be restored in a dedicated location in SAR RAM.
[with contributions for 4460, cleanups from:
Rajeev Kulkarni <[email protected]>
Nishanth Menon <[email protected]>
Axel Haslam <[email protected]>
Avinash.H.M <[email protected]>]
[t-kristo at ti.com: dropped huge data tables as they are no longer needed
with subsequent patches that generate the layouts based on SAR ROM contents, also dropped unnecessary dmm-44xx.h header file.]
--- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/cm1_44xx.h | 2 + arch/arm/mach-omap2/cm2_44xx.h | 2 + arch/arm/mach-omap2/omap-sar.c | 341 ++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 28 --- arch/arm/mach-omap2/omap4-sar-layout.h | 50 ++++ arch/arm/mach-omap2/pm.h | 12 + arch/arm/plat-omap/include/plat/omap44xx.h | 5 + 8 files changed, 413 insertions(+), 29 deletions(-) create mode 100644 arch/arm/mach-omap2/omap-sar.c
arch/arm/mach-omap2/Makefile +1 -1
@@ -27,7 +27,7 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \ - sleep44xx.o + sleep44xx.o omap-sar.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
arch/arm/mach-omap2/cm1_44xx.h +2 -0
@@ -218,8 +218,10 @@#define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0088)/* Function prototypes */ +#ifndef __ASSEMBLER__extern u32 omap4_cm1_read_inst_reg (s16 inst,u16 idx);extern void omap4_cm1_write_inst_reg (u32 val,s16 inst,u16 idx);extern u32 omap4_cm1_rmw_inst_reg_bits (u32 mask,u32 bits,s16 inst,s16 idx); +#endif #endif
arch/arm/mach-omap2/cm2_44xx.h +2 -0
@@ -450,8 +450,10 @@#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0020)/* Function prototypes */ +#ifndef __ASSEMBLER__extern u32 omap4_cm2_read_inst_reg (s16 inst,u16 idx);extern void omap4_cm2_write_inst_reg (u32 val,s16 inst,u16 idx);extern u32 omap4_cm2_rmw_inst_reg_bits (u32 mask,u32 bits,s16 inst,s16 idx); +#endif #endif
arch/arm/mach-omap2/omap-sar.c new file +341 -0
341 lines not on this page · raw message
arch/arm/mach-omap2/omap4-common.c +0 -28
@@ -37,7 +37,6 @@static void __iomem *l2cache_base;#endif -static void __iomem *sar_ram_base;static void __iomem *gic_dist_base_addr;#ifdef CONFIG_OMAP4_ERRATA_I688
@@ -186,30 +185,3 @@ static int __init omap_l2_cache_init(void) }early_initcall (omap_l2_cache_init);#endif - -void __iomem *omap4_get_sar_ram_base (void ) -{ -return sar_ram_base; -} - -/* -* SAR RAM used to save and restore the HW -* context in low power modes -*/ -static int __init omap4_sar_ram_init (void ) -{ -/* -* To avoid code running on other OMAPs in -* multi-omap builds -*/ -if (!cpu_is_omap44xx ()) -return -ENOMEM ; - -/* Static mapping, never released */ - sar_ram_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); -if (WARN_ON (!sar_ram_base)) -return -ENOMEM ; - -return 0 ; -} -early_initcall (omap4_sar_ram_init);
arch/arm/mach-omap2/omap4-sar-layout.h +50 -0
56 lines not on this page · raw message
arch/arm/mach-omap2/pm.h +12 -0
@@ -138,4 +138,16 @@ static inline int omap4_twl_init(void) }#endif +#ifdef CONFIG_PM +extern int omap4_sar_save (void ); +extern void omap4_sar_overwrite (void ); +#else +static inline void omap4_sar_save (void ) +{ +} +static inline void omap4_sar_overwrite (void ) +{ +} +#endif +#endif
arch/arm/plat-omap/include/plat/omap44xx.h +5 -0
@@ -22,6 +22,9 @@#define L4_PER_44XX_BASE 0x48000000#define L4_EMU_44XX_BASE 0x54000000#define L3_44XX_BASE 0x44000000 +#define L3_44XX_BASE_CLK1 L3_44XX_BASE +#define L3_44XX_BASE_CLK2 0x44800000 +#define L3_44XX_BASE_CLK3 0x45000000#define OMAP44XX_EMIF1_BASE 0x4c000000#define OMAP44XX_EMIF2_BASE 0x4d000000#define OMAP44XX_DMM_BASE 0x4e000000
@@ -59,5 +62,7 @@#define OMAP44XX_HSUSB_OHCI_BASE (L4_44XX_BASE + 0x64800)#define OMAP44XX_HSUSB_EHCI_BASE (L4_44XX_BASE + 0x64C00) +#define OMAP44XX_C2C_BASE 0x5c000000 +#endif /* __ASM_ARCH_OMAP44XX_H */
Signature · 1 line
1.7.4.1
Tony Lindgren
maintainerPATCH 5/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
Quoted 9 lines · Tero Kristo
arch/arm/mach-omap2/omap-sar.c new file +9
-0+ +static int omap4_sar_not_accessible (void ) +{ +u32 usbhost_state, usbtll_state; + +/* +* Make sure that USB host and TLL modules are not +* enabled before attempting to save the context +* registers, otherwise this will trigger an exception.
arch/arm/mach-omap2/omap-sar.c line 126
Quoted 10 lines
arch/arm/mach-omap2/omap-sar.c new file +10
-0+*/ + usbhost_state =omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ) + & (OMAP4430_STBYST_MASK |OMAP4430_IDLEST_MASK ); + + usbtll_state =omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ) + &OMAP4430_IDLEST_MASK ;
Formatting here looks bad, maybe just do it in separate steps:
usbhost_state = omap4_cminst... usbhost_state &= OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK;
...
arch/arm/mach-omap2/omap-sar.c line 149
Quoted 7 lines
arch/arm/mach-omap2/omap-sar.c new file +7
-0+/* +* Not supported on ES1.0 silicon +*/ +if (omap_rev () ==OMAP4430_REV_ES1_0 ) { +WARN_ONCE (1 ,"omap4: SAR backup not supported on ES1.0 ..\n" ); +return -ENODEV ; + }
Everytime there's SoC/hardware revision detection in a non __init function, something is most likely wrong.
arch/arm/mach-omap2/omap-sar.c line 203
Quoted 7 lines
arch/arm/mach-omap2/omap-sar.c new file +7
-0+void omap4_sar_overwrite (void ) +{ +u32 val =0 ; +u32 offset =0 ; + +if (cpu_is_omap446x ()) + offset =0x04 ;
Here too.
arch/arm/mach-omap2/omap-sar.c line 267
Quoted 8 lines
arch/arm/mach-omap2/omap-sar.c new file +8
-0+static int __init omap4_sar_ram_init (void ) +{ +/* +* To avoid code running on other OMAPs in +* multi-omap builds +*/ +if (!cpu_is_omap44xx ()) +return -ENODEV ;
You should configure things here instead by setting function pointers or variables.
Regards,
Tony
PATCH 5/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
Quoted 63 lines · Tony Lindgren
Quoted 9 lines · Tero Kristo
arch/arm/mach-omap2/omap-sar.c new file +9
-0+ +static int omap4_sar_not_accessible (void ) +{ +u32 usbhost_state, usbtll_state; + +/* +* Make sure that USB host and TLL modules are not +* enabled before attempting to save the context +* registers, otherwise this will trigger an exception. arch/arm/mach-omap2/omap-sar.c line 126
Quoted 10 lines
arch/arm/mach-omap2/omap-sar.c new file +10
-0+*/ + usbhost_state =omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ) + & (OMAP4430_STBYST_MASK |OMAP4430_IDLEST_MASK ); + + usbtll_state =omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ) + &OMAP4430_IDLEST_MASK ;Formatting here looks bad, maybe just do it in separate steps:
usbhost_state = omap4_cminst... usbhost_state &= OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK;...
arch/arm/mach-omap2/omap-sar.c line 149
Quoted 7 lines
arch/arm/mach-omap2/omap-sar.c new file +7
-0+/* +* Not supported on ES1.0 silicon +*/ +if (omap_rev () ==OMAP4430_REV_ES1_0 ) { +WARN_ONCE (1 ,"omap4: SAR backup not supported on ES1.0 ..\n" ); +return -ENODEV ; + }Everytime there's SoC/hardware revision detection in a non
__initfunction, something is most likely wrong.arch/arm/mach-omap2/omap-sar.c line 203
Quoted 7 lines
arch/arm/mach-omap2/omap-sar.c new file +7
-0+void omap4_sar_overwrite (void ) +{ +u32 val =0 ; +u32 offset =0 ; + +if (cpu_is_omap446x ()) + offset =0x04 ;Here too.
arch/arm/mach-omap2/omap-sar.c line 267
Quoted 8 lines
arch/arm/mach-omap2/omap-sar.c new file +8
-0+static int __init omap4_sar_ram_init (void ) +{ +/* +* To avoid code running on other OMAPs in +* multi-omap builds +*/ +if (!cpu_is_omap44xx ()) +return -ENODEV ;You should configure things here instead by setting function pointers or variables.
Quoted 3 lines
Regards,
Tony
Okay, I can drop rest of these from this patch, most of them do not exist in the final code (removed by later patches for autogeneration), I just left this here for historical reasons.
-Tero
PATCH 6/19 ARM: OMAP4: Auto generate SAR layout contents
In reply to Tero KristoSAR layout contents are now generated automatically based on SAR ROM contents during boot.
u32 offset description
---------- -------------------------
0 pointer to next entry
1 size of DMA transfer in bytes
2 SAR RAM address for save / restore
3 IO address for save / restore
sar_layout_generate() parses this info and stores the resulting data to a list of sar_ram_entry structs, which in turn will be used by sar_save.
--- arch/arm/mach-omap2/omap-sar.c | 290 +++++++++++++++++++++++++++------------- 1 files changed, 194 insertions(+), 96 deletions(-)
arch/arm/mach-omap2/omap-sar.c +194 -96
@@ -2,7 +2,8 @@* OMAP4 Save Restore source file * * Copyright (C) 2010 Texas Instruments, Inc. -* Written by Santosh Shilimkar <[email protected]> +* Santosh Shilimkar <[email protected]> +* Tero Kristo <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +15,7 @@#include <linux/io.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/slab.h> #include "iomap.h" #include "pm.h"
@@ -25,35 +27,18 @@#include "cminst44xx.h" static void __iomem *sar_ram_base; -static void __iomem *omap4_sar_modules[MAX_SAR_MODULES ];static struct powerdomain *l3init_pwrdm;static struct clockdomain *l3init_clkdm;static struct clk *usb_host_ck, *usb_tll_ck; -/* -* SAR_RAM1 register layout consist of EMIF1, EMIF2, CM1, CM2, -* CONTROL_CORE efuse, DMM and USB TLL registers. -* The layout is arranged is a two dimentional array like -* below, -* const u32 sar_ramX_layout[nb_regs_sets][4] = { -* {module_index, reg_offset, size, sar_ram_offset}, -* } -*/ -static const u32 omap443x_sar_ram1_layout[][4 ] = { -}; - -/* -* SAR_RAM2 register layout consist of SYSCTRL_PADCONF_CORE regsiters -*/ -static const u32 omap443x_sar_ram2_layout[][4 ] = { +struct sar_ram_entry { +void __iomem *io_base; +u32 offset; +u32 size; +u32 ram_addr; }; -/* -* SAR_RAM3 and SAR_RAM4 layout is not listed since moslty it's handle by -* secure software. -*/ -static const u32 omap443x_sar_ram3_layout[][4 ] = { -}; +static struct sar_ram_entry *sar_ram_layout[3 ];/* * omap_sar_save :
@@ -63,25 +48,20 @@ static const u32 omap443x_sar_ram3_layout[][4] = {* @sar_bank_offset - where to backup * @sar_layout - constant table containing the backup info */ -static void sar_save (u32 nb_regs,u32 sar_bank,const u32 sar_layout_table[][4 ]) +static void sar_save (struct sar_ram_entry *entry) { -u32 reg_val, size, i, j; +u32 reg_val, size, i;void __iomem *reg_read_addr, *sar_wr_addr; -for (i =0 ; i < nb_regs; i++) { -if (omap4_sar_modules[(sar_layout_table[i][MODULE_ADDR_IDX ])]) { - size = sar_layout_table[i][MODULE_NB_REGS_IDX ]; - reg_read_addr = - omap4_sar_modules[sar_layout_table[i] - [MODULE_ADDR_IDX ]] - + sar_layout_table[i][MODULE_OFFSET_IDX ]; - sar_wr_addr = sar_ram_base + sar_bank + - sar_layout_table[i][SAR_RAM_OFFSET_IDX ]; -for (j =0 ; j < size; j++) { - reg_val =__raw_readl (reg_read_addr + j *4 ); -__raw_writel (reg_val, sar_wr_addr + j *4 ); - } +while (entry->size) { + size = entry->size; + reg_read_addr = entry->io_base + entry->offset; + sar_wr_addr = sar_ram_base + entry->ram_addr; +for (i =0 ; i < size; i++) { + reg_val =__raw_readl (reg_read_addr + i *4 ); +__raw_writel (reg_val, sar_wr_addr + i *4 ); } + entry++; } }
@@ -100,8 +80,7 @@ static void save_sar_bank3(void) l4_secure_clkdm =clkdm_lookup ("l4_secure_clkdm" );clkdm_wakeup (l4_secure_clkdm); -sar_save (ARRAY_SIZE (omap443x_sar_ram3_layout),SAR_BANK3_OFFSET , - omap443x_sar_ram3_layout); +sar_save (sar_ram_layout[2 ]);clkdm_allow_idle (l4_secure_clkdm); }
@@ -116,13 +95,13 @@ static int omap4_sar_not_accessible(void)* registers, otherwise this will trigger an exception. */ usbhost_state =omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , -OMAP4430_CM2_L3INIT_INST , -OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ) +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ) & (OMAP4430_STBYST_MASK |OMAP4430_IDLEST_MASK ); usbtll_state =omap4_cminst_read_inst_reg (OMAP4430_CM2_PARTITION , -OMAP4430_CM2_L3INIT_INST , -OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ) +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ) &OMAP4430_IDLEST_MASK ; if ((usbhost_state == (OMAP4430_STBYST_MASK | OMAP4430_IDLEST_MASK)) &&
@@ -133,12 +112,12 @@ static int omap4_sar_not_accessible(void) }/* -* omap4_sar_save - +* omap_sar_save - * Save the context to SAR_RAM1 and SAR_RAM2 as per * omap4xxx_sar_ram1_layout and omap4xxx_sar_ram2_layout for the device OFF * mode */ -int omap4_sar_save (void ) +int omap_sar_save (void ) {/* * Not supported on ES1.0 silicon
@@ -163,8 +142,7 @@ int omap4_sar_save(void)clk_enable (usb_tll_ck);/* Save SAR BANK1 */ -sar_save (ARRAY_SIZE (omap443x_sar_ram1_layout),SAR_BANK1_OFFSET , - omap443x_sar_ram1_layout); +sar_save (sar_ram_layout[0 ]);clk_disable (usb_host_ck);clk_disable (usb_tll_ck);
@@ -172,8 +150,7 @@ int omap4_sar_save(void)clkdm_allow_idle (l3init_clkdm);/* Save SAR BANK2 */ -sar_save (ARRAY_SIZE (omap443x_sar_ram2_layout),SAR_BANK2_OFFSET , - omap443x_sar_ram2_layout); +sar_save (sar_ram_layout[1 ]);return 0 ; }
@@ -194,13 +171,16 @@ int omap4_sar_save(void)* sequencing, the software must overwrite data read from * the following registers implied in phase2a and phase 2b */ -void omap4_sar_overwrite (void ) +void omap_sar_overwrite (void ) {u32 val =0 ; -u32 offset =0 ; +u32 usb_offset =0x2ec ; +u32 usb_offset2 =0x91c ; -if (cpu_is_omap446x ()) - offset =0x04 ; +if (cpu_is_omap446x ()) { + usb_offset =0x2f4 ; + usb_offset2 =0x920 ; + }/* Overwriting Phase1 data to be restored */ /* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
@@ -215,7 +195,7 @@ void omap4_sar_overwrite(void)/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */ val =__raw_readl (OMAP4430_CM_SHADOW_FREQ_CONFIG1 ); val |=1 <<OMAP4430_FREQ_UPDATE_SHIFT ; - val &= ~OMAP4430_DLL_OVERRIDE_MASK ; + val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK ;__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET +0x104 );/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */ __raw_writel (0x3 , sar_ram_base +SAR_BANK1_OFFSET +0x124 );
@@ -223,29 +203,29 @@ void omap4_sar_overwrite(void)/* Overwriting Phase2a data to be restored */ /* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */ __raw_writel (0x00000012 , - sar_ram_base +SAR_BANK1_OFFSET +0x2ec + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset);/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */ __raw_writel (0x00000011 , - sar_ram_base +SAR_BANK1_OFFSET +0x2f0 + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset +4 );/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */ __raw_writel (0x000090e8 , - sar_ram_base +SAR_BANK1_OFFSET +0x2f4 + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset +8 );/* Overwriting Phase2b data to be restored */ /* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ val =__raw_readl (OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL ); val &= (OMAP4430_CLKSEL_UTMI_P1_MASK |OMAP4430_CLKSEL_UTMI_P2_MASK ); -__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET +0x91c + offset); +__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET + usb_offset2);/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ __raw_writel (0x0000000 , - sar_ram_base +SAR_BANK1_OFFSET +0x920 + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +4 );/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */ __raw_writel (0x00000040 , - sar_ram_base +SAR_BANK1_OFFSET +0x924 + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +8 );/* readback to ensure data reaches to SAR RAM */ barrier (); - val =__raw_readl (sar_ram_base +SAR_BANK1_OFFSET +0x924 + offset); + val =__raw_readl (sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +8 ); }void __iomem *omap4_get_sar_ram_base (void )
@@ -253,6 +233,152 @@ void __iomem *omap4_get_sar_ram_base(void)return sar_ram_base; } +static const u32 sar_rom_phases[] = { +0 ,0x30 ,0x60 +}; + +struct sar_module { +void __iomem *io_base; +u32 base; +u32 size; +bool invalid; +}; + +static struct sar_module *sar_modules; + +static void sar_ioremap_modules (void ) +{ +struct sar_module *mod; + + mod = sar_modules; + +while (mod->base) { +if (!mod->invalid) { + mod->io_base =ioremap (mod->base, mod->size); +if (!mod->io_base) +pr_err ("%s: ioremap failed for %08x[%08x]\n" , + __func__, mod->base, mod->size); +BUG_ON (!mod->io_base); + } + mod++; + } +} + +static int set_sar_io_addr (struct sar_ram_entry *entry,u32 addr) +{ +struct sar_module *mod; + + mod = sar_modules; + +while (mod->base) { +if (addr >= mod->base && addr <= mod->base + mod->size) { +if (mod->invalid) +break ; + entry->io_base = mod->io_base; + entry->offset = addr - mod->base; +return 0 ; + } + mod++; + } +pr_warn ("%s: no matching sar_module for %08x\n" , __func__, addr); +return -EINVAL ; +} + +static int sar_layout_generate (void ) +{ +int phase; +void __iomem *sarrom; +u32 rombase, romend, rambase, ramend; +u32 offset, next; +u16 size; +u32 ram_addr, io_addr; +void *sarram; +struct sar_ram_entry *entry[3 ]; +int bank; +int ret =0 ; + +pr_info ("generating sar_ram layout...\n" ); + + rombase =OMAP44XX_SAR_ROM_BASE ; + romend = rombase +SZ_8K ; + rambase =OMAP44XX_SAR_RAM_BASE ; + ramend = rambase +SAR_BANK4_OFFSET -1 ; + + sarrom =ioremap (rombase,SZ_8K ); + +/* Allocate temporary memory for sar ram layout */ + sarram =kmalloc (SAR_BANK4_OFFSET ,GFP_KERNEL ); +for (bank =0 ; bank <3 ; bank++) + entry[bank] = sarram +SAR_BANK2_OFFSET * bank; + +for (phase =0 ; phase <ARRAY_SIZE (sar_rom_phases); phase++) { + offset = sar_rom_phases[phase]; + +while (1 ) { + next =__raw_readl (sarrom + offset); + size =__raw_readl (sarrom + offset +4 ) &0xffff ; + ram_addr =__raw_readl (sarrom + offset +8 ); + io_addr =__raw_readl (sarrom + offset +12 ); + +if (ram_addr >= rambase && ram_addr <= ramend) { +/* Valid ram address, add entry */ + ram_addr -= rambase; + bank = ram_addr /SAR_BANK2_OFFSET ; +if (!set_sar_io_addr (entry[bank], io_addr)) { + entry[bank]->size = size; + entry[bank]->ram_addr = ram_addr; + entry[bank]++; + } + } + +if (next < rombase || next > romend) +break ; + + offset = next - rombase; + } + } + +for (bank =0 ; bank <3 ; bank++) { + size = (u32 )entry[bank] - + (u32)(sarram +SAR_BANK2_OFFSET * bank); + sar_ram_layout[bank] =kmalloc (size + +sizeof (struct sar_ram_entry ),GFP_KERNEL ); +if (!sar_ram_layout[bank]) { +pr_err ("%s: kmalloc failed\n" , __func__); + goto cleanup; + } +memcpy (sar_ram_layout[bank], sarram +SAR_BANK2_OFFSET * bank, + size); +memset ((void *)sar_ram_layout[bank] + size,0 , +sizeof (struct sar_ram_entry )); + entry[bank] = sar_ram_layout[bank]; + } + +cleanup: +kfree (sarram); +iounmap (sarrom); +pr_info ("sar ram layout created\n" ); +return ret; +} + +static struct sar_module omap44xx_sar_modules[] = { + { .base =OMAP44XX_EMIF1_BASE , .size =SZ_1M }, + { .base =OMAP44XX_EMIF2_BASE , .size =SZ_1M }, + { .base =OMAP44XX_DMM_BASE , .size =SZ_1M }, + { .base =OMAP4430_CM1_BASE , .size =SZ_8K }, + { .base =OMAP4430_CM2_BASE , .size =SZ_8K }, + { .base =OMAP44XX_C2C_BASE , .size =SZ_1M }, + { .base =OMAP443X_CTRL_BASE , .size =SZ_4K }, + { .base =L3_44XX_BASE_CLK1 , .size =SZ_1M }, + { .base =L3_44XX_BASE_CLK2 , .size =SZ_1M }, + { .base =L3_44XX_BASE_CLK3 , .size =SZ_1M }, + { .base =OMAP44XX_USBTLL_BASE , .size =SZ_1M }, + { .base =OMAP44XX_UHH_CONFIG_BASE , .size =SZ_1M }, + { .base =L4_44XX_PHYS , .size =SZ_4M }, + { .base =L4_PER_44XX_PHYS , .size =SZ_4M }, + { .base =0 }, +}; +/* * SAR RAM used to save and restore the HW * context in low power modes
@@ -273,39 +399,11 @@ static int __init omap4_sar_ram_init(void) sar_ram_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K );BUG_ON (!sar_ram_base); -/* -* All these are static mappings so ioremap() will -* just return with mapped VA -*/ - omap4_sar_modules[EMIF1_INDEX ] =ioremap (OMAP44XX_EMIF1_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[EMIF1_INDEX ]); - omap4_sar_modules[EMIF2_INDEX ] =ioremap (OMAP44XX_EMIF2_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[EMIF2_INDEX ]); - omap4_sar_modules[DMM_INDEX ] =ioremap (OMAP44XX_DMM_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[DMM_INDEX ]); - omap4_sar_modules[CM1_INDEX ] =ioremap (OMAP4430_CM1_BASE ,SZ_8K ); -BUG_ON (!omap4_sar_modules[CM1_INDEX ]); - omap4_sar_modules[CM2_INDEX ] =ioremap (OMAP4430_CM2_BASE ,SZ_8K ); -BUG_ON (!omap4_sar_modules[CM2_INDEX ]); - omap4_sar_modules[C2C_INDEX ] =ioremap (OMAP44XX_C2C_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[C2C_INDEX ]); - omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX ] = -ioremap (OMAP443X_CTRL_BASE ,SZ_4K ); -BUG_ON (!omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX ]); - omap4_sar_modules[L3_CLK1_INDEX ] =ioremap (L3_44XX_BASE_CLK1 ,SZ_1M ); -BUG_ON (!omap4_sar_modules[L3_CLK1_INDEX ]); - omap4_sar_modules[L3_CLK2_INDEX ] =ioremap (L3_44XX_BASE_CLK2 ,SZ_1M ); -BUG_ON (!omap4_sar_modules[L3_CLK2_INDEX ]); - omap4_sar_modules[L3_CLK3_INDEX ] =ioremap (L3_44XX_BASE_CLK3 ,SZ_1M ); -BUG_ON (!omap4_sar_modules[L3_CLK3_INDEX ]); - omap4_sar_modules[USBTLL_INDEX ] =ioremap (OMAP44XX_USBTLL_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[USBTLL_INDEX ]); - omap4_sar_modules[UHH_INDEX ] =ioremap (OMAP44XX_UHH_CONFIG_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[UHH_INDEX ]); - omap4_sar_modules[L4CORE_INDEX ] =ioremap (L4_44XX_PHYS ,SZ_4M ); -BUG_ON (!omap4_sar_modules[L4CORE_INDEX ]); - omap4_sar_modules[L4PER_INDEX ] =ioremap (L4_PER_44XX_PHYS ,SZ_4M ); -BUG_ON (!omap4_sar_modules[L4PER_INDEX ]); + sar_modules = omap44xx_sar_modules; + +sar_ioremap_modules (); + +sar_layout_generate ();/* * SAR BANK3 contains all firewall settings and it's saved through
Signature · 1 line
1.7.4.1
Tony Lindgren
maintainerPATCH 6/19 ARM: OMAP4: Auto generate SAR layout contents
Quoted 4 lines · Tero Kristo
arch/arm/mach-omap2/omap-sar.c +1
-1-void omap4_sar_overwrite (void ) +void omap_sar_overwrite (void ) {u32 val =0 ;
arch/arm/mach-omap2/omap-sar.c int omap4_sar_save(void) · line 183
Quoted 10 lines
arch/arm/mach-omap2/omap-sar.c +6
-3-u32 offset =0 ; +u32 usb_offset =0x2ec ; +u32 usb_offset2 =0x91c ; -if (cpu_is_omap446x ()) - offset =0x04 ; +if (cpu_is_omap446x ()) { + usb_offset =0x2f4 ; + usb_offset2 =0x920 ; + }
Here too you should initialized these during __init. Otherwise we'll end up piling more and more if else cpu_is_omapxxxx for future omaps that again might change the offsets.
Tony
PATCH 7/19 ARM: OMAP4: SAR: generate overwrite data based on SAR ROM contents
In reply to Tero Kristoomap_sar_overwrite() now uses offsets detected during init time from the SAR ROM contents.
--- arch/arm/mach-omap2/omap-sar.c | 158 ++++++++++++++++++++++++++++------------ 1 files changed, 112 insertions(+), 46 deletions(-)
arch/arm/mach-omap2/omap-sar.c +112 -46
@@ -38,7 +38,52 @@ struct sar_ram_entry {u32 ram_addr; }; +struct sar_overwrite_entry { +u32 reg_addr; +u32 sar_offset; +bool valid; +}; + +enum { +MEMIF_CLKSTCTRL_IDX , +SHADOW_FREQ_CFG2_IDX , +SHADOW_FREQ_CFG1_IDX , +MEMIF_CLKSTCTRL_2_IDX , +HSUSBHOST_CLKCTRL_IDX , +HSUSBHOST_CLKCTRL_2_IDX , +OW_IDX_SIZE +}; +static struct sar_ram_entry *sar_ram_layout[3 ]; +static struct sar_overwrite_entry *sar_overwrite_data; + +static struct sar_overwrite_entry omap4_sar_overwrite_data[OW_IDX_SIZE ] = { + [MEMIF_CLKSTCTRL_IDX ] = { .reg_addr =0x4a009e0c }, + [SHADOW_FREQ_CFG2_IDX ] = { .reg_addr =0x4a004e2c }, + [SHADOW_FREQ_CFG1_IDX ] = { .reg_addr =0x4a004e30 }, + [MEMIF_CLKSTCTRL_2_IDX ] = { .reg_addr =0x4a009e0c }, + [HSUSBHOST_CLKCTRL_IDX ] = { .reg_addr =0x4a009e54 }, + [HSUSBHOST_CLKCTRL_2_IDX ] = { .reg_addr =0x4a009e54 }, +}; + +static void check_overwrite_data (u32 io_addr,u32 ram_addr,int size) +{ +int i; + +while (size) { +for (i =0 ; i <OW_IDX_SIZE ; i++) { +if (sar_overwrite_data[i].reg_addr == io_addr && + !sar_overwrite_data[i].valid) { + sar_overwrite_data[i].sar_offset = ram_addr; + sar_overwrite_data[i].valid = true; +break ; + } + } + size--; + io_addr +=4 ; + ram_addr +=4 ; + } +}/* * omap_sar_save :
@@ -174,58 +219,76 @@ int omap_sar_save(void)void omap_sar_overwrite (void ) {u32 val =0 ; -u32 usb_offset =0x2ec ; -u32 usb_offset2 =0x91c ; +u32 offset =0 ; + +if (sar_overwrite_data[MEMIF_CLKSTCTRL_IDX ].valid) +__raw_writel (0x2 , sar_ram_base + + sar_overwrite_data[MEMIF_CLKSTCTRL_IDX ].sar_offset); + +if (sar_overwrite_data[SHADOW_FREQ_CFG1_IDX ].valid) { + offset = sar_overwrite_data[SHADOW_FREQ_CFG1_IDX ].sar_offset; + val =__raw_readl (sar_ram_base + offset); + val |=1 <<OMAP4430_FREQ_UPDATE_SHIFT ; + val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK ; +__raw_writel (val, sar_ram_base + offset); + } -if (cpu_is_omap446x ()) { - usb_offset =0x2f4 ; - usb_offset2 =0x920 ; +if (sar_overwrite_data[SHADOW_FREQ_CFG2_IDX ].valid) { + offset = sar_overwrite_data[SHADOW_FREQ_CFG2_IDX ].sar_offset; + val =__raw_readl (sar_ram_base + offset); +/* +* FIXME: Implement FREQ UPDATE for L#/M5 before enabling +* val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT; +*/ +__raw_writel (val, sar_ram_base + offset); } -/* Overwriting Phase1 data to be restored */ -/* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */ -__raw_writel (0x2 , sar_ram_base +SAR_BANK1_OFFSET +0xd0 ); -/* CM1 CM_SHADOW_FREQ_CONFIG2, Enable FREQ UPDATE */ - val =__raw_readl (OMAP4430_CM_SHADOW_FREQ_CONFIG2 ); -/* -* FIXME: Implement FREQ UPDATE for L#/M5 before enabling this -* val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT; -*/ -__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET +0x100 ); -/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */ - val =__raw_readl (OMAP4430_CM_SHADOW_FREQ_CONFIG1 ); - val |=1 <<OMAP4430_FREQ_UPDATE_SHIFT ; - val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK ; -__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET +0x104 ); -/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */ -__raw_writel (0x3 , sar_ram_base +SAR_BANK1_OFFSET +0x124 ); - -/* Overwriting Phase2a data to be restored */ -/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */ -__raw_writel (0x00000012 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset); -/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */ -__raw_writel (0x00000011 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset +4 ); -/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */ -__raw_writel (0x000090e8 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset +8 ); - -/* Overwriting Phase2b data to be restored */ -/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ - val =__raw_readl (OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL ); - val &= (OMAP4430_CLKSEL_UTMI_P1_MASK |OMAP4430_CLKSEL_UTMI_P2_MASK ); -__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET + usb_offset2); -/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ -__raw_writel (0x0000000 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +4 ); -/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */ -__raw_writel (0x00000040 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +8 ); +if (sar_overwrite_data[MEMIF_CLKSTCTRL_2_IDX ].valid) +__raw_writel (0x3 , sar_ram_base + + sar_overwrite_data[MEMIF_CLKSTCTRL_2_IDX ].sar_offset); + +if (sar_overwrite_data[HSUSBHOST_CLKCTRL_IDX ].valid) { + offset = sar_overwrite_data[HSUSBHOST_CLKCTRL_IDX ].sar_offset; + +/* Overwriting Phase2a data to be restored */ +/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */ +__raw_writel (OMAP4430_SAR_MODE_MASK |0x2 , + sar_ram_base + offset); +/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */ +__raw_writel (OMAP4430_SAR_MODE_MASK |0x1 , + sar_ram_base + offset +4 ); +/* +* CM2 CM_SDMA_STATICDEP : Enable static depedency for +* SAR modules +*/ +__raw_writel (OMAP4430_L4WKUP_STATDEP_MASK | +OMAP4430_L4CFG_STATDEP_MASK | +OMAP4430_L3INIT_STATDEP_MASK | +OMAP4430_L3_1_STATDEP_MASK | +OMAP4430_L3_2_STATDEP_MASK | +OMAP4430_ABE_STATDEP_MASK , + sar_ram_base + offset +8 ); + } + +if (sar_overwrite_data[HSUSBHOST_CLKCTRL_2_IDX ].valid) { + offset = sar_overwrite_data[HSUSBHOST_CLKCTRL_2_IDX ].sar_offset; + +/* Overwriting Phase2b data to be restored */ +/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ + val =__raw_readl (OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL ); + val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | +OMAP4430_CLKSEL_UTMI_P2_MASK ); +__raw_writel (val, sar_ram_base + offset); +/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ +__raw_writel (0 , sar_ram_base + offset +4 ); +/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */ +__raw_writel (OMAP4430_L3_2_STATDEP_MASK , + sar_ram_base + offset +8 ); + }/* readback to ensure data reaches to SAR RAM */ barrier (); - val =__raw_readl (sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +8 ); + val =__raw_readl (sar_ram_base + offset +8 ); }void __iomem *omap4_get_sar_ram_base (void )
@@ -327,6 +390,8 @@ static int sar_layout_generate(void)if (!set_sar_io_addr (entry[bank], io_addr)) { entry[bank]->size = size; entry[bank]->ram_addr = ram_addr; +check_overwrite_data (io_addr, ram_addr, + size); entry[bank]++; } }
@@ -400,6 +465,7 @@ static int __init omap4_sar_ram_init(void)BUG_ON (!sar_ram_base); sar_modules = omap44xx_sar_modules; + sar_overwrite_data = omap4_sar_overwrite_data;sar_ioremap_modules ();
Signature · 1 line
1.7.4.1
PATCH 8/19 ARM: OMAP4: PM: Add device-off support
In reply to Tero KristoThis patch adds device off support to OMAP4 device type.
OFF mode is disabled by default, however, there are two ways to enable OFF mode:
a) In the board file, call omap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry
echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).
--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 24 ++++++++++- arch/arm/mach-omap2/omap-wakeupgen.c | 47 +++++++++++++++++++- arch/arm/mach-omap2/pm-debug.c | 17 +++++-- arch/arm/mach-omap2/pm.h | 28 ++++++++++-- arch/arm/mach-omap2/pm44xx.c | 45 +++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 66 +++++++++++++++++++++++++++++ 6 files changed, 214 insertions(+), 13 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +22 -2
@@ -60,6 +60,7 @@#include "prcm44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" +#include "cm44xx.h" #ifdef CONFIG_SMP
@@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) {unsigned int save_state =0 ;unsigned int wakeup_cpu; +int ret;if (omap_rev () ==OMAP4430_REV_ES1_0 )return -ENXIO ;
@@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); -if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && - (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) +if (omap4_device_next_state_off ()) { +/* Save the device context to SAR RAM */ + ret =omap_sar_save (); +if (ret) +return ret; +omap_sar_overwrite (); +omap4_cm_prepare_off (); +omap4_dpll_prepare_off (); + save_state =3 ; + }else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && + (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) { save_state =2 ; + }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) { + save_state =3 ; + }cpu_clear_prev_logic_pwrst (cpu);set_cpu_next_pwrst (cpu, power_state);
@@ -288,6 +302,12 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); +if (omap4_device_prev_state_off ()) { +omap4_dpll_resume_off (); +omap4_cm_resume_off (); +omap4_device_clear_prev_off_state (); + } +pwrdm_post_transition ();return 0 ;
arch/arm/mach-omap2/omap-wakeupgen.c +45 -2
82 lines not on this page · raw message
arch/arm/mach-omap2/pm-debug.c +12 -5
@@ -40,6 +40,7 @@u32 enable_off_mode;static u32 enable_oswr_mode; +static void (*off_mode_enable_func) (int );#ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h>
@@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)else omap_pm_disable_off_mode (); -omap3_pm_off_mode_enable (val); +if (off_mode_enable_func) +off_mode_enable_func (val); }if (option == &enable_oswr_mode)
@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void)pwrdm_for_each (pwrdms_setup, (void *)d); -if (cpu_is_omap34xx ()) - (void )debugfs_create_file ("enable_off_mode" , -S_IRUGO |S_IWUSR , d, &enable_off_mode, - &pm_dbg_option_fops); + (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); +if (cpu_is_omap34xx ()) + off_mode_enable_func = omap3_pm_off_mode_enable; + +if (cpu_is_omap44xx ()) + off_mode_enable_func = omap4_pm_off_mode_enable; + pm_dbg_init_done =1 ;return 0 ;
arch/arm/mach-omap2/pm.h +24 -4
@@ -18,6 +18,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 omap4_pm_off_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 );
@@ -26,6 +27,25 @@ extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);extern int (*omap_pm_suspend)(void );extern void omap_trigger_io_chain (void ); +#ifdef CONFIG_PM +extern void omap4_device_set_state_off (u8 enable); +extern bool omap4_device_prev_state_off (void ); +extern bool omap4_device_next_state_off (void ); +extern void omap4_device_clear_prev_off_state (void ); +#else +static inline void omap4_device_set_state_off (u8 enable) +{ +} +static inline bool omap4_device_prev_state_off (void ) +{ +return false; +} +static inline bool omap4_device_next_state_off (void ) +{ +return false; +} +#endif +#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );extern int omap4_opp_init (void );
@@ -139,13 +159,13 @@ static inline int omap4_twl_init(void)#endif #ifdef CONFIG_PM -extern int omap4_sar_save (void ); -extern void omap4_sar_overwrite (void ); +extern int omap_sar_save (void ); +extern void omap_sar_overwrite (void );#else -static inline void omap4_sar_save (void ) +static inline void omap_sar_save (void ) { } -static inline void omap4_sar_overwrite (void ) +static inline void omap_sar_overwrite (void ) { }#endif
arch/arm/mach-omap2/pm44xx.c +45 -0
57 lines not on this page · raw message
arch/arm/mach-omap2/prm44xx.c +66 -0
72 lines not on this page · raw message
Signature · 1 line
1.7.4.1
PATCH 8/19 ARM: OMAP4: PM: Add device-off support
Hi Tero,
Quoted 42 lines · Tero Kristo
This patch adds device off support to OMAP4 device type.
OFF mode is disabled by default, however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry
echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 24 ++++++++++- arch/arm/mach-omap2/omap-wakeupgen.c | 47 +++++++++++++++++++- arch/arm/mach-omap2/pm-debug.c | 17 +++++-- arch/arm/mach-omap2/pm.h | 28 ++++++++++-- arch/arm/mach-omap2/pm44xx.c | 45 +++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 66 +++++++++++++++++++++++++++++ 6 files changed, 214 insertions(+), 13 deletions(-)arch/arm/mach-omap2/omap-mpuss-lowpower.c +2
-0@@ -60,6 +60,7 @@#include "prcm44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" +#include "cm44xx.h" #ifdef CONFIG_SMP @@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) {unsigned int save_state =0 ;unsigned int wakeup_cpu; +int ret;if (omap_rev () ==OMAP4430_REV_ES1_0 )return -ENXIO ;
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 272
Quoted 10 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +5
-2@@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); -if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && - (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) +if (omap4_device_next_state_off ()) { +/* Save the device context to SAR RAM */ + ret =omap_sar_save (); +if (ret) +return ret;
Is it safe to simply return here? I was not sure if we need to call pwrdm_post_transition, given that we have already called pwrdm_pre_transition on entry.
Cheers
Jon
PATCH 8/19 ARM: OMAP4: PM: Add device-off support
Quoted 51 lines · Jon Hunter
Hi Tero,
Quoted 48 lines · Tero Kristo
This patch adds device off support to OMAP4 device type.
OFF mode is disabled by default, however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry
echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 24 ++++++++++- arch/arm/mach-omap2/omap-wakeupgen.c | 47 +++++++++++++++++++- arch/arm/mach-omap2/pm-debug.c | 17 +++++-- arch/arm/mach-omap2/pm.h | 28 ++++++++++-- arch/arm/mach-omap2/pm44xx.c | 45 +++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 66 +++++++++++++++++++++++++++++ 6 files changed, 214 insertions(+), 13 deletions(-)arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-2@@ -60,6 +60,7 @@#include "prcm44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" +#include "cm44xx.h" #ifdef CONFIG_SMP @@ -232,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) {unsigned int save_state =0 ;unsigned int wakeup_cpu; +int ret;if (omap_rev () ==OMAP4430_REV_ES1_0 )return -ENXIO ;@@ -263,9 +265,21 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); -if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && - (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) +if (omap4_device_next_state_off ()) {
Quoted 8 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 272
Quoted 4 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +4
-0+/* Save the device context to SAR RAM */ + ret =omap_sar_save (); +if (ret) +return ret;Is it safe to simply return here? I was not sure if we need to call
pwrdm_post_transition, given that we have already calledpwrdm_pre_transitionon entry.
Hmm, thats a good point, I'll change the patch slightly. Anyway, currently the potential solo pwrdm_pre_transition() will not break anything, but in future it would, as we are planning to control AUTO_RET feature through the pwrdm_pre / pwrdm_post calls.
-Tero
PATCH 9/19 ARM: OMAP4: PM: add errata support
In reply to Tero KristoAdded similar PM errata flag support as omap3 has. A few errata flags will be added in subsequent patches.
--- arch/arm/mach-omap2/pm.h | 7 +++++++ arch/arm/mach-omap2/pm44xx.c | 1 + 2 files changed, 8 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm.h +7 -0
@@ -131,6 +131,13 @@ extern void enable_omap3630_toggle_l2_on_restore(void);static inline void enable_omap3630_toggle_l2_on_restore (void ) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 ) +extern u16 pm44xx_errata; +#define IS_PM44XX_ERRATUM (id) (pm44xx_errata & (id)) +#else +#define IS_PM44XX_ERRATUM (id) 0 +#endif +#ifdef CONFIG_OMAP_SMARTREFLEX extern int omap_devinit_smartreflex (void );extern void omap_enable_smartreflex_on_init (void );
arch/arm/mach-omap2/pm44xx.c +1 -0
@@ -35,6 +35,7 @@ struct power_state { };static LIST_HEAD (pwrst_list); +u16 pm44xx_errata;#ifdef CONFIG_SUSPEND static int omap4_pm_suspend (void )
Signature · 1 line
1.7.4.1
PATCH 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
In reply to Tero KristoFrom: Santosh Shilimkar <[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
The IVAHD Clocks and Power Domain settings are:
IVAHD_CM2 IVAHD_CLKCTRL_MODULE_MODE = DISABLE IVAHD_CM2 SL2_CLKCTRL_MODULE_MODE = DISABLE IVAHD_CM2 SL2_CLKSTCTRL_CLKTRCTRL = HW_AUTO IVAHD_PRM IVAHD_PWRSTCTRL_POWERSTATE = OFF
The TESLA Clocks and Power Domain settings are:
TESLA_CM1 TESLA_CLKCTRL_MODULE_MODE = DISABLE TESLA_CM1 TESLA_CLKSTCTRL_CLKTRCTRL = HW_AUTO TESLA_PRM TESLA_PWRSTCTRL_POWERSTATE = OFF
This patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 53 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.h | 2 + arch/arm/mach-omap2/pm44xx.c | 9 +++++ 3 files changed, 64 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +53 -0
@@ -52,6 +52,7 @@#include <plat/omap44xx.h> +#include "iomap.h" #include "common.h" #include "omap4-sar-layout.h" #include "pm.h"
@@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);static struct powerdomain *mpuss_pd;static void __iomem *sar_base; +struct reg_tuple { +void __iomem *addr; +u32 val; +}; + +static struct reg_tuple tesla_reg[] = { + {.addr =OMAP4430_CM_TESLA_CLKSTCTRL }, + {.addr =OMAP4430_CM_TESLA_TESLA_CLKCTRL }, + {.addr =OMAP4430_PM_TESLA_PWRSTCTRL }, +}; + +static struct reg_tuple ivahd_reg[] = { + {.addr =OMAP4430_CM_IVAHD_CLKSTCTRL }, + {.addr =OMAP4430_CM_IVAHD_IVAHD_CLKCTRL }, + {.addr =OMAP4430_CM_IVAHD_SL2_CLKCTRL }, + {.addr =OMAP4430_PM_IVAHD_PWRSTCTRL } +}; +/* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup.
@@ -215,6 +234,34 @@ static void save_l2x0_context(void) {}#endif +static inline void save_ivahd_tesla_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (tesla_reg); i++) + tesla_reg[i].val =__raw_readl (tesla_reg[i].addr); + +for (i =0 ; i <ARRAY_SIZE (ivahd_reg); i++) + ivahd_reg[i].val =__raw_readl (ivahd_reg[i].addr); +} + +static inline void restore_ivahd_tesla_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (tesla_reg); i++) +__raw_writel (tesla_reg[i].val, tesla_reg[i].addr); + +for (i =0 ; i <ARRAY_SIZE (ivahd_reg); i++) +__raw_writel (ivahd_reg[i].val, ivahd_reg[i].addr); +} +/** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming
@@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)omap_sar_overwrite ();omap4_cm_prepare_off ();omap4_dpll_prepare_off (); +save_ivahd_tesla_regs (); save_state =3 ; }else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) { +save_ivahd_tesla_regs (); save_state =2 ; }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) { +save_ivahd_tesla_regs (); save_state =3 ; }
@@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); +if (omap4_mpuss_read_prev_context_state ()) +restore_ivahd_tesla_regs (); +if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();omap4_cm_resume_off ();
arch/arm/mach-omap2/pm.h +2 -0
@@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);static inline void enable_omap3630_toggle_l2_on_restore (void ) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM (1 << 0) +#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 )extern u16 pm44xx_errata;#define IS_PM44XX_ERRATUM (id) (pm44xx_errata & (id))
arch/arm/mach-omap2/pm44xx.c +9 -0
@@ -263,6 +263,15 @@ static int __init omap4_pm_init(void) (void )clkdm_for_each (omap_pm_clkdms_setup,NULL ); +/* +* ROM code initializes IVAHD and TESLA clock registers during +* secure RAM restore phase on omap4430 EMU/HS devices, thus +* IVAHD / TESLA clock registers must be saved / restored +* during MPU OSWR / device off. +*/ +if (cpu_is_omap443x () &&omap_type () !=OMAP2_DEVICE_TYPE_GP ) + pm44xx_errata |=PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM ; +#ifdef CONFIG_SUSPEND omap_pm_suspend = omap4_pm_suspend;#endif
Signature · 1 line
1.7.4.1
PATCH 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
Hi Tero,
Quoted 18 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
The IVAHD Clocks and Power Domain settings are:
IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTOIVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF
The TESLA Clocks and Power Domain settings are:
TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLETESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTOTESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFF
Quoted 5 lines
This patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
You may wish to state which devices is impacted by this in the changelog.
Quoted 126 lines
Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: added omap4 pm errata support]Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 53 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.h | 2 + arch/arm/mach-omap2/pm44xx.c | 9 +++++ 3 files changed, 64 insertions(+), 0 deletions(-)arch/arm/mach-omap2/omap-mpuss-lowpower.c +53
-0@@ -52,6 +52,7 @@#include <plat/omap44xx.h> +#include "iomap.h" #include "common.h" #include "omap4-sar-layout.h" #include "pm.h" @@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);static struct powerdomain *mpuss_pd;static void __iomem *sar_base; +struct reg_tuple { +void __iomem *addr; +u32 val; +}; + +static struct reg_tuple tesla_reg[] = { + {.addr =OMAP4430_CM_TESLA_CLKSTCTRL }, + {.addr =OMAP4430_CM_TESLA_TESLA_CLKCTRL }, + {.addr =OMAP4430_PM_TESLA_PWRSTCTRL }, +}; + +static struct reg_tuple ivahd_reg[] = { + {.addr =OMAP4430_CM_IVAHD_CLKSTCTRL }, + {.addr =OMAP4430_CM_IVAHD_IVAHD_CLKCTRL }, + {.addr =OMAP4430_CM_IVAHD_SL2_CLKCTRL }, + {.addr =OMAP4430_PM_IVAHD_PWRSTCTRL } +}; +/* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup. @@ -215,6 +234,34 @@ static void save_l2x0_context(void) {}#endif +static inline void save_ivahd_tesla_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (tesla_reg); i++) + tesla_reg[i].val =__raw_readl (tesla_reg[i].addr); + +for (i =0 ; i <ARRAY_SIZE (ivahd_reg); i++) + ivahd_reg[i].val =__raw_readl (ivahd_reg[i].addr); +} + +static inline void restore_ivahd_tesla_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (tesla_reg); i++) +__raw_writel (tesla_reg[i].val, tesla_reg[i].addr); + +for (i =0 ; i <ARRAY_SIZE (ivahd_reg); i++) +__raw_writel (ivahd_reg[i].val, ivahd_reg[i].addr); +} +/** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming @@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)omap_sar_overwrite ();omap4_cm_prepare_off ();omap4_dpll_prepare_off (); +save_ivahd_tesla_regs (); save_state =3 ; }else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) { +save_ivahd_tesla_regs (); save_state =2 ; }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) { +save_ivahd_tesla_regs (); save_state =3 ; }@@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); +if (omap4_mpuss_read_prev_context_state ()) +restore_ivahd_tesla_regs (); +if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();omap4_cm_resume_off ();arch/arm/mach-omap2/pm.h +2
-0@@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);static inline void enable_omap3630_toggle_l2_on_restore (void ) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM (1 << 0) +#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 )extern u16 pm44xx_errata;#define IS_PM44XX_ERRATUM (id) (pm44xx_errata & (id))arch/arm/mach-omap2/pm44xx.c +0
-0@@ -263,6 +263,15 @@ static int __init omap4_pm_init(void)
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 273
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +8
-0(void )clkdm_for_each (omap_pm_clkdms_setup,NULL ); +/* +* ROM code initializes IVAHD and TESLA clock registers during +* secure RAM restore phase on omap4430 EMU/HS devices, thus +* IVAHD / TESLA clock registers must be saved / restored +* during MPU OSWR / device off. +*/ +if (cpu_is_omap443x () &&omap_type () !=OMAP2_DEVICE_TYPE_GP ) + pm44xx_errata |=PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM ;
This erratum does not impact omap4430 es2.3 so the above should account for that.
Cheers
Jon
PATCH 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
Quoted 21 lines · Jon Hunter
Hi Tero,
Quoted 18 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
The IVAHD Clocks and Power Domain settings are:
IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTOIVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF
The TESLA Clocks and Power Domain settings are:
TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLETESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTOTESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFF
Quoted 7 lines
Quoted 5 lines
This patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
You may wish to state which devices is impacted by this in the changelog.
Okay.
Quoted 129 lines
Quoted 129 lines
Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: added omap4 pm errata support]Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 53 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.h | 2 + arch/arm/mach-omap2/pm44xx.c | 9 +++++ 3 files changed, 64 insertions(+), 0 deletions(-)arch/arm/mach-omap2/omap-mpuss-lowpower.c +53
-0@@ -52,6 +52,7 @@#include <plat/omap44xx.h> +#include "iomap.h" #include "common.h" #include "omap4-sar-layout.h" #include "pm.h" @@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);static struct powerdomain *mpuss_pd;static void __iomem *sar_base; +struct reg_tuple { +void __iomem *addr; +u32 val; +}; + +static struct reg_tuple tesla_reg[] = { + {.addr =OMAP4430_CM_TESLA_CLKSTCTRL }, + {.addr =OMAP4430_CM_TESLA_TESLA_CLKCTRL }, + {.addr =OMAP4430_PM_TESLA_PWRSTCTRL }, +}; + +static struct reg_tuple ivahd_reg[] = { + {.addr =OMAP4430_CM_IVAHD_CLKSTCTRL }, + {.addr =OMAP4430_CM_IVAHD_IVAHD_CLKCTRL }, + {.addr =OMAP4430_CM_IVAHD_SL2_CLKCTRL }, + {.addr =OMAP4430_PM_IVAHD_PWRSTCTRL } +}; +/* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup. @@ -215,6 +234,34 @@ static void save_l2x0_context(void) {}#endif +static inline void save_ivahd_tesla_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (tesla_reg); i++) + tesla_reg[i].val =__raw_readl (tesla_reg[i].addr); + +for (i =0 ; i <ARRAY_SIZE (ivahd_reg); i++) + ivahd_reg[i].val =__raw_readl (ivahd_reg[i].addr); +} + +static inline void restore_ivahd_tesla_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (tesla_reg); i++) +__raw_writel (tesla_reg[i].val, tesla_reg[i].addr); + +for (i =0 ; i <ARRAY_SIZE (ivahd_reg); i++) +__raw_writel (ivahd_reg[i].val, ivahd_reg[i].addr); +} +/** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming @@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)omap_sar_overwrite ();omap4_cm_prepare_off ();omap4_dpll_prepare_off (); +save_ivahd_tesla_regs (); save_state =3 ; }else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) { +save_ivahd_tesla_regs (); save_state =2 ; }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) { +save_ivahd_tesla_regs (); save_state =3 ; }@@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); +if (omap4_mpuss_read_prev_context_state ()) +restore_ivahd_tesla_regs (); +if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();omap4_cm_resume_off ();arch/arm/mach-omap2/pm.h +2
-0@@ -131,6 +131,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);static inline void enable_omap3630_toggle_l2_on_restore (void ) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM (1 << 0) +#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 )extern u16 pm44xx_errata;#define IS_PM44XX_ERRATUM (id) (pm44xx_errata & (id))arch/arm/mach-omap2/pm44xx.c +0
-0@@ -263,6 +263,15 @@ static int __init omap4_pm_init(void) (void )clkdm_for_each (omap_pm_clkdms_setup,NULL );
Quoted 11 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 273
Quoted 8 lines
arch/arm/mach-omap2/pm44xx.c +8
-0+/* +* ROM code initializes IVAHD and TESLA clock registers during +* secure RAM restore phase on omap4430 EMU/HS devices, thus +* IVAHD / TESLA clock registers must be saved / restored +* during MPU OSWR / device off. +*/ +if (cpu_is_omap443x () &&omap_type () !=OMAP2_DEVICE_TYPE_GP ) + pm44xx_errata |=PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM ;This erratum does not impact omap4430 es2.3 so the above should account for that.
Okay, will change that.
-Tero
PATCH 11/19 ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
In reply to Tero KristoFrom: Rajendra Nayak <[email protected]>
On HS devices on the way out of MPU OSWR and OFF ROM code wrongly overwrites the CM L3INSTR registers. So to avoid this, save them and restore on the way out from MPU OSWR/OFF.
--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 35 ++++++++++++++++++++++++++++- arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm44xx.c | 8 ++++++ 3 files changed, 43 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +34 -1
@@ -95,6 +95,12 @@ static struct reg_tuple ivahd_reg[] = { {.addr = OMAP4430_PM_IVAHD_PWRSTCTRL} }; +static struct reg_tuple l3instr_reg[] = { + {.addr =OMAP4430_CM_L3INSTR_L3_3_CLKCTRL }, + {.addr =OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL }, + {.addr =OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL }, +}; +/* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup.
@@ -262,6 +268,28 @@ static inline void restore_ivahd_tesla_regs(void)__raw_writel (ivahd_reg[i].val, ivahd_reg[i].addr); } +static inline void save_l3instr_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_L3INSTR_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (l3instr_reg); i++) + l3instr_reg[i].val =__raw_readl (l3instr_reg[i].addr); +} + +static inline void restore_l3instr_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_L3INSTR_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (l3instr_reg); i++) +__raw_writel (l3instr_reg[i].val, l3instr_reg[i].addr); +} +/** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming
@@ -321,13 +349,16 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)omap4_cm_prepare_off ();omap4_dpll_prepare_off ();save_ivahd_tesla_regs (); +save_l3instr_regs (); save_state =3 ; }else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) {save_ivahd_tesla_regs (); +save_l3instr_regs (); save_state =2 ; }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) {save_ivahd_tesla_regs (); +save_l3instr_regs (); save_state =3 ; }
@@ -352,8 +383,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); -if (omap4_mpuss_read_prev_context_state ()) +if (omap4_mpuss_read_prev_context_state ()) {restore_ivahd_tesla_regs (); +restore_l3instr_regs (); + }if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();
arch/arm/mach-omap2/pm.h +1 -0
@@ -132,6 +132,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ #define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM (1 << 0) +#define PM_OMAP4_ROM_L3INSTR_ERRATUM (1 << 1)#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 )extern u16 pm44xx_errata;
arch/arm/mach-omap2/pm44xx.c +8 -0
@@ -272,6 +272,14 @@ static int __init omap4_pm_init(void)if (cpu_is_omap443x () &&omap_type () !=OMAP2_DEVICE_TYPE_GP ) pm44xx_errata |=PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM ; +/* +* Similar to above errata, ROM code modifies L3INSTR clock +* registers also and these must be saved / restored during +* MPU OSWR / device off. +*/ +if (omap_type () !=OMAP2_DEVICE_TYPE_GP ) + pm44xx_errata |=PM_OMAP4_ROM_L3INSTR_ERRATUM ; +#ifdef CONFIG_SUSPEND omap_pm_suspend = omap4_pm_suspend;#endif
Signature · 1 line
1.7.4.1
PATCH 11/19 ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
Hi Tero,
Quoted 5 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
On HS devices on the way out of MPU OSWR and OFF ROM code wrongly overwrites the CM L3INSTR registers. So to avoid this, save them and restore on the way out from MPU OSWR/OFF.
This appears to be an errata. So, it would be good to state explicitly here that all revisions of all omap4 devices are impacted by this errata. The code implies this but for documentation purposes it would be worth stating.
Cheers
Jon
PATCH 11/19 ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
Quoted 5 lines · Jon Hunter
Hi Tero,
Quoted 2 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
Quoted 8 lines
Quoted 3 lines
On HS devices on the way out of MPU OSWR and OFF ROM code wrongly overwrites the CM L3INSTR registers. So to avoid this, save them and restore on the way out from MPU OSWR/OFF.
This appears to be an errata. So, it would be good to state explicitly here that all revisions of all omap4 devices are impacted by this errata. The code implies this but for documentation purposes it would be worth stating.
Okay, I'll add some extra beef here.
-Tero
PATCH 12/19 ARM: OMAP4: PM: update ROM return address for OSWR and OFF
In reply to Tero KristoFrom: Carlos Leija <[email protected]>
At wakeup from OFF/OSWR CPU1 will call secure HAL service through a local secure dispatcher with MMU off, thus ROM will save a PA return address. Later in the wakeup, when SMC driver calls an RPC through omap4_secure_dispatcher (MMU is on now), ROM code won't log the new return address as RPCs are handled different. Thus ROM will attempt to return to a PA address when the MMU is on and the system will hang.
We need to do this for OSWR state and OFF state of mpu power domain, not just for device off(mpu pd OFF).
--- arch/arm/mach-omap2/include/mach/omap-secure.h | 1 + arch/arm/mach-omap2/omap-mpuss-lowpower.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/include/mach/omap-secure.h +1 -0
@@ -43,6 +43,7 @@#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113/* Secure PPA(Primary Protected Application) APIs */ +#define OMAP4_PPA_SERVICE_0 0x21#define OMAP4_PPA_L2_POR_INDEX 0x23#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
arch/arm/mach-omap2/omap-mpuss-lowpower.c +13 -0
@@ -52,6 +52,8 @@#include <plat/omap44xx.h> +#include <mach/omap-secure.h> +#include "iomap.h" #include "common.h" #include "omap4-sar-layout.h"
@@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON );if (omap4_mpuss_read_prev_context_state ()) { +/* +* Dummy dispatcher call after OSWR and OFF +* Restore the right return Kernel address (with MMU on) for +* subsequent calls to secure ROM. Otherwise the return address +* will be to a PA return address and the system will hang. +*/ +if (omap_type () !=OMAP2_DEVICE_TYPE_GP ) +omap_secure_dispatcher (OMAP4_PPA_SERVICE_0 , +FLAG_START_CRITICAL , +0 ,0 ,0 ,0 ,0 ); +restore_ivahd_tesla_regs ();restore_l3instr_regs (); }
Signature · 1 line
1.7.4.1
Tony Lindgren
maintainerPATCH 12/19 ARM: OMAP4: PM: update ROM return address for OSWR and OFF
Quoted 7 lines · Tero Kristo
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0@@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON );if (omap4_mpuss_read_prev_context_state ()) { +/* +* Dummy dispatcher call after OSWR and OFF +* Restore the right return Kernel address (with MMU on) for
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 401
Quoted 10 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +8
-0+* subsequent calls to secure ROM. Otherwise the return address +* will be to a PA return address and the system will hang. +*/ +if (omap_type () !=OMAP2_DEVICE_TYPE_GP ) +omap_secure_dispatcher (OMAP4_PPA_SERVICE_0 , +FLAG_START_CRITICAL , +0 ,0 ,0 ,0 ,0 ); +restore_ivahd_tesla_regs ();restore_l3instr_regs ();
This SoC test here too should be only done once during init.
Tony
PATCH 12/19 ARM: OMAP4: PM: update ROM return address for OSWR and OFF
Quoted 4 lines · Tony Lindgren
Quoted 3 lines · Tero Kristo
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0@@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON );
Quoted 16 lines
Quoted 4 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0if (omap4_mpuss_read_prev_context_state ()) { +/* +* Dummy dispatcher call after OSWR and OFF +* Restore the right return Kernel address (with MMU on) for arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 401
Quoted 10 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +8
-0+* subsequent calls to secure ROM. Otherwise the return address +* will be to a PA return address and the system will hang. +*/ +if (omap_type () !=OMAP2_DEVICE_TYPE_GP ) +omap_secure_dispatcher (OMAP4_PPA_SERVICE_0 , +FLAG_START_CRITICAL , +0 ,0 ,0 ,0 ,0 ); +restore_ivahd_tesla_regs ();restore_l3instr_regs ();This SoC test here too should be only done once during init.
You sure about this one? I will end up creating a variable omap_is_gp or such, which looks somewhat silly and is going to be a duplicate (it will not provide any extra value in addition to the existing omap_type() check.) Also, similar checks are used elsewhere in the kernel, look at omap-wakeupgen.c, pm34xx.c, pm44xx.c, control.c for example. Should all of these be replaced? Well, most of these are related to secure context saving so maybe the mechanism behind these should be changed somehow globally.
-Tero
PATCH 13/19 ARM: OMAP4: PM: Mark the PPI and SPI interrupts as non-secure for GP
In reply to Tero KristoFrom: Axel Haslam <[email protected]>
ROM code restores part of the GIC context during wakeup from device off mode from the SAR RAM. If the PPI and SPI interrupts are not marked as non-secure on GP chips, this crashes the device during wakeup, thus mark them as non-secure.
--- arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/omap-wakeupgen.c | 21 +++++++++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 5 +++++ arch/arm/mach-omap2/omap4-sar-layout.h | 3 +++ 4 files changed, 30 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/common.h +1 -0
@@ -200,6 +200,7 @@ static inline void __iomem *omap4_get_scu_base(void)extern void __init gic_init_irq (void );extern void gic_dist_disable (void ); +extern u32 gic_readl (u32 offset,u8 idx);extern void omap_smc1 (u32 fn,u32 arg);extern void __iomem *omap4_get_sar_ram_base (void );extern void omap_do_wfi (void );
arch/arm/mach-omap2/omap-wakeupgen.c +21 -0
@@ -41,6 +41,7 @@#define CPU_ENA_OFFSET 0x400#define CPU0_ID 0x0#define CPU1_ID 0x1 +#define GIC_ISR_NON_SECURE 0xffffffffstatic void __iomem *wakeupgen_base;static void __iomem *sar_base;
@@ -387,6 +388,7 @@ int __init omap_wakeupgen_init(void) {int i;unsigned int boot_cpu =smp_processor_id (); +int max_spi_reg;/* Not supported on OMAP4 ES1.0 silicon */ if (omap_rev () ==OMAP4430_REV_ES1_0 ) {
@@ -422,6 +424,25 @@ int __init omap_wakeupgen_init(void)for (i =0 ; i <NR_IRQS ; i++) irq_target_cpu[i] = boot_cpu; +/* +* Find out how many interrupts are supported. +* OMAP4 supports max of 128 SPIs where as GIC can support +* up to 1020 interrupt sources. On OMAP4, maximum SPIs are +* fused in DIST_CTR bit-fields as 128. Hence the code is safe +* from reserved register writes since its well within 1020. +*/ + max_spi_reg =gic_readl (GIC_DIST_CTR ,0 ) &0x1f ; + +if (omap_type () ==OMAP2_DEVICE_TYPE_GP ) { + sar_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU0_OFFSET ,0 ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU1_OFFSET ,0 ); +for (i =0 ; i < max_spi_reg; i++) +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i); +iounmap (sar_base); + sar_base =NULL ; + } +irq_hotplug_init ();irq_pm_init ();
arch/arm/mach-omap2/omap4-common.c +5 -0
@@ -112,6 +112,11 @@ void gic_dist_disable(void)__raw_writel (0x0 , gic_dist_base_addr +GIC_DIST_CTRL ); } +u32 gic_readl (u32 offset,u8 idx) +{ +return __raw_readl (gic_dist_base_addr + offset +4 * idx); +} +#ifdef CONFIG_CACHE_L2X0 void __iomem *omap4_get_l2cache_base (void )
arch/arm/mach-omap2/omap4-sar-layout.h +3 -0
@@ -85,6 +85,9 @@#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508) +#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c) +#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510) +#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514)/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
Signature · 1 line
1.7.4.1
PATCH 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
In reply to Tero Kristosave_secure_all needs l3_main_3_ick and l4_secure_clkdm enabled, otherwise the secure ROM code will crash.
--- arch/arm/mach-omap2/omap-wakeupgen.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-wakeupgen.c +20 -0
@@ -29,10 +29,12 @@#include <mach/omap-wakeupgen.h> #include <mach/omap-secure.h> +#include <plat/omap_hwmod.h> #include "omap4-sar-layout.h" #include "common.h" #include "pm.h" +#include "clockdomain.h" #define NR_REG_BANKS 4#define MAX_IRQS 128
@@ -49,6 +51,8 @@ static DEFINE_SPINLOCK(wakeupgen_lock);static unsigned int irq_target_cpu[NR_IRQS ];static struct powerdomain *mpuss_pd; +static struct clockdomain *l4_secure_clkdm; +static struct omap_hwmod *l3_main_3_oh;/* * Static helper functions.
@@ -300,10 +304,18 @@ static void save_secure_ram(void)static void save_secure_all (void ) {u32 ret; + +omap_hwmod_enable (l3_main_3_oh); +clkdm_wakeup (l4_secure_clkdm); + ret =omap_secure_dispatcher (OMAP4_HAL_SAVEALL_INDEX ,FLAG_START_CRITICAL ,1 ,omap_secure_ram_mempool_base (),0 ,0 ,0 ); + +clkdm_allow_idle (l4_secure_clkdm); +omap_hwmod_idle (l3_main_3_oh); +if (ret !=API_HAL_RET_VALUE_OK )pr_err ("Secure all context save failed\n" ); }
@@ -441,6 +453,14 @@ int __init omap_wakeupgen_init(void)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i);iounmap (sar_base); sar_base =NULL ; + }else { + l3_main_3_oh =omap_hwmod_lookup ("l3_main_3" ); +if (!l3_main_3_oh) +pr_err ("%s: failed to get l3_main_3_oh\n" , __func__); + + l4_secure_clkdm =clkdm_lookup ("l4_secure_clkdm" ); +if (!l4_secure_clkdm) +pr_err ("%s: failed to get l4_secure_clkdm\n" , __func__); }irq_hotplug_init ();
Signature · 1 line
1.7.4.1
PATCH 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
In reply to Tero KristoFrom: Santosh Shilimkar <[email protected]>
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when EMIF_SDRAM_CONFIG is restored first before EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.
--- .../include/mach/ctrl_module_wkup_44xx.h | 2 + arch/arm/mach-omap2/pm44xx.c | 24 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2 -0
@@ -28,6 +28,8 @@#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG 0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG 0x011c#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468
arch/arm/mach-omap2/pm44xx.c +24 -0
@@ -17,6 +17,9 @@#include <linux/err.h> #include <linux/slab.h> #include <asm/system_misc.h> +#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> #include "common.h" #include "clockdomain.h"
@@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)pr_err ("Power Management for TI OMAP4.\n" ); +/* +* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF +* Mode Transition When CS1 Is Used On EMIF": +* Overwrite EMIF1/EMIF2 +* SECURE_EMIF1_SDRAM_CONFIG2_REG +* SECURE_EMIF2_SDRAM_CONFIG2_REG +*/ +if (cpu_is_omap443x ()) { +void __iomem *secure_ctrl_mod; + + secure_ctrl_mod =ioremap (OMAP4_CTRL_MODULE_WKUP ,SZ_4K ); +BUG_ON (!secure_ctrl_mod); + +__raw_writel (0x10 , secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ); +__raw_writel (0x10 , secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ); +wmb (); +iounmap (secure_ctrl_mod); + } + ret =pwrdm_for_each (pwrdms_setup,NULL );if (ret) {pr_err ("Failed to setup powerdomains\n" );
Signature · 1 line
1.7.4.1
PATCH 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
Hi Tero,
Quoted 55 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>--- .../include/mach/ctrl_module_wkup_44xx.h | 2 + arch/arm/mach-omap2/pm44xx.c | 24 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0@@ -28,6 +28,8 @@#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG 0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG 0x011c#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468arch/arm/mach-omap2/pm44xx.c +10
-0@@ -17,6 +17,9 @@#include <linux/err.h> #include <linux/slab.h> #include <asm/system_misc.h> +#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> #include "common.h" #include "clockdomain.h" @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)pr_err ("Power Management for TI OMAP4.\n" ); +/* +* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF +* Mode Transition When CS1 Is Used On EMIF": +* Overwrite EMIF1/EMIF2 +* SECURE_EMIF1_SDRAM_CONFIG2_REG +* SECURE_EMIF2_SDRAM_CONFIG2_REG +*/
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 237
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+if (cpu_is_omap443x ()) { +void __iomem *secure_ctrl_mod; + + secure_ctrl_mod =ioremap (OMAP4_CTRL_MODULE_WKUP ,SZ_4K ); +BUG_ON (!secure_ctrl_mod); + +__raw_writel (0x10 , secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ); +__raw_writel (0x10 , secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG );
According to the erratum description the above registers are used to restore the EMIFx_SDRAM_CONFIG2 registers. So although the value 0x10, maybe the value being used for EMIFx_SDRAM_CONFIG2 registers, shouldn't we read the EMIFx_SDRAM_CONFIG2 registers and store them in the above registers?
Cheers
Jon
PATCH 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
Quoted 66 lines · Jon Hunter
Hi Tero,
Quoted 63 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>--- .../include/mach/ctrl_module_wkup_44xx.h | 2 + arch/arm/mach-omap2/pm44xx.c | 24 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0@@ -28,6 +28,8 @@#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG 0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG 0x011c#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468arch/arm/mach-omap2/pm44xx.c +18
-0@@ -17,6 +17,9 @@#include <linux/err.h> #include <linux/slab.h> #include <asm/system_misc.h> +#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> #include "common.h" #include "clockdomain.h" @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)pr_err ("Power Management for TI OMAP4.\n" ); +/* +* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF +* Mode Transition When CS1 Is Used On EMIF": +* Overwrite EMIF1/EMIF2 +* SECURE_EMIF1_SDRAM_CONFIG2_REG +* SECURE_EMIF2_SDRAM_CONFIG2_REG +*/ +if (cpu_is_omap443x ()) { +void __iomem *secure_ctrl_mod; + + secure_ctrl_mod =ioremap (OMAP4_CTRL_MODULE_WKUP ,SZ_4K ); +BUG_ON (!secure_ctrl_mod); + +__raw_writel (0x10 , secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG );
Quoted 8 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 237
Quoted 2 lines
arch/arm/mach-omap2/pm44xx.c +2
-0+__raw_writel (0x10 , secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG );According to the erratum description the above registers are used to restore the
EMIFx_SDRAM_CONFIG2registers. So although the value0x10, maybe the value being used forEMIFx_SDRAM_CONFIG2registers, shouldn't we read theEMIFx_SDRAM_CONFIG2registers and store them in the above registers?
This might be a good idea, however, this patch might be tagged as TEMP until the EMIF driver is in place, this fix should rather be located there. I'll take a look at this if I can change the implementation a bit.
-Tero
PATCH 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
Quoted 76 lines · Tero Kristo
Quoted 66 lines · Jon Hunter
Hi Tero,
Quoted 63 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>---
?.../include/mach/ctrl_module_wkup_44xx.h ? ? ? ? ? | ? ?2 + ?arch/arm/mach-omap2/pm44xx.c ? ? ? ? ? ? ? ? ? ? ? | ? 24 ++++++++++++++++++++ ?2 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +0
-0@@ -28,6 +28,8 @@?#define
OMAP4_CTRL_MODULE_WKUP_IP_REVISION? ? ? ?0x0000?#defineOMAP4_CTRL_MODULE_WKUP_IP_HWINFO? ? ? ? ?0x0004?#defineOMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG? ? ? ? ? ? ? ?0x0010arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0+#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ?0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ?0x011c?#define
OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0? ? ? ?0x0460 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1? ? ? ?0x0464 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2? ? ? ?0x0468arch/arm/mach-omap2/pm44xx.c +0
-0@@ -17,6 +17,9 @@?#include <
linux/err.h>
?#include <linux/slab.h>
?#include <asm/system_misc.h>arch/arm/mach-omap2/pm44xx.c +3
-0+#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> ?#include "
common.h"
?#include "clockdomain.h"arch/arm/mach-omap2/pm44xx.c +15
-0@@ -215,6 +218,27 @@ static int __init omap4_pm_init(void) ? ? pr_err("Power Management for TI OMAP4.\n"); + ? /* + ? ?* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF + ? ?* Mode Transition When CS1 Is Used On EMIF": + ? ?* Overwrite EMIF1/EMIF2 + ? ?* SECURE_EMIF1_SDRAM_CONFIG2_REG + ? ?* SECURE_EMIF2_SDRAM_CONFIG2_REG + ? ?*/ + ? if (cpu_is_omap443x()) { + ? ? ? ? ? void __iomem *secure_ctrl_mod; + + ? ? ? ? ? secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K); + ? ? ? ? ? BUG_ON(!secure_ctrl_mod); + + ? ? ? ? ? __raw_writel(0x10, secure_ctrl_mod + + ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG);Quoted 8 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 237
Quoted 2 lines
arch/arm/mach-omap2/pm44xx.c +2
-0+ ? ? ? ? ? __raw_writel(0x10, secure_ctrl_mod + + ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);According to the erratum description the above registers are used to restore the
EMIFx_SDRAM_CONFIG2registers. So although the value0x10, maybe the value being used forEMIFx_SDRAM_CONFIG2registers, shouldn't we read theEMIFx_SDRAM_CONFIG2registers and store them in the above registers?
Quoted 5 lines
This might be a good idea, however, this patch might be tagged as TEMP until the EMIF driver is in place, this fix should rather be located there. I'll take a look at this if I can change the implementation a bit.
This patch doesn't have any dependency with EMIF driver since it's more of SAR restore BUG. If the dependency is from the regsister macro etc point of view, PM code can to the mapping and since it is needed only once in the init. EMIF driver is unware of SAR restore phase and that was the purpose of the DMA bases SAR restore design.
Hope this clarifies.
Regards
Santosh
PATCH 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
In reply to Tero KristoHi Tero,
Quoted 76 lines · Tero Kristo
Quoted 66 lines · Jon Hunter
Hi Tero,
Quoted 63 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>--- .../include/mach/ctrl_module_wkup_44xx.h | 2 + arch/arm/mach-omap2/pm44xx.c | 24 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0@@ -28,6 +28,8 @@#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG 0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG 0x011c#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468arch/arm/mach-omap2/pm44xx.c +18
-0@@ -17,6 +17,9 @@#include <linux/err.h> #include <linux/slab.h> #include <asm/system_misc.h> +#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> #include "common.h" #include "clockdomain.h" @@ -215,6 +218,27 @@ static int __init omap4_pm_init(void)pr_err ("Power Management for TI OMAP4.\n" ); +/* +* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF +* Mode Transition When CS1 Is Used On EMIF": +* Overwrite EMIF1/EMIF2 +* SECURE_EMIF1_SDRAM_CONFIG2_REG +* SECURE_EMIF2_SDRAM_CONFIG2_REG +*/ +if (cpu_is_omap443x ()) { +void __iomem *secure_ctrl_mod; + + secure_ctrl_mod =ioremap (OMAP4_CTRL_MODULE_WKUP ,SZ_4K ); +BUG_ON (!secure_ctrl_mod); + +__raw_writel (0x10 , secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG );Quoted 8 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 237
Quoted 2 lines
arch/arm/mach-omap2/pm44xx.c +2
-0+__raw_writel (0x10 , secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG );According to the erratum description the above registers are used to restore the
EMIFx_SDRAM_CONFIG2registers. So although the value0x10, maybe the value being used forEMIFx_SDRAM_CONFIG2registers, shouldn't we read theEMIFx_SDRAM_CONFIG2registers and store them in the above registers?
Quoted 4 lines
This might be a good idea, however, this patch might be tagged as TEMP until the EMIF driver is in place, this fix should rather be located there. I'll take a look at this if I can change the implementation a bit.
By the way, I did dump the EMIF1_SDRAM_CONFIG2 register on a omap4403 and it is configured to 0x10. So I think that reading this register and saving would be safe.
Cheers
Jon
PATCH 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
Quoted 79 lines · Jon Hunter
Hi Tero,
Quoted 76 lines · Tero Kristo
Quoted 74 lines · Jon Hunter
Hi Tero,
Quoted 55 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>---
?.../include/mach/ctrl_module_wkup_44xx.h ? ? ? ? ? | ? ?2 + ?arch/arm/mach-omap2/pm44xx.c ? ? ? ? ? ? ? ? ? ? ? | ? 24 ++++++++++++++++++++ ?2 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +0
-0@@ -28,6 +28,8 @@?#define
OMAP4_CTRL_MODULE_WKUP_IP_REVISION? ? ? ?0x0000?#defineOMAP4_CTRL_MODULE_WKUP_IP_HWINFO? ? ? ? ?0x0004?#defineOMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG? ? ? ? ? ? ? ?0x0010arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0+#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ?0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ?0x011c?#define
OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0? ? ? ?0x0460 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1? ? ? ?0x0464 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2? ? ? ?0x0468arch/arm/mach-omap2/pm44xx.c +0
-0@@ -17,6 +17,9 @@?#include <
linux/err.h>
?#include <linux/slab.h>
?#include <asm/system_misc.h>arch/arm/mach-omap2/pm44xx.c +3
-0+#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> ?#include "
common.h"
?#include "clockdomain.h"arch/arm/mach-omap2/pm44xx.c +7
-0@@ -215,6 +218,27 @@ static int __init omap4_pm_init(void) ? ? pr_err("Power Management for TI OMAP4.\n"); + ? /* +? ?* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF +? ?* Mode Transition When CS1 Is Used On EMIF": +? ?* Overwrite EMIF1/EMIF2 +? ?* SECURE_EMIF1_SDRAM_CONFIG2_REG +? ?* SECURE_EMIF2_SDRAM_CONFIG2_REG +? ?*/ arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 237
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+ ? if (cpu_is_omap443x()) { + ? ? ? ? ? void __iomem *secure_ctrl_mod; + + ? ? ? ? ? secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K); + ? ? ? ? ? BUG_ON(!secure_ctrl_mod); + + ? ? ? ? ? __raw_writel(0x10, secure_ctrl_mod + + ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG); + ? ? ? ? ? __raw_writel(0x10, secure_ctrl_mod + + ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG);According to the erratum description the above registers are used to restore the
EMIFx_SDRAM_CONFIG2registers. So although the value0x10, maybe the value being used forEMIFx_SDRAM_CONFIG2registers, shouldn't we read theEMIFx_SDRAM_CONFIG2registers and store them in the above registers?
Quoted 9 lines
Quoted 4 lines
This might be a good idea, however, this patch might be tagged as TEMP until the EMIF driver is in place, this fix should rather be located there. I'll take a look at this if I can change the implementation a bit.
By the way, I did dump the
EMIF1_SDRAM_CONFIG2register on a omap4403 and it is configured to0x10. So I think that reading this register and saving would be safe.
That's right. The reason it is harcoded is, it will be 0x10 or 0x0. Writing 0x10 even of we use 1 chip select doesn't create any issue as such.
But go ahead and read the register and store it. That way it will appear bit cleaner.
Regards
Santosh
PATCH 16/19 TEMP: ARM: OMAP4: prevent voltage transitions
In reply to Tero KristoDuring device off, the off-mode voltage transitions are enabled on reset. Because the voltage control logic is not still completely functional for OMAP4, we must disable the voltage transitions for device off for now. This can only be done by disabling the I2C channel it seems.
This patch does not prevent voltage scaling done by voltdm->scale / DVFS.
--- arch/arm/mach-omap2/pm44xx.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm44xx.c +22 -0
@@ -25,6 +25,9 @@#include "clockdomain.h" #include "powerdomain.h" #include "pm.h" +#include "voltage.h" +#include "prm44xx.h" +#include "prm-regbits-44xx.h" struct power_state {struct powerdomain *pwrdm;
@@ -207,6 +210,7 @@ static int __init omap4_pm_init(void)int ret;struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm; +struct voltagedomain *mpu_voltdm;if (!cpu_is_omap44xx ())return -ENODEV ;
@@ -279,6 +283,24 @@ static int __init omap4_pm_init(void) goto err2; } +/* +* XXX: voltage config is not still completely valid for +* OMAP4, and this causes crashes on some platform during +* device off because voltage transitions for device off +* are enabled on reset. Thus, we have to disable the I2C +* channel completely in the VOLTCTRL register to avoid +* trouble. Remove this once voltconfigs are valid. +*/ + mpu_voltdm =voltdm_lookup ("mpu" ); +if (!mpu_voltdm) { +pr_err ("Failed to get MPU voltdm\n" ); + goto err2; + } + mpu_voltdm->write (OMAP4430_VDD_MPU_I2C_DISABLE_MASK | +OMAP4430_VDD_CORE_I2C_DISABLE_MASK | +OMAP4430_VDD_IVA_I2C_DISABLE_MASK , +OMAP4_PRM_VOLTCTRL_OFFSET ); + ret =omap4_mpuss_init ();if (ret) {pr_err ("Failed to initialise OMAP4 MPUSS\n" );
Signature · 1 line
1.7.4.1
PATCH 17/19 ARM: OMAP4: put cpu1 back to sleep if no wake request
In reply to Tero KristoIf AUX_CORE_BOOT0 does not indicate wakeup request for cpu1, put it back to off. This is needed during wakeup from device off to prevent cpu1 from being stuck indefinitely in the wakeup loop and also to prevent wakeup problem on GP chips with device off mode.
--- arch/arm/mach-omap2/omap-headsmp.S | 45 ++++++++++++++++++++++++++++++++--- 1 files changed, 41 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/omap-headsmp.S +41 -4
@@ -17,8 +17,37 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <mach/omap-secure.h> +#include "prcm_mpu44xx.h" + +#define CPU1_PWRSTCTRL (OMAP4430_PRCM_MPU_BASE + OMAP4430_PRCM_MPU_CPU1_INST + \ + OMAP4_PM_CPU1_PWRSTCTRL_OFFSET) __CPUINIT + +ENTRY(omap_cpu1_off) + ldr r12, =CPU1_PWRSTCTRL + ldr r0, [r12] + and r0, #3 + cmp r0, #2 + beq exit_cpu1_off + + mov r0, #0x3 + mov r1, #0x0 + ldr r12, =OMAP4_MON_SCU_PWR_INDEX + dsb + smc #0 + + isb + dsb + dmb + wfi + nop + nop +exit_cpu1_off: + mov pc, lr +ENDPROC(omap_cpu1_off) + /* * OMAP4 specific entry point for secondary CPU to jump from ROM * code. This routine also provides a holding flag into which
@@ -27,32 +56,40 @@ * register AuxCoreBoot0. */ ENTRY(omap_secondary_startup) -hold: ldr r12,=0x103 + 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 + beq omap_cont_boot + + bl omap_cpu1_off + b omap_secondary_startup /* * we've been released from the wait loop,secondary_stack * should now contain the SVC stack for this core */ +omap_cont_boot: b secondary_startup ENDPROC(omap_secondary_startup) ENTRY(omap_secondary_startup_4460) -hold_2: ldr r12,=0x103 + 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 + beq omap4460_cont_boot + + bl omap_cpu1_off + b omap_secondary_startup_4460 +omap4460_cont_boot: /* * GIC distributor control register has changed between * CortexA9 r1pX and r2pX. The Control Register secure
Signature · 1 line
1.7.4.1
PATCH 18/19 ARM: OMAP4460: wakeupgen: set GIC_CPU0 backup status flag always
In reply to Tero KristoWithout this, CPU0 will crash in the ROM code during wakeup from device off. This patch also clears the GIC save area, to prevent ROM code from writing garbage to the GIC registers during wakeup. The actual GIC restore is done by kernel.
This bug fix applies only to OMAP4460, it is fixed on OMAP4470.
--- arch/arm/mach-omap2/omap-wakeupgen.c | 14 ++++++++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 1 + 2 files changed, 15 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-wakeupgen.c +14 -0
@@ -447,10 +447,24 @@ int __init omap_wakeupgen_init(void)if (omap_type () ==OMAP2_DEVICE_TYPE_GP ) { sar_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); +/* Clean GIC SAR area */ +for (i =SAR_BACKUP_STATUS_OFFSET ; i <WAKEUPGENENB_OFFSET_CPU0 ; + i +=4 ) +sar_writel (0 , i,0 ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU0_OFFSET ,0 );sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU1_OFFSET ,0 );for (i =0 ; i < max_spi_reg; i++)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i); + +/* +* Set CPU0 GIC backup flag permanently for omap4460, +* this is needed because of the ROM code bug that breaks +* GIC during wakeup from device off +*/ +if (cpu_is_omap446x ()) +__raw_writel (SAR_BACKUP_STATUS_GIC_CPU0 , + sar_base +SAR_BACKUP_STATUS_OFFSET );iounmap (sar_base); sar_base =NULL ; }else {
arch/arm/mach-omap2/omap4-sar-layout.h +1 -0
@@ -88,6 +88,7 @@#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c)#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510)#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514) +#define SAR_BACKUP_STATUS_GIC_CPU0 0x1/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
Signature · 1 line
1.7.4.1
PATCH 19/19 ARM: OMAP4: powerdomain: update mpu / core off counters during device off
In reply to Tero KristoCurrently device off does not have any counters / timers of its own and it is impossible to track the time spent in this state. In device off, MPU / CORE powerdomains enter OSWR, so normally the RETENTION state times / counts are increased during device off.
This patch adds a new field to the powerdomain struct for context loss register, which is checked during pwrdm_post_transition to see if a device off type context loss has happened. If this is the case, the counters + timers for OFF state are touched instead of RETENTION.
--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 1 - arch/arm/mach-omap2/powerdomain.c | 9 +++++++++ arch/arm/mach-omap2/powerdomain.h | 2 ++ arch/arm/mach-omap2/powerdomains44xx_data.c | 2 ++ arch/arm/mach-omap2/prm44xx.c | 15 +++++++++++++++ arch/arm/mach-omap2/prm44xx.h | 2 ++ 6 files changed, 30 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0 -1
@@ -404,7 +404,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();omap4_cm_resume_off (); -omap4_device_clear_prev_off_state (); }pwrdm_post_transition ();
arch/arm/mach-omap2/powerdomain.c +9 -0
@@ -160,6 +160,15 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)break ;case PWRDM_STATE_PREV : prev =pwrdm_read_prev_pwrst (pwrdm); + +/* +* If powerdomain has context offset defined, check if +* the domain has lost context (i.e. entered off) +*/ +if (pwrdm->context_offs) +if (omap4_pwrdm_lost_context_rff (pwrdm->prcm_offs, + pwrdm->context_offs)) + prev =PWRDM_POWER_OFF ;if (pwrdm->state != prev) pwrdm->state_counter[prev]++;if (prev ==PWRDM_POWER_RET )
arch/arm/mach-omap2/powerdomain.h +2 -0
@@ -82,6 +82,7 @@ struct powerdomain;* @name: Powerdomain name * @voltdm: voltagedomain containing this powerdomain * @prcm_offs: the address offset from CM_BASE/PRM_BASE +* @context_offs: the address offset for the CONTEXT register * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs * @pwrsts: Possible powerdomain power states * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
@@ -106,6 +107,7 @@ struct powerdomain {struct voltagedomain *ptr; } voltdm;const s16 prcm_offs; +const s16 context_offs;const u8 pwrsts;const u8 pwrsts_logic_ret;const u8 flags;
arch/arm/mach-omap2/powerdomains44xx_data.c +2 -0
@@ -36,6 +36,7 @@ static struct powerdomain core_44xx_pwrdm = { .voltdm = { .name = "core" }, .prcm_offs = OMAP4430_PRM_CORE_INST, .prcm_partition = OMAP4430_PRM_PARTITION, + .context_offs = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET, .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 5,
@@ -205,6 +206,7 @@ static struct powerdomain mpu_44xx_pwrdm = { .voltdm = { .name = "mpu" }, .prcm_offs = OMAP4430_PRM_MPU_INST, .prcm_partition = OMAP4430_PRM_PARTITION, + .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET, .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 3,
arch/arm/mach-omap2/prm44xx.c +15 -0
@@ -274,6 +274,21 @@ static void __init omap4_enable_io_wakeup(void) OMAP4_PRM_IO_PMCTRL_OFFSET); } +bool omap4_pwrdm_lost_context_rff (s16 inst,s16 offset) +{ +u32 val; + + val =omap4_prminst_read_inst_reg (OMAP4430_PRM_PARTITION , inst, offset); + +if (val &OMAP4430_LOSTCONTEXT_RFF_MASK ) { +omap4_prminst_write_inst_reg (val,OMAP4430_PRM_PARTITION , inst, + offset); +return true; + } + +return false; +} +/** * omap4_device_set_state_off() - setup device off state * @enable: set to off or not.
arch/arm/mach-omap2/prm44xx.h +2 -0
@@ -770,6 +770,8 @@ extern void omap44xx_prm_ocp_barrier(void);extern void omap44xx_prm_save_and_clear_irqen (u32 *saved_mask);extern void omap44xx_prm_restore_irqen (u32 *saved_mask); +extern bool omap4_pwrdm_lost_context_rff (s16 inst,s16 offset); +# endif #endif
Signature · 1 line
1.7.4.1
cover ARM: OMAP4 device off support
In reply to Tero KristoQuoted 9 lines · Tero Kristo
Hi,
First version for this work. Applies on top of mainline + iochain set + OMAP4 core retention set. Working tree available here:
tree:git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-offTested on omap4430 EMU blaze + omap4460 GP panda boards.
Quoted 8 lines
Some drivers have issues with device off, most notably MMC, as it breaks device off on blaze device after 1 entry to device off mode:
[ ?208.906921]
omap_i2comap_i2c.1: XRDY IRQ while no data to send [ ?209.905639]omap_i2comap_i2c.1: controller timed out
[ ?209.905792] twl:i2c_readfailed to transfer all messages
[ ?209.905792]omap_hsmmcomap_hsmmc.1: could not set regulator OCR (-110) [ ?212.296203] mmc0: error -110 during resume (card was removed?)
Hi Tero,
I tried your branch on gp/emu devices but could not reproduce this issue. My observation is that while resuming, omap_hsmmc.1 eMMC is trying to turn on phoenix vaux1 regulator via i2c which fails due to controller timeout.
Note: eMMC is present only on sdp/blaze
Quoted 15 lines
[ ?212.562164] PM: resume of devices complete after 3656.007 msecs [ ?212.660125] Restarting tasks ... done.
## echo mem > /sys/power/state [ ?220.376892] PM: Syncing filesystems ... done. [ ?220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done. [ ?220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don e. [ ?220.439605] Suspending console(s) (use no_console_suspend to debug) [ ?220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110 [ ?220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110 [ ?220.454711] PM: Some devices failed to suspend [ ?220.718261] PM: resume of devices complete after 263.539 msecs [ ?220.743988] Restarting tasks ... done.
Quoted 5 lines
Attempting to disable MMC from config prevented boot completely for me, so this issue is likely to stay until someone fixes the MMC driver. Panda device works fine though, although the wakeup from device off is slow due to problems with some other drivers (most likely I2C.)
can you try this patch if you want to disable MMC
http://permalink.gmane.org/gmane.linux.ports.arm.omap/74540
or
http://www.spinics.net/lists/linux-omap/msg67879.html
and build omap_hsmmc as module.
Quoted 17 lines
Off mode is disabled by default, it can be enabled by either calling
omap4_pm_enable_off_mode(1)from board files or alternatively writing to a debugfs node from userspace:echo 1 > /debug/pm_debug/enable_off_mode
Device off entry can be tracked through the debugfs also, it increases the
core_pwrdmOFF state counter / timer, as this is an invalid state for the chip normally (core enters OSWR in device off.) Not sure if this a good way to do this but comments are welcome.-Tero
--
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
cover ARM: OMAP4 device off support
Quoted 18 lines · Balaji
Quoted 9 lines · Tero Kristo
Hi,
First version for this work. Applies on top of mainline + iochain set + OMAP4 core retention set. Working tree available here:
tree:git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-offTested on omap4430 EMU blaze + omap4460 GP panda boards.
Quoted 8 lines
Some drivers have issues with device off, most notably MMC, as it breaks device off on blaze device after 1 entry to device off mode:
[ 208.906921] omap_i2c omap_i2c.1: XRDY IRQ while no data to send [ 209.905639] omap_i2c omap_i2c.1: controller timed out [ 209.905792] twl: i2c_read failed to transfer all messages [ 209.905792] omap_hsmmc omap_hsmmc.1: could not set regulator OCR (-110) [ 212.296203] mmc0: error -110 during resume (card was removed?)
Quoted 7 lines
Hi Tero,
I tried your branch on gp/emu devices but could not reproduce this issue. My observation is that while resuming, omap_hsmmc.1 eMMC is trying to turn on phoenix vaux1 regulator via i2c which fails due to controller timeout.
Note: eMMC is present only on sdp/blaze
Did you try this with off-mode enabled and did you check the device actually goes to off? (see pm_debug/count and verify core off count is increasing.) And as said, I was only able to see this problem on a blaze device, panda works fine. But yes, you are probably right and it is not an MMC driver issue but I2C.
Quoted 16 lines
Quoted 16 lines
[ 212.562164] PM: resume of devices complete after 3656.007 msecs [ 212.660125] Restarting tasks ... done. # # echo mem > /sys/power/state [ 220.376892] PM: Syncing filesystems ... done. [ 220.382476] Freezing user space processes ... (elapsed 0.01 seconds) done. [ 220.408386] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don e. [ 220.439605] Suspending console(s) (use no_console_suspend to debug) [ 220.454650] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -110 [ 220.454711] PM: Device omap_hsmmc.1 failed to suspend: error -110 [ 220.454711] PM: Some devices failed to suspend [ 220.718261] PM: resume of devices complete after 263.539 msecs [ 220.743988] Restarting tasks ... done.
Quoted 8 lines
Quoted 5 lines
Attempting to disable MMC from config prevented boot completely for me, so this issue is likely to stay until someone fixes the MMC driver. Panda device works fine though, although the wakeup from device off is slow due to problems with some other drivers (most likely I2C.)
can you try this patch if you want to disable MMC
http://permalink.gmane.org/gmane.linux.ports.arm.omap/74540
Tried this patch and disabled MMC completely. Device off now works with blaze board also multiple times.
-Tero
Quoted 21 lines
or
http://www.spinics.net/lists/linux-omap/msg67879.html
and buildomap_hsmmcas module.Quoted 17 lines
Off mode is disabled by default, it can be enabled by either calling
omap4_pm_enable_off_mode(1)from board files or alternatively writing to a debugfs node from userspace:echo 1 > /debug/pm_debug/enable_off_mode
Device off entry can be tracked through the debugfs also, it increases the
core_pwrdmOFF state counter / timer, as this is an invalid state for the chip normally (core enters OSWR in device off.) Not sure if this a good way to do this but comments are welcome.-Tero
--
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
cover ARM: OMAP4 device off support
Tero Kristo <[email protected]> writes:
[...]
Quoted 11 lines
Quoted 5 lines
I tried your branch on gp/emu devices but could not reproduce this issue. My observation is that while resuming, omap_hsmmc.1 eMMC is trying to turn on phoenix vaux1 regulator via i2c which fails due to controller timeout.
Note: eMMC is present only on sdp/blazeDid you try this with off-mode enabled and did you check the device actually goes to off? (see pm_debug/count and verify core off count is increasing.) And as said, I was only able to see this problem on a blaze device, panda works fine. But yes, you are probably right and it is not an MMC driver issue but I2C.
Can you try the patch below? It sounds like the same problem.
Kevin
Quoted 1 line
From
999f34629140f436099050eb7aac514bfd2a2235Mon Sep 17 00:00:00 2001
From: NeilBrown <[email protected]>
Date: Fri, 30 Dec 2011 12:40:30 +1100
Subject: [PATCH] OMAP/I2C - Fix timeout problem during suspend.
On a board with OMAP3 processor and TWL4030 Power management, we need to talk to the TWL4030 during late suspend but cannot because the I2C interrupt is disabled (as late suspend disables interrupt).
e.g. I get messages like:
[ 62.161102] musb-omap2430 musb-omap2430: LATE power domain suspend [ 63.167205] omap_i2c omap_i2c.1: controller timed out [ 63.183044] twl: i2c_read failed to transfer all messages [ 64.182861] omap_i2c omap_i2c.1: controller timed out [ 64.198455] twl: i2c_write failed to transfer all messages [ 65.198455] omap_i2c omap_i2c.1: controller timed out [ 65.203765] twl: i2c_write failed to transfer all messages
The stack shows omap2430_runtime_suspend calling twl4030_set_suspend which tries to power-down the USB PHY (twl4030_phy_suspend -> twl4030_phy_power -> __twl4030_phy_power which as a nice WARN_ON that helps).
Then we get the same in resume:
[ 69.603912] musb-omap2430 musb-omap2430: EARLY power domain resume [ 70.610473] omap_i2c omap_i2c.1: controller timed out [ 70.626129] twl: i2c_write failed to transfer all messages
etc.
So don't disable interrupts for I2C.
--- drivers/i2c/busses/i2c-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-omap.c +1 -1
@@ -1092,7 +1092,7 @@ omap_i2c_probe(struct platform_device *pdev) isr = (dev->rev <OMAP_I2C_OMAP1_REV_2 ) ? omap_i2c_omap1_isr : omap_i2c_isr; - r =request_irq (dev->irq, isr,0 , pdev->name, dev); + r =request_irq (dev->irq, isr,IRQF_NO_SUSPEND , pdev->name, dev);if (r) {dev_err (dev->dev,"failure requesting irq %i\n" , dev->irq);
Signature · 1 line
1.7.9.2
cover ARM: OMAP4 device off support
Quoted 10 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 6 lines
Quoted 5 lines
I tried your branch on gp/emu devices but could not reproduce this issue. My observation is that while resuming, omap_hsmmc.1 eMMC is trying to turn on phoenix vaux1 regulator via i2c which fails due to controller timeout.
Note: eMMC is present only on sdp/blaze
Quoted 7 lines
Quoted 5 lines
Did you try this with off-mode enabled and did you check the device actually goes to off? (see pm_debug/count and verify core off count is increasing.) And as said, I was only able to see this problem on a blaze device, panda works fine. But yes, you are probably right and it is not an MMC driver issue but I2C.
Can you try the patch below? It sounds like the same problem.
Doesn't help with this one. I guess I2C loses context during device off and it is not restored properly.
-Tero
Quoted 56 lines
Kevin
From
999f34629140f436099050eb7aac514bfd2a2235Mon Sep 17 00:00:00 2001
From: NeilBrown <[email protected]>
Date: Fri, 30 Dec 2011 12:40:30 +1100
Subject: [PATCH] OMAP/I2C - Fix timeout problem during suspend.On a board with OMAP3 processor and TWL4030 Power management, we need to talk to the TWL4030 during late suspend but cannot because the I2C interrupt is disabled (as late suspend disables interrupt).
e.g. I get messages like:
[ 62.161102] musb-omap2430 musb-omap2430: LATE power domain suspend [ 63.167205] omap_i2c omap_i2c.1: controller timed out [ 63.183044] twl: i2c_read failed to transfer all messages [ 64.182861] omap_i2c omap_i2c.1: controller timed out [ 64.198455] twl: i2c_write failed to transfer all messages [ 65.198455] omap_i2c omap_i2c.1: controller timed out [ 65.203765] twl: i2c_write failed to transfer all messagesThe stack shows
omap2430_runtime_suspendcallingtwl4030_set_suspendwhich tries to power-down the USB PHY (twl4030_phy_suspend->twl4030_phy_power->__twl4030_phy_powerwhich as a niceWARN_ONthat helps).Then we get the same in resume:
[ 69.603912] musb-omap2430 musb-omap2430: EARLY power domain resume [ 70.610473] omap_i2c omap_i2c.1: controller timed out [ 70.626129] twl: i2c_write failed to transfer all messagesetc.
So don't disable interrupts for I2C.
Signed-off-by NeilBrown <[email protected]>--- drivers/i2c/busses/i2c-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/i2c/busses/i2c-omap.c +1
-1@@ -1092,7 +1092,7 @@ omap_i2c_probe(struct platform_device *pdev) isr = (dev->rev <OMAP_I2C_OMAP1_REV_2 ) ? omap_i2c_omap1_isr : omap_i2c_isr; - r =request_irq (dev->irq, isr,0 , pdev->name, dev); + r =request_irq (dev->irq, isr,IRQF_NO_SUSPEND , pdev->name, dev);if (r) {dev_err (dev->dev,"failure requesting irq %i\n" , dev->irq);
cover ARM: OMAP4 device off support
Quoted 17 lines · Tero Kristo
Quoted 16 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 11 lines
Quoted 5 lines
I tried your branch on gp/emu devices but could not reproduce this issue. My observation is that while resuming, omap_hsmmc.1 eMMC is trying to turn on phoenix vaux1 regulator via i2c which fails due to controller timeout.
Note: eMMC is present only on sdp/blazeDid you try this with off-mode enabled and did you check the device actually goes to off? (see pm_debug/count and verify core off count is increasing.) And as said, I was only able to see this problem on a blaze device, panda works fine. But yes, you are probably right and it is not an MMC driver issue but I2C.
Quoted 6 lines
Quoted 1 line
Can you try the patch below? ?It sounds like the same problem.
Doesn't help with this one. I guess I2C loses context during device off and it is not restored properly.
-Tero
Could you try the following patch
cover ARM: OMAP4 device off support
Quoted 20 lines · Shubhrajyoti
Quoted 19 lines · Tero Kristo
Quoted 17 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 11 lines
Quoted 5 lines
I tried your branch on gp/emu devices but could not reproduce this issue. My observation is that while resuming, omap_hsmmc.1 eMMC is trying to turn on phoenix vaux1 regulator via i2c which fails due to controller timeout.
Note: eMMC is present only on sdp/blazeDid you try this with off-mode enabled and did you check the device actually goes to off? (see pm_debug/count and verify core off count is increasing.) And as said, I was only able to see this problem on a blaze device, panda works fine. But yes, you are probably right and it is not an MMC driver issue but I2C.
Can you try the patch below? It sounds like the same problem.
Quoted 7 lines
Quoted 4 lines
Doesn't help with this one. I guess I2C loses context during device off and it is not restored properly.
-Tero
Could you try the following patch
That does the trick, after this it is working fine on blaze, and this also fixes the timeout issues seen on panda board (meaning wake-up from device off is much faster.)
-Tero
cover ARM: OMAP4 device off support
Quoted 24 lines · Tero Kristo
Quoted 23 lines · Shubhrajyoti
Quoted 22 lines · Tero Kristo
Quoted 10 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 6 lines
Quoted 5 lines
I tried your branch on gp/emu devices but could not reproduce this issue. My observation is that while resuming, omap_hsmmc.1 eMMC is trying to turn on phoenix vaux1 regulator via i2c which fails due to controller timeout.
Note: eMMC is present only on sdp/blazeQuoted 7 lines
Quoted 5 lines
Did you try this with off-mode enabled and did you check the device actually goes to off? (see pm_debug/count and verify core off count is increasing.) And as said, I was only able to see this problem on a blaze device, panda works fine. But yes, you are probably right and it is not an MMC driver issue but I2C.
Can you try the patch below? ?It sounds like the same problem.
Doesn't help with this one. I guess I2C loses context during device off and it is not restored properly.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
-Tero
Could you try the following patch
That does the trick, after this it is working fine on blaze, and this also fixes the timeout issues seen on panda board (meaning wake-up from device off is much faster.)
Thats great.
Feel free to try the following.
I2C conditional restore"
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg66859.html
Also cooked a below rfc/untested patch for mmc restore.
Quoted 1 line
From
c28ec76f8a20c3ce59b72245ab9f3bc293b1ac43Mon Sep 17 00:00:00 2001
From: Shubhrajyoti D <[email protected]>
Date: Mon, 23 Apr 2012 11:52:54 +0530
Subject: [RFC PATCH] hsmmc: omap: Support for device off
Attempt to have device off support. Current the function hsmmc_get_context_loss is made NULL for OMAP4. Remove it as post Terro's patches context may be lost. Also it is good to have no assumptions of the context loss in the driver.
--- arch/arm/mach-omap2/hsmmc.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-)
arch/arm/mach-omap2/hsmmc.c +0 -6
@@ -32,17 +32,11 @@ static u16 control_mmc1;#define HSMMC_NAME_LEN 9 -#if defined(CONFIG_ARCH_OMAP3 ) && defined(CONFIG_PM ) -static int hsmmc_get_context_loss (struct device *dev) {return omap_pm_get_dev_context_loss_count (dev); } -#else -#define hsmmc_get_context_loss NULL -#endif -static void omap_hsmmc1_before_set_reg (struct device *dev,int slot,int power_on,int vdd) {
--
1.7.0.4
cover ARM: OMAP4 device off support
In reply to Tero KristoQuoted 6 lines · Tero Kristo
Hi,
First version for this work. Applies on top of mainline + iochain set + OMAP4 core retention set. Working tree available here:
tree:git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-off
FYI... seems your get repo is corrupted. I tried fetching both with git and https protocols:
$ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git $ git fetch tero fatal: The remote end hung up unexpectedly fatal: protocol error: bad pack heade $ git remote rm tero $ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git $ git fetch tero error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed error: Fetch failed.
Kevin
cover ARM: OMAP4 device off support
Quoted 12 lines · Kevin Hilman
Quoted 6 lines · Tero Kristo
Hi,
First version for this work. Applies on top of mainline + iochain set + OMAP4 core retention set. Working tree available here:
tree:git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-offFYI... seems your get repo is corrupted. I tried fetching both with git and https protocols:
Quoted 10 lines
$ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git $ git fetch tero fatal: The remote end hung up unexpectedly fatal: protocol error: bad pack heade $ git remote rm tero $ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git $ git fetch tero error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed error: Fetch failed.
You will have a partially transferred pack file in your repository...
cover ARM: OMAP4 device off support
Quoted 24 lines · Russell King - ARM Linux
Quoted 12 lines · Kevin Hilman
Quoted 6 lines · Tero Kristo
Hi,
First version for this work. Applies on top of mainline + iochain set + OMAP4 core retention set. Working tree available here:
tree:git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-offFYI... seems your get repo is corrupted. I tried fetching both with git and https protocols:
Quoted 10 lines
$ git remote add tero git://gitorious.org/~kristo/omap-pm/omap-pm-work.git $ git fetch tero fatal: The remote end hung up unexpectedly fatal: protocol error: bad pack heade $ git remote rm tero $ git remote add tero https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git $ git fetch tero error: Unable to find 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed under https://git.gitorious.org/~kristo/omap-pm/omap-pm-work.git Cannot obtain needed object 653621e4dd02d4a2117e1b813d9c5f1ccb11c9ed error: Fetch failed.
Quoted 1 line
You will have a partially transferred pack file in your repository...
Strange, well I pushed 1 new branch and it looks like it is cloning properly now.
-Tero