[COMMON] media: mfc: DRV4.0: replace opr and ctrl to run
authorSunyoung Kang <sy0816.kang@samsung.com>
Thu, 28 Jun 2018 08:56:34 +0000 (17:56 +0900)
committerSunyoung Kang <sy0816.kang@samsung.com>
Mon, 23 Jul 2018 06:18:52 +0000 (15:18 +0900)
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>
16 files changed:
drivers/media/platform/exynos/mfc/Makefile
drivers/media/platform/exynos/mfc/mfc.c
drivers/media/platform/exynos/mfc/mfc_ctrl.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_ctrl.h [deleted file]
drivers/media/platform/exynos/mfc/mfc_dec_v4l2.c
drivers/media/platform/exynos/mfc/mfc_dec_vb2.c
drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c
drivers/media/platform/exynos/mfc/mfc_enc_vb2.c
drivers/media/platform/exynos/mfc/mfc_hw_reg_api.c
drivers/media/platform/exynos/mfc/mfc_hw_reg_api.h
drivers/media/platform/exynos/mfc/mfc_hwlock.c
drivers/media/platform/exynos/mfc/mfc_isr.c
drivers/media/platform/exynos/mfc/mfc_opr.c [deleted file]
drivers/media/platform/exynos/mfc/mfc_opr.h [deleted file]
drivers/media/platform/exynos/mfc/mfc_run.c [new file with mode: 0644]
drivers/media/platform/exynos/mfc/mfc_run.h [new file with mode: 0644]

index d13d890ad48869ef16aeb687aa22900f58a73355..32a248c7afc6f90b928e2789e47a0b422d32b13c 100644 (file)
@@ -1,6 +1,6 @@
 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
index 9faf350489144f78905c9609b8d8e2257fbb3939..cc5c950b2a3595afad323c95e7883cd2e33de479 100644 (file)
 #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"
@@ -381,7 +380,7 @@ static int __mfc_init_instance(struct mfc_dev *dev, struct mfc_ctx *ctx)
        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;
@@ -713,7 +712,7 @@ static int mfc_release(struct file *file)
        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);
@@ -1469,7 +1468,7 @@ static int mfc_remove(struct platform_device *pdev)
        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);
@@ -1515,38 +1514,62 @@ static void mfc_shutdown(struct platform_device *pdev)
 }
 
 #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;
 }
diff --git a/drivers/media/platform/exynos/mfc/mfc_ctrl.c b/drivers/media/platform/exynos/mfc/mfc_ctrl.c
deleted file mode 100644 (file)
index 9da4eb3..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * 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;
-}
diff --git a/drivers/media/platform/exynos/mfc/mfc_ctrl.h b/drivers/media/platform/exynos/mfc/mfc_ctrl.h
deleted file mode 100644 (file)
index a8ad791..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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 */
index 27dc71142f677236a138c79c203cb82f5f22ee78..1e3c13b73088e91cac0fbbdb607e3438512f7c75 100644 (file)
@@ -14,7 +14,7 @@
 #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"
 
index a07446e16b594129f332028b6c3c03ed9fd83cc6..9d5850ba6c275a29b7f52492566b13f3ae8873a2 100644 (file)
@@ -14,7 +14,7 @@
 
 #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"
index d491a2379eb68e7f27d5ffb61c4d766b8f4112eb..aff1dc8b3abf9f80f9f7a801f453eb8679cef83b 100644 (file)
@@ -15,7 +15,7 @@
 
 #include "mfc_hwlock.h"
 #include "mfc_otf.h"
-#include "mfc_opr.h"
+#include "mfc_run.h"
 #include "mfc_sync.h"
 
 #include "mfc_qos.h"
index 6d9ef8f24ca9fccdf1ea6a6c0dd8085729b95541..b33c1e0412875bb927488e6e7a21497e6025defc 100644 (file)
@@ -14,7 +14,7 @@
 
 #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"
index 40260069d3ff7b9a9c4ff54b1484425e59c80507..2ad7d472a1efdcbde453ffae19058d6890898c07 100644 (file)
 #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);
@@ -39,8 +34,6 @@ int mfc_reset_mfc(struct mfc_dev *dev)
        MFC_WRITEL(0, MFC_REG_MFC_RESET);
 
        mfc_debug_leave();
-
-       return 0;
 }
 
 void mfc_set_risc_base_addr(struct mfc_dev *dev,
index 9d1245ddf684e3ec305ef030627d1482730cb3b7..542d47883fff47df73fc7d05f939d36708aba92d 100644 (file)
@@ -102,7 +102,7 @@ static inline void mfc_enable_all_clocks(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);
index 4e5cfd548ade31203455d327e01c2d14c882f658..69bb9727d011f0def395a38522527590b8ac955f 100644 (file)
@@ -14,7 +14,7 @@
 
 #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"
index d940839dcc13a269f1c4ea8f02f1af7d7e5b77c8..cbd1cc1d14ee2f0ea89a665778eb43e4c3fa779e 100644 (file)
@@ -15,7 +15,6 @@
 #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"
diff --git a/drivers/media/platform/exynos/mfc/mfc_opr.c b/drivers/media/platform/exynos/mfc/mfc_opr.c
deleted file mode 100644 (file)
index 67a03ab..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * 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;
-}
diff --git a/drivers/media/platform/exynos/mfc/mfc_opr.h b/drivers/media/platform/exynos/mfc/mfc_opr.h
deleted file mode 100644 (file)
index 75b2984..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 */
diff --git a/drivers/media/platform/exynos/mfc/mfc_run.c b/drivers/media/platform/exynos/mfc/mfc_run.c
new file mode 100644 (file)
index 0000000..ffc17c1
--- /dev/null
@@ -0,0 +1,598 @@
+/*
+ * 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;
+}
diff --git a/drivers/media/platform/exynos/mfc/mfc_run.h b/drivers/media/platform/exynos/mfc/mfc_run.h
new file mode 100644 (file)
index 0000000..06970cf
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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 */