From 77facb00004998bdf8302a45955c849ad332735d Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Mon, 7 Nov 2011 18:33:22 +0800 Subject: [PATCH] rk29: rm old vpu driver --- arch/arm/mach-rk29/Kconfig | 9 - arch/arm/mach-rk29/Makefile | 4 +- arch/arm/mach-rk29/vpu.c | 945 ------------------------------------ 3 files changed, 1 insertion(+), 957 deletions(-) delete mode 100644 arch/arm/mach-rk29/vpu.c diff --git a/arch/arm/mach-rk29/Kconfig b/arch/arm/mach-rk29/Kconfig index 07631697203c..cfde2d8ab54d 100644 --- a/arch/arm/mach-rk29/Kconfig +++ b/arch/arm/mach-rk29/Kconfig @@ -178,19 +178,10 @@ config WIFI_CONTROL_FUNC menu "RK29 VPU (Video Processing Unit) support" config RK29_VPU - bool - depends on ARCH_RK29 - default y - -config RK29_VPU_SERVICE bool "VPU service driver in kernel" depends on ARCH_RK29 default y -config RK29_VPU_OLD - bool "Old version for RK29 VPU (Video Processing Unit)" - depends on ARCH_RK29 && !RK29_VPU_SERVICE - config RK29_VPU_DEBUG bool "RK29 VPU debugging" depends on RK29_VPU != n diff --git a/arch/arm/mach-rk29/Makefile b/arch/arm/mach-rk29/Makefile index 11fbfae0c21d..df2e7a0b3c26 100644 --- a/arch/arm/mach-rk29/Makefile +++ b/arch/arm/mach-rk29/Makefile @@ -9,11 +9,9 @@ obj-$(CONFIG_USB_GADGET) += usb_detect.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_DDR_FREQ) += ddrfreq.o -obj-$(CONFIG_RK29_VPU) += vpu_mem.o +obj-$(CONFIG_RK29_VPU) += vpu_mem.o vpu_service.o obj-$(CONFIG_RK29_I2C_INSRAM) += i2c_sram.o obj-y += spi_sram.o -obj-$(CONFIG_RK29_VPU_SERVICE) += vpu_service.o -obj-$(CONFIG_RK29_VPU_OLD) += vpu.o obj-$(CONFIG_RK29_PWM_INSRAM) += pwm_sram.o obj-$(CONFIG_MACH_RK29SDK) += board-rk29sdk.o board-rk29sdk-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o obj-$(CONFIG_MACH_RK29_P91) += board-rk29-p91.o board-rk29-p91-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o diff --git a/arch/arm/mach-rk29/vpu.c b/arch/arm/mach-rk29/vpu.c deleted file mode 100644 index 37d95b35e428..000000000000 --- a/arch/arm/mach-rk29/vpu.c +++ /dev/null @@ -1,945 +0,0 @@ -/* arch/arm/mach-rk29/vpu.c - * - * Copyright (C) 2010 ROCKCHIP, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifdef CONFIG_RK29_VPU_DEBUG -#define DEBUG -#define pr_fmt(fmt) "VPU: %s: " fmt, __func__ -#else -#define pr_fmt(fmt) "VPU: " fmt -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - - -#define DEC_INTERRUPT_REGISTER 1 -#define PP_INTERRUPT_REGISTER 60 -#define ENC_INTERRUPT_REGISTER 1 - -#define DEC_INTERRUPT_BIT 0x100 -#define PP_INTERRUPT_BIT 0x100 -#define ENC_INTERRUPT_BIT 0x1 - -#define DEC_IO_SIZE ((100 + 1) * 4) /* bytes */ -#define ENC_IO_SIZE (96 * 4) /* bytes */ - -typedef enum -{ - VPU_ENC = 0x0, - VPU_DEC = 0x1, - VPU_PP = 0x2, - VPU_DEC_PP = 0x3, - VPU_TYPE_BUTT , -} VPU_CLIENT_TYPE; - -#define REG_NUM_DEC (60) -#define REG_NUM_PP (41) -#define REG_NUM_ENC (96) -#define REG_NUM_DEC_PP (REG_NUM_DEC+REG_NUM_PP) -#define SIZE_REG(reg) ((reg)*4) - -static const u16 dec_hw_ids[] = { 0x8190, 0x8170, 0x9170, 0x9190, 0x6731 }; -static const u16 enc_hw_ids[] = { 0x6280, 0x7280, 0x8270 }; -static u32 regs_enc[REG_NUM_ENC]; -static u32 regs_dec[REG_NUM_DEC_PP]; -static u32 *regs_pp = ®s_dec[REG_NUM_DEC]; - -#define VPU_REG_EN_ENC 14 -#define VPU_REG_ENC_GATE 2 -#define VPU_REG_ENC_GATE_BIT (1<<4) - -#define VPU_REG_EN_DEC 1 -#define VPU_REG_DEC_GATE 2 -#define VPU_REG_DEC_GATE_BIT (1<<10) -#define VPU_REG_EN_PP 0 -#define VPU_REG_PP_GATE 1 -#define VPU_REG_PP_GATE_BIT (1<<8) -#define VPU_REG_EN_DEC_PP 1 -#define VPU_REG_DEC_PP_GATE 61 -#define VPU_REG_DEC_PP_GATE_BIT (1<<8) - -struct vpu_device { - unsigned long iobaseaddr; - unsigned int iosize; - volatile u32 *hwregs; - unsigned int irq; -}; - -static struct vpu_device dec_dev; -static struct vpu_device pp_dev; -static struct vpu_device enc_dev; - -struct vpu_client { - atomic_t dec_event; - atomic_t enc_event; - struct fasync_struct *async_queue; - wait_queue_head_t wait; - struct file *filp; /* for /proc/vpu */ - bool enabled; -}; -static struct vpu_client client; - -static struct clk *aclk_vepu; -static struct clk *hclk_vepu; -static struct clk *aclk_ddr_vepu; -static struct clk *hclk_cpu_vcodec; - -static void vpu_release_io(void); - -static void vpu_get_clk(void) -{ - aclk_vepu = clk_get(NULL, "aclk_vepu"); - hclk_vepu = clk_get(NULL, "hclk_vepu"); - aclk_ddr_vepu = clk_get(NULL, "aclk_ddr_vepu"); - hclk_cpu_vcodec = clk_get(NULL, "hclk_cpu_vcodec"); -} - -static void vpu_put_clk(void) -{ - clk_put(aclk_vepu); - clk_put(hclk_vepu); - clk_put(aclk_ddr_vepu); - clk_put(hclk_cpu_vcodec); -} - -static u32 vpu_is_working(void) -{ - u32 irq_status; - u32 vpu_status = 0; - irq_status = readl(dec_dev.hwregs + DEC_INTERRUPT_REGISTER); - vpu_status |= irq_status&1; - irq_status = readl(enc_dev.hwregs + ENC_INTERRUPT_REGISTER); - vpu_status |= irq_status&1; - irq_status = readl(pp_dev.hwregs + PP_INTERRUPT_REGISTER); - vpu_status |= irq_status&1; - - return vpu_status; -} - -static void vpu_power_on(void) -{ - pr_debug("power on\n"); - if (client.enabled) - return; - - clk_enable(aclk_vepu); - clk_enable(hclk_vepu); - clk_enable(hclk_cpu_vcodec); - udelay(10); - pmu_set_power_domain(PD_VCODEC, true); - udelay(10); - clk_enable(aclk_ddr_vepu); - client.enabled = true; -} - -static void vpu_power_off(void) -{ - pr_debug("power off\n"); - if (!client.enabled) - return; - - while (vpu_is_working()) - udelay(10); - - pmu_set_power_domain(PD_VCODEC, false); - udelay(10); - clk_disable(hclk_cpu_vcodec); - clk_disable(aclk_ddr_vepu); - clk_disable(hclk_vepu); - clk_disable(aclk_vepu); - - client.enabled = false; -} - -static void vpu_power_test(void) -{ -#if 0 - if (pmu_power_domain_is_on(PD_VCODEC)) { - printk("power domain is on, test closing\n"); - - while (vpu_is_working()) - msleep(1); - - printk("power off\n"); - pmu_set_power_domain(PD_VCODEC, false); - - printk("clock off hclk_cpu_vcodec\n"); - clk_disable(hclk_cpu_vcodec); - printk("clock off hclk_vepu\n"); - clk_disable(hclk_vepu); - printk("clock off aclk_ddr_vepu\n"); - clk_disable(aclk_ddr_vepu); - printk("clock off aclk_vepu\n"); - clk_disable(aclk_vepu); - } else { - printk("power domain is off, test opening\n"); - - printk("clock on : hclk_vepu\n"); - clk_enable(hclk_vepu); - printk("clock on : hclk_cpu_vcodec\n"); - clk_enable(hclk_cpu_vcodec); - printk("clock on : aclk_vepu\n"); - clk_enable(aclk_vepu); - printk("clock on : aclk_ddr_vepu\n"); - clk_enable(aclk_ddr_vepu); - - printk("power on\n"); - pmu_set_power_domain(PD_VCODEC, true); - - #if 1 - udelay(100); - - printk("clock reset\n"); - cru_set_soft_reset(SOFT_RST_CPU_VODEC_A2A_AHB, true); - cru_set_soft_reset(SOFT_RST_DDR_VCODEC_PORT, true); - cru_set_soft_reset(SOFT_RST_VCODEC_AHB_BUS, true); - cru_set_soft_reset(SOFT_RST_VCODEC_AXI_BUS, true); - - printk("clock unreset\n"); - cru_set_soft_reset(SOFT_RST_VCODEC_AXI_BUS, false); - cru_set_soft_reset(SOFT_RST_VCODEC_AHB_BUS, false); - cru_set_soft_reset(SOFT_RST_DDR_VCODEC_PORT, false); - cru_set_soft_reset(SOFT_RST_CPU_VODEC_A2A_AHB, false); - #endif - } -#endif -} - -static long vpu_write_dec(u32 *src) -{ - int i; - u32 *dst = (u32 *)dec_dev.hwregs; - - for (i = REG_NUM_DEC - 1; i > VPU_REG_DEC_GATE; i--) - dst[i] = src[i]; - - dsb(); - - dst[VPU_REG_DEC_GATE] = src[VPU_REG_DEC_GATE] | VPU_REG_DEC_GATE_BIT; - dst[VPU_REG_EN_DEC] = src[VPU_REG_EN_DEC]; - - return 0; -} - -static long vpu_write_dec_pp(u32 *src) -{ - int i; - u32 *dst = (u32 *)dec_dev.hwregs; - - for (i = VPU_REG_EN_DEC_PP + 1; i < REG_NUM_DEC_PP; i++) - dst[i] = src[i]; - - dsb(); - - dst[VPU_REG_DEC_PP_GATE] = src[VPU_REG_DEC_PP_GATE] | VPU_REG_PP_GATE_BIT; - dst[VPU_REG_DEC_GATE] = src[VPU_REG_DEC_GATE] | VPU_REG_DEC_GATE_BIT; - dst[VPU_REG_EN_DEC] = src[VPU_REG_EN_DEC]; - - return 0; -} - -static long vpu_write_enc(u32 *src) -{ - int i; - u32 *dst = (u32 *)enc_dev.hwregs; - - dst[VPU_REG_EN_ENC] = src[VPU_REG_EN_ENC] & 0x6; - - for (i = 0; i < VPU_REG_EN_ENC; i++) - dst[i] = src[i]; - - for (i = VPU_REG_EN_ENC + 1; i < REG_NUM_ENC; i++) - dst[i] = src[i]; - - dsb(); - - dst[VPU_REG_ENC_GATE] = src[VPU_REG_ENC_GATE] | VPU_REG_ENC_GATE_BIT; - dst[VPU_REG_EN_ENC] = src[VPU_REG_EN_ENC]; - - return 0; -} - -static long vpu_write_pp(u32 *src) -{ - int i; - u32 *dst = (u32 *)dec_dev.hwregs + PP_INTERRUPT_REGISTER; - - dst[VPU_REG_PP_GATE] = src[VPU_REG_PP_GATE] | VPU_REG_PP_GATE_BIT; - - for (i = VPU_REG_PP_GATE + 1; i < REG_NUM_PP; i++) - dst[i] = src[i]; - - dsb(); - - dst[VPU_REG_EN_PP] = src[VPU_REG_EN_PP]; - - return 0; -} - -static long vpu_read_dec(u32 *dst) -{ - int i; - volatile u32 *src = dec_dev.hwregs; - - for (i = 0; i < REG_NUM_DEC; i++) - *dst++ = *src++; - - return 0; -} - -static long vpu_read_dec_pp(u32 *dst) -{ - int i; - volatile u32 *src = dec_dev.hwregs; - - for (i = 0; i < REG_NUM_DEC_PP; i++) - *dst++ = *src++; - - return 0; -} - -static long vpu_read_enc(u32 *dst) -{ - int i; - volatile u32 *src = enc_dev.hwregs; - - for (i = 0; i < REG_NUM_ENC; i++) - *dst++ = *src++; - - return 0; -} - -static long vpu_read_pp(u32 *dst) -{ - int i; - volatile u32 *src = dec_dev.hwregs + PP_INTERRUPT_REGISTER; - - for (i = 0; i < REG_NUM_PP; i++) - *dst++ = *src++; - - return 0; -} - -static long vpu_clear_irqs(VPU_CLIENT_TYPE type) -{ - long ret = 0; - switch (type) { - case VPU_ENC : { - writel(0, &enc_dev.hwregs[ENC_INTERRUPT_REGISTER]); - break; - } - case VPU_DEC : { - writel(0, &dec_dev.hwregs[DEC_INTERRUPT_REGISTER]); - break; - } - case VPU_PP : { - writel(0, &pp_dev.hwregs[PP_INTERRUPT_REGISTER]); - break; - } - case VPU_DEC_PP : { - writel(0, &pp_dev.hwregs[PP_INTERRUPT_REGISTER]); - writel(0, &dec_dev.hwregs[DEC_INTERRUPT_REGISTER]); - break; - } - default : { - printk("undefined vpu_clear_irqs case\n"); - ret = -1; - } - } - - return ret; -} - -static long vpu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - pr_debug("ioctl cmd 0x%08x\n", cmd); - - switch (cmd) { - case VPU_IOC_CLOCK_ON: { - vpu_power_on(); - break; - } - case VPU_IOC_CLOCK_OFF: { - vpu_power_off(); - break; - } - case VPU_IOC_CLOCK_RESET: - case VPU_IOC_CLOCK_UNRESET: - case VPU_IOC_DOMAIN_ON: - case VPU_IOC_DOMAIN_OFF: { - break; - } - - - case VPU_IOC_TEST: { - vpu_power_test(); - break; - } - - - case VPU_IOC_WR_DEC: { - if (copy_from_user(regs_dec, (void __user *)arg, SIZE_REG(REG_NUM_DEC))) { - printk("VPU_IOC_WR_DEC copy_from_user failed\n"); - return -EFAULT; - } - vpu_write_dec(regs_dec); - break; - } - - case VPU_IOC_WR_DEC_PP: { - if (copy_from_user(regs_dec, (void __user *)arg, SIZE_REG(REG_NUM_DEC_PP))) { - printk("VPU_IOC_WR_DEC_PP copy_from_user failed\n"); - return -EFAULT; - } - vpu_write_dec_pp(regs_dec); - break; - } - - case VPU_IOC_WR_ENC: { - if (copy_from_user(regs_enc, (void __user *)arg, SIZE_REG(REG_NUM_ENC))) { - printk("VPU_IOC_WR_ENC copy_from_user failed\n"); - return -EFAULT; - } - vpu_write_enc(regs_enc); - break; - } - - case VPU_IOC_WR_PP: { - if (copy_from_user(regs_pp, (void __user *)arg, SIZE_REG(REG_NUM_PP))) { - printk("VPU_IOC_WR_PP copy_from_user failed\n"); - return -EFAULT; - } - vpu_write_pp(regs_pp); - break; - } - - - case VPU_IOC_RD_DEC: { - vpu_read_dec(regs_dec); - if (copy_to_user((void __user *)arg, regs_dec, SIZE_REG(REG_NUM_DEC))) { - printk("VPU_IOC_RD_DEC copy_to_user failed\n"); - return -EFAULT; - } - break; - } - - case VPU_IOC_RD_DEC_PP: { - vpu_read_dec_pp(regs_dec); - if (copy_to_user((void __user *)arg, regs_dec, SIZE_REG(REG_NUM_DEC_PP))) { - printk("VPU_IOC_RD_DEC_PP copy_to_user failed\n"); - return -EFAULT; - } - break; - } - - case VPU_IOC_RD_ENC: { - vpu_read_enc(regs_enc); - if (copy_to_user((void __user *)arg, regs_enc, SIZE_REG(REG_NUM_ENC))) { - printk("VPU_IOC_RD_ENC copy_to_user failed\n"); - return -EFAULT; - } - break; - } - - case VPU_IOC_RD_PP: { - vpu_read_pp(regs_pp); - if (copy_to_user((void __user *)arg, regs_pp, SIZE_REG(REG_NUM_PP))) { - printk("VPU_IOC_RD_PP copy_to_user failed\n"); - return -EFAULT; - } - break; - } - - - case VPU_IOC_CLS_IRQ: { - return vpu_clear_irqs(arg); - break; - } - - default: { - printk("undefined ioctl cmd\n"); - return -ENOTTY; - } - } - - return 0; -} - -static int vpu_open(struct inode *inode, struct file *filp) -{ - if (client.filp) { - printk("vpu is already opened\n"); - return -EBUSY; - } - - client.filp = filp; - vpu_power_on(); - - pr_debug("dev opened\n"); - return nonseekable_open(inode, filp); -} - -static int vpu_fasync(int fd, struct file *filp, int mode) -{ - return fasync_helper(fd, filp, mode, &client.async_queue); -} - -static int vpu_release(struct inode *inode, struct file *filp) -{ - msleep(50); - /* remove this filp from the asynchronusly notified filp's */ - vpu_fasync(-1, filp, 0); - - client.async_queue = NULL; - client.filp = NULL; - - vpu_power_off(); - - pr_debug("dev closed\n"); - return 0; -} - -static int vpu_check_hw_id(struct vpu_device * dev, const u16 *hwids, size_t num) -{ - u32 hwid = readl(dev->hwregs); - pr_info("HW ID = 0x%08x\n", hwid); - - hwid = (hwid >> 16) & 0xFFFF; /* product version only */ - - while (num--) { - if (hwid == hwids[num]) { - pr_info("Compatible HW found at 0x%08lx\n", dev->iobaseaddr); - return 1; - } - } - - pr_info("No Compatible HW found at 0x%08lx\n", dev->iobaseaddr); - return 0; -} - -static int vpu_reserve_io(void) -{ - if (!request_mem_region(dec_dev.iobaseaddr, dec_dev.iosize, "hx170dec")) { - pr_info("failed to reserve dec HW regs\n"); - return -EBUSY; - } - - dec_dev.hwregs = - (volatile u32 *)ioremap_nocache(dec_dev.iobaseaddr, dec_dev.iosize); - - if (dec_dev.hwregs == NULL) { - pr_info("failed to ioremap dec HW regs\n"); - goto err; - } - - /* check for correct HW */ - if (!vpu_check_hw_id(&dec_dev, dec_hw_ids, ARRAY_SIZE(dec_hw_ids))) { - goto err; - } - - if (!request_mem_region(enc_dev.iobaseaddr, enc_dev.iosize, "hx280enc")) { - pr_info("failed to reserve enc HW regs\n"); - goto err; - } - - enc_dev.hwregs = - (volatile u32 *)ioremap_nocache(enc_dev.iobaseaddr, enc_dev.iosize); - - if (enc_dev.hwregs == NULL) { - pr_info("failed to ioremap enc HW regs\n"); - goto err; - } - - /* check for correct HW */ - if (!vpu_check_hw_id(&enc_dev, enc_hw_ids, ARRAY_SIZE(enc_hw_ids))) { - goto err; - } - return 0; - -err: - vpu_release_io(); - return -EBUSY; -} - -static void vpu_release_io(void) -{ - if (dec_dev.hwregs) - iounmap((void *)dec_dev.hwregs); - release_mem_region(dec_dev.iobaseaddr, dec_dev.iosize); - - if (enc_dev.hwregs) - iounmap((void *)enc_dev.hwregs); - release_mem_region(enc_dev.iobaseaddr, enc_dev.iosize); -} - -static void vpu_event_notify(void) -{ - wake_up_interruptible(&client.wait); - if (client.async_queue) - kill_fasync(&client.async_queue, SIGIO, POLL_IN); -} - -static irqreturn_t hx170dec_isr(int irq, void *dev_id) -{ - struct vpu_device *dev = (struct vpu_device *) dev_id; - u32 irq_status_dec; - u32 irq_status_pp; - u32 event = VPU_IRQ_EVENT_DEC_BIT; - - pr_debug("dec_isr\n"); - - /* interrupt status register read */ - irq_status_dec = readl(dev->hwregs + DEC_INTERRUPT_REGISTER); - irq_status_pp = readl(dev->hwregs + PP_INTERRUPT_REGISTER); - - if (irq_status_dec & DEC_INTERRUPT_BIT) { - /* clear dec IRQ */ - writel(irq_status_dec & (~DEC_INTERRUPT_BIT), - dev->hwregs + DEC_INTERRUPT_REGISTER); - - event |= VPU_IRQ_EVENT_DEC_IRQ_BIT; - - pr_debug("DEC IRQ received!\n"); - } - - if (irq_status_pp & PP_INTERRUPT_BIT) { - /* clear pp IRQ */ - writel(irq_status_pp & (~DEC_INTERRUPT_BIT), - dev->hwregs + PP_INTERRUPT_REGISTER); - - event |= VPU_IRQ_EVENT_PP_IRQ_BIT; - - pr_debug("PP IRQ received!\n"); - } - - atomic_set(&client.dec_event, event); - vpu_event_notify(); - - return IRQ_HANDLED; -} - -static irqreturn_t hx280enc_isr(int irq, void *dev_id) -{ - struct vpu_device *dev = (struct vpu_device *) dev_id; - u32 irq_status; - u32 event = VPU_IRQ_EVENT_ENC_BIT; - - pr_debug("enc_isr\n"); - - irq_status = readl(dev->hwregs + ENC_INTERRUPT_REGISTER); - - if (likely(irq_status & ENC_INTERRUPT_BIT)) { - /* clear enc IRQ */ - writel(irq_status & (~ENC_INTERRUPT_BIT), - dev->hwregs + ENC_INTERRUPT_REGISTER); - - event |= VPU_IRQ_EVENT_ENC_IRQ_BIT; - - pr_debug("ENC IRQ received!\n"); - } - - atomic_set(&client.enc_event, event); - vpu_event_notify(); - - return IRQ_HANDLED; -} - -static int vpu_mmap(struct file *fp, struct vm_area_struct *vm) -{ - unsigned long pfn; - - /* Only support the simple cases where we map in a register page. */ - if (((vm->vm_end - vm->vm_start) > RK29_VCODEC_SIZE) || vm->vm_pgoff) - return -EINVAL; - - vm->vm_flags |= VM_IO | VM_RESERVED; - vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot); - pfn = RK29_VCODEC_PHYS >> PAGE_SHIFT; - pr_debug("size = 0x%x, page no. = 0x%x\n", - (int)(vm->vm_end - vm->vm_start), (int)pfn); - return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start, - vm->vm_page_prot) ? -EAGAIN : 0; -} - -static unsigned int vpu_poll(struct file *filep, poll_table *wait) -{ - poll_wait(filep, &client.wait, wait); - - if (atomic_read(&client.dec_event) || atomic_read(&client.enc_event)) - return POLLIN | POLLRDNORM; - return 0; -} - -static ssize_t vpu_read(struct file *filep, char __user *buf, - size_t count, loff_t *ppos) -{ - DECLARE_WAITQUEUE(wait, current); - ssize_t retval; - u32 irq_event; - - if (count != sizeof(u32)) - return -EINVAL; - - add_wait_queue(&client.wait, &wait); - - do { - set_current_state(TASK_INTERRUPTIBLE); - - irq_event = atomic_xchg(&client.dec_event, 0) | atomic_xchg(&client.enc_event, 0); - - if (irq_event) { - if (copy_to_user(buf, &irq_event, count)) - retval = -EFAULT; - else - retval = count; - break; - } - - if (filep->f_flags & O_NONBLOCK) { - retval = -EAGAIN; - break; - } - - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - schedule(); - } while (1); - - __set_current_state(TASK_RUNNING); - remove_wait_queue(&client.wait, &wait); - - return retval; -} - -static const struct file_operations vpu_fops = { - .read = vpu_read, - .poll = vpu_poll, - .unlocked_ioctl = vpu_ioctl, - .mmap = vpu_mmap, - .open = vpu_open, - .release = vpu_release, - .fasync = vpu_fasync, -}; - -static struct miscdevice vpu_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "vpu", - .fops = &vpu_fops, -}; - -static void vpu_shutdown(struct platform_device *pdev) -{ - pr_info("shutdown..."); - vpu_power_off(); - pr_cont("done\n"); -} - -static int vpu_suspend(struct platform_device *pdev, pm_message_t state) -{ - bool enabled = client.enabled; - mdelay(50); - 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, - }, - .shutdown = vpu_shutdown, - .suspend = vpu_suspend, - .resume = vpu_resume, -}; - -static int __init vpu_init(void) -{ - int ret; - - pr_debug("baseaddr = 0x%08x vdpu irq = %d vepu irq = %d\n", RK29_VCODEC_PHYS, IRQ_VDPU, IRQ_VEPU); - - dec_dev.iobaseaddr = RK29_VCODEC_PHYS + 0x200; - dec_dev.iosize = DEC_IO_SIZE; - dec_dev.irq = IRQ_VDPU; - - enc_dev.iobaseaddr = RK29_VCODEC_PHYS; - enc_dev.iosize = ENC_IO_SIZE; - enc_dev.irq = IRQ_VEPU; - - vpu_get_clk(); - vpu_power_on(); - - ret = vpu_reserve_io(); - if (ret < 0) { - goto err_reserve_io; - } - pp_dev = dec_dev; - - init_waitqueue_head(&client.wait); - atomic_set(&client.dec_event, 0); - atomic_set(&client.enc_event, 0); - - /* get the IRQ line */ - ret = request_irq(IRQ_VDPU, hx170dec_isr, 0, "hx170dec", (void *)&dec_dev); - if (ret != 0) { - pr_err("can't request vdpu irq %d\n", IRQ_VDPU); - goto err_req_vdpu_irq; - } - - ret = request_irq(IRQ_VEPU, hx280enc_isr, 0, "hx280enc", (void *)&enc_dev); - if (ret != 0) { - pr_err("can't request vepu irq %d\n", IRQ_VEPU); - goto err_req_vepu_irq; - } - - ret = misc_register(&vpu_misc_device); - if (ret) { - pr_err("misc_register failed\n"); - goto err_register; - } - - vpu_power_off(); - - platform_device_register(&vpu_pm_device); - platform_driver_probe(&vpu_pm_driver, NULL); - pr_info("init success\n"); - - memset(regs_enc, 0, sizeof(regs_enc)); - memset(regs_dec, 0, sizeof(regs_dec)); - - return 0; - -err_register: - free_irq(IRQ_VEPU, (void *)&enc_dev); -err_req_vepu_irq: - free_irq(IRQ_VDPU, (void *)&dec_dev); -err_req_vdpu_irq: - vpu_release_io(); -err_reserve_io: - vpu_power_off(); - vpu_put_clk(); - pr_info("init failed\n"); - return ret; -} - -static void __exit vpu_exit(void) -{ - platform_device_unregister(&vpu_pm_device); - platform_driver_unregister(&vpu_pm_driver); - - vpu_power_on(); - - misc_deregister(&vpu_misc_device); - free_irq(IRQ_VEPU, (void *)&enc_dev); - free_irq(IRQ_VDPU, (void *)&dec_dev); - vpu_release_io(); - - vpu_power_off(); - vpu_put_clk(); -} - -module_init(vpu_init); -module_exit(vpu_exit); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_PROC_FS -#include -#include - -static int proc_vpu_show(struct seq_file *s, void *v) -{ - unsigned int i, n; - s32 irq_event = atomic_read(&client.dec_event) | atomic_read(&client.enc_event); - - seq_printf(s, client.filp ? "Opened\n" : "Closed\n"); - seq_printf(s, "irq_event: 0x%08x (%s%s%s%s%s)\n", irq_event, - irq_event & VPU_IRQ_EVENT_DEC_BIT ? "DEC " : "", - irq_event & VPU_IRQ_EVENT_DEC_IRQ_BIT ? "DEC_IRQ " : "", - irq_event & VPU_IRQ_EVENT_PP_IRQ_BIT ? "PP_IRQ " : "", - irq_event & VPU_IRQ_EVENT_ENC_BIT ? "ENC " : "", - irq_event & VPU_IRQ_EVENT_ENC_IRQ_BIT ? "ENC_IRQ" : ""); - - vpu_power_on(); - seq_printf(s, "\nENC Registers:\n"); - n = enc_dev.iosize >> 2; - for (i = 0; i < n; i++) { - seq_printf(s, "\tswreg%d = %08X\n", i, readl(enc_dev.hwregs + i)); - } - seq_printf(s, "\nDEC Registers:\n"); - n = dec_dev.iosize >> 2; - for (i = 0; i < n; i++) { - seq_printf(s, "\tswreg%d = %08X\n", i, readl(dec_dev.hwregs + i)); - } - vpu_power_off(); - return 0; -} - -static int proc_vpu_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_vpu_show, NULL); -} - -static const struct file_operations proc_vpu_fops = { - .open = proc_vpu_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init vpu_proc_init(void) -{ - proc_create("vpu", 0, NULL, &proc_vpu_fops); - return 0; - -} -late_initcall(vpu_proc_init); -#endif /* CONFIG_PROC_FS */ - -- 2.34.1