Signed-off-by: Andrew-CT Chen <andrew-ct.chen@xxxxxxxxxxxx>
diff --git a/drivers/media/platform/mtk-vcodec/Kconfig b/drivers/media/platform/mtk-vcodec/Kconfig
new file mode 100644
index 0000000..1c0b935
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/Kconfig
@@ -0,0 +1,5 @@
+config MEDIATEK_VPU
+ bool
+ ---help---
+ This driver provides downloading firmware vpu (video processor unit)
+ and communicating with vpu.
diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
new file mode 100644
index 0000000..c7f7174
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -0,0 +1,12 @@
+obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk_vcodec_intr.o \
+ mtk_vcodec_util.o \
+ mtk_vcodec_enc_drv.o \
+ mtk_vcodec_enc.o \
+ mtk_vcodec_enc_pm.o
+
+obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += common/
+
+ccflags-y += -I$(srctree)/drivers/media/platform/mtk-vcodec/include \
+ -I$(srctree)/drivers/media/platform/mtk-vcodec \
+ -I$(srctree)/drivers/media/platform/mtk-vpu
diff --git a/drivers/media/platform/mtk-vcodec/common/Makefile b/drivers/media/platform/mtk-vcodec/common/Makefile
new file mode 100644
index 0000000..477ab80
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/common/Makefile
@@ -0,0 +1,8 @@
+obj-y += \
+ venc_drv_if.o
+
+ccflags-y += \
+ -I$(srctree)/include/ \
+ -I$(srctree)/drivers/media/platform/mtk-vcodec \
+ -I$(srctree)/drivers/media/platform/mtk-vcodec/include \
+ -I$(srctree)/drivers/media/platform/mtk-vpu
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
new file mode 100644
index 0000000..22239f8
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -0,0 +1,441 @@
+/*
+* Copyright (c) 2015 MediaTek Inc.
+* Author: PC Chen <pc.chen@xxxxxxxxxxxx>
+* Tiffany Lin <tiffany.lin@xxxxxxxxxxxx>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* 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.
+*/
+
+#ifndef _MTK_VCODEC_DRV_H_
+#define _MTK_VCODEC_DRV_H_
+
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "venc_drv_if.h"
+
+#define MTK_VCODEC_MAX_INSTANCES 32
+#define MTK_VCODEC_MAX_FRAME_SIZE 0x800000
+#define MTK_VIDEO_MAX_FRAME 32
+#define MTK_MAX_CTRLS 10
+
+#define MTK_VCODEC_DRV_NAME "mtk_vcodec_drv"
+#define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc"
+
+#define MTK_VENC_IRQ_STATUS_SPS 0x1
+#define MTK_VENC_IRQ_STATUS_PPS 0x2
+#define MTK_VENC_IRQ_STATUS_FRM 0x4
+#define MTK_VENC_IRQ_STATUS_DRAM 0x8
+#define MTK_VENC_IRQ_STATUS_PAUSE 0x10
+#define MTK_VENC_IRQ_STATUS_SWITCH 0x20
+#define MTK_VENC_IRQ_STATUS_OFFSET 0x05C
+#define MTK_VENC_IRQ_ACK_OFFSET 0x060
+
+#define MTK_VCODEC_MAX_PLANES 3
+
+#define VDEC_HW_ACTIVE 0x10
+#define VDEC_IRQ_CFG 0x11
+#define VDEC_IRQ_CLR 0x10
+
+#define VDEC_IRQ_CFG_REG 0xa4
+#define NUM_MAX_ALLOC_CTX 4
+#define MTK_V4L2_BENCHMARK 0
+#define USE_ENCODE_THREAD 1
+
+/**
+ * enum mtk_hw_reg_idx - MTK hw register base index
+ */
+enum mtk_hw_reg_idx {
+ VDEC_SYS,
+ VDEC_MISC,
+ VDEC_LD,
+ VDEC_TOP,
+ VDEC_CM,
+ VDEC_AD,
+ VDEC_AV,
+ VDEC_PP,
+ VDEC_HWD,
+ VDEC_HWQ,
+ VDEC_HWB,
+ VDEC_HWG,
+ NUM_MAX_VDEC_REG_BASE,
+ VENC_SYS = NUM_MAX_VDEC_REG_BASE,
+ VENC_LT_SYS,
+ NUM_MAX_VCODEC_REG_BASE
+};
+
+/**
+ * enum mtk_instance_type - The type of an MTK Vcodec instance.
+ */
+enum mtk_instance_type {
+ MTK_INST_DECODER = 0,
+ MTK_INST_ENCODER = 1,
+};
+
+/**
+ * enum mtk_instance_state - The state of an MTK Vcodec instance.
+ * @MTK_STATE_FREE - default state when instance create
+ * @MTK_STATE_CREATE - vdec instance is create
+ * @MTK_STATE_INIT - vdec instance is init
+ * @MTK_STATE_CONFIG - reserved for encoder
+ * @MTK_STATE_HEADER - vdec had sps/pps header parsed
+ * @MTK_STATE_RUNNING - vdec is decoding
+ * @MTK_STATE_FLUSH - vdec is flushing
+ * @MTK_STATE_RES_CHANGE - vdec detect resolution change
+ * @MTK_STATE_FINISH - ctx instance is stopped streaming
+ * @MTK_STATE_DEINIT - before release ctx instance
+ * @MTK_STATE_ERROR - vdec has something wrong
+ * @MTK_STATE_ABORT - abort work in working thread
+ */
+enum mtk_instance_state {
+ MTK_STATE_FREE = 0,
+ MTK_STATE_CREATE = (1 << 0),
+ MTK_STATE_INIT = (1 << 1),
+ MTK_STATE_CONFIG = (1 << 2),
+ MTK_STATE_HEADER = (1 << 3),
+ MTK_STATE_RUNNING = (1 << 4),
+ MTK_STATE_FLUSH = (1 << 5),
+ MTK_STATE_RES_CHANGE = (1 << 6),
+ MTK_STATE_FINISH = (1 << 7),
+ MTK_STATE_DEINIT = (1 << 8),
+ MTK_STATE_ERROR = (1 << 9),
+ MTK_STATE_ABORT = (1 << 10),
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
new file mode 100644
index 0000000..8e1b6f0
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -0,0 +1,1773 @@
[...]
+static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
+ struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
+ int ret;
+#if MTK_V4L2_BENCHMARK
+ struct timeval begin, end;
+
+ do_gettimeofday(&begin);
+#endif
+
+ if (!(vb2_start_streaming_called(&ctx->m2m_ctx->out_q_ctx.q) &
+ vb2_start_streaming_called(&ctx->m2m_ctx->cap_q_ctx.q))) {
+ mtk_v4l2_debug(1, "[%d]-> out=%d cap=%d",
+ ctx->idx,
+ vb2_start_streaming_called(&ctx->m2m_ctx->out_q_ctx.q),
+ vb2_start_streaming_called(&ctx->m2m_ctx->cap_q_ctx.q));
+ return 0;
+ }
+
+ if ((ctx->state & (MTK_STATE_ERROR | MTK_STATE_ABORT)))
+ return -EINVAL;
+
+ if (ctx->state == MTK_STATE_FREE) {
+ ret = venc_if_create(ctx,
+ ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc,
+ &ctx->h_enc);
+
+ if (ret != 0) {
+ ctx->state |= MTK_STATE_ERROR;
+ v4l2_err(v4l2_dev, "invalid codec type=%x\n",
+ ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc);
+ v4l2_err(v4l2_dev, "venc_if_create failed=%d\n", ret);
+ return -EINVAL;
+ }
+
+ if (ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc ==
+ V4L2_PIX_FMT_H264)
+ ctx->hdr = 1;
+
+ ctx->state |= MTK_STATE_CREATE;
+ }
+
+ if ((ctx->state & MTK_STATE_CREATE) && !(ctx->state & MTK_STATE_INIT)) {
+ ret = venc_if_init(ctx->h_enc);
+ if (ret != 0) {
+ ctx->state |= MTK_STATE_ERROR;
+ v4l2_err(v4l2_dev, "venc_if_init failed=%d\n", ret);
+ return -EINVAL;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h> +
new file mode 100644
index 0000000..a8e683a
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2015 MediaTek Inc.
+* Author: PC Chen <pc.chen@xxxxxxxxxxxx>
+* Tiffany Lin <tiffany.lin@xxxxxxxxxxxx>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* 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.
+*/
+
+#ifndef _MTK_VCODEC_UTIL_H_
+#define _MTK_VCODEC_UTIL_H_
+
+#include <linux/types.h>
+#include <linux/dma-direction.h>
+
+struct mtk_vcodec_mem {
+ size_t size;
+ void *va;
+ dma_addr_t dma_addr;
+};
+
+extern int mtk_v4l2_dbg_level;
+extern bool mtk_vcodec_dbg;
+
+#define mtk_v4l2_debug(level, fmt, args...) \
+ do { \
+ if (mtk_v4l2_dbg_level >= level) \
+ pr_info("[MTK_V4L2] level=%d %s(),%d: " fmt "\n",\
+ level, __func__, __LINE__, ##args); \
+ } while (0)
+#define mtk_v4l2_err(fmt, args...) \
+ pr_err("[MTK_V4L2][ERROR] %s:%d: " fmt "\n", __func__, __LINE__, \
+ ##args)
+#define mtk_v4l2_debug_enter() mtk_v4l2_debug(5, "+\n")
+#define mtk_v4l2_debug_leave() mtk_v4l2_debug(5, "-\n")
+#define mtk_vcodec_debug(h, fmt, args...) \
+ do { \
+ if (mtk_vcodec_dbg) \
+ pr_info("[MTK_VCODEC][%d]: %s() " fmt "\n", \
+ ((struct mtk_vcodec_ctx *)h->ctx)->idx, \
+ __func__, ##args); \
+ } while (0)
+
+#define mtk_vcodec_err(h, fmt, args...) \
+ pr_err("[MTK_VCODEC][ERROR][%d]: %s() " fmt "\n", \
+ ((struct mtk_vcodec_ctx *)h->ctx)->idx, __func__, ##args)
+
+#define mtk_vcodec_debug_enter(h) mtk_vcodec_debug(h, "+\n")
+#define mtk_vcodec_debug_leave(h) mtk_vcodec_debug(h, "-\n")