From 7337c8dc883b7f16179de9e183f0fe1509855ace Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 20 Jan 2011 19:27:44 +0800 Subject: [PATCH] rk29: vpu: add suspend/resume --- arch/arm/mach-rk29/vpu.c | 98 ++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/arch/arm/mach-rk29/vpu.c b/arch/arm/mach-rk29/vpu.c index 2bc9aa7320ac..debb49389c0c 100644 --- a/arch/arm/mach-rk29/vpu.c +++ b/arch/arm/mach-rk29/vpu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -107,19 +108,21 @@ static void vpu_power_on(void) return; pr_debug("power domain on\n"); pmu_set_power_domain(PD_VCODEC, true); - udelay(10); + udelay(10); clk_enable(aclk_vepu); clk_enable(hclk_vepu); clk_enable(aclk_ddr_vepu); clk_enable(hclk_cpu_vcodec); - udelay(10); - writel( (1<<27), RK29_CRU_BASE + CRU_SOFTRST0_CON ); - writel( (1<<19), RK29_CRU_BASE + CRU_SOFTRST2_CON ); - writel( (1<<18), RK29_CRU_BASE + CRU_SOFTRST2_CON ); - writel( (1<<15), RK29_CRU_BASE + CRU_SOFTRST2_CON ); - udelay(10); - writel( 0, RK29_CRU_BASE + CRU_SOFTRST0_CON ); - writel( 0, RK29_CRU_BASE + CRU_SOFTRST2_CON ); + udelay(10); + cru_set_soft_reset(SOFT_RST_CPU_VODEC_A2A_AHB, true); + cru_set_soft_reset(SOFT_RST_VCODEC_AHB_BUS, true); + cru_set_soft_reset(SOFT_RST_VCODEC_AXI_BUS, true); + cru_set_soft_reset(SOFT_RST_DDR_VCODEC_PORT, true); + udelay(10); + cru_set_soft_reset(SOFT_RST_CPU_VODEC_A2A_AHB, false); + cru_set_soft_reset(SOFT_RST_VCODEC_AHB_BUS, false); + cru_set_soft_reset(SOFT_RST_VCODEC_AXI_BUS, false); + cru_set_soft_reset(SOFT_RST_DDR_VCODEC_PORT, false); client.enabled = true; } @@ -329,28 +332,6 @@ static irqreturn_t hx280enc_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static void vpu_reset_dec_asic(struct vpu_device * dev) -{ - unsigned int i, n = dev->iosize >> 2; - - writel(0, dev->hwregs + DEC_INTERRUPT_REGISTER); - - for (i = 1; i < n; i++) { - writel(0, dev->hwregs + i); - } -} - -static void vpu_reset_enc_asic(struct vpu_device * dev) -{ - unsigned int i, n = dev->iosize >> 2; - - writel(0, dev->hwregs + 14); - - for (i = 4; i < n; i++) { - writel(0, dev->hwregs + i); - } -} - static int vpu_mmap(struct file *fp, struct vm_area_struct *vm) { unsigned long pfn; @@ -436,6 +417,39 @@ static struct miscdevice vpu_misc_device = { .fops = &vpu_fops, }; +#ifdef CONFIG_PM +static int vpu_suspend(struct platform_device *pdev, pm_message_t state) +{ + bool enabled = client.enabled; + vpu_power_off(); + client.enabled = enabled; + return 0; +} + +static int vpu_resume(struct platform_device *pdev) +{ + if (client.enabled) { + client.enabled = false; + vpu_power_on(); + } + return 0; +} + +static struct platform_device vpu_pm_device = { + .name = "vpu", + .id = -1, +}; + +static struct platform_driver vpu_pm_driver = { + .driver = { + .name = "vpu", + .owner = THIS_MODULE, + }, + .suspend = vpu_suspend, + .resume = vpu_resume, +}; +#endif + static int __init vpu_init(void) { int ret; @@ -463,9 +477,6 @@ static int __init vpu_init(void) atomic_set(&client.dec_event, 0); atomic_set(&client.enc_event, 0); - vpu_reset_dec_asic(&dec_dev); /* reset hardware */ - vpu_reset_enc_asic(&enc_dev); /* reset hardware */ - /* get the IRQ line */ ret = request_irq(IRQ_VDPU, hx170dec_isr, 0, "hx170dec", (void *)&dec_dev); if (ret != 0) { @@ -486,6 +497,11 @@ static int __init vpu_init(void) } vpu_power_off(); + +#ifdef CONFIG_PM + platform_device_register(&vpu_pm_device); + platform_driver_probe(&vpu_pm_driver, NULL); +#endif pr_info("init success\n"); return 0; @@ -505,16 +521,12 @@ err_reserve_io: static void __exit vpu_exit(void) { - vpu_power_on(); - - /* clear dec IRQ */ - writel(0, dec_dev.hwregs + DEC_INTERRUPT_REGISTER); - /* clear pp IRQ */ - writel(0, dec_dev.hwregs + PP_INTERRUPT_REGISTER); +#ifdef CONFIG_PM + platform_device_unregister(&vpu_pm_device); + platform_driver_unregister(&vpu_pm_driver); +#endif - writel(0, enc_dev.hwregs + 14); /* disable HW */ - /* clear enc IRQ */ - writel(0, enc_dev.hwregs + ENC_INTERRUPT_REGISTER); + vpu_power_on(); misc_deregister(&vpu_misc_device); free_irq(IRQ_VEPU, (void *)&enc_dev); -- 2.34.1