129 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2016 MediaTek Inc.4 * Author: PC Chen <pc.chen@mediatek.com>5 * Tiffany Lin <tiffany.lin@mediatek.com>6 */7 8#include <linux/interrupt.h>9#include <linux/kernel.h>10#include <linux/slab.h>11 12#include "vdec_drv_if.h"13#include "mtk_vcodec_dec.h"14#include "vdec_drv_base.h"15#include "mtk_vcodec_dec_pm.h"16 17int vdec_if_init(struct mtk_vcodec_dec_ctx *ctx, unsigned int fourcc)18{19 enum mtk_vdec_hw_arch hw_arch = ctx->dev->vdec_pdata->hw_arch;20 int ret = 0;21 22 switch (fourcc) {23 case V4L2_PIX_FMT_H264_SLICE:24 if (!ctx->dev->vdec_pdata->is_subdev_supported) {25 ctx->dec_if = &vdec_h264_slice_if;26 ctx->hw_id = MTK_VDEC_CORE;27 } else {28 ctx->dec_if = &vdec_h264_slice_multi_if;29 ctx->hw_id = IS_VDEC_LAT_ARCH(hw_arch) ? MTK_VDEC_LAT0 : MTK_VDEC_CORE;30 }31 break;32 case V4L2_PIX_FMT_H264:33 ctx->dec_if = &vdec_h264_if;34 ctx->hw_id = MTK_VDEC_CORE;35 break;36 case V4L2_PIX_FMT_VP8_FRAME:37 ctx->dec_if = &vdec_vp8_slice_if;38 ctx->hw_id = MTK_VDEC_CORE;39 break;40 case V4L2_PIX_FMT_VP8:41 ctx->dec_if = &vdec_vp8_if;42 ctx->hw_id = MTK_VDEC_CORE;43 break;44 case V4L2_PIX_FMT_VP9:45 ctx->dec_if = &vdec_vp9_if;46 ctx->hw_id = MTK_VDEC_CORE;47 break;48 case V4L2_PIX_FMT_VP9_FRAME:49 ctx->dec_if = &vdec_vp9_slice_lat_if;50 ctx->hw_id = IS_VDEC_LAT_ARCH(hw_arch) ? MTK_VDEC_LAT0 : MTK_VDEC_CORE;51 break;52 case V4L2_PIX_FMT_HEVC_SLICE:53 ctx->dec_if = &vdec_hevc_slice_multi_if;54 ctx->hw_id = MTK_VDEC_LAT0;55 break;56 case V4L2_PIX_FMT_AV1_FRAME:57 ctx->dec_if = &vdec_av1_slice_lat_if;58 ctx->hw_id = MTK_VDEC_LAT0;59 break;60 default:61 return -EINVAL;62 }63 64 mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);65 ret = ctx->dec_if->init(ctx);66 mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);67 68 return ret;69}70 71int vdec_if_decode(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_mem *bs,72 struct vdec_fb *fb, bool *res_chg)73{74 int ret = 0;75 76 if (bs) {77 if ((bs->dma_addr & 63) != 0) {78 mtk_v4l2_vdec_err(ctx, "bs dma_addr should 64 byte align");79 return -EINVAL;80 }81 }82 83 if (fb) {84 if (((fb->base_y.dma_addr & 511) != 0) ||85 ((fb->base_c.dma_addr & 511) != 0)) {86 mtk_v4l2_vdec_err(ctx, "frame buffer dma_addr should 512 byte align");87 return -EINVAL;88 }89 }90 91 if (!ctx->drv_handle)92 return -EIO;93 94 mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);95 mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);96 ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);97 mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);98 mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);99 100 return ret;101}102 103int vdec_if_get_param(struct mtk_vcodec_dec_ctx *ctx, enum vdec_get_param_type type,104 void *out)105{106 int ret = 0;107 108 if (!ctx->drv_handle)109 return -EIO;110 111 mtk_vdec_lock(ctx);112 ret = ctx->dec_if->get_param(ctx->drv_handle, type, out);113 mtk_vdec_unlock(ctx);114 115 return ret;116}117 118void vdec_if_deinit(struct mtk_vcodec_dec_ctx *ctx)119{120 if (!ctx->drv_handle)121 return;122 123 mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);124 ctx->dec_if->deinit(ctx->drv_handle);125 mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);126 127 ctx->drv_handle = NULL;128}129