linux/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   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_ctx *ctx, unsigned int fourcc)
  18{
  19        int ret = 0;
  20
  21        switch (fourcc) {
  22        case V4L2_PIX_FMT_H264_SLICE:
  23                ctx->dec_if = &vdec_h264_slice_if;
  24                break;
  25        case V4L2_PIX_FMT_H264:
  26                ctx->dec_if = &vdec_h264_if;
  27                ctx->hw_id = MTK_VDEC_CORE;
  28                break;
  29        case V4L2_PIX_FMT_VP8:
  30                ctx->dec_if = &vdec_vp8_if;
  31                ctx->hw_id = MTK_VDEC_CORE;
  32                break;
  33        case V4L2_PIX_FMT_VP9:
  34                ctx->dec_if = &vdec_vp9_if;
  35                ctx->hw_id = MTK_VDEC_CORE;
  36                break;
  37        default:
  38                return -EINVAL;
  39        }
  40
  41        mtk_vdec_lock(ctx);
  42        mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
  43        ret = ctx->dec_if->init(ctx);
  44        mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
  45        mtk_vdec_unlock(ctx);
  46
  47        return ret;
  48}
  49
  50int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
  51                   struct vdec_fb *fb, bool *res_chg)
  52{
  53        int ret = 0;
  54
  55        if (bs) {
  56                if ((bs->dma_addr & 63) != 0) {
  57                        mtk_v4l2_err("bs dma_addr should 64 byte align");
  58                        return -EINVAL;
  59                }
  60        }
  61
  62        if (fb) {
  63                if (((fb->base_y.dma_addr & 511) != 0) ||
  64                    ((fb->base_c.dma_addr & 511) != 0)) {
  65                        mtk_v4l2_err("frame buffer dma_addr should 512 byte align");
  66                        return -EINVAL;
  67                }
  68        }
  69
  70        if (!ctx->drv_handle)
  71                return -EIO;
  72
  73        mtk_vdec_lock(ctx);
  74
  75        mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
  76        mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
  77        ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
  78        mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
  79        mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
  80
  81        mtk_vdec_unlock(ctx);
  82
  83        return ret;
  84}
  85
  86int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type,
  87                      void *out)
  88{
  89        int ret = 0;
  90
  91        if (!ctx->drv_handle)
  92                return -EIO;
  93
  94        mtk_vdec_lock(ctx);
  95        ret = ctx->dec_if->get_param(ctx->drv_handle, type, out);
  96        mtk_vdec_unlock(ctx);
  97
  98        return ret;
  99}
 100
 101void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 102{
 103        if (!ctx->drv_handle)
 104                return;
 105
 106        mtk_vdec_lock(ctx);
 107        mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 108        ctx->dec_if->deinit(ctx->drv_handle);
 109        mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 110        mtk_vdec_unlock(ctx);
 111
 112        ctx->drv_handle = NULL;
 113}
 114