root/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wake_up_ctx
  2. mtk_vcodec_dec_irq_handler
  3. mtk_vcodec_dec_reset_handler
  4. fops_vcodec_open
  5. fops_vcodec_release
  6. mtk_vcodec_probe
  7. mtk_vcodec_dec_remove

   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/slab.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/irq.h>
  11 #include <linux/module.h>
  12 #include <linux/of_device.h>
  13 #include <linux/of.h>
  14 #include <media/v4l2-event.h>
  15 #include <media/v4l2-mem2mem.h>
  16 #include <media/videobuf2-dma-contig.h>
  17 
  18 #include "mtk_vcodec_drv.h"
  19 #include "mtk_vcodec_dec.h"
  20 #include "mtk_vcodec_dec_pm.h"
  21 #include "mtk_vcodec_intr.h"
  22 #include "mtk_vcodec_util.h"
  23 #include "mtk_vpu.h"
  24 
  25 #define VDEC_HW_ACTIVE  0x10
  26 #define VDEC_IRQ_CFG    0x11
  27 #define VDEC_IRQ_CLR    0x10
  28 #define VDEC_IRQ_CFG_REG        0xa4
  29 
  30 module_param(mtk_v4l2_dbg_level, int, 0644);
  31 module_param(mtk_vcodec_dbg, bool, 0644);
  32 
  33 /* Wake up context wait_queue */
  34 static void wake_up_ctx(struct mtk_vcodec_ctx *ctx)
  35 {
  36         ctx->int_cond = 1;
  37         wake_up_interruptible(&ctx->queue);
  38 }
  39 
  40 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
  41 {
  42         struct mtk_vcodec_dev *dev = priv;
  43         struct mtk_vcodec_ctx *ctx;
  44         u32 cg_status = 0;
  45         unsigned int dec_done_status = 0;
  46         void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
  47                                         VDEC_IRQ_CFG_REG;
  48 
  49         ctx = mtk_vcodec_get_curr_ctx(dev);
  50 
  51         /* check if HW active or not */
  52         cg_status = readl(dev->reg_base[0]);
  53         if ((cg_status & VDEC_HW_ACTIVE) != 0) {
  54                 mtk_v4l2_err("DEC ISR, VDEC active is not 0x0 (0x%08x)",
  55                              cg_status);
  56                 return IRQ_HANDLED;
  57         }
  58 
  59         dec_done_status = readl(vdec_misc_addr);
  60         ctx->irq_status = dec_done_status;
  61         if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
  62                 MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
  63                 return IRQ_HANDLED;
  64 
  65         /* clear interrupt */
  66         writel((readl(vdec_misc_addr) | VDEC_IRQ_CFG),
  67                 dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
  68         writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
  69                 dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
  70 
  71         wake_up_ctx(ctx);
  72 
  73         mtk_v4l2_debug(3,
  74                         "mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
  75                         ctx->id, dec_done_status);
  76 
  77         return IRQ_HANDLED;
  78 }
  79 
  80 static void mtk_vcodec_dec_reset_handler(void *priv)
  81 {
  82         struct mtk_vcodec_dev *dev = priv;
  83         struct mtk_vcodec_ctx *ctx;
  84 
  85         mtk_v4l2_err("Watchdog timeout!!");
  86 
  87         mutex_lock(&dev->dev_mutex);
  88         list_for_each_entry(ctx, &dev->ctx_list, list) {
  89                 ctx->state = MTK_STATE_ABORT;
  90                 mtk_v4l2_debug(0, "[%d] Change to state MTK_STATE_ERROR",
  91                                 ctx->id);
  92         }
  93         mutex_unlock(&dev->dev_mutex);
  94 }
  95 
  96 static int fops_vcodec_open(struct file *file)
  97 {
  98         struct mtk_vcodec_dev *dev = video_drvdata(file);
  99         struct mtk_vcodec_ctx *ctx = NULL;
 100         struct mtk_video_dec_buf *mtk_buf = NULL;
 101         int ret = 0;
 102         struct vb2_queue *src_vq;
 103 
 104         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 105         if (!ctx)
 106                 return -ENOMEM;
 107         mtk_buf = kzalloc(sizeof(*mtk_buf), GFP_KERNEL);
 108         if (!mtk_buf) {
 109                 kfree(ctx);
 110                 return -ENOMEM;
 111         }
 112 
 113         mutex_lock(&dev->dev_mutex);
 114         ctx->empty_flush_buf = mtk_buf;
 115         ctx->id = dev->id_counter++;
 116         v4l2_fh_init(&ctx->fh, video_devdata(file));
 117         file->private_data = &ctx->fh;
 118         v4l2_fh_add(&ctx->fh);
 119         INIT_LIST_HEAD(&ctx->list);
 120         ctx->dev = dev;
 121         init_waitqueue_head(&ctx->queue);
 122         mutex_init(&ctx->lock);
 123 
 124         ctx->type = MTK_INST_DECODER;
 125         ret = mtk_vcodec_dec_ctrls_setup(ctx);
 126         if (ret) {
 127                 mtk_v4l2_err("Failed to setup mt vcodec controls");
 128                 goto err_ctrls_setup;
 129         }
 130         ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_dec, ctx,
 131                 &mtk_vcodec_dec_queue_init);
 132         if (IS_ERR((__force void *)ctx->m2m_ctx)) {
 133                 ret = PTR_ERR((__force void *)ctx->m2m_ctx);
 134                 mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)",
 135                         ret);
 136                 goto err_m2m_ctx_init;
 137         }
 138         src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 139                                 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 140         ctx->empty_flush_buf->vb.vb2_buf.vb2_queue = src_vq;
 141         ctx->empty_flush_buf->lastframe = true;
 142         mtk_vcodec_dec_set_default_params(ctx);
 143 
 144         if (v4l2_fh_is_singular(&ctx->fh)) {
 145                 mtk_vcodec_dec_pw_on(&dev->pm);
 146                 /*
 147                  * vpu_load_firmware checks if it was loaded already and
 148                  * does nothing in that case
 149                  */
 150                 ret = vpu_load_firmware(dev->vpu_plat_dev);
 151                 if (ret < 0) {
 152                         /*
 153                          * Return 0 if downloading firmware successfully,
 154                          * otherwise it is failed
 155                          */
 156                         mtk_v4l2_err("vpu_load_firmware failed!");
 157                         goto err_load_fw;
 158                 }
 159 
 160                 dev->dec_capability =
 161                         vpu_get_vdec_hw_capa(dev->vpu_plat_dev);
 162                 mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability);
 163         }
 164 
 165         list_add(&ctx->list, &dev->ctx_list);
 166 
 167         mutex_unlock(&dev->dev_mutex);
 168         mtk_v4l2_debug(0, "%s decoder [%d]", dev_name(&dev->plat_dev->dev),
 169                         ctx->id);
 170         return ret;
 171 
 172         /* Deinit when failure occurred */
 173 err_load_fw:
 174         v4l2_m2m_ctx_release(ctx->m2m_ctx);
 175 err_m2m_ctx_init:
 176         v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 177 err_ctrls_setup:
 178         v4l2_fh_del(&ctx->fh);
 179         v4l2_fh_exit(&ctx->fh);
 180         kfree(ctx->empty_flush_buf);
 181         kfree(ctx);
 182         mutex_unlock(&dev->dev_mutex);
 183 
 184         return ret;
 185 }
 186 
 187 static int fops_vcodec_release(struct file *file)
 188 {
 189         struct mtk_vcodec_dev *dev = video_drvdata(file);
 190         struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
 191 
 192         mtk_v4l2_debug(0, "[%d] decoder", ctx->id);
 193         mutex_lock(&dev->dev_mutex);
 194 
 195         /*
 196          * Call v4l2_m2m_ctx_release before mtk_vcodec_dec_release. First, it
 197          * makes sure the worker thread is not running after vdec_if_deinit.
 198          * Second, the decoder will be flushed and all the buffers will be
 199          * returned in stop_streaming.
 200          */
 201         v4l2_m2m_ctx_release(ctx->m2m_ctx);
 202         mtk_vcodec_dec_release(ctx);
 203 
 204         if (v4l2_fh_is_singular(&ctx->fh))
 205                 mtk_vcodec_dec_pw_off(&dev->pm);
 206         v4l2_fh_del(&ctx->fh);
 207         v4l2_fh_exit(&ctx->fh);
 208         v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 209 
 210         list_del_init(&ctx->list);
 211         kfree(ctx->empty_flush_buf);
 212         kfree(ctx);
 213         mutex_unlock(&dev->dev_mutex);
 214         return 0;
 215 }
 216 
 217 static const struct v4l2_file_operations mtk_vcodec_fops = {
 218         .owner          = THIS_MODULE,
 219         .open           = fops_vcodec_open,
 220         .release        = fops_vcodec_release,
 221         .poll           = v4l2_m2m_fop_poll,
 222         .unlocked_ioctl = video_ioctl2,
 223         .mmap           = v4l2_m2m_fop_mmap,
 224 };
 225 
 226 static int mtk_vcodec_probe(struct platform_device *pdev)
 227 {
 228         struct mtk_vcodec_dev *dev;
 229         struct video_device *vfd_dec;
 230         struct resource *res;
 231         int i, ret;
 232 
 233         dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 234         if (!dev)
 235                 return -ENOMEM;
 236 
 237         INIT_LIST_HEAD(&dev->ctx_list);
 238         dev->plat_dev = pdev;
 239 
 240         dev->vpu_plat_dev = vpu_get_plat_device(dev->plat_dev);
 241         if (dev->vpu_plat_dev == NULL) {
 242                 mtk_v4l2_err("[VPU] vpu device in not ready");
 243                 return -EPROBE_DEFER;
 244         }
 245 
 246         vpu_wdt_reg_handler(dev->vpu_plat_dev, mtk_vcodec_dec_reset_handler,
 247                         dev, VPU_RST_DEC);
 248 
 249         ret = mtk_vcodec_init_dec_pm(dev);
 250         if (ret < 0) {
 251                 dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
 252                 return ret;
 253         }
 254 
 255         for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) {
 256                 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
 257                 if (res == NULL) {
 258                         dev_err(&pdev->dev, "get memory resource failed.");
 259                         ret = -ENXIO;
 260                         goto err_res;
 261                 }
 262                 dev->reg_base[i] = devm_ioremap_resource(&pdev->dev, res);
 263                 if (IS_ERR((__force void *)dev->reg_base[i])) {
 264                         ret = PTR_ERR((__force void *)dev->reg_base[i]);
 265                         goto err_res;
 266                 }
 267                 mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
 268         }
 269 
 270         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 271         if (res == NULL) {
 272                 dev_err(&pdev->dev, "failed to get irq resource");
 273                 ret = -ENOENT;
 274                 goto err_res;
 275         }
 276 
 277         dev->dec_irq = platform_get_irq(pdev, 0);
 278         ret = devm_request_irq(&pdev->dev, dev->dec_irq,
 279                         mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
 280         if (ret) {
 281                 dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
 282                         dev->dec_irq,
 283                         ret);
 284                 goto err_res;
 285         }
 286 
 287         disable_irq(dev->dec_irq);
 288         mutex_init(&dev->dec_mutex);
 289         mutex_init(&dev->dev_mutex);
 290         spin_lock_init(&dev->irqlock);
 291 
 292         snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
 293                 "[/MTK_V4L2_VDEC]");
 294 
 295         ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
 296         if (ret) {
 297                 mtk_v4l2_err("v4l2_device_register err=%d", ret);
 298                 goto err_res;
 299         }
 300 
 301         init_waitqueue_head(&dev->queue);
 302 
 303         vfd_dec = video_device_alloc();
 304         if (!vfd_dec) {
 305                 mtk_v4l2_err("Failed to allocate video device");
 306                 ret = -ENOMEM;
 307                 goto err_dec_alloc;
 308         }
 309         vfd_dec->fops           = &mtk_vcodec_fops;
 310         vfd_dec->ioctl_ops      = &mtk_vdec_ioctl_ops;
 311         vfd_dec->release        = video_device_release;
 312         vfd_dec->lock           = &dev->dev_mutex;
 313         vfd_dec->v4l2_dev       = &dev->v4l2_dev;
 314         vfd_dec->vfl_dir        = VFL_DIR_M2M;
 315         vfd_dec->device_caps    = V4L2_CAP_VIDEO_M2M_MPLANE |
 316                         V4L2_CAP_STREAMING;
 317 
 318         snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s",
 319                 MTK_VCODEC_DEC_NAME);
 320         video_set_drvdata(vfd_dec, dev);
 321         dev->vfd_dec = vfd_dec;
 322         platform_set_drvdata(pdev, dev);
 323 
 324         dev->m2m_dev_dec = v4l2_m2m_init(&mtk_vdec_m2m_ops);
 325         if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
 326                 mtk_v4l2_err("Failed to init mem2mem dec device");
 327                 ret = PTR_ERR((__force void *)dev->m2m_dev_dec);
 328                 goto err_dec_mem_init;
 329         }
 330 
 331         dev->decode_workqueue =
 332                 alloc_ordered_workqueue(MTK_VCODEC_DEC_NAME,
 333                         WQ_MEM_RECLAIM | WQ_FREEZABLE);
 334         if (!dev->decode_workqueue) {
 335                 mtk_v4l2_err("Failed to create decode workqueue");
 336                 ret = -EINVAL;
 337                 goto err_event_workq;
 338         }
 339 
 340         ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 0);
 341         if (ret) {
 342                 mtk_v4l2_err("Failed to register video device");
 343                 goto err_dec_reg;
 344         }
 345 
 346         mtk_v4l2_debug(0, "decoder registered as /dev/video%d",
 347                 vfd_dec->num);
 348 
 349         return 0;
 350 
 351 err_dec_reg:
 352         destroy_workqueue(dev->decode_workqueue);
 353 err_event_workq:
 354         v4l2_m2m_release(dev->m2m_dev_dec);
 355 err_dec_mem_init:
 356         video_unregister_device(vfd_dec);
 357 err_dec_alloc:
 358         v4l2_device_unregister(&dev->v4l2_dev);
 359 err_res:
 360         mtk_vcodec_release_dec_pm(dev);
 361         return ret;
 362 }
 363 
 364 static const struct of_device_id mtk_vcodec_match[] = {
 365         {.compatible = "mediatek,mt8173-vcodec-dec",},
 366         {},
 367 };
 368 
 369 MODULE_DEVICE_TABLE(of, mtk_vcodec_match);
 370 
 371 static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 372 {
 373         struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev);
 374 
 375         flush_workqueue(dev->decode_workqueue);
 376         destroy_workqueue(dev->decode_workqueue);
 377         if (dev->m2m_dev_dec)
 378                 v4l2_m2m_release(dev->m2m_dev_dec);
 379 
 380         if (dev->vfd_dec)
 381                 video_unregister_device(dev->vfd_dec);
 382 
 383         v4l2_device_unregister(&dev->v4l2_dev);
 384         mtk_vcodec_release_dec_pm(dev);
 385         return 0;
 386 }
 387 
 388 static struct platform_driver mtk_vcodec_dec_driver = {
 389         .probe  = mtk_vcodec_probe,
 390         .remove = mtk_vcodec_dec_remove,
 391         .driver = {
 392                 .name   = MTK_VCODEC_DEC_NAME,
 393                 .of_match_table = mtk_vcodec_match,
 394         },
 395 };
 396 
 397 module_platform_driver(mtk_vcodec_dec_driver);
 398 
 399 MODULE_LICENSE("GPL v2");
 400 MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");

/* [<][>][^][v][top][bottom][index][help] */