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