linux/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2016 MediaTek Inc.
   3 * Author: PC Chen <pc.chen@mediatek.com>
   4 *         Tiffany Lin <tiffany.lin@mediatek.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#include <linux/interrupt.h>
  17#include <linux/kernel.h>
  18#include <linux/slab.h>
  19
  20#include "vdec_drv_if.h"
  21#include "mtk_vcodec_dec.h"
  22#include "vdec_drv_base.h"
  23#include "mtk_vcodec_dec_pm.h"
  24#include "mtk_vpu.h"
  25
  26const struct vdec_common_if *get_h264_dec_comm_if(void);
  27const struct vdec_common_if *get_vp8_dec_comm_if(void);
  28const struct vdec_common_if *get_vp9_dec_comm_if(void);
  29
  30int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
  31{
  32        int ret = 0;
  33
  34        switch (fourcc) {
  35        case V4L2_PIX_FMT_H264:
  36                ctx->dec_if = get_h264_dec_comm_if();
  37                break;
  38        case V4L2_PIX_FMT_VP8:
  39                ctx->dec_if = get_vp8_dec_comm_if();
  40                break;
  41        case V4L2_PIX_FMT_VP9:
  42                ctx->dec_if = get_vp9_dec_comm_if();
  43                break;
  44        default:
  45                return -EINVAL;
  46        }
  47
  48        mtk_vdec_lock(ctx);
  49        mtk_vcodec_dec_clock_on(&ctx->dev->pm);
  50        ret = ctx->dec_if->init(ctx, &ctx->drv_handle);
  51        mtk_vcodec_dec_clock_off(&ctx->dev->pm);
  52        mtk_vdec_unlock(ctx);
  53
  54        return ret;
  55}
  56
  57int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
  58                   struct vdec_fb *fb, bool *res_chg)
  59{
  60        int ret = 0;
  61
  62        if (bs) {
  63                if ((bs->dma_addr & 63) != 0) {
  64                        mtk_v4l2_err("bs dma_addr should 64 byte align");
  65                        return -EINVAL;
  66                }
  67        }
  68
  69        if (fb) {
  70                if (((fb->base_y.dma_addr & 511) != 0) ||
  71                    ((fb->base_c.dma_addr & 511) != 0)) {
  72                        mtk_v4l2_err("frame buffer dma_addr should 512 byte align");
  73                        return -EINVAL;
  74                }
  75        }
  76
  77        if (ctx->drv_handle == 0)
  78                return -EIO;
  79
  80        mtk_vdec_lock(ctx);
  81
  82        mtk_vcodec_set_curr_ctx(ctx->dev, ctx);
  83        mtk_vcodec_dec_clock_on(&ctx->dev->pm);
  84        enable_irq(ctx->dev->dec_irq);
  85        ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
  86        disable_irq(ctx->dev->dec_irq);
  87        mtk_vcodec_dec_clock_off(&ctx->dev->pm);
  88        mtk_vcodec_set_curr_ctx(ctx->dev, NULL);
  89
  90        mtk_vdec_unlock(ctx);
  91
  92        return ret;
  93}
  94
  95int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type,
  96                      void *out)
  97{
  98        int ret = 0;
  99
 100        if (ctx->drv_handle == 0)
 101                return -EIO;
 102
 103        mtk_vdec_lock(ctx);
 104        ret = ctx->dec_if->get_param(ctx->drv_handle, type, out);
 105        mtk_vdec_unlock(ctx);
 106
 107        return ret;
 108}
 109
 110void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 111{
 112        if (ctx->drv_handle == 0)
 113                return;
 114
 115        mtk_vdec_lock(ctx);
 116        mtk_vcodec_dec_clock_on(&ctx->dev->pm);
 117        ctx->dec_if->deinit(ctx->drv_handle);
 118        mtk_vcodec_dec_clock_off(&ctx->dev->pm);
 119        mtk_vdec_unlock(ctx);
 120
 121        ctx->drv_handle = 0;
 122}
 123