aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Chen <jason.chen@linaro.org>2011-12-06 15:47:50 +0800
committerJason Chen <jason.chen@linaro.org>2011-12-06 15:47:50 +0800
commit38c4cd88cd12180dbee0e6e587e60846f44d0728 (patch)
treea9267fc65aa00ec71dc9892e6dce77a4468ba7c4
parente18312782b8183fc8109c4a8554291afee73ee63 (diff)
downloadlinux-linaro-38c4cd88cd12180dbee0e6e587e60846f44d0728.tar.gz
MXC VPU: merge to fsl 2.6.38 branch
to vpu commit c4c513c0f6d8ae7b77e05300a9496498c77fc767 Signed-off-by: Jason Chen <jason.chen@linaro.org>
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_vpu.h3
-rw-r--r--drivers/mxc/vpu/Kconfig2
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c68
3 files changed, 51 insertions, 22 deletions
diff --git a/arch/arm/plat-mxc/include/mach/mxc_vpu.h b/arch/arm/plat-mxc/include/mach/mxc_vpu.h
index 0f81fb9eb7d..dd162a22dfe 100644
--- a/arch/arm/plat-mxc/include/mach/mxc_vpu.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_vpu.h
@@ -55,11 +55,14 @@ struct vpu_mem_desc {
#define VPU_IOC_REQ_VSHARE_MEM _IO(VPU_IOC_MAGIC, 9)
#define VPU_IOC_SYS_SW_RESET _IO(VPU_IOC_MAGIC, 11)
#define VPU_IOC_GET_SHARE_MEM _IO(VPU_IOC_MAGIC, 12)
+#define VPU_IOC_QUERY_BITWORK_MEM _IO(VPU_IOC_MAGIC, 13)
+#define VPU_IOC_SET_BITWORK_MEM _IO(VPU_IOC_MAGIC, 14)
#define BIT_CODE_RUN 0x000
#define BIT_CODE_DOWN 0x004
#define BIT_INT_CLEAR 0x00C
#define BIT_INT_STATUS 0x010
+#define BIT_INT_REASON 0x174
#define MJPEG_PIC_STATUS_REG 0x3004
diff --git a/drivers/mxc/vpu/Kconfig b/drivers/mxc/vpu/Kconfig
index dada2040e2a..f712241fa85 100644
--- a/drivers/mxc/vpu/Kconfig
+++ b/drivers/mxc/vpu/Kconfig
@@ -6,7 +6,7 @@ menu "MXC VPU(Video Processing Unit) support"
config MXC_VPU
tristate "Support for MXC VPU(Video Processing Unit)"
- depends on (ARCH_MX3 || ARCH_MX27 || ARCH_MX37 || ARCH_MX5 || ARCH_MX6)
+ depends on (ARCH_MX3 || ARCH_MX27 || ARCH_MX37 || ARCH_MX5 || SOC_IMX6Q)
default y
---help---
The VPU codec device provides codec function for H.264/MPEG4/H.263,
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 957d0ba0f7f..c2d40bbfa1e 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -19,7 +19,6 @@
* @ingroup VPU
*/
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
@@ -28,6 +27,7 @@
#include <linux/platform_device.h>
#include <linux/kdev_t.h>
#include <linux/dma-mapping.h>
+#include <linux/iram_alloc.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/clk.h>
@@ -42,7 +42,6 @@
#include <asm/sizes.h>
#include <mach/clock.h>
#include <mach/hardware.h>
-#include <mach/iram.h>
#include <mach/mxc_vpu.h>
@@ -87,6 +86,7 @@ static struct mxc_vpu_platform_data *vpu_plat;
static struct iram_setting iram;
/* implement the blocking ioctl */
+static int irq_status;
static int codec_done;
static wait_queue_head_t vpu_queue;
@@ -212,14 +212,17 @@ static inline void vpu_worker_callback(struct work_struct *w)
if (dev->async_queue)
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
- codec_done = 1;
- wake_up_interruptible(&vpu_queue);
-
+ irq_status = 1;
/*
* Clock is gated on when dec/enc started, gate it off when
- * interrupt is received.
+ * codec is done.
*/
- clk_disable(vpu_clk);
+ if (codec_done) {
+ clk_disable(vpu_clk);
+ codec_done = 0;
+ }
+
+ wake_up_interruptible(&vpu_queue);
}
/*!
@@ -228,8 +231,11 @@ static inline void vpu_worker_callback(struct work_struct *w)
static irqreturn_t vpu_ipi_irq_handler(int irq, void *dev_id)
{
struct vpu_priv *dev = dev_id;
+ unsigned long reg;
- READ_REG(BIT_INT_STATUS);
+ reg = READ_REG(BIT_INT_REASON);
+ if (reg & 0x8)
+ codec_done = 1;
WRITE_REG(0x1, BIT_INT_CLEAR);
queue_work(dev->workqueue, &dev->work);
@@ -244,8 +250,11 @@ static irqreturn_t vpu_ipi_irq_handler(int irq, void *dev_id)
static irqreturn_t vpu_jpu_irq_handler(int irq, void *dev_id)
{
struct vpu_priv *dev = dev_id;
+ unsigned long reg;
- WRITE_REG(0, MJPEG_PIC_STATUS_REG);
+ reg = READ_REG(MJPEG_PIC_STATUS_REG);
+ if (reg & 0x3)
+ codec_done = 1;
queue_work(dev->workqueue, &dev->work);
@@ -352,7 +361,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
{
u_long timeout = (u_long) arg;
if (!wait_event_interruptible_timeout
- (vpu_queue, codec_done != 0,
+ (vpu_queue, irq_status != 0,
msecs_to_jiffies(timeout))) {
printk(KERN_WARNING "VPU blocking: timeout.\n");
ret = -ETIME;
@@ -361,7 +370,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
"VPU interrupt received.\n");
ret = -ERESTARTSYS;
} else
- codec_done = 0;
+ irq_status = 0;
break;
}
case VPU_IOC_IRAM_SETTING:
@@ -471,6 +480,26 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
}
break;
}
+ /*
+ * The following two ioctl is used when user allocates working buffer
+ * and register it to vpu driver.
+ */
+ case VPU_IOC_QUERY_BITWORK_MEM:
+ {
+ if (copy_to_user((void __user *)arg,
+ &bitwork_mem,
+ sizeof(struct vpu_mem_desc)))
+ ret = -EFAULT;
+ break;
+ }
+ case VPU_IOC_SET_BITWORK_MEM:
+ {
+ if (copy_from_user(&bitwork_mem,
+ (struct vpu_mem_desc *)arg,
+ sizeof(struct vpu_mem_desc)))
+ ret = -EFAULT;
+ break;
+ }
case VPU_IOC_SYS_SW_RESET:
{
if (vpu_plat->reset)
@@ -625,7 +654,7 @@ static int vpu_dev_probe(struct platform_device *pdev)
iram.end = addr + vpu_plat->iram_size - 1;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu_regs");
if (!res) {
printk(KERN_ERR "vpu: unable to get vpu base addr\n");
return -ENODEV;
@@ -659,30 +688,27 @@ static int vpu_dev_probe(struct platform_device *pdev)
goto err_out_class;
}
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
+ vpu_ipi_irq = platform_get_irq_byname(pdev, "vpu_ipi_irq");
+ if (vpu_ipi_irq < 0) {
printk(KERN_ERR "vpu: unable to get vpu interrupt\n");
err = -ENXIO;
goto err_out_class;
}
- vpu_ipi_irq = res->start;
-
err = request_irq(vpu_ipi_irq, vpu_ipi_irq_handler, 0, "VPU_CODEC_IRQ",
(void *)(&vpu_data));
if (err)
goto err_out_class;
#ifdef MXC_VPU_HAS_JPU
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
- if (!res) {
+ vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq");
+ if (vpu_jpu_irq < 0) {
printk(KERN_ERR "vpu: unable to get vpu jpu interrupt\n");
err = -ENXIO;
free_irq(vpu_ipi_irq, &vpu_data);
goto err_out_class;
}
- vpu_jpu_irq = res->start;
- err = request_irq(vpu_jpu_irq, vpu_jpu_irq_handler, 0, "VPU_JPG_IRQ",
- (void *)(&vpu_data));
+ err = request_irq(vpu_jpu_irq, vpu_jpu_irq_handler, IRQF_TRIGGER_RISING,
+ "VPU_JPG_IRQ", (void *)(&vpu_data));
if (err) {
free_irq(vpu_ipi_irq, &vpu_data);
goto err_out_class;