From f443027fd05ad0aedb5e5d211de8f70825ede3a3 Mon Sep 17 00:00:00 2001 From: Sunyoung Kang Date: Tue, 26 Jun 2018 16:34:00 +0900 Subject: [PATCH] [COMMON] media: mfc: DRV4.0: delete mfc_inst Ths mfc_inst is similar to mfc_cmd, so it is merged to cmd. In this process, the following changes were made. < merge > - mfc_open_inst => mfc_cmd_open_inst - mfc_close_inst => mfc_cmd_close_inst < rename > - mfc_abort_inst => mfc_cmd_abort_inst - mfc_init_decode => mfc_cmd_init_decode - mfc_decode_one_frame => mfc_cmd_dec_one_frame - mfc_init_encode => mfc_cmd_init_encode - mfc_encode_one_frame => mfc_cmd_enc_one_frame < move > - mfc_h264_set_aso_slice_order => mfc_set_aso_slice_order_h264 in enc_param.c < add > - mfc_set_enc_params() in enc_param.c And unnecessary code in mfc_cmd has been removed. Change-Id: I638f02ff0100921f2e82c19ed1089538a6add0c1 Signed-off-by: Sunyoung Kang --- drivers/media/platform/exynos/mfc/Makefile | 2 +- drivers/media/platform/exynos/mfc/mfc.c | 1 - drivers/media/platform/exynos/mfc/mfc_cmd.c | 276 ++++++++++++-- drivers/media/platform/exynos/mfc/mfc_cmd.h | 10 + .../media/platform/exynos/mfc/mfc_enc_param.c | 48 +++ .../media/platform/exynos/mfc/mfc_enc_param.h | 9 +- .../media/platform/exynos/mfc/mfc_hwlock.c | 11 +- drivers/media/platform/exynos/mfc/mfc_inst.c | 359 ------------------ drivers/media/platform/exynos/mfc/mfc_inst.h | 28 -- drivers/media/platform/exynos/mfc/mfc_opr.c | 20 +- drivers/media/platform/exynos/mfc/mfc_otf.c | 5 +- 11 files changed, 317 insertions(+), 452 deletions(-) delete mode 100644 drivers/media/platform/exynos/mfc/mfc_inst.c delete mode 100644 drivers/media/platform/exynos/mfc/mfc_inst.h diff --git a/drivers/media/platform/exynos/mfc/Makefile b/drivers/media/platform/exynos/mfc/Makefile index 40c8cf76551e..d13d890ad488 100644 --- a/drivers/media/platform/exynos/mfc/Makefile +++ b/drivers/media/platform/exynos/mfc/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_VIDEO_EXYNOS_MFC) := exynos_mfc.o exynos_mfc-y += mfc.o mfc_isr.o mfc_dec_v4l2.o mfc_dec_vb2.o mfc_enc_v4l2.o mfc_enc_vb2.o exynos_mfc-y += mfc_ctrl.o mfc_hwlock.o mfc_nal_q.o mfc_watchdog.o mfc_opr.o mfc_sync.o -exynos_mfc-y += mfc_pm.o mfc_inst.o mfc_cmd.o mfc_hw_reg_api.o mfc_reg_api.o mfc_perf_measure.o +exynos_mfc-y += mfc_pm.o mfc_cmd.o mfc_hw_reg_api.o mfc_reg_api.o mfc_perf_measure.o exynos_mfc-y += mfc_dec_ctrl.o mfc_enc_ctrl.o mfc_enc_param.o exynos_mfc-y += mfc_queue.o mfc_buf.o mfc_utils.o mfc_qos.o mfc_mem.o exynos_mfc-y += mfc_debugfs.o mfc_otf.o diff --git a/drivers/media/platform/exynos/mfc/mfc.c b/drivers/media/platform/exynos/mfc/mfc.c index 8f5e8d3eedc3..9faf35048914 100644 --- a/drivers/media/platform/exynos/mfc/mfc.c +++ b/drivers/media/platform/exynos/mfc/mfc.c @@ -36,7 +36,6 @@ #include "mfc_opr.h" #include "mfc_sync.h" -#include "mfc_inst.h" #include "mfc_pm.h" #include "mfc_perf_measure.h" #include "mfc_reg_api.h" diff --git a/drivers/media/platform/exynos/mfc/mfc_cmd.c b/drivers/media/platform/exynos/mfc/mfc_cmd.c index bbbb4fb5bf4f..1591c1cddf45 100644 --- a/drivers/media/platform/exynos/mfc/mfc_cmd.c +++ b/drivers/media/platform/exynos/mfc/mfc_cmd.c @@ -14,8 +14,10 @@ #include "mfc_cmd.h" +#include "mfc_perf_measure.h" #include "mfc_reg_api.h" #include "mfc_hw_reg_api.h" +#include "mfc_enc_param.h" #include "mfc_mmcache.h" #include "mfc_utils.h" @@ -29,11 +31,6 @@ int mfc_cmd_sys_init(struct mfc_dev *dev, mfc_debug_enter(); - if (!dev) { - mfc_err_dev("no mfc device to run\n"); - return -EINVAL; - } - mfc_clean_dev_int_flags(dev); buf_size = dev->variant->buf_size->ctx_buf; @@ -75,17 +72,31 @@ void mfc_cmd_wakeup(struct mfc_dev *dev) /* Open a new instance and get its number */ int mfc_cmd_open_inst(struct mfc_ctx *ctx) { - struct mfc_dev *dev; + struct mfc_dev *dev = ctx->dev; + unsigned int reg; mfc_debug_enter(); - if (!ctx) { - mfc_err_dev("no mfc context to run\n"); - return -EINVAL; + /* Preparing decoding - getting instance number */ + mfc_debug(2, "Getting instance number\n"); + mfc_clean_ctx_int_flags(ctx); + + reg = MFC_READL(MFC_REG_CODEC_CONTROL); + /* Clear OTF_CONTROL[2:1] & OTF_DEBUG[3] */ + reg &= ~(0x7 << 1); + if (ctx->otf_handle) { + /* Set OTF_CONTROL[2:1], 0: Non-OTF, 1: OTF+HWFC, 2: OTF only */ + reg |= (0x1 << 1); + mfc_info_ctx("HWFC + OTF enabled\n"); + if (otf_dump && !ctx->is_drm) { + /* Set OTF_DEBUG[3] for OTF path dump */ + reg |= (0x1 << 3); + mfc_info_ctx("Debugging mode enabled\n"); + } } - dev = ctx->dev; - mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode); + MFC_WRITEL(reg, MFC_REG_CODEC_CONTROL); + mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode); MFC_WRITEL(ctx->codec_mode, MFC_REG_CODEC_TYPE); MFC_WRITEL(ctx->instance_ctx_buf.daddr, MFC_REG_CONTEXT_MEM_ADDR); MFC_WRITEL(ctx->instance_ctx_buf.size, MFC_REG_CONTEXT_MEM_SIZE); @@ -102,15 +113,17 @@ int mfc_cmd_open_inst(struct mfc_ctx *ctx) /* Close instance */ int mfc_cmd_close_inst(struct mfc_ctx *ctx) { - struct mfc_dev *dev; + struct mfc_dev *dev = ctx->dev; mfc_debug_enter(); - if (!ctx) { - mfc_err_dev("no mfc context to run\n"); + /* Closing decoding instance */ + mfc_debug(2, "Returning instance number\n"); + mfc_clean_ctx_int_flags(ctx); + if (ctx->state == MFCINST_FREE) { + mfc_err_ctx("ctx already free status\n"); return -EINVAL; } - dev = ctx->dev; MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); @@ -121,6 +134,18 @@ int mfc_cmd_close_inst(struct mfc_ctx *ctx) return 0; } +int mfc_cmd_abort_inst(struct mfc_ctx *ctx) +{ + struct mfc_dev *dev = ctx->dev; + + mfc_clean_ctx_int_flags(ctx); + + MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); + mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_NAL_ABORT); + + return 0; +} + int mfc_cmd_dpb_flush(struct mfc_ctx *ctx) { struct mfc_dev *dev = ctx->dev; @@ -138,11 +163,6 @@ int mfc_cmd_dpb_flush(struct mfc_ctx *ctx) int mfc_cmd_cache_flush(struct mfc_dev *dev) { - if (!dev) { - mfc_err_dev("no mfc device to run\n"); - return -EINVAL; - } - mfc_clean_dev_int_flags(dev); mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_CACHE_FLUSH); @@ -151,22 +171,11 @@ int mfc_cmd_cache_flush(struct mfc_dev *dev) int mfc_cmd_dec_init_buffers(struct mfc_ctx *ctx) { - struct mfc_dev *dev; - struct mfc_dec *dec; + struct mfc_dev *dev = ctx->dev; + struct mfc_dec *dec = ctx->dec_priv; unsigned int reg = 0, pix_val; int ret; - if (!ctx) { - mfc_err_dev("no mfc context to run\n"); - return -EINVAL; - } - dec = ctx->dec_priv; - dev = ctx->dev; - if (!dev) { - mfc_err_ctx("no mfc device to run\n"); - return -EINVAL; - } - switch (ctx->dst_fmt->fourcc) { case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV12N: @@ -238,15 +247,9 @@ int mfc_cmd_dec_init_buffers(struct mfc_ctx *ctx) int mfc_cmd_enc_init_buffers(struct mfc_ctx *ctx) { - struct mfc_dev *dev; + struct mfc_dev *dev = ctx->dev; int ret; - dev = ctx->dev; - if (!dev) { - mfc_err_dev("no mfc device to run\n"); - return -EINVAL; - } - /* * Header was generated now starting processing * First set the reference frame buffers @@ -290,3 +293,196 @@ int mfc_cmd_enc_init_buffers(struct mfc_ctx *ctx) return ret; } + +/* Initialize decoding */ +int mfc_cmd_init_decode(struct mfc_ctx *ctx) +{ + struct mfc_dev *dev = ctx->dev; + struct mfc_dec *dec = ctx->dec_priv; + unsigned int reg = 0; + int fmo_aso_ctrl = 0; + + mfc_debug_enter(); + + mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no, MFC_REG_H2R_CMD_SEQ_HEADER); + mfc_debug(2, "BUFs: %08x\n", MFC_READL(MFC_REG_D_CPB_BUFFER_ADDR)); + + /* + * When user sets desplay_delay to 0, + * It works as "display_delay enable" and delay set to 0. + * If user wants display_delay disable, It should be + * set to negative value. + */ + if (dec->display_delay >= 0) { + reg |= (0x1 << MFC_REG_D_DEC_OPT_DISPLAY_DELAY_EN_SHIFT); + MFC_WRITEL(dec->display_delay, MFC_REG_D_DISPLAY_DELAY); + } + + /* FMO_ASO_CTRL - 0: Enable, 1: Disable */ + reg |= ((fmo_aso_ctrl & MFC_REG_D_DEC_OPT_FMO_ASO_CTRL_MASK) + << MFC_REG_D_DEC_OPT_FMO_ASO_CTRL_SHIFT); + + reg |= ((dec->idr_decoding & MFC_REG_D_DEC_OPT_IDR_DECODING_MASK) + << MFC_REG_D_DEC_OPT_IDR_DECODING_SHIFT); + + /* VC1 RCV: Discard to parse additional header as default */ + if (IS_VC1_RCV_DEC(ctx)) + reg |= (0x1 << MFC_REG_D_DEC_OPT_DISCARD_RCV_HEADER_SHIFT); + + /* conceal control to specific color */ + reg |= (0x4 << MFC_REG_D_DEC_OPT_CONCEAL_CONTROL_SHIFT); + + /* Disable parallel processing if nal_q_parallel_disable was set */ + if (nal_q_parallel_disable) + reg |= (0x2 << MFC_REG_D_DEC_OPT_PARALLEL_DISABLE_SHIFT); + + /* Realloc buffer for resolution decrease case in NAL QUEUE mode */ + reg |= (0x1 << MFC_REG_D_DEC_OPT_REALLOC_CONTROL_SHIFT); + + /* Parsing all including PPS */ + reg |= (0x1 << MFC_REG_D_DEC_OPT_SPECIAL_PARSING_SHIFT); + + MFC_WRITEL(reg, MFC_REG_D_DEC_OPTIONS); + + MFC_WRITEL(MFC_CONCEAL_COLOR, MFC_REG_D_FORCE_PIXEL_VAL); + + if (IS_FIMV1_DEC(ctx)) { + mfc_debug(2, "Setting FIMV1 resolution to %dx%d\n", + ctx->img_width, ctx->img_height); + MFC_WRITEL(ctx->img_width, MFC_REG_D_SET_FRAME_WIDTH); + MFC_WRITEL(ctx->img_height, MFC_REG_D_SET_FRAME_HEIGHT); + } + + mfc_set_pixel_format(dev, ctx->dst_fmt->fourcc); + + reg = 0; + /* Enable realloc interface if SEI is enabled */ + if (dec->sei_parse) + reg |= (0x1 << MFC_REG_D_SEI_ENABLE_NEED_INIT_BUFFER_SHIFT); + if (MFC_FEATURE_SUPPORT(dev, dev->pdata->static_info_dec)) { + reg |= (0x1 << MFC_REG_D_SEI_ENABLE_CONTENT_LIGHT_SHIFT); + reg |= (0x1 << MFC_REG_D_SEI_ENABLE_MASTERING_DISPLAY_SHIFT); + } + reg |= (0x1 << MFC_REG_D_SEI_ENABLE_RECOVERY_PARSING_SHIFT); + + MFC_WRITEL(reg, MFC_REG_D_SEI_ENABLE); + mfc_debug(2, "SEI enable was set, 0x%x\n", MFC_READL(MFC_REG_D_SEI_ENABLE)); + + MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); + + if (sfr_dump & MFC_DUMP_DEC_SEQ_START) + call_dop(dev, dump_regs, dev); + + mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_SEQ_HEADER); + + mfc_debug_leave(); + return 0; +} + +/* Decode a single frame */ +int mfc_cmd_dec_one_frame(struct mfc_ctx *ctx, int last_frame) +{ + struct mfc_dev *dev = ctx->dev; + struct mfc_dec *dec = ctx->dec_priv; + u32 reg = 0; + + mfc_debug(2, "Dynamic:0x%08x, Available:0x%lx\n", + dec->dynamic_set, dec->available_dpb); + + reg = MFC_READL(MFC_REG_D_NAL_START_OPTIONS); + reg &= ~(0x1 << MFC_REG_D_NAL_START_OPT_BLACK_BAR_SHIFT); + reg |= ((dec->detect_black_bar & 0x1) << MFC_REG_D_NAL_START_OPT_BLACK_BAR_SHIFT); + MFC_WRITEL(reg, MFC_REG_D_NAL_START_OPTIONS); + mfc_debug(3, "[BLACKBAR] black bar detect set: %#x\n", reg); + + MFC_WRITEL(dec->dynamic_set, MFC_REG_D_DYNAMIC_DPB_FLAG_LOWER); + MFC_WRITEL(0x0, MFC_REG_D_DYNAMIC_DPB_FLAG_UPPER); + MFC_WRITEL(dec->available_dpb, MFC_REG_D_AVAILABLE_DPB_FLAG_LOWER); + MFC_WRITEL(0x0, MFC_REG_D_AVAILABLE_DPB_FLAG_UPPER); + MFC_WRITEL(dec->slice_enable, MFC_REG_D_SLICE_IF_ENABLE); + MFC_WRITEL(MFC_TIMEOUT_VALUE, MFC_REG_DEC_TIMEOUT_VALUE); + + MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); + + if ((sfr_dump & MFC_DUMP_DEC_NAL_START) && !ctx->check_dump) { + call_dop(dev, dump_regs, dev); + ctx->check_dump = 1; + } + + /* + * Issue different commands to instance basing on whether it + * is the last frame or not. + */ + switch (last_frame) { + case 0: + mfc_perf_measure_on(dev); + + mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_NAL_START); + break; + case 1: + mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_LAST_FRAME); + break; + } + + mfc_debug(2, "Decoding a usual frame\n"); + return 0; +} + +int mfc_cmd_init_encode(struct mfc_ctx *ctx) +{ + struct mfc_dev *dev = ctx->dev; + int ret; + + mfc_debug(2, "++\n"); + + ret = mfc_set_enc_params(ctx); + if (ret) { + mfc_debug(2, "fail to set enc params\n"); + return ret; + } + + MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); + + if (sfr_dump & MFC_DUMP_ENC_SEQ_START) + call_dop(dev, dump_regs, dev); + + mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_SEQ_HEADER); + + mfc_debug(2, "--\n"); + + return 0; +} + +/* Encode a single frame */ +int mfc_cmd_enc_one_frame(struct mfc_ctx *ctx, int last_frame) +{ + struct mfc_dev *dev = ctx->dev; + + mfc_debug(2, "++\n"); + + MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); + + if ((sfr_dump & MFC_DUMP_ENC_NAL_START) && !ctx->check_dump) { + call_dop(dev, dump_regs, dev); + ctx->check_dump = 1; + } + + /* + * Issue different commands to instance basing on whether it + * is the last frame or not. + */ + switch (last_frame) { + case 0: + mfc_perf_measure_on(dev); + + mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_NAL_START); + break; + case 1: + mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_LAST_FRAME); + break; + } + + mfc_debug(2, "--\n"); + + return 0; +} diff --git a/drivers/media/platform/exynos/mfc/mfc_cmd.h b/drivers/media/platform/exynos/mfc/mfc_cmd.h index 2f5b79584424..64407284a65f 100644 --- a/drivers/media/platform/exynos/mfc/mfc_cmd.h +++ b/drivers/media/platform/exynos/mfc/mfc_cmd.h @@ -19,11 +19,21 @@ int mfc_cmd_sys_init(struct mfc_dev *dev, enum mfc_buf_usage_type buf_type); void mfc_cmd_sleep(struct mfc_dev *dev); void mfc_cmd_wakeup(struct mfc_dev *dev); + int mfc_cmd_open_inst(struct mfc_ctx *ctx); int mfc_cmd_close_inst(struct mfc_ctx *ctx); +int mfc_cmd_abort_inst(struct mfc_ctx *ctx); + int mfc_cmd_dpb_flush(struct mfc_ctx *ctx); int mfc_cmd_cache_flush(struct mfc_dev *dev); + int mfc_cmd_dec_init_buffers(struct mfc_ctx *ctx); int mfc_cmd_enc_init_buffers(struct mfc_ctx *ctx); +int mfc_cmd_init_decode(struct mfc_ctx *ctx); +int mfc_cmd_dec_one_frame(struct mfc_ctx *ctx, int last_frame); + +int mfc_cmd_init_encode(struct mfc_ctx *ctx); +int mfc_cmd_enc_one_frame(struct mfc_ctx *ctx, int last_frame); + #endif /* __MFC_CMD_H */ diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_param.c b/drivers/media/platform/exynos/mfc/mfc_enc_param.c index d037643a5b53..275f5ec20711 100644 --- a/drivers/media/platform/exynos/mfc/mfc_enc_param.c +++ b/drivers/media/platform/exynos/mfc/mfc_enc_param.c @@ -48,6 +48,21 @@ void mfc_set_slice_mode(struct mfc_ctx *ctx) } } +void mfc_set_aso_slice_order_h264(struct mfc_ctx *ctx) +{ + struct mfc_dev *dev = ctx->dev; + struct mfc_enc *enc = ctx->enc_priv; + struct mfc_enc_params *p = &enc->params; + struct mfc_h264_enc_params *p_264 = &p->codec.h264; + int i; + + if (p_264->aso_enable) { + for (i = 0; i < 8; i++) + MFC_WRITEL(p_264->aso_slice_order[i], + MFC_REG_E_H264_ASO_SLICE_ORDER_0 + i * 4); + } +} + static void __mfc_set_gop_size(struct mfc_ctx *ctx, int ctrl_mode) { struct mfc_dev *dev = ctx->dev; @@ -1395,3 +1410,36 @@ void mfc_set_enc_params_bpg(struct mfc_ctx *ctx) } MFC_WRITEL(reg, MFC_REG_E_PICTURE_PROFILE); } + +int mfc_set_enc_params(struct mfc_ctx *ctx) +{ + struct mfc_dev *dev = ctx->dev; + + if (IS_H264_ENC(ctx)) + mfc_set_enc_params_h264(ctx); + else if (IS_MPEG4_ENC(ctx)) + mfc_set_enc_params_mpeg4(ctx); + else if (IS_H263_ENC(ctx)) + mfc_set_enc_params_h263(ctx); + else if (IS_VP8_ENC(ctx)) + mfc_set_enc_params_vp8(ctx); + else if (IS_VP9_ENC(ctx)) + mfc_set_enc_params_vp9(ctx); + else if (IS_HEVC_ENC(ctx)) + mfc_set_enc_params_hevc(ctx); + else if (IS_BPG_ENC(ctx)) + mfc_set_enc_params_bpg(ctx); + else { + mfc_err_ctx("Unknown codec for encoding (%x)\n", + ctx->codec_mode); + return -EINVAL; + } + + mfc_debug(5, "RC) Bitrate: %d / framerate: %#x / config %#x / mode %#x\n", + MFC_READL(MFC_REG_E_RC_BIT_RATE), + MFC_READL(MFC_REG_E_RC_FRAME_RATE), + MFC_READL(MFC_REG_E_RC_CONFIG), + MFC_READL(MFC_REG_E_RC_MODE)); + + return 0; +} diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_param.h b/drivers/media/platform/exynos/mfc/mfc_enc_param.h index 63fa5c896cfa..383c3a198c39 100644 --- a/drivers/media/platform/exynos/mfc/mfc_enc_param.h +++ b/drivers/media/platform/exynos/mfc/mfc_enc_param.h @@ -16,12 +16,7 @@ #include "mfc_common.h" void mfc_set_slice_mode(struct mfc_ctx *ctx); -void mfc_set_enc_params_h264(struct mfc_ctx *ctx); -void mfc_set_enc_params_mpeg4(struct mfc_ctx *ctx); -void mfc_set_enc_params_h263(struct mfc_ctx *ctx); -void mfc_set_enc_params_vp8(struct mfc_ctx *ctx); -void mfc_set_enc_params_vp9(struct mfc_ctx *ctx); -void mfc_set_enc_params_hevc(struct mfc_ctx *ctx); -void mfc_set_enc_params_bpg(struct mfc_ctx *ctx); +void mfc_set_aso_slice_order_h264(struct mfc_ctx *ctx); +int mfc_set_enc_params(struct mfc_ctx *ctx); #endif /* __MFC_ENC_PARAM_H */ diff --git a/drivers/media/platform/exynos/mfc/mfc_hwlock.c b/drivers/media/platform/exynos/mfc/mfc_hwlock.c index f67ba97070c0..4e5cfd548ade 100644 --- a/drivers/media/platform/exynos/mfc/mfc_hwlock.c +++ b/drivers/media/platform/exynos/mfc/mfc_hwlock.c @@ -17,7 +17,6 @@ #include "mfc_opr.h" #include "mfc_sync.h" -#include "mfc_inst.h" #include "mfc_pm.h" #include "mfc_cmd.h" #include "mfc_reg_api.h" @@ -735,10 +734,10 @@ static int __mfc_just_run_dec(struct mfc_ctx *ctx) ret = mfc_run_dec_frame(ctx); break; case MFCINST_INIT: - ret = mfc_open_inst(ctx); + ret = mfc_cmd_open_inst(ctx); break; case MFCINST_RETURN_INST: - ret = mfc_close_inst(ctx); + ret = mfc_cmd_close_inst(ctx); break; case MFCINST_GOT_INST: case MFCINST_SPECIAL_PARSING: @@ -792,10 +791,10 @@ static int __mfc_just_run_enc(struct mfc_ctx *ctx) ret = mfc_run_enc_frame(ctx); break; case MFCINST_INIT: - ret = mfc_open_inst(ctx); + ret = mfc_cmd_open_inst(ctx); break; case MFCINST_RETURN_INST: - ret = mfc_close_inst(ctx); + ret = mfc_cmd_close_inst(ctx); break; case MFCINST_GOT_INST: if (ctx->otf_handle) { @@ -808,7 +807,7 @@ static int __mfc_just_run_enc(struct mfc_ctx *ctx) ret = mfc_cmd_enc_init_buffers(ctx); break; case MFCINST_ABORT_INST: - ret = mfc_abort_inst(ctx); + ret = mfc_cmd_abort_inst(ctx); break; default: mfc_info_ctx("can't try command(encoder just_run), state : %d\n", ctx->state); diff --git a/drivers/media/platform/exynos/mfc/mfc_inst.c b/drivers/media/platform/exynos/mfc/mfc_inst.c deleted file mode 100644 index 2e37a49f7f3f..000000000000 --- a/drivers/media/platform/exynos/mfc/mfc_inst.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * drivers/media/platform/exynos/mfc/mfc_inst.c - * - * Copyright (c) 2016 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 "mfc_inst.h" - -#include "mfc_cmd.h" -#include "mfc_enc_param.h" -#include "mfc_perf_measure.h" -#include "mfc_reg_api.h" -#include "mfc_hw_reg_api.h" - -#include "mfc_utils.h" - -int mfc_open_inst(struct mfc_ctx *ctx) -{ - struct mfc_dev *dev = ctx->dev; - unsigned int reg; - int ret; - - /* Preparing decoding - getting instance number */ - mfc_debug(2, "Getting instance number\n"); - mfc_clean_ctx_int_flags(ctx); - - reg = MFC_READL(MFC_REG_CODEC_CONTROL); - /* Clear OTF_CONTROL[2:1] & OTF_DEBUG[3] */ - reg &= ~(0x7 << 1); - if (ctx->otf_handle) { - /* Set OTF_CONTROL[2:1], 0: Non-OTF, 1: OTF+HWFC, 2: OTF only */ - reg |= (0x1 << 1); - mfc_info_ctx("HWFC + OTF enabled\n"); - if (otf_dump && !ctx->is_drm) { - /* Set OTF_DEBUG[3] for OTF path dump */ - reg |= (0x1 << 3); - mfc_info_ctx("Debugging mode enabled\n"); - } - } - MFC_WRITEL(reg, MFC_REG_CODEC_CONTROL); - - - ret = mfc_cmd_open_inst(ctx); - if (ret) { - mfc_err_ctx("Failed to create a new instance\n"); - mfc_change_state(ctx, MFCINST_ERROR); - } - - return ret; -} - -int mfc_close_inst(struct mfc_ctx *ctx) -{ - int ret = -EINVAL; - - /* Closing decoding instance */ - mfc_debug(2, "Returning instance number\n"); - mfc_clean_ctx_int_flags(ctx); - if (ctx->state == MFCINST_FREE) { - mfc_err_ctx("ctx already free status\n"); - return ret; - } - - ret = mfc_cmd_close_inst(ctx); - if (ret) { - mfc_err_ctx("Failed to return an instance\n"); - mfc_change_state(ctx, MFCINST_ERROR); - } - - return ret; -} - -int mfc_abort_inst(struct mfc_ctx *ctx) -{ - struct mfc_dev *dev; - - if (!ctx) { - mfc_err_dev("no mfc context to run\n"); - return -EINVAL; - } - - dev = ctx->dev; - if (!dev) { - mfc_err_dev("no mfc device to run\n"); - return -EINVAL; - } - - mfc_clean_ctx_int_flags(ctx); - - MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); - mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_NAL_ABORT); - - return 0; -} - -/* Initialize decoding */ -int mfc_init_decode(struct mfc_ctx *ctx) -{ - struct mfc_dev *dev; - struct mfc_dec *dec; - unsigned int reg = 0; - int fmo_aso_ctrl = 0; - - mfc_debug_enter(); - if (!ctx) { - mfc_err_dev("no mfc context to run\n"); - return -EINVAL; - } - - dev = ctx->dev; - if (!dev) { - mfc_err_dev("no mfc device to run\n"); - return -EINVAL; - } - - dec = ctx->dec_priv; - if (!dec) { - mfc_err_dev("no mfc decoder to run\n"); - return -EINVAL; - } - mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no, MFC_REG_H2R_CMD_SEQ_HEADER); - mfc_debug(2, "BUFs: %08x\n", MFC_READL(MFC_REG_D_CPB_BUFFER_ADDR)); - - /* When user sets desplay_delay to 0, - * It works as "display_delay enable" and delay set to 0. - * If user wants display_delay disable, It should be - * set to negative value. */ - if (dec->display_delay >= 0) { - reg |= (0x1 << MFC_REG_D_DEC_OPT_DISPLAY_DELAY_EN_SHIFT); - MFC_WRITEL(dec->display_delay, MFC_REG_D_DISPLAY_DELAY); - } - - /* FMO_ASO_CTRL - 0: Enable, 1: Disable */ - reg |= ((fmo_aso_ctrl & MFC_REG_D_DEC_OPT_FMO_ASO_CTRL_MASK) - << MFC_REG_D_DEC_OPT_FMO_ASO_CTRL_SHIFT); - - reg |= ((dec->idr_decoding & MFC_REG_D_DEC_OPT_IDR_DECODING_MASK) - << MFC_REG_D_DEC_OPT_IDR_DECODING_SHIFT); - - /* VC1 RCV: Discard to parse additional header as default */ - if (IS_VC1_RCV_DEC(ctx)) - reg |= (0x1 << MFC_REG_D_DEC_OPT_DISCARD_RCV_HEADER_SHIFT); - - /* conceal control to specific color */ - reg |= (0x4 << MFC_REG_D_DEC_OPT_CONCEAL_CONTROL_SHIFT); - - /* Disable parallel processing if nal_q_parallel_disable was set */ - if (nal_q_parallel_disable) - reg |= (0x2 << MFC_REG_D_DEC_OPT_PARALLEL_DISABLE_SHIFT); - - /* Realloc buffer for resolution decrease case in NAL QUEUE mode */ - reg |= (0x1 << MFC_REG_D_DEC_OPT_REALLOC_CONTROL_SHIFT); - - /* Parsing all including PPS */ - reg |= (0x1 << MFC_REG_D_DEC_OPT_SPECIAL_PARSING_SHIFT); - - MFC_WRITEL(reg, MFC_REG_D_DEC_OPTIONS); - - MFC_WRITEL(MFC_CONCEAL_COLOR, MFC_REG_D_FORCE_PIXEL_VAL); - - if (IS_FIMV1_DEC(ctx)) { - mfc_debug(2, "Setting FIMV1 resolution to %dx%d\n", - ctx->img_width, ctx->img_height); - MFC_WRITEL(ctx->img_width, MFC_REG_D_SET_FRAME_WIDTH); - MFC_WRITEL(ctx->img_height, MFC_REG_D_SET_FRAME_HEIGHT); - } - - mfc_set_pixel_format(dev, ctx->dst_fmt->fourcc); - - reg = 0; - /* Enable realloc interface if SEI is enabled */ - if (dec->sei_parse) - reg |= (0x1 << MFC_REG_D_SEI_ENABLE_NEED_INIT_BUFFER_SHIFT); - if (MFC_FEATURE_SUPPORT(dev, dev->pdata->static_info_dec)) { - reg |= (0x1 << MFC_REG_D_SEI_ENABLE_CONTENT_LIGHT_SHIFT); - reg |= (0x1 << MFC_REG_D_SEI_ENABLE_MASTERING_DISPLAY_SHIFT); - } - reg |= (0x1 << MFC_REG_D_SEI_ENABLE_RECOVERY_PARSING_SHIFT); - - MFC_WRITEL(reg, MFC_REG_D_SEI_ENABLE); - mfc_debug(2, "SEI enable was set, 0x%x\n", MFC_READL(MFC_REG_D_SEI_ENABLE)); - - MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); - - if (sfr_dump & MFC_DUMP_DEC_SEQ_START) - call_dop(dev, dump_regs, dev); - - mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_SEQ_HEADER); - - mfc_debug_leave(); - return 0; -} - -/* Decode a single frame */ -int mfc_decode_one_frame(struct mfc_ctx *ctx, int last_frame) -{ - struct mfc_dev *dev; - struct mfc_dec *dec; - u32 reg = 0; - - if (!ctx) { - mfc_err_dev("no mfc context to run\n"); - return -EINVAL; - } - - dev = ctx->dev; - if (!dev) { - mfc_err_dev("no mfc device to run\n"); - return -EINVAL; - } - - dec = ctx->dec_priv; - if (!dec) { - mfc_err_dev("no mfc decoder to run\n"); - return -EINVAL; - } - - mfc_debug(2, "Dynamic:0x%08x, Available:0x%lx\n", - dec->dynamic_set, dec->available_dpb); - - reg = MFC_READL(MFC_REG_D_NAL_START_OPTIONS); - reg &= ~(0x1 << MFC_REG_D_NAL_START_OPT_BLACK_BAR_SHIFT); - reg |= ((dec->detect_black_bar & 0x1) << MFC_REG_D_NAL_START_OPT_BLACK_BAR_SHIFT); - MFC_WRITEL(reg, MFC_REG_D_NAL_START_OPTIONS); - mfc_debug(3, "[BLACKBAR] black bar detect set: %#x\n", reg); - - MFC_WRITEL(dec->dynamic_set, MFC_REG_D_DYNAMIC_DPB_FLAG_LOWER); - MFC_WRITEL(0x0, MFC_REG_D_DYNAMIC_DPB_FLAG_UPPER); - MFC_WRITEL(dec->available_dpb, MFC_REG_D_AVAILABLE_DPB_FLAG_LOWER); - MFC_WRITEL(0x0, MFC_REG_D_AVAILABLE_DPB_FLAG_UPPER); - MFC_WRITEL(dec->slice_enable, MFC_REG_D_SLICE_IF_ENABLE); - MFC_WRITEL(MFC_TIMEOUT_VALUE, MFC_REG_DEC_TIMEOUT_VALUE); - - MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); - - if ((sfr_dump & MFC_DUMP_DEC_NAL_START) && !ctx->check_dump) { - call_dop(dev, dump_regs, dev); - ctx->check_dump = 1; - } - - /* Issue different commands to instance basing on whether it - * is the last frame or not. */ - switch (last_frame) { - case 0: - mfc_perf_measure_on(dev); - - mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_NAL_START); - break; - case 1: - mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_LAST_FRAME); - break; - } - - mfc_debug(2, "Decoding a usual frame\n"); - return 0; -} - -int mfc_init_encode(struct mfc_ctx *ctx) -{ - struct mfc_dev *dev = ctx->dev; - - mfc_debug(2, "++\n"); - - if (IS_H264_ENC(ctx)) - mfc_set_enc_params_h264(ctx); - else if (IS_MPEG4_ENC(ctx)) - mfc_set_enc_params_mpeg4(ctx); - else if (IS_H263_ENC(ctx)) - mfc_set_enc_params_h263(ctx); - else if (IS_VP8_ENC(ctx)) - mfc_set_enc_params_vp8(ctx); - else if (IS_VP9_ENC(ctx)) - mfc_set_enc_params_vp9(ctx); - else if (IS_HEVC_ENC(ctx)) - mfc_set_enc_params_hevc(ctx); - else if (IS_BPG_ENC(ctx)) - mfc_set_enc_params_bpg(ctx); - else { - mfc_err_ctx("Unknown codec for encoding (%x)\n", - ctx->codec_mode); - return -EINVAL; - } - - mfc_debug(5, "RC) Bitrate: %d / framerate: %#x / config %#x / mode %#x\n", - MFC_READL(MFC_REG_E_RC_BIT_RATE), - MFC_READL(MFC_REG_E_RC_FRAME_RATE), - MFC_READL(MFC_REG_E_RC_CONFIG), - MFC_READL(MFC_REG_E_RC_MODE)); - - MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); - - if (sfr_dump & MFC_DUMP_ENC_SEQ_START) - call_dop(dev, dump_regs, dev); - - mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_SEQ_HEADER); - - mfc_debug(2, "--\n"); - - return 0; -} - -static int mfc_h264_set_aso_slice_order(struct mfc_ctx *ctx) -{ - struct mfc_dev *dev = ctx->dev; - struct mfc_enc *enc = ctx->enc_priv; - struct mfc_enc_params *p = &enc->params; - struct mfc_h264_enc_params *p_264 = &p->codec.h264; - int i; - - if (p_264->aso_enable) { - for (i = 0; i < 8; i++) - MFC_WRITEL(p_264->aso_slice_order[i], - MFC_REG_E_H264_ASO_SLICE_ORDER_0 + i * 4); - } - return 0; -} - -/* Encode a single frame */ -int mfc_encode_one_frame(struct mfc_ctx *ctx, int last_frame) -{ - struct mfc_dev *dev = ctx->dev; - - mfc_debug(2, "++\n"); - - if (IS_H264_ENC(ctx)) - mfc_h264_set_aso_slice_order(ctx); - - mfc_set_slice_mode(ctx); - - MFC_WRITEL(ctx->inst_no, MFC_REG_INSTANCE_ID); - - if ((sfr_dump & MFC_DUMP_ENC_NAL_START) && !ctx->check_dump) { - call_dop(dev, dump_regs, dev); - ctx->check_dump = 1; - } - - /* Issue different commands to instance basing on whether it - * is the last frame or not. */ - switch (last_frame) { - case 0: - mfc_perf_measure_on(dev); - - mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_NAL_START); - break; - case 1: - mfc_cmd_host2risc(dev, MFC_REG_H2R_CMD_LAST_FRAME); - break; - } - - mfc_debug(2, "--\n"); - - return 0; -} diff --git a/drivers/media/platform/exynos/mfc/mfc_inst.h b/drivers/media/platform/exynos/mfc/mfc_inst.h deleted file mode 100644 index 909b0d99af33..000000000000 --- a/drivers/media/platform/exynos/mfc/mfc_inst.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * drivers/media/platform/exynos/mfc/mfc_inst.h - * - * Copyright (c) 2016 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 __MFC_INST_H -#define __MFC_INST_H __FILE__ - -#include "mfc_common.h" - -int mfc_open_inst(struct mfc_ctx *ctx); -int mfc_close_inst(struct mfc_ctx *ctx); -int mfc_abort_inst(struct mfc_ctx *ctx); - -int mfc_init_decode(struct mfc_ctx *ctx); -int mfc_decode_one_frame(struct mfc_ctx *ctx, int last_frame); - -int mfc_init_encode(struct mfc_ctx *ctx); -int mfc_encode_one_frame(struct mfc_ctx *ctx, int last_frame); - -#endif /* __MFC_INST_H */ diff --git a/drivers/media/platform/exynos/mfc/mfc_opr.c b/drivers/media/platform/exynos/mfc/mfc_opr.c index 34bd0be0ff4e..67a03ab19bb3 100644 --- a/drivers/media/platform/exynos/mfc/mfc_opr.c +++ b/drivers/media/platform/exynos/mfc/mfc_opr.c @@ -12,8 +12,9 @@ #include "mfc_opr.h" -#include "mfc_inst.h" +#include "mfc_cmd.h" #include "mfc_reg_api.h" +#include "mfc_enc_param.h" #include "mfc_queue.h" #include "mfc_utils.h" @@ -64,7 +65,7 @@ int mfc_run_dec_init(struct mfc_ctx *ctx) mfc_debug(2, "Header addr: 0x%08llx\n", src_mb->addr[0][0]); mfc_clean_ctx_int_flags(ctx); - mfc_init_decode(ctx); + mfc_cmd_init_decode(ctx); return 0; } @@ -144,7 +145,7 @@ int mfc_run_dec_frame(struct mfc_ctx *ctx) mfc_clean_ctx_int_flags(ctx); last_frame = __mfc_check_last_frame(ctx, src_mb); - mfc_decode_one_frame(ctx, last_frame); + mfc_cmd_dec_one_frame(ctx, last_frame); return 0; } @@ -209,7 +210,7 @@ int mfc_run_dec_last_frames(struct mfc_ctx *ctx) mfc_set_dynamic_dpb(ctx, dst_mb); mfc_clean_ctx_int_flags(ctx); - mfc_decode_one_frame(ctx, 1); + mfc_cmd_dec_one_frame(ctx, 1); return 0; } @@ -238,7 +239,7 @@ int mfc_run_enc_init(struct mfc_ctx *ctx) mfc_debug(2, "Header addr: 0x%08llx\n", dst_mb->addr[0][0]); mfc_clean_ctx_int_flags(ctx); - ret = mfc_init_encode(ctx); + ret = mfc_cmd_init_encode(ctx); return ret; } @@ -299,7 +300,12 @@ int mfc_run_enc_frame(struct mfc_ctx *ctx) mfc_err_ctx("failed in set_buf_ctrls_val\n"); mfc_clean_ctx_int_flags(ctx); - mfc_encode_one_frame(ctx, last_frame); + + if (IS_H264_ENC(ctx)) + mfc_set_aso_slice_order_h264(ctx); + mfc_set_slice_mode(ctx); + + mfc_cmd_enc_one_frame(ctx, last_frame); return 0; } @@ -330,7 +336,7 @@ int mfc_run_enc_last_frames(struct mfc_ctx *ctx) mfc_set_enc_stream_buffer(ctx, dst_mb); mfc_clean_ctx_int_flags(ctx); - mfc_encode_one_frame(ctx, 1); + mfc_cmd_enc_one_frame(ctx, 1); return 0; } diff --git a/drivers/media/platform/exynos/mfc/mfc_otf.c b/drivers/media/platform/exynos/mfc/mfc_otf.c index 59b04c43adce..981d1c41535e 100644 --- a/drivers/media/platform/exynos/mfc/mfc_otf.c +++ b/drivers/media/platform/exynos/mfc/mfc_otf.c @@ -23,7 +23,6 @@ #include "mfc_sync.h" -#include "mfc_inst.h" #include "mfc_pm.h" #include "mfc_cmd.h" #include "mfc_reg_api.h" @@ -406,7 +405,7 @@ int mfc_otf_run_enc_init(struct mfc_ctx *ctx) mfc_set_enc_stride(ctx); mfc_clean_ctx_int_flags(ctx); - ret = mfc_init_encode(ctx); + ret = mfc_cmd_init_encode(ctx); mfc_debug_leave(); @@ -456,7 +455,7 @@ int mfc_otf_run_enc_frame(struct mfc_ctx *ctx) /* Set stream buffer size to handle buffer full */ mfc_clean_ctx_int_flags(ctx); - mfc_encode_one_frame(ctx, 0); + mfc_cmd_enc_one_frame(ctx, 0); mfc_debug_leave(); -- 2.20.1