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