summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Cai <r63905@freescale.com>2009-10-10 16:30:06 +0800
committerRobby Cai <r63905@freescale.com>2009-10-10 16:33:55 +0800
commit8a11c56d9d30fd239ef3413be45bc45d6b712e79 (patch)
tree068e7af5d6115e871b4a8add87644623ad4e661f
parent8635334b08952f242aba2e7cf916a47b117f4169 (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.h2
-rw-r--r--drivers/media/video/pxp.c55
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,
};