[media] s5p-mfc: Update MFC v4l2 driver to support MFC6.x
Multi Format Codec 6.x is a hardware video coding acceleration module present in new Exynos5 SoC series. It is capable of handling several new video codecs for decoding and encoding. Signed-off-by: Jeongtae Park <jtp.park@samsung.com> Signed-off-by: Janghyuck Kim <janghyuck.kim@samsung.com> Signed-off-by: Jaeryul Oh <jaeryul.oh@samsung.com> Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> Signed-off-by: Arun Kumar K <arun.kk@samsung.com> Acked-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
5b781e171e
commit
f96f3cfa0b
15 changed files with 2678 additions and 169 deletions
|
@ -165,12 +165,12 @@ config VIDEO_SAMSUNG_S5P_JPEG
|
|||
This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
|
||||
|
||||
config VIDEO_SAMSUNG_S5P_MFC
|
||||
tristate "Samsung S5P MFC 5.1 Video Codec"
|
||||
tristate "Samsung S5P MFC Video Codec"
|
||||
depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
|
||||
select VIDEOBUF2_DMA_CONTIG
|
||||
default n
|
||||
help
|
||||
MFC 5.1 driver for V4L2.
|
||||
MFC 5.1 and 6.x driver for V4L2
|
||||
|
||||
config VIDEO_MX2_EMMAPRP
|
||||
tristate "MX2 eMMa-PrP support"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
|
||||
s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr.o
|
||||
s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o
|
||||
s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
|
||||
s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd.o
|
||||
s5p-mfc-y += s5p_mfc_pm.o
|
||||
s5p-mfc-y += s5p_mfc_opr_v5.o s5p_mfc_cmd_v5.o
|
||||
s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o
|
||||
s5p-mfc-y += s5p_mfc_opr.o s5p_mfc_opr_v5.o s5p_mfc_opr_v6.o
|
||||
s5p-mfc-y += s5p_mfc_cmd.o s5p_mfc_cmd_v5.o s5p_mfc_cmd_v6.o
|
||||
|
|
|
@ -147,6 +147,7 @@
|
|||
#define S5P_FIMV_ENC_PROFILE_H264_MAIN 0
|
||||
#define S5P_FIMV_ENC_PROFILE_H264_HIGH 1
|
||||
#define S5P_FIMV_ENC_PROFILE_H264_BASELINE 2
|
||||
#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
|
||||
#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
|
||||
#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
|
||||
#define S5P_FIMV_ENC_PIC_STRUCT 0x083c /* picture field/frame flag */
|
||||
|
@ -216,6 +217,7 @@
|
|||
#define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK (3<<4)
|
||||
#define S5P_FIMV_DEC_STATUS_RESOLUTION_INC (1<<4)
|
||||
#define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC (2<<4)
|
||||
#define S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT 4
|
||||
|
||||
/* Decode frame address */
|
||||
#define S5P_FIMV_DECODE_Y_ADR 0x2024
|
||||
|
@ -380,6 +382,16 @@
|
|||
#define S5P_FIMV_R2H_CMD_EDFU_INIT_RET 16
|
||||
#define S5P_FIMV_R2H_CMD_ERR_RET 32
|
||||
|
||||
/* Dummy definition for MFCv6 compatibilty */
|
||||
#define S5P_FIMV_CODEC_H264_MVC_DEC -1
|
||||
#define S5P_FIMV_R2H_CMD_FIELD_DONE_RET -1
|
||||
#define S5P_FIMV_MFC_RESET -1
|
||||
#define S5P_FIMV_RISC_ON -1
|
||||
#define S5P_FIMV_RISC_BASE_ADDRESS -1
|
||||
#define S5P_FIMV_CODEC_VP8_DEC -1
|
||||
#define S5P_FIMV_REG_CLEAR_BEGIN 0
|
||||
#define S5P_FIMV_REG_CLEAR_COUNT 0
|
||||
|
||||
/* Error handling defines */
|
||||
#define S5P_FIMV_ERR_WARNINGS_START 145
|
||||
#define S5P_FIMV_ERR_DEC_MASK 0xFFFF
|
||||
|
@ -435,4 +447,13 @@
|
|||
#define MFC_VERSION 0x51
|
||||
#define MFC_NUM_PORTS 2
|
||||
|
||||
#define S5P_FIMV_SHARED_FRAME_PACK_SEI_AVAIL 0x16C
|
||||
#define S5P_FIMV_SHARED_FRAME_PACK_ARRGMENT_ID 0x170
|
||||
#define S5P_FIMV_SHARED_FRAME_PACK_SEI_INFO 0x174
|
||||
#define S5P_FIMV_SHARED_FRAME_PACK_GRID_POS 0x178
|
||||
|
||||
/* Values for resolution change in display status */
|
||||
#define S5P_FIMV_RES_INCREASE 1
|
||||
#define S5P_FIMV_RES_DECREASE 2
|
||||
|
||||
#endif /* _REGS_FIMV_H */
|
||||
|
|
|
@ -330,12 +330,14 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
|
|||
|
||||
dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
|
||||
& S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
|
||||
res_change = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
|
||||
& S5P_FIMV_DEC_STATUS_RESOLUTION_MASK;
|
||||
res_change = (s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
|
||||
& S5P_FIMV_DEC_STATUS_RESOLUTION_MASK)
|
||||
>> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT;
|
||||
mfc_debug(2, "Frame Status: %x\n", dst_frame_status);
|
||||
if (ctx->state == MFCINST_RES_CHANGE_INIT)
|
||||
ctx->state = MFCINST_RES_CHANGE_FLUSH;
|
||||
if (res_change) {
|
||||
if (res_change == S5P_FIMV_RES_INCREASE ||
|
||||
res_change == S5P_FIMV_RES_DECREASE) {
|
||||
ctx->state = MFCINST_RES_CHANGE_INIT;
|
||||
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
|
||||
wake_up_ctx(ctx, reason, err);
|
||||
|
@ -494,10 +496,28 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
|
|||
|
||||
ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count,
|
||||
dev);
|
||||
ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count,
|
||||
dev);
|
||||
if (ctx->img_width == 0 || ctx->img_height == 0)
|
||||
ctx->state = MFCINST_ERROR;
|
||||
else
|
||||
ctx->state = MFCINST_HEAD_PARSED;
|
||||
|
||||
if ((ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
|
||||
ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) &&
|
||||
!list_empty(&ctx->src_queue)) {
|
||||
struct s5p_mfc_buf *src_buf;
|
||||
src_buf = list_entry(ctx->src_queue.next,
|
||||
struct s5p_mfc_buf, list);
|
||||
if (s5p_mfc_hw_call(dev->mfc_ops, get_consumed_stream,
|
||||
dev) <
|
||||
src_buf->b->v4l2_planes[0].bytesused)
|
||||
ctx->head_processed = 0;
|
||||
else
|
||||
ctx->head_processed = 1;
|
||||
} else {
|
||||
ctx->head_processed = 1;
|
||||
}
|
||||
}
|
||||
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
|
||||
clear_work_bit(ctx);
|
||||
|
@ -526,7 +546,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
|
|||
clear_work_bit(ctx);
|
||||
if (err == 0) {
|
||||
ctx->state = MFCINST_RUNNING;
|
||||
if (!ctx->dpb_flush_flag) {
|
||||
if (!ctx->dpb_flush_flag && ctx->head_processed) {
|
||||
spin_lock_irqsave(&dev->irqlock, flags);
|
||||
if (!list_empty(&ctx->src_queue)) {
|
||||
src_buf = list_entry(ctx->src_queue.next,
|
||||
|
@ -1071,6 +1091,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
|
|||
ret = -ENODEV;
|
||||
goto err_res;
|
||||
}
|
||||
|
||||
dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r",
|
||||
match_child);
|
||||
if (!dev->mem_dev_r) {
|
||||
|
@ -1301,12 +1322,47 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = {
|
|||
.port_num = MFC_NUM_PORTS,
|
||||
.buf_size = &buf_size_v5,
|
||||
.buf_align = &mfc_buf_align_v5,
|
||||
.mclk_name = "sclk_mfc",
|
||||
.fw_name = "s5p-mfc.fw",
|
||||
};
|
||||
|
||||
struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
|
||||
.dev_ctx = MFC_CTX_BUF_SIZE_V6,
|
||||
.h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V6,
|
||||
.other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V6,
|
||||
.h264_enc_ctx = MFC_H264_ENC_CTX_BUF_SIZE_V6,
|
||||
.other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V6,
|
||||
};
|
||||
|
||||
struct s5p_mfc_buf_size buf_size_v6 = {
|
||||
.fw = MAX_FW_SIZE_V6,
|
||||
.cpb = MAX_CPB_SIZE_V6,
|
||||
.priv = &mfc_buf_size_v6,
|
||||
};
|
||||
|
||||
struct s5p_mfc_buf_align mfc_buf_align_v6 = {
|
||||
.base = 0,
|
||||
};
|
||||
|
||||
static struct s5p_mfc_variant mfc_drvdata_v6 = {
|
||||
.version = MFC_VERSION_V6,
|
||||
.port_num = MFC_NUM_PORTS_V6,
|
||||
.buf_size = &buf_size_v6,
|
||||
.buf_align = &mfc_buf_align_v6,
|
||||
.mclk_name = "aclk_333",
|
||||
.fw_name = "s5p-mfc-v6.fw",
|
||||
};
|
||||
|
||||
static struct platform_device_id mfc_driver_ids[] = {
|
||||
{
|
||||
.name = "s5p-mfc",
|
||||
.driver_data = (unsigned long)&mfc_drvdata_v5,
|
||||
}, {
|
||||
.name = "s5p-mfc-v5",
|
||||
.driver_data = (unsigned long)&mfc_drvdata_v5,
|
||||
}, {
|
||||
.name = "s5p-mfc-v6",
|
||||
.driver_data = (unsigned long)&mfc_drvdata_v6,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
|
|
@ -14,11 +14,16 @@
|
|||
#include "s5p_mfc_common.h"
|
||||
#include "s5p_mfc_debug.h"
|
||||
#include "s5p_mfc_cmd_v5.h"
|
||||
#include "s5p_mfc_cmd_v6.h"
|
||||
|
||||
static struct s5p_mfc_hw_cmds *s5p_mfc_cmds;
|
||||
|
||||
void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev)
|
||||
{
|
||||
s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v5();
|
||||
if (IS_MFCV6(dev))
|
||||
s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v6();
|
||||
else
|
||||
s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v5();
|
||||
|
||||
dev->mfc_cmds = s5p_mfc_cmds;
|
||||
}
|
||||
|
|
156
drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
Normal file
156
drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
|
||||
*
|
||||
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "s5p_mfc_common.h"
|
||||
|
||||
#include "s5p_mfc_cmd.h"
|
||||
#include "s5p_mfc_debug.h"
|
||||
#include "s5p_mfc_intr.h"
|
||||
#include "s5p_mfc_opr.h"
|
||||
|
||||
int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd,
|
||||
struct s5p_mfc_cmd_args *args)
|
||||
{
|
||||
mfc_debug(2, "Issue the command: %d\n", cmd);
|
||||
|
||||
/* Reset RISC2HOST command */
|
||||
mfc_write(dev, 0x0, S5P_FIMV_RISC2HOST_CMD_V6);
|
||||
|
||||
/* Issue the command */
|
||||
mfc_write(dev, cmd, S5P_FIMV_HOST2RISC_CMD_V6);
|
||||
mfc_write(dev, 0x1, S5P_FIMV_HOST2RISC_INT_V6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev)
|
||||
{
|
||||
struct s5p_mfc_cmd_args h2r_args;
|
||||
struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
|
||||
|
||||
s5p_mfc_hw_call(dev->mfc_ops, alloc_dev_context_buffer, dev);
|
||||
mfc_write(dev, dev->ctx_buf.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
|
||||
mfc_write(dev, buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
|
||||
return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SYS_INIT_V6,
|
||||
&h2r_args);
|
||||
}
|
||||
|
||||
int s5p_mfc_sleep_cmd_v6(struct s5p_mfc_dev *dev)
|
||||
{
|
||||
struct s5p_mfc_cmd_args h2r_args;
|
||||
|
||||
memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
|
||||
return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SLEEP_V6,
|
||||
&h2r_args);
|
||||
}
|
||||
|
||||
int s5p_mfc_wakeup_cmd_v6(struct s5p_mfc_dev *dev)
|
||||
{
|
||||
struct s5p_mfc_cmd_args h2r_args;
|
||||
|
||||
memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
|
||||
return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_WAKEUP_V6,
|
||||
&h2r_args);
|
||||
}
|
||||
|
||||
/* Open a new instance and get its number */
|
||||
int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
|
||||
{
|
||||
struct s5p_mfc_dev *dev = ctx->dev;
|
||||
struct s5p_mfc_cmd_args h2r_args;
|
||||
int codec_type;
|
||||
|
||||
mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode);
|
||||
dev->curr_ctx = ctx->num;
|
||||
switch (ctx->codec_mode) {
|
||||
case S5P_MFC_CODEC_H264_DEC:
|
||||
codec_type = S5P_FIMV_CODEC_H264_DEC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_H264_MVC_DEC:
|
||||
codec_type = S5P_FIMV_CODEC_H264_MVC_DEC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_VC1_DEC:
|
||||
codec_type = S5P_FIMV_CODEC_VC1_DEC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_MPEG4_DEC:
|
||||
codec_type = S5P_FIMV_CODEC_MPEG4_DEC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_MPEG2_DEC:
|
||||
codec_type = S5P_FIMV_CODEC_MPEG2_DEC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_H263_DEC:
|
||||
codec_type = S5P_FIMV_CODEC_H263_DEC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_VC1RCV_DEC:
|
||||
codec_type = S5P_FIMV_CODEC_VC1RCV_DEC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_VP8_DEC:
|
||||
codec_type = S5P_FIMV_CODEC_VP8_DEC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_H264_ENC:
|
||||
codec_type = S5P_FIMV_CODEC_H264_ENC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_H264_MVC_ENC:
|
||||
codec_type = S5P_FIMV_CODEC_H264_MVC_ENC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_MPEG4_ENC:
|
||||
codec_type = S5P_FIMV_CODEC_MPEG4_ENC_V6;
|
||||
break;
|
||||
case S5P_MFC_CODEC_H263_ENC:
|
||||
codec_type = S5P_FIMV_CODEC_H263_ENC_V6;
|
||||
break;
|
||||
default:
|
||||
codec_type = S5P_FIMV_CODEC_NONE_V6;
|
||||
};
|
||||
mfc_write(dev, codec_type, S5P_FIMV_CODEC_TYPE_V6);
|
||||
mfc_write(dev, ctx->ctx.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
|
||||
mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
|
||||
mfc_write(dev, 0, S5P_FIMV_D_CRC_CTRL_V6); /* no crc */
|
||||
|
||||
return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6,
|
||||
&h2r_args);
|
||||
}
|
||||
|
||||
/* Close instance */
|
||||
int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
|
||||
{
|
||||
struct s5p_mfc_dev *dev = ctx->dev;
|
||||
struct s5p_mfc_cmd_args h2r_args;
|
||||
int ret = 0;
|
||||
|
||||
dev->curr_ctx = ctx->num;
|
||||
if (ctx->state != MFCINST_FREE) {
|
||||
mfc_write(dev, ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
|
||||
ret = s5p_mfc_cmd_host2risc_v6(dev,
|
||||
S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6,
|
||||
&h2r_args);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize cmd function pointers for MFC v6 */
|
||||
static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = {
|
||||
.cmd_host2risc = s5p_mfc_cmd_host2risc_v6,
|
||||
.sys_init_cmd = s5p_mfc_sys_init_cmd_v6,
|
||||
.sleep_cmd = s5p_mfc_sleep_cmd_v6,
|
||||
.wakeup_cmd = s5p_mfc_wakeup_cmd_v6,
|
||||
.open_inst_cmd = s5p_mfc_open_inst_cmd_v6,
|
||||
.close_inst_cmd = s5p_mfc_close_inst_cmd_v6,
|
||||
};
|
||||
|
||||
struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void)
|
||||
{
|
||||
return &s5p_mfc_cmds_v6;
|
||||
}
|
20
drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
Normal file
20
drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef S5P_MFC_CMD_V6_H_
|
||||
#define S5P_MFC_CMD_V6_H_
|
||||
|
||||
#include "s5p_mfc_common.h"
|
||||
|
||||
struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void);
|
||||
|
||||
#endif /* S5P_MFC_CMD_H_ */
|
|
@ -16,13 +16,14 @@
|
|||
#ifndef S5P_MFC_COMMON_H_
|
||||
#define S5P_MFC_COMMON_H_
|
||||
|
||||
#include "regs-mfc.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 "regs-mfc.h"
|
||||
#include "regs-mfc-v6.h"
|
||||
|
||||
/* Definitions related to MFC memory */
|
||||
|
||||
|
@ -206,6 +207,14 @@ struct s5p_mfc_buf_size_v5 {
|
|||
unsigned int shm;
|
||||
};
|
||||
|
||||
struct s5p_mfc_buf_size_v6 {
|
||||
unsigned int dev_ctx;
|
||||
unsigned int h264_dec_ctx;
|
||||
unsigned int other_dec_ctx;
|
||||
unsigned int h264_enc_ctx;
|
||||
unsigned int other_enc_ctx;
|
||||
};
|
||||
|
||||
struct s5p_mfc_buf_size {
|
||||
unsigned int fw;
|
||||
unsigned int cpb;
|
||||
|
@ -221,6 +230,8 @@ struct s5p_mfc_variant {
|
|||
unsigned int port_num;
|
||||
struct s5p_mfc_buf_size *buf_size;
|
||||
struct s5p_mfc_buf_align *buf_align;
|
||||
char *mclk_name;
|
||||
char *fw_name;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -277,6 +288,7 @@ struct s5p_mfc_priv_buf {
|
|||
* @watchdog_work: worker for the watchdog
|
||||
* @alloc_ctx: videobuf2 allocator contexts for two memory banks
|
||||
* @enter_suspend: flag set when entering suspend
|
||||
* @ctx_buf: common context memory (MFCv6)
|
||||
* @warn_start: hardware error code from which warnings start
|
||||
* @mfc_ops: ops structure holding HW operation function pointers
|
||||
* @mfc_cmds: cmd structure holding HW commands function pointers
|
||||
|
@ -318,6 +330,7 @@ struct s5p_mfc_dev {
|
|||
void *alloc_ctx[2];
|
||||
unsigned long enter_suspend;
|
||||
|
||||
struct s5p_mfc_priv_buf ctx_buf;
|
||||
int warn_start;
|
||||
struct s5p_mfc_hw_ops *mfc_ops;
|
||||
struct s5p_mfc_hw_cmds *mfc_cmds;
|
||||
|
@ -354,6 +367,22 @@ struct s5p_mfc_h264_enc_params {
|
|||
int level;
|
||||
u16 cpb_size;
|
||||
int interlace;
|
||||
u8 hier_qp;
|
||||
u8 hier_qp_type;
|
||||
u8 hier_qp_layer;
|
||||
u8 hier_qp_layer_qp[7];
|
||||
u8 sei_frame_packing;
|
||||
u8 sei_fp_curr_frame_0;
|
||||
u8 sei_fp_arrangement_type;
|
||||
|
||||
u8 fmo;
|
||||
u8 fmo_map_type;
|
||||
u8 fmo_slice_grp;
|
||||
u8 fmo_chg_dir;
|
||||
u32 fmo_chg_rate;
|
||||
u32 fmo_run_len[4];
|
||||
u8 aso;
|
||||
u32 aso_slice_order[8];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -396,6 +425,7 @@ struct s5p_mfc_enc_params {
|
|||
u32 rc_bitrate;
|
||||
u16 rc_reaction_coeff;
|
||||
u16 vbv_size;
|
||||
u32 vbv_delay;
|
||||
|
||||
enum v4l2_mpeg_video_header_mode seq_hdr_mode;
|
||||
enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
|
||||
|
@ -461,6 +491,8 @@ struct s5p_mfc_codec_ops {
|
|||
* decoding buffer
|
||||
* @dpb_flush_flag: flag used to indicate that a DPB buffers are being
|
||||
* flushed
|
||||
* @head_processed: flag mentioning whether the header data is processed
|
||||
* completely or not
|
||||
* @bank1_buf: handle to memory allocated for temporary buffers from
|
||||
* memory bank 1
|
||||
* @bank1_phys: address of the temporary buffers from memory bank 1
|
||||
|
@ -485,14 +517,20 @@ struct s5p_mfc_codec_ops {
|
|||
* @display_delay_enable: display delay for H264 enable flag
|
||||
* @after_packed_pb: flag used to track buffer when stream is in
|
||||
* Packed PB format
|
||||
* @sei_fp_parse: enable/disable parsing of frame packing SEI information
|
||||
* @dpb_count: count of the DPB buffers required by MFC hw
|
||||
* @total_dpb_count: count of DPB buffers with additional buffers
|
||||
* requested by the application
|
||||
* @ctx: context buffer information
|
||||
* @dsc: descriptor buffer information
|
||||
* @shm: shared memory buffer information
|
||||
* @mv_count: number of MV buffers allocated for decoding
|
||||
* @enc_params: encoding parameters for MFC
|
||||
* @enc_dst_buf_size: size of the buffers for encoder output
|
||||
* @luma_dpb_size: dpb buffer size for luma
|
||||
* @chroma_dpb_size: dpb buffer size for chroma
|
||||
* @me_buffer_size: size of the motion estimation buffer
|
||||
* @tmv_buffer_size: size of temporal predictor motion vector buffer
|
||||
* @frame_type: used to force the type of the next encoded frame
|
||||
* @ref_queue: list of the reference buffers for encoding
|
||||
* @ref_queue_cnt: number of the buffers in the reference list
|
||||
|
@ -541,6 +579,7 @@ struct s5p_mfc_ctx {
|
|||
unsigned long consumed_stream;
|
||||
|
||||
unsigned int dpb_flush_flag;
|
||||
unsigned int head_processed;
|
||||
|
||||
/* Buffers */
|
||||
void *bank1_buf;
|
||||
|
@ -570,10 +609,11 @@ struct s5p_mfc_ctx {
|
|||
int display_delay;
|
||||
int display_delay_enable;
|
||||
int after_packed_pb;
|
||||
int sei_fp_parse;
|
||||
|
||||
int dpb_count;
|
||||
int total_dpb_count;
|
||||
|
||||
int mv_count;
|
||||
/* Buffers */
|
||||
struct s5p_mfc_priv_buf ctx;
|
||||
struct s5p_mfc_priv_buf dsc;
|
||||
|
@ -582,16 +622,28 @@ struct s5p_mfc_ctx {
|
|||
struct s5p_mfc_enc_params enc_params;
|
||||
|
||||
size_t enc_dst_buf_size;
|
||||
size_t luma_dpb_size;
|
||||
size_t chroma_dpb_size;
|
||||
size_t me_buffer_size;
|
||||
size_t tmv_buffer_size;
|
||||
|
||||
enum v4l2_mpeg_mfc51_video_force_frame_type force_frame_type;
|
||||
|
||||
struct list_head ref_queue;
|
||||
unsigned int ref_queue_cnt;
|
||||
|
||||
enum v4l2_mpeg_video_multi_slice_mode slice_mode;
|
||||
union {
|
||||
unsigned int mb;
|
||||
unsigned int bits;
|
||||
} slice_size;
|
||||
|
||||
struct s5p_mfc_codec_ops *c_ops;
|
||||
|
||||
struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
unsigned int frame_tag;
|
||||
size_t scratch_buf_size;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -637,4 +689,9 @@ void set_work_bit(struct s5p_mfc_ctx *ctx);
|
|||
void clear_work_bit_irqsave(struct s5p_mfc_ctx *ctx);
|
||||
void set_work_bit_irqsave(struct s5p_mfc_ctx *ctx);
|
||||
|
||||
#define HAS_PORTNUM(dev) (dev ? (dev->variant ? \
|
||||
(dev->variant->port_num ? 1 : 0) : 0) : 0)
|
||||
#define IS_TWOPORT(dev) (dev->variant->port_num == 2 ? 1 : 0)
|
||||
#define IS_MFCV6(dev) (dev->variant->version >= 0x60 ? 1 : 0)
|
||||
|
||||
#endif /* S5P_MFC_COMMON_H_ */
|
||||
|
|
|
@ -37,8 +37,9 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
|
|||
/* Firmare has to be present as a separate file or compiled
|
||||
* into kernel. */
|
||||
mfc_debug_enter();
|
||||
|
||||
err = request_firmware((const struct firmware **)&fw_blob,
|
||||
"s5p-mfc.fw", dev->v4l2_dev.dev);
|
||||
dev->variant->fw_name, dev->v4l2_dev.dev);
|
||||
if (err != 0) {
|
||||
mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
|
||||
return -EINVAL;
|
||||
|
@ -82,32 +83,37 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
|
|||
return -EIO;
|
||||
}
|
||||
dev->bank1 = s5p_mfc_bitproc_phys;
|
||||
b_base = vb2_dma_contig_memops.alloc(
|
||||
dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], 1 << MFC_BASE_ALIGN_ORDER);
|
||||
if (IS_ERR(b_base)) {
|
||||
vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
|
||||
s5p_mfc_bitproc_phys = 0;
|
||||
s5p_mfc_bitproc_buf = NULL;
|
||||
mfc_err("Allocating bank2 base failed\n");
|
||||
release_firmware(fw_blob);
|
||||
return -ENOMEM;
|
||||
if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
|
||||
b_base = vb2_dma_contig_memops.alloc(
|
||||
dev->alloc_ctx[MFC_BANK2_ALLOC_CTX],
|
||||
1 << MFC_BASE_ALIGN_ORDER);
|
||||
if (IS_ERR(b_base)) {
|
||||
vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
|
||||
s5p_mfc_bitproc_phys = 0;
|
||||
s5p_mfc_bitproc_buf = NULL;
|
||||
mfc_err("Allocating bank2 base failed\n");
|
||||
release_firmware(fw_blob);
|
||||
return -ENOMEM;
|
||||
}
|
||||
bank2_base_phys = s5p_mfc_mem_cookie(
|
||||
dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
|
||||
vb2_dma_contig_memops.put(b_base);
|
||||
if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
|
||||
mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
|
||||
vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
|
||||
s5p_mfc_bitproc_phys = 0;
|
||||
s5p_mfc_bitproc_buf = NULL;
|
||||
release_firmware(fw_blob);
|
||||
return -EIO;
|
||||
}
|
||||
/* Valid buffers passed to MFC encoder with LAST_FRAME command
|
||||
* should not have address of bank2 - MFC will treat it as a null frame.
|
||||
* To avoid such situation we set bank2 address below the pool address.
|
||||
*/
|
||||
dev->bank2 = bank2_base_phys - (1 << MFC_BASE_ALIGN_ORDER);
|
||||
} else {
|
||||
dev->bank2 = dev->bank1;
|
||||
}
|
||||
bank2_base_phys = s5p_mfc_mem_cookie(
|
||||
dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
|
||||
vb2_dma_contig_memops.put(b_base);
|
||||
if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
|
||||
mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
|
||||
vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
|
||||
s5p_mfc_bitproc_phys = 0;
|
||||
s5p_mfc_bitproc_buf = NULL;
|
||||
release_firmware(fw_blob);
|
||||
return -EIO;
|
||||
}
|
||||
/* Valid buffers passed to MFC encoder with LAST_FRAME command
|
||||
* should not have address of bank2 - MFC will treat it as a null frame.
|
||||
* To avoid such situation we set bank2 address below the pool address.
|
||||
*/
|
||||
dev->bank2 = bank2_base_phys - (1 << MFC_BASE_ALIGN_ORDER);
|
||||
memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
|
||||
wmb();
|
||||
release_firmware(fw_blob);
|
||||
|
@ -124,8 +130,9 @@ int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
|
|||
/* Firmare has to be present as a separate file or compiled
|
||||
* into kernel. */
|
||||
mfc_debug_enter();
|
||||
|
||||
err = request_firmware((const struct firmware **)&fw_blob,
|
||||
"s5p-mfc.fw", dev->v4l2_dev.dev);
|
||||
dev->variant->fw_name, dev->v4l2_dev.dev);
|
||||
if (err != 0) {
|
||||
mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
|
||||
return -EINVAL;
|
||||
|
@ -166,46 +173,81 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
|
|||
{
|
||||
unsigned int mc_status;
|
||||
unsigned long timeout;
|
||||
int i;
|
||||
|
||||
mfc_debug_enter();
|
||||
/* Stop procedure */
|
||||
/* reset RISC */
|
||||
mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
|
||||
/* All reset except for MC */
|
||||
mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
|
||||
mdelay(10);
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
|
||||
/* Check MC status */
|
||||
do {
|
||||
if (time_after(jiffies, timeout)) {
|
||||
mfc_err("Timeout while resetting MFC\n");
|
||||
return -EIO;
|
||||
}
|
||||
if (IS_MFCV6(dev)) {
|
||||
/* Reset IP */
|
||||
/* except RISC, reset */
|
||||
mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET_V6);
|
||||
/* reset release */
|
||||
mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET_V6);
|
||||
|
||||
mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
|
||||
/* Zero Initialization of MFC registers */
|
||||
mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
|
||||
mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6);
|
||||
mfc_write(dev, 0, S5P_FIMV_FW_VERSION_V6);
|
||||
|
||||
} while (mc_status & 0x3);
|
||||
for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++)
|
||||
mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
|
||||
|
||||
/* Reset */
|
||||
mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6);
|
||||
mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6);
|
||||
mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6);
|
||||
} else {
|
||||
/* Stop procedure */
|
||||
/* reset RISC */
|
||||
mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
|
||||
/* All reset except for MC */
|
||||
mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
|
||||
mdelay(10);
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
|
||||
/* Check MC status */
|
||||
do {
|
||||
if (time_after(jiffies, timeout)) {
|
||||
mfc_err("Timeout while resetting MFC\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
|
||||
|
||||
} while (mc_status & 0x3);
|
||||
|
||||
mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
|
||||
mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
|
||||
}
|
||||
|
||||
mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
|
||||
mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
|
||||
mfc_debug_leave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
|
||||
{
|
||||
mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
|
||||
mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
|
||||
mfc_debug(2, "Bank1: %08x, Bank2: %08x\n", dev->bank1, dev->bank2);
|
||||
if (IS_MFCV6(dev)) {
|
||||
mfc_write(dev, dev->bank1, S5P_FIMV_RISC_BASE_ADDRESS_V6);
|
||||
mfc_debug(2, "Base Address : %08x\n", dev->bank1);
|
||||
} else {
|
||||
mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
|
||||
mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
|
||||
mfc_debug(2, "Bank1: %08x, Bank2: %08x\n",
|
||||
dev->bank1, dev->bank2);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
|
||||
{
|
||||
mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
|
||||
mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
|
||||
mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
|
||||
mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
|
||||
if (IS_MFCV6(dev)) {
|
||||
/* Zero initialization should be done before RESET.
|
||||
* Nothing to do here. */
|
||||
} else {
|
||||
mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
|
||||
mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
|
||||
mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
|
||||
mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize hardware */
|
||||
|
@ -233,7 +275,10 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
|
|||
s5p_mfc_clear_cmds(dev);
|
||||
/* 3. Release reset signal to the RISC */
|
||||
s5p_mfc_clean_dev_int_flags(dev);
|
||||
mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
|
||||
if (IS_MFCV6(dev))
|
||||
mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
|
||||
else
|
||||
mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
|
||||
mfc_debug(2, "Will now wait for completion of firmware transfer\n");
|
||||
if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) {
|
||||
mfc_err("Failed to load firmware\n");
|
||||
|
@ -267,7 +312,11 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
|
|||
s5p_mfc_clock_off();
|
||||
return -EIO;
|
||||
}
|
||||
ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
|
||||
if (IS_MFCV6(dev))
|
||||
ver = mfc_read(dev, S5P_FIMV_FW_VERSION_V6);
|
||||
else
|
||||
ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
|
||||
|
||||
mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
|
||||
(ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
|
||||
s5p_mfc_clock_off();
|
||||
|
@ -342,7 +391,10 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
|
|||
return ret;
|
||||
}
|
||||
/* 4. Release reset signal to the RISC */
|
||||
mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
|
||||
if (IS_MFCV6(dev))
|
||||
mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
|
||||
else
|
||||
mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
|
||||
mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
|
||||
if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) {
|
||||
mfc_err("Failed to load firmware\n");
|
||||
|
|
|
@ -31,9 +31,16 @@
|
|||
#include "s5p_mfc_pm.h"
|
||||
|
||||
#define DEF_SRC_FMT_DEC V4L2_PIX_FMT_H264
|
||||
#define DEF_DST_FMT_DEC V4L2_PIX_FMT_NV12MT
|
||||
#define DEF_DST_FMT_DEC V4L2_PIX_FMT_NV12MT_16X16
|
||||
|
||||
static struct s5p_mfc_fmt formats[] = {
|
||||
{
|
||||
.name = "4:2:0 2 Planes 16x16 Tiles",
|
||||
.fourcc = V4L2_PIX_FMT_NV12MT_16X16,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
},
|
||||
{
|
||||
.name = "4:2:0 2 Planes 64x32 Tiles",
|
||||
.fourcc = V4L2_PIX_FMT_NV12MT,
|
||||
|
@ -42,67 +49,88 @@ static struct s5p_mfc_fmt formats[] = {
|
|||
.num_planes = 2,
|
||||
},
|
||||
{
|
||||
.name = "4:2:0 2 Planes",
|
||||
.fourcc = V4L2_PIX_FMT_NV12M,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
.name = "4:2:0 2 Planes Y/CbCr",
|
||||
.fourcc = V4L2_PIX_FMT_NV12M,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
},
|
||||
{
|
||||
.name = "H264 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H264,
|
||||
.codec_mode = S5P_MFC_CODEC_H264_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
.name = "4:2:0 2 Planes Y/CrCb",
|
||||
.fourcc = V4L2_PIX_FMT_NV21M,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
},
|
||||
{
|
||||
.name = "H263 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H263,
|
||||
.codec_mode = S5P_MFC_CODEC_H263_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
.name = "H264 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H264,
|
||||
.codec_mode = S5P_MFC_CODEC_H264_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "MPEG1 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_MPEG1,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
.name = "H264/MVC Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H264_MVC,
|
||||
.codec_mode = S5P_MFC_CODEC_H264_MVC_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "MPEG2 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_MPEG2,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
.name = "H263 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H263,
|
||||
.codec_mode = S5P_MFC_CODEC_H263_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "MPEG4 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_MPEG4,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
.name = "MPEG1 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_MPEG1,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "XviD Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_XVID,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
.name = "MPEG2 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_MPEG2,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "VC1 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
|
||||
.codec_mode = S5P_MFC_CODEC_VC1_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
.name = "MPEG4 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_MPEG4,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "VC1 RCV Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
|
||||
.codec_mode = S5P_MFC_CODEC_VC1RCV_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
.name = "XviD Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_XVID,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "VC1 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
|
||||
.codec_mode = S5P_MFC_CODEC_VC1_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "VC1 RCV Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
|
||||
.codec_mode = S5P_MFC_CODEC_VC1RCV_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "VP8 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_VP8,
|
||||
.codec_mode = S5P_MFC_CODEC_VP8_DEC,
|
||||
.type = MFC_FMT_DEC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -343,21 +371,36 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
|
|||
/* Try format */
|
||||
static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
|
||||
{
|
||||
struct s5p_mfc_dev *dev = video_drvdata(file);
|
||||
struct s5p_mfc_fmt *fmt;
|
||||
|
||||
if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
mfc_err("This node supports decoding only\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
fmt = find_format(f, MFC_FMT_DEC);
|
||||
if (!fmt) {
|
||||
mfc_err("Unsupported format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fmt->type != MFC_FMT_DEC) {
|
||||
mfc_err("\n");
|
||||
return -EINVAL;
|
||||
mfc_debug(2, "Type is %d\n", f->type);
|
||||
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
fmt = find_format(f, MFC_FMT_DEC);
|
||||
if (!fmt) {
|
||||
mfc_err("Unsupported format for source.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
|
||||
mfc_err("Not supported format.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
fmt = find_format(f, MFC_FMT_RAW);
|
||||
if (!fmt) {
|
||||
mfc_err("Unsupported format for destination.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
|
||||
mfc_err("Not supported format.\n");
|
||||
return -EINVAL;
|
||||
} else if (!IS_MFCV6(dev) &&
|
||||
(fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
|
||||
mfc_err("Not supported format.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -380,6 +423,27 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
|
|||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
fmt = find_format(f, MFC_FMT_RAW);
|
||||
if (!fmt) {
|
||||
mfc_err("Unsupported format for source.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!IS_MFCV6(dev) && (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
|
||||
mfc_err("Not supported format.\n");
|
||||
return -EINVAL;
|
||||
} else if (IS_MFCV6(dev) &&
|
||||
(fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
|
||||
mfc_err("Not supported format.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ctx->dst_fmt = fmt;
|
||||
mfc_debug_leave();
|
||||
return ret;
|
||||
} else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
mfc_err("Wrong type error for S_FMT : %d", f->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
fmt = find_format(f, MFC_FMT_DEC);
|
||||
if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) {
|
||||
mfc_err("Unknown codec\n");
|
||||
|
@ -392,6 +456,10 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
|
|||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
|
||||
mfc_err("Not supported format.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ctx->src_fmt = fmt;
|
||||
ctx->codec_mode = fmt->codec_mode;
|
||||
mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
|
||||
|
@ -756,6 +824,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
|
|||
void *allocators[])
|
||||
{
|
||||
struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
|
||||
struct s5p_mfc_dev *dev = ctx->dev;
|
||||
|
||||
/* Video output for decoding (source)
|
||||
* this can be set after getting an instance */
|
||||
|
@ -791,7 +860,13 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
|
|||
vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
psize[0] = ctx->luma_size;
|
||||
psize[1] = ctx->chroma_size;
|
||||
allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
|
||||
|
||||
if (IS_MFCV6(dev))
|
||||
allocators[0] =
|
||||
ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
|
||||
else
|
||||
allocators[0] =
|
||||
ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
|
||||
allocators[1] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
|
||||
} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
|
||||
ctx->state == MFCINST_INIT) {
|
||||
|
|
|
@ -36,39 +36,53 @@
|
|||
|
||||
static struct s5p_mfc_fmt formats[] = {
|
||||
{
|
||||
.name = "4:2:0 2 Planes 64x32 Tiles",
|
||||
.fourcc = V4L2_PIX_FMT_NV12MT,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
.name = "4:2:0 2 Planes 16x16 Tiles",
|
||||
.fourcc = V4L2_PIX_FMT_NV12MT_16X16,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
},
|
||||
{
|
||||
.name = "4:2:0 2 Planes",
|
||||
.fourcc = V4L2_PIX_FMT_NV12M,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
.name = "4:2:0 2 Planes 64x32 Tiles",
|
||||
.fourcc = V4L2_PIX_FMT_NV12MT,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
},
|
||||
{
|
||||
.name = "H264 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H264,
|
||||
.codec_mode = S5P_MFC_CODEC_H264_ENC,
|
||||
.type = MFC_FMT_ENC,
|
||||
.num_planes = 1,
|
||||
.name = "4:2:0 2 Planes Y/CbCr",
|
||||
.fourcc = V4L2_PIX_FMT_NV12M,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
},
|
||||
{
|
||||
.name = "MPEG4 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_MPEG4,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG4_ENC,
|
||||
.type = MFC_FMT_ENC,
|
||||
.num_planes = 1,
|
||||
.name = "4:2:0 2 Planes Y/CrCb",
|
||||
.fourcc = V4L2_PIX_FMT_NV21M,
|
||||
.codec_mode = S5P_MFC_CODEC_NONE,
|
||||
.type = MFC_FMT_RAW,
|
||||
.num_planes = 2,
|
||||
},
|
||||
{
|
||||
.name = "H263 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H263,
|
||||
.codec_mode = S5P_MFC_CODEC_H263_ENC,
|
||||
.type = MFC_FMT_ENC,
|
||||
.num_planes = 1,
|
||||
.name = "H264 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H264,
|
||||
.codec_mode = S5P_MFC_CODEC_H264_ENC,
|
||||
.type = MFC_FMT_ENC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "MPEG4 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_MPEG4,
|
||||
.codec_mode = S5P_MFC_CODEC_MPEG4_ENC,
|
||||
.type = MFC_FMT_ENC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
{
|
||||
.name = "H263 Encoded Stream",
|
||||
.fourcc = V4L2_PIX_FMT_H263,
|
||||
.codec_mode = S5P_MFC_CODEC_H263_ENC,
|
||||
.type = MFC_FMT_ENC,
|
||||
.num_planes = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -576,7 +590,8 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
|
|||
if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1)
|
||||
return 1;
|
||||
/* context is ready to encode a frame */
|
||||
if (ctx->state == MFCINST_RUNNING &&
|
||||
if ((ctx->state == MFCINST_RUNNING ||
|
||||
ctx->state == MFCINST_HEAD_PARSED) &&
|
||||
ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
|
||||
return 1;
|
||||
/* context is ready to encode remaining frames */
|
||||
|
@ -645,10 +660,19 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
|
|||
vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
|
||||
spin_unlock_irqrestore(&dev->irqlock, flags);
|
||||
}
|
||||
ctx->state = MFCINST_RUNNING;
|
||||
if (s5p_mfc_ctx_ready(ctx))
|
||||
set_work_bit_irqsave(ctx);
|
||||
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
|
||||
if (IS_MFCV6(dev)) {
|
||||
ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
|
||||
} else {
|
||||
ctx->state = MFCINST_RUNNING;
|
||||
if (s5p_mfc_ctx_ready(ctx))
|
||||
set_work_bit_irqsave(ctx);
|
||||
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
|
||||
}
|
||||
|
||||
if (IS_MFCV6(dev))
|
||||
ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops,
|
||||
get_enc_dpb_count, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -965,6 +989,17 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
|
|||
mfc_err("failed to set output format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IS_MFCV6(dev) &&
|
||||
(fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) {
|
||||
mfc_err("Not supported format.\n");
|
||||
return -EINVAL;
|
||||
} else if (IS_MFCV6(dev) &&
|
||||
(fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
|
||||
mfc_err("Not supported format.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fmt->num_planes != pix_fmt_mp->num_planes) {
|
||||
mfc_err("failed to set output format\n");
|
||||
ret = -EINVAL;
|
||||
|
@ -998,6 +1033,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
|
|||
static int vidioc_reqbufs(struct file *file, void *priv,
|
||||
struct v4l2_requestbuffers *reqbufs)
|
||||
{
|
||||
struct s5p_mfc_dev *dev = video_drvdata(file);
|
||||
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
|
||||
int ret = 0;
|
||||
|
||||
|
@ -1017,13 +1053,16 @@ static int vidioc_reqbufs(struct file *file, void *priv,
|
|||
return ret;
|
||||
}
|
||||
ctx->capture_state = QUEUE_BUFS_REQUESTED;
|
||||
ret = s5p_mfc_hw_call(ctx->dev->mfc_ops, alloc_codec_buffers,
|
||||
ctx);
|
||||
if (ret) {
|
||||
mfc_err("Failed to allocate encoding buffers\n");
|
||||
reqbufs->count = 0;
|
||||
ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
|
||||
return -ENOMEM;
|
||||
|
||||
if (!IS_MFCV6(dev)) {
|
||||
ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
|
||||
alloc_codec_buffers, ctx);
|
||||
if (ret) {
|
||||
mfc_err("Failed to allocate encoding buffers\n");
|
||||
reqbufs->count = 0;
|
||||
ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
} else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
if (ctx->output_state != QUEUE_FREE) {
|
||||
|
@ -1286,6 +1325,13 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
|
|||
p->codec.h264.profile =
|
||||
S5P_FIMV_ENC_PROFILE_H264_BASELINE;
|
||||
break;
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
|
||||
if (IS_MFCV6(dev))
|
||||
p->codec.h264.profile =
|
||||
S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
@ -1559,6 +1605,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
|
|||
unsigned int psize[], void *allocators[])
|
||||
{
|
||||
struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
|
||||
struct s5p_mfc_dev *dev = ctx->dev;
|
||||
|
||||
if (ctx->state != MFCINST_GOT_INST) {
|
||||
mfc_err("inavlid state: %d\n", ctx->state);
|
||||
|
@ -1587,8 +1634,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
|
|||
*buf_count = MFC_MAX_BUFFERS;
|
||||
psize[0] = ctx->luma_size;
|
||||
psize[1] = ctx->chroma_size;
|
||||
allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
|
||||
allocators[1] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
|
||||
if (IS_MFCV6(dev)) {
|
||||
allocators[0] =
|
||||
ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
|
||||
allocators[1] =
|
||||
ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
|
||||
} else {
|
||||
allocators[0] =
|
||||
ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
|
||||
allocators[1] =
|
||||
ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
|
||||
}
|
||||
} else {
|
||||
mfc_err("inavlid queue type: %d\n", vq->type);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -14,12 +14,18 @@
|
|||
|
||||
#include "s5p_mfc_opr.h"
|
||||
#include "s5p_mfc_opr_v5.h"
|
||||
#include "s5p_mfc_opr_v6.h"
|
||||
|
||||
static struct s5p_mfc_hw_ops *s5p_mfc_ops;
|
||||
|
||||
void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev)
|
||||
{
|
||||
s5p_mfc_ops = s5p_mfc_init_hw_ops_v5();
|
||||
dev->warn_start = S5P_FIMV_ERR_WARNINGS_START;
|
||||
if (IS_MFCV6(dev)) {
|
||||
s5p_mfc_ops = s5p_mfc_init_hw_ops_v6();
|
||||
dev->warn_start = S5P_FIMV_ERR_WARNINGS_START_V6;
|
||||
} else {
|
||||
s5p_mfc_ops = s5p_mfc_init_hw_ops_v5();
|
||||
dev->warn_start = S5P_FIMV_ERR_WARNINGS_START;
|
||||
}
|
||||
dev->mfc_ops = s5p_mfc_ops;
|
||||
}
|
||||
|
|
1956
drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
Normal file
1956
drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
Normal file
File diff suppressed because it is too large
Load diff
50
drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
Normal file
50
drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
|
||||
*
|
||||
* Header file for Samsung MFC (Multi Function Codec - FIMV) driver
|
||||
* Contains declarations of hw related functions.
|
||||
*
|
||||
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef S5P_MFC_OPR_V6_H_
|
||||
#define S5P_MFC_OPR_V6_H_
|
||||
|
||||
#include "s5p_mfc_common.h"
|
||||
#include "s5p_mfc_opr.h"
|
||||
|
||||
#define MFC_CTRL_MODE_CUSTOM MFC_CTRL_MODE_SFR
|
||||
|
||||
#define MB_WIDTH(x_size) DIV_ROUND_UP(x_size, 16)
|
||||
#define MB_HEIGHT(y_size) DIV_ROUND_UP(y_size, 16)
|
||||
#define S5P_MFC_DEC_MV_SIZE_V6(x, y) (MB_WIDTH(x) * \
|
||||
(((MB_HEIGHT(y)+1)/2)*2) * 64 + 128)
|
||||
|
||||
/* Definition */
|
||||
#define ENC_MULTI_SLICE_MB_MAX ((1 << 30) - 1)
|
||||
#define ENC_MULTI_SLICE_BIT_MIN 2800
|
||||
#define ENC_INTRA_REFRESH_MB_MAX ((1 << 18) - 1)
|
||||
#define ENC_VBV_BUF_SIZE_MAX ((1 << 30) - 1)
|
||||
#define ENC_H264_LOOP_FILTER_AB_MIN -12
|
||||
#define ENC_H264_LOOP_FILTER_AB_MAX 12
|
||||
#define ENC_H264_RC_FRAME_RATE_MAX ((1 << 16) - 1)
|
||||
#define ENC_H263_RC_FRAME_RATE_MAX ((1 << 16) - 1)
|
||||
#define ENC_H264_PROFILE_MAX 3
|
||||
#define ENC_H264_LEVEL_MAX 42
|
||||
#define ENC_MPEG4_VOP_TIME_RES_MAX ((1 << 16) - 1)
|
||||
#define FRAME_DELTA_H264_H263 1
|
||||
#define TIGHT_CBR_MAX 10
|
||||
|
||||
/* Definitions for shared memory compatibility */
|
||||
#define PIC_TIME_TOP_V6 S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6
|
||||
#define PIC_TIME_BOT_V6 S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6
|
||||
#define CROP_INFO_H_V6 S5P_FIMV_D_DISPLAY_CROP_INFO1_V6
|
||||
#define CROP_INFO_V_V6 S5P_FIMV_D_DISPLAY_CROP_INFO2_V6
|
||||
|
||||
struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void);
|
||||
#endif /* S5P_MFC_OPR_V6_H_ */
|
|
@ -20,7 +20,6 @@
|
|||
#include "s5p_mfc_debug.h"
|
||||
#include "s5p_mfc_pm.h"
|
||||
|
||||
#define MFC_CLKNAME "sclk_mfc"
|
||||
#define MFC_GATE_CLK_NAME "mfc"
|
||||
|
||||
#define CLK_DEBUG
|
||||
|
@ -51,7 +50,7 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
|
|||
goto err_p_ip_clk;
|
||||
}
|
||||
|
||||
pm->clock = clk_get(&dev->plat_dev->dev, MFC_CLKNAME);
|
||||
pm->clock = clk_get(&dev->plat_dev->dev, dev->variant->mclk_name);
|
||||
if (IS_ERR(pm->clock)) {
|
||||
mfc_err("Failed to get MFC clock\n");
|
||||
ret = PTR_ERR(pm->clock);
|
||||
|
|
Loading…
Reference in a new issue