summaryrefslogtreecommitdiff
path: root/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c')
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c76
1 files changed, 68 insertions, 8 deletions
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 64535d33bff8..f5b1e1aab301 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -5,11 +5,13 @@
*/
#include <linux/clk.h>
+#include <linux/interrupt.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <soc/mediatek/smi.h>
+#include "mtk_vcodec_dec_hw.h"
#include "mtk_vcodec_dec_pm.h"
#include "mtk_vcodec_util.h"
@@ -85,10 +87,23 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
}
EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm);
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
{
+ struct mtk_vdec_hw_dev *subdev_dev;
+ struct mtk_vcodec_pm *pm;
int ret;
+ if (vdec_dev->vdec_pdata->is_subdev_supported) {
+ subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+ if (!subdev_dev) {
+ mtk_v4l2_err("Failed to get hw dev\n");
+ return -EINVAL;
+ }
+ pm = &subdev_dev->pm;
+ } else {
+ pm = &vdec_dev->pm;
+ }
+
ret = pm_runtime_resume_and_get(pm->dev);
if (ret)
mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
@@ -97,21 +112,50 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
}
EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
{
+ struct mtk_vdec_hw_dev *subdev_dev;
+ struct mtk_vcodec_pm *pm;
int ret;
+ if (vdec_dev->vdec_pdata->is_subdev_supported) {
+ subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+ if (!subdev_dev) {
+ mtk_v4l2_err("Failed to get hw dev\n");
+ return;
+ }
+ pm = &subdev_dev->pm;
+ } else {
+ pm = &vdec_dev->pm;
+ }
+
ret = pm_runtime_put_sync(pm->dev);
if (ret)
mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
}
EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
{
- struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
- int ret, i = 0;
+ struct mtk_vdec_hw_dev *subdev_dev;
+ struct mtk_vcodec_pm *pm;
+ struct mtk_vcodec_clk *dec_clk;
+ int ret, i;
+
+ if (vdec_dev->vdec_pdata->is_subdev_supported) {
+ subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+ if (!subdev_dev) {
+ mtk_v4l2_err("Failed to get hw dev\n");
+ return;
+ }
+ pm = &subdev_dev->pm;
+ enable_irq(subdev_dev->dec_irq);
+ } else {
+ pm = &vdec_dev->pm;
+ enable_irq(vdec_dev->dec_irq);
+ }
+ dec_clk = &pm->vdec_clk;
for (i = 0; i < dec_clk->clk_num; i++) {
ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
if (ret) {
@@ -134,11 +178,27 @@ error:
}
EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
{
- struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
- int i = 0;
+ struct mtk_vdec_hw_dev *subdev_dev;
+ struct mtk_vcodec_pm *pm;
+ struct mtk_vcodec_clk *dec_clk;
+ int i;
+ if (vdec_dev->vdec_pdata->is_subdev_supported) {
+ subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+ if (!subdev_dev) {
+ mtk_v4l2_err("Failed to get hw dev\n");
+ return;
+ }
+ pm = &subdev_dev->pm;
+ disable_irq(subdev_dev->dec_irq);
+ } else {
+ pm = &vdec_dev->pm;
+ disable_irq(vdec_dev->dec_irq);
+ }
+
+ dec_clk = &pm->vdec_clk;
mtk_smi_larb_put(pm->larbvdec);
for (i = dec_clk->clk_num - 1; i >= 0; i--)
clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);