summaryrefslogtreecommitdiff
path: root/drivers/media/video/pxp.c
diff options
context:
space:
mode:
authorRobby Cai <r63905@freescale.com>2009-10-10 16:30:06 +0800
committerAlejandro Gonzalez <alex.gonzalez@digi.com>2010-02-12 17:19:19 +0100
commit1b830502003614bc4a328abe6291dbb47c5d14bb (patch)
tree5ada195b3d700cc1335e10649404cfefadf9d103 /drivers/media/video/pxp.c
parent6bed85a30de198de8eb9f463dcd7ffa9dcfb5280 (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>
Diffstat (limited to 'drivers/media/video/pxp.c')
-rw-r--r--drivers/media/video/pxp.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/media/video/pxp.c b/drivers/media/video/pxp.c
index 0c9d858630be..02b1fe3b364e 100644
--- a/drivers/media/video/pxp.c
+++ b/drivers/media/video/pxp.c
@@ -47,6 +47,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",
@@ -1204,12 +1212,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,
};