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

Configure Feed

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

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