diff options
author | Robby Cai <r63905@freescale.com> | 2009-10-10 16:30:06 +0800 |
---|---|---|
committer | Robby Cai <r63905@freescale.com> | 2009-10-10 16:33:55 +0800 |
commit | 8a11c56d9d30fd239ef3413be45bc45d6b712e79 (patch) | |
tree | 068e7af5d6115e871b4a8add87644623ad4e661f | |
parent | 8635334b08952f242aba2e7cf916a47b117f4169 (diff) |
ENGR00116416-1 reset PXP module when it's inactive
Putting PXP in reset state gains the lowest power.
Restrore the PXP regs once PXP comes out of reset state.
Signed-off-by: Robby Cai <r63905@freescale.com>
-rw-r--r-- | arch/arm/mach-stmp3xxx/include/mach/regs-pxp.h | 2 | ||||
-rw-r--r-- | drivers/media/video/pxp.c | 55 |
2 files changed, 57 insertions, 0 deletions
diff --git a/arch/arm/mach-stmp3xxx/include/mach/regs-pxp.h b/arch/arm/mach-stmp3xxx/include/mach/regs-pxp.h index b4160f120c6e..12e0e5f86b4e 100644 --- a/arch/arm/mach-stmp3xxx/include/mach/regs-pxp.h +++ b/arch/arm/mach-stmp3xxx/include/mach/regs-pxp.h @@ -315,6 +315,8 @@ HW_REGISTER_0(HW_PXP_VERSION, REGS_PXP_BASE, 0x000001f0) #define BM_PXP_VERSION_STEP 0x0000FFFF #define BF_PXP_VERSION_STEP(v) \ (((v) << 0) & BM_PXP_VERSION_STEP) + +#define HW_PXP_OL0_ADDR (REGS_PXP_BASE + 0x00000200) /* * multi-register-define name HW_PXP_OLn * base 0x00000200 diff --git a/drivers/media/video/pxp.c b/drivers/media/video/pxp.c index e82339ad357c..bc15e9479d3b 100644 --- a/drivers/media/video/pxp.c +++ b/drivers/media/video/pxp.c @@ -46,6 +46,14 @@ #define V4L2_OUTPUT_TYPE_INTERNAL 4 +#define REG_OFFSET 0x10 +#define REGS1_NUMS 16 +#define REGS2_NUMS 5 +#define REGS3_NUMS 32 +static u32 regs1[REGS1_NUMS]; +static u32 regs2[REGS2_NUMS]; +static u32 regs3[REGS3_NUMS]; + static struct pxp_data_format pxp_s0_formats[] = { { .name = "24-bit RGB", @@ -1201,12 +1209,59 @@ static int __devexit pxp_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int pxp_suspend(struct platform_device *pdev, pm_message_t state) +{ + int i; + + while (HW_PXP_CTRL_RD() & BM_PXP_CTRL_ENABLE) + ; + + for (i = 0; i < REGS1_NUMS; i++) + regs1[i] = __raw_readl(HW_PXP_CTRL_ADDR + REG_OFFSET * i); + + for (i = 0; i < REGS2_NUMS; i++) + regs2[i] = __raw_readl(HW_PXP_PAGETABLE_ADDR + REG_OFFSET * i); + + for (i = 0; i < REGS3_NUMS; i++) + regs3[i] = __raw_readl(HW_PXP_OL0_ADDR + REG_OFFSET * i); + + HW_PXP_CTRL_SET(BM_PXP_CTRL_SFTRST); + + return 0; +} + +static int pxp_resume(struct platform_device *pdev) +{ + int i; + + /* Pull PxP out of reset */ + HW_PXP_CTRL_WR(0); + + for (i = 0; i < REGS1_NUMS; i++) + __raw_writel(regs1[i], HW_PXP_CTRL_ADDR + REG_OFFSET * i); + + for (i = 0; i < REGS2_NUMS; i++) + __raw_writel(regs2[i], HW_PXP_PAGETABLE_ADDR + REG_OFFSET * i); + + for (i = 0; i < REGS3_NUMS; i++) + __raw_writel(regs3[i], HW_PXP_OL0_ADDR + REG_OFFSET * i); + + return 0; +} +#else +#define pxp_suspend NULL +#define pxp_resume NULL +#endif + static struct platform_driver pxp_driver = { .driver = { .name = PXP_DRIVER_NAME, }, .probe = pxp_probe, .remove = __exit_p(pxp_remove), + .suspend = pxp_suspend, + .resume = pxp_resume, }; |