The mfc_opr and mfc_ctrl perform a similar function to operate HW.
This merges the both together and changes the name to mfc_run.
- apply "mfc_run" prefix to function name in mfc_run
- move hwlock code in sleep/wakeup function to caller
- remove unnecessary code
Change-Id: I23320d6c454c353de30e9c761b3f581e20d28a7b
Signed-off-by: Sunyoung Kang <sy0816.kang@samsung.com>
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_hwlock.o mfc_nal_q.o mfc_watchdog.o mfc_run.o mfc_sync.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
#include "mfc_dec_v4l2.h"
#include "mfc_enc_v4l2.h"
-#include "mfc_ctrl.h"
+#include "mfc_run.h"
#include "mfc_hwlock.h"
#include "mfc_nal_q.h"
#include "mfc_otf.h"
#include "mfc_watchdog.h"
#include "mfc_debugfs.h"
-#include "mfc_opr.h"
#include "mfc_sync.h"
#include "mfc_pm.h"
dev->preempt_ctx = MFC_NO_INSTANCE_SET;
dev->curr_ctx_is_drm = ctx->is_drm;
- ret = mfc_init_hw(dev);
+ ret = mfc_run_init_hw(dev);
if (ret) {
mfc_err_ctx("Failed to init mfc h/w\n");
goto err_hw_init;
dev->num_inst--;
if (dev->num_inst == 0) {
- mfc_deinit_hw(dev);
+ mfc_run_deinit_hw(dev);
if (perf_boost_mode)
mfc_perf_boost_disable(dev);
mfc_destroy_listable_wq_dev(dev);
iovmm_deactivate(&pdev->dev);
mfc_debug(2, "Will now deinit HW\n");
- mfc_deinit_hw(dev);
+ mfc_run_deinit_hw(dev);
free_irq(dev->irq, dev);
if (dev->has_mmcache)
iounmap(dev->mmcache.base);
}
#ifdef CONFIG_PM_SLEEP
-static int mfc_suspend(struct device *dev)
+static int mfc_suspend(struct device *device)
{
- struct mfc_dev *m_dev = platform_get_drvdata(to_platform_device(dev));
+ struct mfc_dev *dev = platform_get_drvdata(to_platform_device(device));
int ret;
- if (!m_dev) {
+ if (!dev) {
mfc_err_dev("no mfc device to run\n");
return -EINVAL;
}
- if (m_dev->num_inst == 0)
+ if (dev->num_inst == 0)
return 0;
- ret = mfc_sleep(m_dev);
+ MFC_TRACE_DEV_HWLOCK("**sleep\n");
+ ret = mfc_get_hwlock_dev(dev);
+ if (ret < 0) {
+ mfc_err_dev("Failed to get hwlock\n");
+ mfc_err_dev("dev:0x%lx, bits:0x%lx, owned:%d, wl:%d, trans:%d\n",
+ dev->hwlock.dev, dev->hwlock.bits, dev->hwlock.owned_by_irq,
+ dev->hwlock.wl_count, dev->hwlock.transfer_owner);
+ return -EBUSY;
+ }
+
+ ret = mfc_run_sleep(dev);
+ if (ret == 0)
+ mfc_release_hwlock_dev(dev);
return ret;
}
-static int mfc_resume(struct device *dev)
+static int mfc_resume(struct device *device)
{
- struct mfc_dev *m_dev = platform_get_drvdata(to_platform_device(dev));
+ struct mfc_dev *dev = platform_get_drvdata(to_platform_device(device));
int ret;
- if (!m_dev) {
+ if (!dev) {
mfc_err_dev("no mfc device to run\n");
return -EINVAL;
}
- if (m_dev->num_inst == 0)
+ if (dev->num_inst == 0)
return 0;
- ret = mfc_wakeup(m_dev);
+ MFC_TRACE_DEV_HWLOCK("**wakeup\n");
+ ret = mfc_get_hwlock_dev(dev);
+ if (ret < 0) {
+ mfc_err_dev("Failed to get hwlock\n");
+ mfc_err_dev("dev:0x%lx, bits:0x%lx, owned:%d, wl:%d, trans:%d\n",
+ dev->hwlock.dev, dev->hwlock.bits, dev->hwlock.owned_by_irq,
+ dev->hwlock.wl_count, dev->hwlock.transfer_owner);
+ return -EBUSY;
+ }
+
+ ret = mfc_run_wakeup(dev);
+ if (ret == 0)
+ mfc_release_hwlock_dev(dev);
return ret;
}
+++ /dev/null
-/*
- * drivers/media/platform/exynos/mfc/mfc_ctrl.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_ctrl.h"
-
-#include "mfc_hwlock.h"
-#include "mfc_nal_q.h"
-#include "mfc_sync.h"
-
-#include "mfc_pm.h"
-#include "mfc_cmd.h"
-#include "mfc_reg_api.h"
-#include "mfc_hw_reg_api.h"
-
-#include "mfc_utils.h"
-
-/* Initialize hardware */
-static int __mfc_init_hw(struct mfc_dev *dev, enum mfc_buf_usage_type buf_type)
-{
- int fw_ver;
- int ret = 0;
- int curr_ctx_is_drm_backup;
-
- mfc_debug_enter();
-
- if (!dev) {
- mfc_err_dev("no mfc device to run\n");
- return -EINVAL;
- }
-
- curr_ctx_is_drm_backup = dev->curr_ctx_is_drm;
-
- if (!dev->fw_buf.dma_buf)
- return -EINVAL;
-
- /* 0. MFC reset */
- mfc_debug(2, "MFC reset...\n");
-
- /* At init time, do not call secure API */
- if (buf_type == MFCBUF_NORMAL)
- dev->curr_ctx_is_drm = 0;
- else if (buf_type == MFCBUF_DRM)
- dev->curr_ctx_is_drm = 1;
-
- ret = mfc_pm_clock_on(dev);
- if (ret) {
- mfc_err_dev("Failed to enable clock before reset(%d)\n", ret);
- dev->curr_ctx_is_drm = curr_ctx_is_drm_backup;
- return ret;
- }
-
- ret = mfc_reset_mfc(dev);
- if (ret) {
- mfc_err_dev("Failed to reset MFC - timeout\n");
- goto err_init_hw;
- }
- mfc_debug(2, "Done MFC reset...\n");
-
- /* 1. Set DRAM base Addr */
- mfc_set_risc_base_addr(dev, buf_type);
-
- /* 2. Release reset signal to the RISC */
- mfc_risc_on(dev);
-
- mfc_debug(2, "Will now wait for completion of firmware transfer\n");
- if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_FW_STATUS_RET)) {
- mfc_err_dev("Failed to RISC_ON\n");
- mfc_clean_dev_int_flags(dev);
- ret = -EIO;
- goto err_init_hw;
- }
-
- /* 3. Initialize firmware */
- ret = mfc_cmd_sys_init(dev, buf_type);
- if (ret) {
- mfc_err_dev("Failed to send command to MFC - timeout\n");
- goto err_init_hw;
- }
-
- mfc_debug(2, "Ok, now will write a command to init the system\n");
- if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_SYS_INIT_RET)) {
- mfc_err_dev("Failed to SYS_INIT\n");
- mfc_clean_dev_int_flags(dev);
- ret = -EIO;
- goto err_init_hw;
- }
-
- dev->int_condition = 0;
- if (dev->int_err != 0 || dev->int_reason != MFC_REG_R2H_CMD_SYS_INIT_RET) {
- /* Failure. */
- mfc_err_dev("Failed to init firmware - error: %d, int: %d\n",
- dev->int_err, dev->int_reason);
- ret = -EIO;
- goto err_init_hw;
- }
-
- dev->fw.fimv_info = mfc_get_fimv_info();
- if (dev->fw.fimv_info != 'D' && dev->fw.fimv_info != 'E')
- dev->fw.fimv_info = 'N';
-
- mfc_info_dev("[F/W] MFC v%x.%x, %02xyy %02xmm %02xdd (%c)\n",
- MFC_VER_MAJOR(dev),
- MFC_VER_MINOR(dev),
- mfc_get_fw_ver_year(),
- mfc_get_fw_ver_month(),
- mfc_get_fw_ver_date(),
- dev->fw.fimv_info);
-
- dev->fw.date = mfc_get_fw_ver_all();
- /* Check MFC version and F/W version */
- fw_ver = mfc_get_mfc_version();
- if (fw_ver != dev->pdata->ip_ver) {
- mfc_err_dev("Invalid F/W version(0x%x) for MFC H/W(0x%x)\n",
- fw_ver, dev->pdata->ip_ver);
- ret = -EIO;
- goto err_init_hw;
- }
-
-#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
- /* Cache flush for base address change */
- mfc_cmd_cache_flush(dev);
- if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_CACHE_FLUSH_RET)) {
- mfc_err_dev("Failed to CACHE_FLUSH\n");
- mfc_clean_dev_int_flags(dev);
- ret = -EIO;
- goto err_init_hw;
- }
-
- if (buf_type == MFCBUF_DRM && !curr_ctx_is_drm_backup) {
- mfc_pm_clock_off(dev);
- dev->curr_ctx_is_drm = curr_ctx_is_drm_backup;
- mfc_pm_clock_on_with_base(dev, MFCBUF_NORMAL);
- }
-#endif
-
-err_init_hw:
- mfc_pm_clock_off(dev);
- dev->curr_ctx_is_drm = curr_ctx_is_drm_backup;
- mfc_debug_leave();
-
- return ret;
-}
-
-/* Wrapper : Initialize hardware */
-int mfc_init_hw(struct mfc_dev *dev)
-{
- int ret;
-
- ret = __mfc_init_hw(dev, MFCBUF_NORMAL);
- if (ret)
- return ret;
-
-#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
- if (dev->fw.drm_status) {
- ret = __mfc_init_hw(dev, MFCBUF_DRM);
- if (ret)
- return ret;
- }
-#endif
-
- return ret;
-}
-
-/* Deinitialize hardware */
-void mfc_deinit_hw(struct mfc_dev *dev)
-{
- int ret;
-
- mfc_debug(2, "mfc deinit start\n");
-
- if (!dev) {
- mfc_err_dev("no mfc device to run\n");
- return;
- }
-
- ret = mfc_pm_clock_on(dev);
- if (ret) {
- mfc_err_dev("Failed to enable clock before reset(%d)\n", ret);
- return;
- }
-
- mfc_mfc_off(dev);
-
- mfc_pm_clock_off(dev);
-
- mfc_debug(2, "mfc deinit completed\n");
-}
-
-int mfc_sleep(struct mfc_dev *dev)
-{
- struct mfc_ctx *ctx;
- int ret;
- int old_state, i;
- int need_cache_flush = 0;
-
- mfc_debug_enter();
-
- if (!dev) {
- mfc_err_dev("no mfc device to run\n");
- return -EINVAL;
- }
-
- ctx = dev->ctx[dev->curr_ctx];
- if (!ctx) {
- for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
- if (dev->ctx[i]) {
- ctx = dev->ctx[i];
- break;
- }
- }
- if (!ctx) {
- mfc_err_dev("no mfc context to run\n");
- return -EINVAL;
- } else {
- mfc_info_dev("ctx is changed %d -> %d\n",
- dev->curr_ctx, ctx->num);
- dev->curr_ctx = ctx->num;
- if (dev->curr_ctx_is_drm != ctx->is_drm) {
- need_cache_flush = 1;
- mfc_info_dev("DRM attribute is changed %d->%d\n",
- dev->curr_ctx_is_drm, ctx->is_drm);
- }
- }
- }
- old_state = ctx->state;
- mfc_change_state(ctx, MFCINST_ABORT);
- MFC_TRACE_DEV_HWLOCK("**sleep (ctx:%d)\n", ctx->num);
- ret = mfc_get_hwlock_dev(dev);
- if (ret < 0) {
- mfc_err_dev("Failed to get hwlock\n");
- mfc_err_dev("dev.hwlock.dev = 0x%lx, bits = 0x%lx, owned_by_irq = %d, wl_count = %d, transfer_owner = %d\n",
- dev->hwlock.dev, dev->hwlock.bits, dev->hwlock.owned_by_irq,
- dev->hwlock.wl_count, dev->hwlock.transfer_owner);
- return -EBUSY;
- }
-
- mfc_info_dev("curr_ctx_is_drm:%d, hwlock.bits:%lu, hwlock.dev:%lu\n",
- dev->curr_ctx_is_drm, dev->hwlock.bits, dev->hwlock.dev);
-
- mfc_change_state(ctx, old_state);
- mfc_pm_clock_on(dev);
-
- if (need_cache_flush)
- mfc_cache_flush(dev, ctx->is_drm);
-
- mfc_cmd_sleep(dev);
-
- if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_SLEEP_RET)) {
- mfc_err_dev("Failed to SLEEP\n");
- dev->logging_data->cause |= (1 << MFC_CAUSE_FAIL_SLEEP);
- call_dop(dev, dump_and_stop_always, dev);
- return -EIO;
- }
-
- dev->int_condition = 0;
- if (dev->int_err != 0 || dev->int_reason != MFC_REG_R2H_CMD_SLEEP_RET) {
- /* Failure. */
- mfc_err_dev("Failed to sleep - error: %d, int: %d\n",
- dev->int_err, dev->int_reason);
- ret = -EIO;
- goto err_mfc_sleep;
- }
-
- dev->sleep = 1;
-
-err_mfc_sleep:
- mfc_mfc_off(dev);
- mfc_pm_clock_off(dev);
- mfc_release_hwlock_dev(dev);
- mfc_debug_leave();
-
- return ret;
-}
-
-int mfc_wakeup(struct mfc_dev *dev)
-{
- enum mfc_buf_usage_type buf_type;
- int ret = 0;
-
- mfc_debug_enter();
-
- if (!dev) {
- mfc_err_dev("no mfc device to run\n");
- return -EINVAL;
- }
- mfc_info_dev("curr_ctx_is_drm:%d\n", dev->curr_ctx_is_drm);
-
- MFC_TRACE_DEV_HWLOCK("**wakeup\n");
- ret = mfc_get_hwlock_dev(dev);
- if (ret < 0) {
- mfc_err_dev("Failed to get hwlock\n");
- mfc_err_dev("dev.hwlock.dev = 0x%lx, bits = 0x%lx, owned_by_irq = %d, wl_count = %d, transfer_owner = %d\n",
- dev->hwlock.dev, dev->hwlock.bits, dev->hwlock.owned_by_irq,
- dev->hwlock.wl_count, dev->hwlock.transfer_owner);
- return -EBUSY;
- }
-
- dev->sleep = 0;
-
- /* 0. MFC reset */
- mfc_debug(2, "MFC reset...\n");
-
- mfc_pm_clock_on(dev);
-
- ret = mfc_reset_mfc(dev);
- if (ret) {
- mfc_err_dev("Failed to reset MFC - timeout\n");
- goto err_mfc_wakeup;
- }
- mfc_debug(2, "Done MFC reset...\n");
- if (dev->curr_ctx_is_drm)
- buf_type = MFCBUF_DRM;
- else
- buf_type = MFCBUF_NORMAL;
-
- /* 1. Set DRAM base Addr */
- mfc_set_risc_base_addr(dev, buf_type);
-
- /* 2. Release reset signal to the RISC */
- mfc_risc_on(dev);
-
- mfc_debug(2, "Will now wait for completion of firmware transfer\n");
- if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_FW_STATUS_RET)) {
- mfc_err_dev("Failed to RISC_ON\n");
- dev->logging_data->cause |= (1 << MFC_CAUSE_FAIL_RISC_ON);
- call_dop(dev, dump_and_stop_always, dev);
- return -EIO;
- }
-
- mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
- mfc_cmd_wakeup(dev);
-
- mfc_debug(2, "Will now wait for completion of firmware wake up\n");
- if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_WAKEUP_RET)) {
- mfc_err_dev("Failed to WAKEUP\n");
- dev->logging_data->cause |= (1 << MFC_CAUSE_FAIL_WAKEUP);
- call_dop(dev, dump_and_stop_always, dev);
- return -EIO;
- }
-
- dev->int_condition = 0;
- if (dev->int_err != 0 || dev->int_reason != MFC_REG_R2H_CMD_WAKEUP_RET) {
- /* Failure. */
- mfc_err_dev("Failed to wakeup - error: %d, int: %d\n",
- dev->int_err, dev->int_reason);
- ret = -EIO;
- goto err_mfc_wakeup;
- }
-
-err_mfc_wakeup:
- mfc_pm_clock_off(dev);
-
- mfc_release_hwlock_dev(dev);
-
- mfc_debug_leave();
-
- return ret;
-}
+++ /dev/null
-/*
- * drivers/media/platform/exynos/mfc/mfc_ctrl.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_CTRL_H
-#define __MFC_CTRL_H __FILE__
-
-#include "mfc_common.h"
-
-int mfc_init_hw(struct mfc_dev *dev);
-void mfc_deinit_hw(struct mfc_dev *dev);
-
-int mfc_sleep(struct mfc_dev *dev);
-int mfc_wakeup(struct mfc_dev *dev);
-
-#endif /* __MFC_CTRL_H */
#include "mfc_dec_internal.h"
#include "mfc_hwlock.h"
-#include "mfc_opr.h"
+#include "mfc_run.h"
#include "mfc_sync.h"
#include "mfc_mmcache.h"
#include "mfc_hwlock.h"
#include "mfc_nal_q.h"
-#include "mfc_opr.h"
+#include "mfc_run.h"
#include "mfc_sync.h"
#include "mfc_queue.h"
#include "mfc_hwlock.h"
#include "mfc_otf.h"
-#include "mfc_opr.h"
+#include "mfc_run.h"
#include "mfc_sync.h"
#include "mfc_qos.h"
#include "mfc_hwlock.h"
#include "mfc_nal_q.h"
-#include "mfc_opr.h"
+#include "mfc_run.h"
#include "mfc_sync.h"
#include "mfc_qos.h"
#include "mfc_pm.h"
/* Reset the device */
-int mfc_reset_mfc(struct mfc_dev *dev)
+void mfc_reset_mfc(struct mfc_dev *dev)
{
int i;
mfc_debug_enter();
- if (!dev) {
- mfc_err_dev("no mfc device to run\n");
- return -EINVAL;
- }
-
/* Zero Initialization of MFC registers */
MFC_WRITEL(0, MFC_REG_RISC2HOST_CMD);
MFC_WRITEL(0, MFC_REG_HOST2RISC_CMD);
MFC_WRITEL(0, MFC_REG_MFC_RESET);
mfc_debug_leave();
-
- return 0;
}
void mfc_set_risc_base_addr(struct mfc_dev *dev,
MFC_WRITEL(0xFFFFFFFF, MFC_REG_MFC_FW_CLOCK);
}
-int mfc_reset_mfc(struct mfc_dev *dev);
+void mfc_reset_mfc(struct mfc_dev *dev);
void mfc_set_risc_base_addr(struct mfc_dev *dev,
enum mfc_buf_usage_type buf_type);
void mfc_cmd_host2risc(struct mfc_dev *dev, int cmd);
#include "mfc_nal_q.h"
#include "mfc_otf.h"
-#include "mfc_opr.h"
+#include "mfc_run.h"
#include "mfc_sync.h"
#include "mfc_pm.h"
#include "mfc_hwlock.h"
#include "mfc_nal_q.h"
#include "mfc_otf.h"
-#include "mfc_opr.h"
#include "mfc_sync.h"
#include "mfc_pm.h"
+++ /dev/null
-/*
- * drivers/media/platform/exynos/mfc/mfc_opr.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_opr.h"
-
-#include "mfc_cmd.h"
-#include "mfc_reg_api.h"
-#include "mfc_enc_param.h"
-
-#include "mfc_queue.h"
-#include "mfc_utils.h"
-#include "mfc_mem.h"
-
-int mfc_run_dec_init(struct mfc_ctx *ctx)
-{
- struct mfc_dev *dev;
- struct mfc_buf *src_mb;
- struct mfc_dec *dec = NULL;
-
- 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;
- /* Initializing decoding - parsing header */
-
- /* Get the next source buffer */
- src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
- if (!src_mb) {
- mfc_err_dev("no src buffers\n");
- return -EAGAIN;
- }
-
- mfc_debug(2, "Preparing to init decoding\n");
- mfc_debug(2, "Header size: %d, (offset: %lu)\n",
- src_mb->vb.vb2_buf.planes[0].bytesused, dec->consumed);
-
- if (dec->consumed) {
- mfc_set_dec_stream_buffer(ctx, src_mb, dec->consumed, dec->remained_size);
- } else {
- /* decoder src buffer CFW PROT */
- if (ctx->is_drm) {
- int index = src_mb->vb.vb2_buf.index;
-
- mfc_stream_protect(ctx, src_mb, index);
- }
-
- mfc_set_dec_stream_buffer(ctx, src_mb,
- 0, src_mb->vb.vb2_buf.planes[0].bytesused);
- }
-
- mfc_debug(2, "Header addr: 0x%08llx\n", src_mb->addr[0][0]);
- mfc_clean_ctx_int_flags(ctx);
- mfc_cmd_init_decode(ctx);
-
- return 0;
-}
-
-static int __mfc_check_last_frame(struct mfc_ctx *ctx, struct mfc_buf *mfc_buf)
-{
- if (mfc_buf->vb.reserved2 & FLAG_LAST_FRAME) {
- mfc_debug(2, "Setting ctx->state to FINISHING\n");
- mfc_change_state(ctx, MFCINST_FINISHING);
- return 1;
- }
-
- return 0;
-}
-
-int mfc_run_dec_frame(struct mfc_ctx *ctx)
-{
- struct mfc_dev *dev;
- struct mfc_buf *src_mb, *dst_mb;
- struct mfc_dec *dec;
- int last_frame = 0;
- unsigned int index;
-
- if (!ctx) {
- mfc_err_dev("no mfc context to run\n");
- return -EINVAL;
- }
- dec = ctx->dec_priv;
- dev = ctx->dev;
- if (!dev) {
- mfc_err_dev("no mfc device to run\n");
- return -EINVAL;
- }
-
- if (mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0) &&
- mfc_is_queue_count_smaller(&ctx->buf_queue_lock,
- &ctx->ref_buf_queue, (ctx->dpb_count + 5))) {
- return -EAGAIN;
- }
-
- /* Get the next source buffer */
- src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_SET_USED);
- if (!src_mb) {
- mfc_debug(2, "no src buffers\n");
- return -EAGAIN;
- }
-
- /* decoder src buffer CFW PROT */
- if (ctx->is_drm) {
- if (!dec->consumed) {
- index = src_mb->vb.vb2_buf.index;
- mfc_stream_protect(ctx, src_mb, index);
- }
- }
-
- if (src_mb->vb.reserved2 & FLAG_EMPTY_DATA)
- src_mb->vb.vb2_buf.planes[0].bytesused = 0;
-
- if (dec->consumed)
- mfc_set_dec_stream_buffer(ctx, src_mb, dec->consumed, dec->remained_size);
- else
- mfc_set_dec_stream_buffer(ctx, src_mb, 0, src_mb->vb.vb2_buf.planes[0].bytesused);
-
- /* Try to use the non-referenced DPB on dst-queue */
- dst_mb = mfc_search_for_dpb(ctx, dec->dynamic_used);
- if (!dst_mb) {
- mfc_debug(2, "[DPB] couldn't find dst buffers\n");
- return -EAGAIN;
- }
-
- index = src_mb->vb.vb2_buf.index;
- if (call_cop(ctx, set_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
- mfc_err_ctx("failed in set_buf_ctrls_val\n");
-
- mfc_set_dynamic_dpb(ctx, dst_mb);
-
- mfc_clean_ctx_int_flags(ctx);
-
- last_frame = __mfc_check_last_frame(ctx, src_mb);
- mfc_cmd_dec_one_frame(ctx, last_frame);
-
- return 0;
-}
-
-int mfc_run_dec_last_frames(struct mfc_ctx *ctx)
-{
- struct mfc_dev *dev;
- struct mfc_buf *src_mb, *dst_mb;
- struct mfc_dec *dec;
-
- if (!ctx) {
- mfc_err_dev("no mfc context to run\n");
- return -EINVAL;
- }
-
- dec = ctx->dec_priv;
- if (!dec) {
- mfc_err_dev("no decoder context to run\n");
- return -EINVAL;
- }
-
- dev = ctx->dev;
- if (!dev) {
- mfc_err_dev("no mfc device to run\n");
- return -EINVAL;
- }
-
- if (mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0)) {
- mfc_debug(2, "no dst buffer\n");
- return -EAGAIN;
- }
-
- /* Get the next source buffer */
- src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_SET_USED);
-
- /* Frames are being decoded */
- if (!src_mb) {
- mfc_debug(2, "no src buffers\n");
- mfc_set_dec_stream_buffer(ctx, 0, 0, 0);
- } else {
- if (dec->consumed) {
- mfc_set_dec_stream_buffer(ctx, src_mb, dec->consumed, dec->remained_size);
- } else {
- /* decoder src buffer CFW PROT */
- if (ctx->is_drm) {
- int index = src_mb->vb.vb2_buf.index;
-
- mfc_stream_protect(ctx, src_mb, index);
- }
-
- mfc_set_dec_stream_buffer(ctx, src_mb, 0, 0);
- }
- }
-
- /* Try to use the non-referenced DPB on dst-queue */
- dst_mb = mfc_search_for_dpb(ctx, dec->dynamic_used);
- if (!dst_mb) {
- mfc_debug(2, "[DPB] couldn't find dst buffers\n");
- return -EAGAIN;
- }
-
- mfc_set_dynamic_dpb(ctx, dst_mb);
-
- mfc_clean_ctx_int_flags(ctx);
- mfc_cmd_dec_one_frame(ctx, 1);
-
- return 0;
-}
-
-int mfc_run_enc_init(struct mfc_ctx *ctx)
-{
- struct mfc_buf *dst_mb;
- int ret;
-
- dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
- if (!dst_mb) {
- mfc_debug(2, "no dst buffers\n");
- return -EAGAIN;
- }
-
- /* encoder dst buffer CFW PROT */
- if (ctx->is_drm) {
- int index = dst_mb->vb.vb2_buf.index;
-
- mfc_stream_protect(ctx, dst_mb, index);
- }
- mfc_set_enc_stream_buffer(ctx, dst_mb);
-
- mfc_set_enc_stride(ctx);
-
- mfc_debug(2, "Header addr: 0x%08llx\n", dst_mb->addr[0][0]);
- mfc_clean_ctx_int_flags(ctx);
-
- ret = mfc_cmd_init_encode(ctx);
- return ret;
-}
-
-int mfc_run_enc_frame(struct mfc_ctx *ctx)
-{
- struct mfc_buf *dst_mb;
- struct mfc_buf *src_mb;
- struct mfc_raw_info *raw;
- unsigned int index, i;
- int last_frame = 0;
-
- raw = &ctx->raw_buf;
-
- /* Get the next source buffer */
- src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_SET_USED);
- if (!src_mb) {
- mfc_debug(2, "no src buffers\n");
- return -EAGAIN;
- }
-
- if (src_mb->num_valid_bufs > 0) {
- /* last image in a buffer container */
- if (src_mb->next_index == (src_mb->num_valid_bufs - 1)) {
- mfc_debug(4, "[BUFCON] last image in a container\n");
- last_frame = __mfc_check_last_frame(ctx, src_mb);
- }
- } else {
- last_frame = __mfc_check_last_frame(ctx, src_mb);
- }
-
- index = src_mb->vb.vb2_buf.index;
-
- /* encoder src buffer CFW PROT */
- if (ctx->is_drm)
- mfc_raw_protect(ctx, src_mb, index);
-
- mfc_set_enc_frame_buffer(ctx, src_mb, raw->num_planes);
-
- dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_SET_USED);
- if (!dst_mb) {
- mfc_debug(2, "no dst buffers\n");
- return -EAGAIN;
- }
-
- /* encoder dst buffer CFW PROT */
- if (ctx->is_drm) {
- i = dst_mb->vb.vb2_buf.index;
- mfc_stream_protect(ctx, dst_mb, i);
- }
- mfc_debug(2, "nal start : src index from src_buf_queue:%d\n",
- src_mb->vb.vb2_buf.index);
- mfc_debug(2, "nal start : dst index from dst_buf_queue:%d\n",
- dst_mb->vb.vb2_buf.index);
-
- mfc_set_enc_stream_buffer(ctx, dst_mb);
-
- if (call_cop(ctx, set_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
- mfc_err_ctx("failed in set_buf_ctrls_val\n");
-
- mfc_clean_ctx_int_flags(ctx);
-
- 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;
-}
-
-int mfc_run_enc_last_frames(struct mfc_ctx *ctx)
-{
- struct mfc_buf *dst_mb;
- struct mfc_raw_info *raw;
-
- raw = &ctx->raw_buf;
-
- dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_SET_USED);
- if (!dst_mb) {
- mfc_debug(2, "no dst buffers\n");
- return -EAGAIN;
- }
-
- mfc_debug(2, "Set address zero for all planes\n");
- mfc_set_enc_frame_buffer(ctx, 0, raw->num_planes);
-
- /* encoder dst buffer CFW PROT */
- if (ctx->is_drm) {
- int index = dst_mb->vb.vb2_buf.index;
-
- mfc_stream_protect(ctx, dst_mb, index);
- }
-
- mfc_set_enc_stream_buffer(ctx, dst_mb);
-
- mfc_clean_ctx_int_flags(ctx);
- mfc_cmd_enc_one_frame(ctx, 1);
-
- return 0;
-}
+++ /dev/null
-/*
- * drivers/media/platform/exynos/mfc/mfc_opr.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_OPR_H
-#define __MFC_OPR_H __FILE__
-
-#include "mfc_common.h"
-
-int mfc_run_dec_init(struct mfc_ctx *ctx);
-int mfc_run_dec_frame(struct mfc_ctx *ctx);
-int mfc_run_dec_last_frames(struct mfc_ctx *ctx);
-int mfc_run_enc_init(struct mfc_ctx *ctx);
-int mfc_run_enc_frame(struct mfc_ctx *ctx);
-int mfc_run_enc_last_frames(struct mfc_ctx *ctx);
-
-#endif /* __MFC_OPR_H */
--- /dev/null
+/*
+ * drivers/media/platform/exynos/mfc/mfc_run.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_run.h"
+
+#include "mfc_nal_q.h"
+#include "mfc_sync.h"
+#include "mfc_hwlock.h"
+
+#include "mfc_pm.h"
+#include "mfc_cmd.h"
+#include "mfc_reg_api.h"
+#include "mfc_hw_reg_api.h"
+#include "mfc_enc_param.h"
+
+#include "mfc_queue.h"
+#include "mfc_utils.h"
+#include "mfc_mem.h"
+
+/* Initialize hardware */
+static int __mfc_init_hw(struct mfc_dev *dev, enum mfc_buf_usage_type buf_type)
+{
+ int fw_ver;
+ int ret = 0;
+ int curr_ctx_is_drm_backup;
+
+ mfc_debug_enter();
+
+ curr_ctx_is_drm_backup = dev->curr_ctx_is_drm;
+
+ if (!dev->fw_buf.dma_buf)
+ return -EINVAL;
+
+ /* 0. MFC reset */
+ mfc_debug(2, "MFC reset...\n");
+
+ /* At init time, do not call secure API */
+ if (buf_type == MFCBUF_NORMAL)
+ dev->curr_ctx_is_drm = 0;
+ else if (buf_type == MFCBUF_DRM)
+ dev->curr_ctx_is_drm = 1;
+
+ ret = mfc_pm_clock_on(dev);
+ if (ret) {
+ mfc_err_dev("Failed to enable clock before reset(%d)\n", ret);
+ dev->curr_ctx_is_drm = curr_ctx_is_drm_backup;
+ return ret;
+ }
+
+ mfc_reset_mfc(dev);
+ mfc_debug(2, "Done MFC reset...\n");
+
+ /* 1. Set DRAM base Addr */
+ mfc_set_risc_base_addr(dev, buf_type);
+
+ /* 2. Release reset signal to the RISC */
+ mfc_risc_on(dev);
+
+ mfc_debug(2, "Will now wait for completion of firmware transfer\n");
+ if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_FW_STATUS_RET)) {
+ mfc_err_dev("Failed to RISC_ON\n");
+ mfc_clean_dev_int_flags(dev);
+ ret = -EIO;
+ goto err_init_hw;
+ }
+
+ /* 3. Initialize firmware */
+ ret = mfc_cmd_sys_init(dev, buf_type);
+ if (ret) {
+ mfc_err_dev("Failed to send command to MFC - timeout\n");
+ goto err_init_hw;
+ }
+
+ mfc_debug(2, "Ok, now will write a command to init the system\n");
+ if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_SYS_INIT_RET)) {
+ mfc_err_dev("Failed to SYS_INIT\n");
+ mfc_clean_dev_int_flags(dev);
+ ret = -EIO;
+ goto err_init_hw;
+ }
+
+ dev->int_condition = 0;
+ if (dev->int_err != 0 || dev->int_reason != MFC_REG_R2H_CMD_SYS_INIT_RET) {
+ /* Failure. */
+ mfc_err_dev("Failed to init firmware - error: %d, int: %d\n",
+ dev->int_err, dev->int_reason);
+ ret = -EIO;
+ goto err_init_hw;
+ }
+
+ dev->fw.fimv_info = mfc_get_fimv_info();
+ if (dev->fw.fimv_info != 'D' && dev->fw.fimv_info != 'E')
+ dev->fw.fimv_info = 'N';
+
+ mfc_info_dev("[F/W] MFC v%x.%x, %02xyy %02xmm %02xdd (%c)\n",
+ MFC_VER_MAJOR(dev),
+ MFC_VER_MINOR(dev),
+ mfc_get_fw_ver_year(),
+ mfc_get_fw_ver_month(),
+ mfc_get_fw_ver_date(),
+ dev->fw.fimv_info);
+
+ dev->fw.date = mfc_get_fw_ver_all();
+ /* Check MFC version and F/W version */
+ fw_ver = mfc_get_mfc_version();
+ if (fw_ver != dev->pdata->ip_ver) {
+ mfc_err_dev("Invalid F/W version(0x%x) for MFC H/W(0x%x)\n",
+ fw_ver, dev->pdata->ip_ver);
+ ret = -EIO;
+ goto err_init_hw;
+ }
+
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ /* Cache flush for base address change */
+ mfc_cmd_cache_flush(dev);
+ if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_CACHE_FLUSH_RET)) {
+ mfc_err_dev("Failed to CACHE_FLUSH\n");
+ mfc_clean_dev_int_flags(dev);
+ ret = -EIO;
+ goto err_init_hw;
+ }
+
+ if (buf_type == MFCBUF_DRM && !curr_ctx_is_drm_backup) {
+ mfc_pm_clock_off(dev);
+ dev->curr_ctx_is_drm = curr_ctx_is_drm_backup;
+ mfc_pm_clock_on_with_base(dev, MFCBUF_NORMAL);
+ }
+#endif
+
+err_init_hw:
+ mfc_pm_clock_off(dev);
+ dev->curr_ctx_is_drm = curr_ctx_is_drm_backup;
+ mfc_debug_leave();
+
+ return ret;
+}
+
+/* Wrapper : Initialize hardware */
+int mfc_run_init_hw(struct mfc_dev *dev)
+{
+ int ret;
+
+ ret = __mfc_init_hw(dev, MFCBUF_NORMAL);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ if (dev->fw.drm_status)
+ ret = __mfc_init_hw(dev, MFCBUF_DRM);
+#endif
+
+ return ret;
+}
+
+/* Deinitialize hardware */
+void mfc_run_deinit_hw(struct mfc_dev *dev)
+{
+ int ret;
+
+ mfc_debug(2, "mfc deinit start\n");
+
+ ret = mfc_pm_clock_on(dev);
+ if (ret) {
+ mfc_err_dev("Failed to enable clock before reset(%d)\n", ret);
+ return;
+ }
+
+ mfc_mfc_off(dev);
+
+ mfc_pm_clock_off(dev);
+
+ mfc_debug(2, "mfc deinit completed\n");
+}
+
+int mfc_run_sleep(struct mfc_dev *dev)
+{
+ struct mfc_ctx *ctx;
+ int old_state, i;
+ int need_cache_flush = 0;
+
+ mfc_debug_enter();
+
+ ctx = dev->ctx[dev->curr_ctx];
+ if (!ctx) {
+ for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
+ if (dev->ctx[i]) {
+ ctx = dev->ctx[i];
+ break;
+ }
+ }
+
+ if (!ctx) {
+ mfc_err_dev("no mfc context to run\n");
+ return -EINVAL;
+ }
+ mfc_info_dev("ctx is changed %d -> %d\n", dev->curr_ctx, ctx->num);
+
+ dev->curr_ctx = ctx->num;
+ if (dev->curr_ctx_is_drm != ctx->is_drm) {
+ need_cache_flush = 1;
+ mfc_info_dev("DRM attribute is changed %d->%d\n",
+ dev->curr_ctx_is_drm, ctx->is_drm);
+ }
+ }
+ mfc_info_dev("curr_ctx_is_drm:%d\n", dev->curr_ctx_is_drm);
+
+ mfc_pm_clock_on(dev);
+
+ if (need_cache_flush)
+ mfc_cache_flush(dev, ctx->is_drm);
+
+ mfc_cmd_sleep(dev);
+
+ if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_SLEEP_RET)) {
+ mfc_err_dev("Failed to SLEEP\n");
+ dev->logging_data->cause |= (1 << MFC_CAUSE_FAIL_SLEEP);
+ call_dop(dev, dump_and_stop_always, dev);
+ return -EBUSY;
+ }
+
+ dev->int_condition = 0;
+ if (dev->int_err != 0 || dev->int_reason != MFC_REG_R2H_CMD_SLEEP_RET) {
+ /* Failure. */
+ mfc_err_dev("Failed to sleep - error: %d, int: %d\n",
+ dev->int_err, dev->int_reason);
+ call_dop(dev, dump_and_stop_always, dev);
+ return -EBUSY;
+ }
+
+ dev->sleep = 1;
+
+ mfc_mfc_off(dev);
+ mfc_pm_clock_off(dev);
+
+ mfc_debug_leave();
+
+ return 0;
+}
+
+int mfc_run_wakeup(struct mfc_dev *dev)
+{
+ enum mfc_buf_usage_type buf_type;
+ int ret = 0;
+
+ mfc_debug_enter();
+ mfc_info_dev("curr_ctx_is_drm:%d\n", dev->curr_ctx_is_drm);
+
+ /* 0. MFC reset */
+ mfc_debug(2, "MFC reset...\n");
+
+ ret = mfc_pm_clock_on(dev);
+ if (ret) {
+ mfc_err_dev("Failed to enable clock before reset(%d)\n", ret);
+ return ret;
+ }
+
+ mfc_reset_mfc(dev);
+ mfc_debug(2, "Done MFC reset...\n");
+
+ if (dev->curr_ctx_is_drm)
+ buf_type = MFCBUF_DRM;
+ else
+ buf_type = MFCBUF_NORMAL;
+
+ /* 1. Set DRAM base Addr */
+ mfc_set_risc_base_addr(dev, buf_type);
+
+ /* 2. Release reset signal to the RISC */
+ mfc_risc_on(dev);
+
+ mfc_debug(2, "Will now wait for completion of firmware transfer\n");
+ if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_FW_STATUS_RET)) {
+ mfc_err_dev("Failed to RISC_ON\n");
+ dev->logging_data->cause |= (1 << MFC_CAUSE_FAIL_RISC_ON);
+ call_dop(dev, dump_and_stop_always, dev);
+ return -EBUSY;
+ }
+
+ mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
+ mfc_cmd_wakeup(dev);
+
+ mfc_debug(2, "Will now wait for completion of firmware wake up\n");
+ if (mfc_wait_for_done_dev(dev, MFC_REG_R2H_CMD_WAKEUP_RET)) {
+ mfc_err_dev("Failed to WAKEUP\n");
+ dev->logging_data->cause |= (1 << MFC_CAUSE_FAIL_WAKEUP);
+ call_dop(dev, dump_and_stop_always, dev);
+ return -EBUSY;
+ }
+
+ dev->int_condition = 0;
+ if (dev->int_err != 0 || dev->int_reason != MFC_REG_R2H_CMD_WAKEUP_RET) {
+ /* Failure. */
+ mfc_err_dev("Failed to wakeup - error: %d, int: %d\n",
+ dev->int_err, dev->int_reason);
+ call_dop(dev, dump_and_stop_always, dev);
+ return -EBUSY;
+ }
+
+ dev->sleep = 0;
+
+ mfc_pm_clock_off(dev);
+
+ mfc_debug_leave();
+
+ return ret;
+}
+
+int mfc_run_dec_init(struct mfc_ctx *ctx)
+{
+ struct mfc_dev *dev = ctx->dev;
+ struct mfc_dec *dec = ctx->dec_priv;
+ struct mfc_buf *src_mb;
+
+ /* Initializing decoding - parsing header */
+
+ /* Get the next source buffer */
+ src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_NO_TOUCH_USED);
+ if (!src_mb) {
+ mfc_err_dev("no src buffers\n");
+ return -EAGAIN;
+ }
+
+ mfc_debug(2, "Preparing to init decoding\n");
+ mfc_debug(2, "Header size: %d, (offset: %lu)\n",
+ src_mb->vb.vb2_buf.planes[0].bytesused, dec->consumed);
+
+ if (dec->consumed) {
+ mfc_set_dec_stream_buffer(ctx, src_mb, dec->consumed, dec->remained_size);
+ } else {
+ /* decoder src buffer CFW PROT */
+ if (ctx->is_drm) {
+ int index = src_mb->vb.vb2_buf.index;
+
+ mfc_stream_protect(ctx, src_mb, index);
+ }
+
+ mfc_set_dec_stream_buffer(ctx, src_mb,
+ 0, src_mb->vb.vb2_buf.planes[0].bytesused);
+ }
+
+ mfc_debug(2, "Header addr: 0x%08llx\n", src_mb->addr[0][0]);
+ mfc_clean_ctx_int_flags(ctx);
+ mfc_cmd_init_decode(ctx);
+
+ return 0;
+}
+
+static int __mfc_check_last_frame(struct mfc_ctx *ctx, struct mfc_buf *mfc_buf)
+{
+ if (mfc_buf->vb.reserved2 & FLAG_LAST_FRAME) {
+ mfc_debug(2, "Setting ctx->state to FINISHING\n");
+ mfc_change_state(ctx, MFCINST_FINISHING);
+ return 1;
+ }
+
+ return 0;
+}
+
+int mfc_run_dec_frame(struct mfc_ctx *ctx)
+{
+ struct mfc_dev *dev = ctx->dev;
+ struct mfc_dec *dec = ctx->dec_priv;
+ struct mfc_buf *src_mb, *dst_mb;
+ int last_frame = 0;
+ unsigned int index;
+
+ if (mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0) &&
+ mfc_is_queue_count_smaller(&ctx->buf_queue_lock,
+ &ctx->ref_buf_queue, (ctx->dpb_count + 5))) {
+ return -EAGAIN;
+ }
+
+ /* Get the next source buffer */
+ src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_SET_USED);
+ if (!src_mb) {
+ mfc_debug(2, "no src buffers\n");
+ return -EAGAIN;
+ }
+
+ /* decoder src buffer CFW PROT */
+ if (ctx->is_drm) {
+ if (!dec->consumed) {
+ index = src_mb->vb.vb2_buf.index;
+ mfc_stream_protect(ctx, src_mb, index);
+ }
+ }
+
+ if (src_mb->vb.reserved2 & FLAG_EMPTY_DATA)
+ src_mb->vb.vb2_buf.planes[0].bytesused = 0;
+
+ if (dec->consumed)
+ mfc_set_dec_stream_buffer(ctx, src_mb, dec->consumed, dec->remained_size);
+ else
+ mfc_set_dec_stream_buffer(ctx, src_mb, 0, src_mb->vb.vb2_buf.planes[0].bytesused);
+
+ /* Try to use the non-referenced DPB on dst-queue */
+ dst_mb = mfc_search_for_dpb(ctx, dec->dynamic_used);
+ if (!dst_mb) {
+ mfc_debug(2, "[DPB] couldn't find dst buffers\n");
+ return -EAGAIN;
+ }
+
+ index = src_mb->vb.vb2_buf.index;
+ if (call_cop(ctx, set_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
+ mfc_err_ctx("failed in set_buf_ctrls_val\n");
+
+ mfc_set_dynamic_dpb(ctx, dst_mb);
+
+ mfc_clean_ctx_int_flags(ctx);
+
+ last_frame = __mfc_check_last_frame(ctx, src_mb);
+ mfc_cmd_dec_one_frame(ctx, last_frame);
+
+ return 0;
+}
+
+int mfc_run_dec_last_frames(struct mfc_ctx *ctx)
+{
+ struct mfc_dev *dev = ctx->dev;
+ struct mfc_dec *dec = ctx->dec_priv;
+ struct mfc_buf *src_mb, *dst_mb;
+
+ if (mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0)) {
+ mfc_debug(2, "no dst buffer\n");
+ return -EAGAIN;
+ }
+
+ /* Get the next source buffer */
+ src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_SET_USED);
+
+ /* Frames are being decoded */
+ if (!src_mb) {
+ mfc_debug(2, "no src buffers\n");
+ mfc_set_dec_stream_buffer(ctx, 0, 0, 0);
+ } else {
+ if (dec->consumed) {
+ mfc_set_dec_stream_buffer(ctx, src_mb, dec->consumed, dec->remained_size);
+ } else {
+ /* decoder src buffer CFW PROT */
+ if (ctx->is_drm) {
+ int index = src_mb->vb.vb2_buf.index;
+
+ mfc_stream_protect(ctx, src_mb, index);
+ }
+
+ mfc_set_dec_stream_buffer(ctx, src_mb, 0, 0);
+ }
+ }
+
+ /* Try to use the non-referenced DPB on dst-queue */
+ dst_mb = mfc_search_for_dpb(ctx, dec->dynamic_used);
+ if (!dst_mb) {
+ mfc_debug(2, "[DPB] couldn't find dst buffers\n");
+ return -EAGAIN;
+ }
+
+ mfc_set_dynamic_dpb(ctx, dst_mb);
+
+ mfc_clean_ctx_int_flags(ctx);
+ mfc_cmd_dec_one_frame(ctx, 1);
+
+ return 0;
+}
+
+int mfc_run_enc_init(struct mfc_ctx *ctx)
+{
+ struct mfc_buf *dst_mb;
+ int ret;
+
+ dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
+ if (!dst_mb) {
+ mfc_debug(2, "no dst buffers\n");
+ return -EAGAIN;
+ }
+
+ /* encoder dst buffer CFW PROT */
+ if (ctx->is_drm) {
+ int index = dst_mb->vb.vb2_buf.index;
+
+ mfc_stream_protect(ctx, dst_mb, index);
+ }
+ mfc_set_enc_stream_buffer(ctx, dst_mb);
+
+ mfc_set_enc_stride(ctx);
+
+ mfc_debug(2, "Header addr: 0x%08llx\n", dst_mb->addr[0][0]);
+ mfc_clean_ctx_int_flags(ctx);
+
+ ret = mfc_cmd_init_encode(ctx);
+ return ret;
+}
+
+int mfc_run_enc_frame(struct mfc_ctx *ctx)
+{
+ struct mfc_buf *dst_mb;
+ struct mfc_buf *src_mb;
+ struct mfc_raw_info *raw;
+ unsigned int index, i;
+ int last_frame = 0;
+
+ raw = &ctx->raw_buf;
+
+ /* Get the next source buffer */
+ src_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, MFC_BUF_SET_USED);
+ if (!src_mb) {
+ mfc_debug(2, "no src buffers\n");
+ return -EAGAIN;
+ }
+
+ if (src_mb->num_valid_bufs > 0) {
+ /* last image in a buffer container */
+ if (src_mb->next_index == (src_mb->num_valid_bufs - 1)) {
+ mfc_debug(4, "[BUFCON] last image in a container\n");
+ last_frame = __mfc_check_last_frame(ctx, src_mb);
+ }
+ } else {
+ last_frame = __mfc_check_last_frame(ctx, src_mb);
+ }
+
+ index = src_mb->vb.vb2_buf.index;
+
+ /* encoder src buffer CFW PROT */
+ if (ctx->is_drm)
+ mfc_raw_protect(ctx, src_mb, index);
+
+ mfc_set_enc_frame_buffer(ctx, src_mb, raw->num_planes);
+
+ dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_SET_USED);
+ if (!dst_mb) {
+ mfc_debug(2, "no dst buffers\n");
+ return -EAGAIN;
+ }
+
+ /* encoder dst buffer CFW PROT */
+ if (ctx->is_drm) {
+ i = dst_mb->vb.vb2_buf.index;
+ mfc_stream_protect(ctx, dst_mb, i);
+ }
+ mfc_debug(2, "nal start : src index from src_buf_queue:%d\n",
+ src_mb->vb.vb2_buf.index);
+ mfc_debug(2, "nal start : dst index from dst_buf_queue:%d\n",
+ dst_mb->vb.vb2_buf.index);
+
+ mfc_set_enc_stream_buffer(ctx, dst_mb);
+
+ if (call_cop(ctx, set_buf_ctrls_val, ctx, &ctx->src_ctrls[index]) < 0)
+ mfc_err_ctx("failed in set_buf_ctrls_val\n");
+
+ mfc_clean_ctx_int_flags(ctx);
+
+ 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;
+}
+
+int mfc_run_enc_last_frames(struct mfc_ctx *ctx)
+{
+ struct mfc_buf *dst_mb;
+ struct mfc_raw_info *raw;
+
+ raw = &ctx->raw_buf;
+
+ dst_mb = mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_SET_USED);
+ if (!dst_mb) {
+ mfc_debug(2, "no dst buffers\n");
+ return -EAGAIN;
+ }
+
+ mfc_debug(2, "Set address zero for all planes\n");
+ mfc_set_enc_frame_buffer(ctx, 0, raw->num_planes);
+
+ /* encoder dst buffer CFW PROT */
+ if (ctx->is_drm) {
+ int index = dst_mb->vb.vb2_buf.index;
+
+ mfc_stream_protect(ctx, dst_mb, index);
+ }
+
+ mfc_set_enc_stream_buffer(ctx, dst_mb);
+
+ mfc_clean_ctx_int_flags(ctx);
+ mfc_cmd_enc_one_frame(ctx, 1);
+
+ return 0;
+}
--- /dev/null
+/*
+ * drivers/media/platform/exynos/mfc/mfc_run.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_RUN_H
+#define __MFC_RUN_H __FILE__
+
+#include "mfc_common.h"
+
+int mfc_run_init_hw(struct mfc_dev *dev);
+void mfc_run_deinit_hw(struct mfc_dev *dev);
+
+int mfc_run_sleep(struct mfc_dev *dev);
+int mfc_run_wakeup(struct mfc_dev *dev);
+
+int mfc_run_dec_init(struct mfc_ctx *ctx);
+int mfc_run_dec_frame(struct mfc_ctx *ctx);
+int mfc_run_dec_last_frames(struct mfc_ctx *ctx);
+
+int mfc_run_enc_init(struct mfc_ctx *ctx);
+int mfc_run_enc_frame(struct mfc_ctx *ctx);
+int mfc_run_enc_last_frames(struct mfc_ctx *ctx);
+
+#endif /* __MFC_RUN_H */