Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.8 394 lines 10 kB view raw
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 30module_param(mtk_v4l2_dbg_level, int, 0644); 31module_param(mtk_vcodec_dbg, bool, 0644); 32 33/* Wake up context wait_queue */ 34static void wake_up_ctx(struct mtk_vcodec_ctx *ctx) 35{ 36 ctx->int_cond = 1; 37 wake_up_interruptible(&ctx->queue); 38} 39 40static 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 80static 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 96static 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->m2m_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 */ 173err_load_fw: 174 v4l2_m2m_ctx_release(ctx->m2m_ctx); 175err_m2m_ctx_init: 176 v4l2_ctrl_handler_free(&ctx->ctrl_hdl); 177err_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 187static 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 217static 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 226static 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 dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i); 257 if (IS_ERR((__force void *)dev->reg_base[i])) { 258 ret = PTR_ERR((__force void *)dev->reg_base[i]); 259 goto err_res; 260 } 261 mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]); 262 } 263 264 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 265 if (res == NULL) { 266 dev_err(&pdev->dev, "failed to get irq resource"); 267 ret = -ENOENT; 268 goto err_res; 269 } 270 271 dev->dec_irq = platform_get_irq(pdev, 0); 272 ret = devm_request_irq(&pdev->dev, dev->dec_irq, 273 mtk_vcodec_dec_irq_handler, 0, pdev->name, dev); 274 if (ret) { 275 dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)", 276 dev->dec_irq, 277 ret); 278 goto err_res; 279 } 280 281 disable_irq(dev->dec_irq); 282 mutex_init(&dev->dec_mutex); 283 mutex_init(&dev->dev_mutex); 284 spin_lock_init(&dev->irqlock); 285 286 snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s", 287 "[/MTK_V4L2_VDEC]"); 288 289 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); 290 if (ret) { 291 mtk_v4l2_err("v4l2_device_register err=%d", ret); 292 goto err_res; 293 } 294 295 init_waitqueue_head(&dev->queue); 296 297 vfd_dec = video_device_alloc(); 298 if (!vfd_dec) { 299 mtk_v4l2_err("Failed to allocate video device"); 300 ret = -ENOMEM; 301 goto err_dec_alloc; 302 } 303 vfd_dec->fops = &mtk_vcodec_fops; 304 vfd_dec->ioctl_ops = &mtk_vdec_ioctl_ops; 305 vfd_dec->release = video_device_release; 306 vfd_dec->lock = &dev->dev_mutex; 307 vfd_dec->v4l2_dev = &dev->v4l2_dev; 308 vfd_dec->vfl_dir = VFL_DIR_M2M; 309 vfd_dec->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | 310 V4L2_CAP_STREAMING; 311 312 snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s", 313 MTK_VCODEC_DEC_NAME); 314 video_set_drvdata(vfd_dec, dev); 315 dev->vfd_dec = vfd_dec; 316 platform_set_drvdata(pdev, dev); 317 318 dev->m2m_dev_dec = v4l2_m2m_init(&mtk_vdec_m2m_ops); 319 if (IS_ERR((__force void *)dev->m2m_dev_dec)) { 320 mtk_v4l2_err("Failed to init mem2mem dec device"); 321 ret = PTR_ERR((__force void *)dev->m2m_dev_dec); 322 goto err_dec_mem_init; 323 } 324 325 dev->decode_workqueue = 326 alloc_ordered_workqueue(MTK_VCODEC_DEC_NAME, 327 WQ_MEM_RECLAIM | WQ_FREEZABLE); 328 if (!dev->decode_workqueue) { 329 mtk_v4l2_err("Failed to create decode workqueue"); 330 ret = -EINVAL; 331 goto err_event_workq; 332 } 333 334 ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 0); 335 if (ret) { 336 mtk_v4l2_err("Failed to register video device"); 337 goto err_dec_reg; 338 } 339 340 mtk_v4l2_debug(0, "decoder registered as /dev/video%d", 341 vfd_dec->num); 342 343 return 0; 344 345err_dec_reg: 346 destroy_workqueue(dev->decode_workqueue); 347err_event_workq: 348 v4l2_m2m_release(dev->m2m_dev_dec); 349err_dec_mem_init: 350 video_unregister_device(vfd_dec); 351err_dec_alloc: 352 v4l2_device_unregister(&dev->v4l2_dev); 353err_res: 354 mtk_vcodec_release_dec_pm(dev); 355 return ret; 356} 357 358static const struct of_device_id mtk_vcodec_match[] = { 359 {.compatible = "mediatek,mt8173-vcodec-dec",}, 360 {}, 361}; 362 363MODULE_DEVICE_TABLE(of, mtk_vcodec_match); 364 365static int mtk_vcodec_dec_remove(struct platform_device *pdev) 366{ 367 struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev); 368 369 flush_workqueue(dev->decode_workqueue); 370 destroy_workqueue(dev->decode_workqueue); 371 if (dev->m2m_dev_dec) 372 v4l2_m2m_release(dev->m2m_dev_dec); 373 374 if (dev->vfd_dec) 375 video_unregister_device(dev->vfd_dec); 376 377 v4l2_device_unregister(&dev->v4l2_dev); 378 mtk_vcodec_release_dec_pm(dev); 379 return 0; 380} 381 382static struct platform_driver mtk_vcodec_dec_driver = { 383 .probe = mtk_vcodec_probe, 384 .remove = mtk_vcodec_dec_remove, 385 .driver = { 386 .name = MTK_VCODEC_DEC_NAME, 387 .of_match_table = mtk_vcodec_match, 388 }, 389}; 390 391module_platform_driver(mtk_vcodec_dec_driver); 392 393MODULE_LICENSE("GPL v2"); 394MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");