• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_vcodec_fw.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 */
wake_up_ctx(struct mtk_vcodec_ctx * ctx)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 
mtk_vcodec_dec_irq_handler(int irq,void * priv)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 
fops_vcodec_open(struct file * file)80 static int fops_vcodec_open(struct file *file)
81 {
82 	struct mtk_vcodec_dev *dev = video_drvdata(file);
83 	struct mtk_vcodec_ctx *ctx = NULL;
84 	struct mtk_video_dec_buf *mtk_buf = NULL;
85 	int ret = 0;
86 	struct vb2_queue *src_vq;
87 
88 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
89 	if (!ctx)
90 		return -ENOMEM;
91 	mtk_buf = kzalloc(sizeof(*mtk_buf), GFP_KERNEL);
92 	if (!mtk_buf) {
93 		kfree(ctx);
94 		return -ENOMEM;
95 	}
96 
97 	mutex_lock(&dev->dev_mutex);
98 	ctx->empty_flush_buf = mtk_buf;
99 	ctx->id = dev->id_counter++;
100 	v4l2_fh_init(&ctx->fh, video_devdata(file));
101 	file->private_data = &ctx->fh;
102 	v4l2_fh_add(&ctx->fh);
103 	INIT_LIST_HEAD(&ctx->list);
104 	ctx->dev = dev;
105 	init_waitqueue_head(&ctx->queue);
106 	mutex_init(&ctx->lock);
107 
108 	ctx->type = MTK_INST_DECODER;
109 	ret = mtk_vcodec_dec_ctrls_setup(ctx);
110 	if (ret) {
111 		mtk_v4l2_err("Failed to setup mt vcodec controls");
112 		goto err_ctrls_setup;
113 	}
114 	ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_dec, ctx,
115 		&mtk_vcodec_dec_queue_init);
116 	if (IS_ERR((__force void *)ctx->m2m_ctx)) {
117 		ret = PTR_ERR((__force void *)ctx->m2m_ctx);
118 		mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)",
119 			ret);
120 		goto err_m2m_ctx_init;
121 	}
122 	src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
123 				V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
124 	ctx->empty_flush_buf->m2m_buf.vb.vb2_buf.vb2_queue = src_vq;
125 	ctx->empty_flush_buf->lastframe = true;
126 	mtk_vcodec_dec_set_default_params(ctx);
127 
128 	if (v4l2_fh_is_singular(&ctx->fh)) {
129 		ret = mtk_vcodec_dec_pw_on(&dev->pm);
130 		if (ret < 0)
131 			goto err_load_fw;
132 		/*
133 		 * Does nothing if firmware was already loaded.
134 		 */
135 		ret = mtk_vcodec_fw_load_firmware(dev->fw_handler);
136 		if (ret < 0) {
137 			/*
138 			 * Return 0 if downloading firmware successfully,
139 			 * otherwise it is failed
140 			 */
141 			mtk_v4l2_err("failed to load firmware!");
142 			goto err_load_fw;
143 		}
144 
145 		dev->dec_capability =
146 			mtk_vcodec_fw_get_vdec_capa(dev->fw_handler);
147 		mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability);
148 	}
149 
150 	list_add(&ctx->list, &dev->ctx_list);
151 
152 	mutex_unlock(&dev->dev_mutex);
153 	mtk_v4l2_debug(0, "%s decoder [%d]", dev_name(&dev->plat_dev->dev),
154 			ctx->id);
155 	return ret;
156 
157 	/* Deinit when failure occurred */
158 err_load_fw:
159 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
160 err_m2m_ctx_init:
161 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
162 err_ctrls_setup:
163 	v4l2_fh_del(&ctx->fh);
164 	v4l2_fh_exit(&ctx->fh);
165 	kfree(ctx->empty_flush_buf);
166 	kfree(ctx);
167 	mutex_unlock(&dev->dev_mutex);
168 
169 	return ret;
170 }
171 
fops_vcodec_release(struct file * file)172 static int fops_vcodec_release(struct file *file)
173 {
174 	struct mtk_vcodec_dev *dev = video_drvdata(file);
175 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
176 
177 	mtk_v4l2_debug(0, "[%d] decoder", ctx->id);
178 	mutex_lock(&dev->dev_mutex);
179 
180 	/*
181 	 * Call v4l2_m2m_ctx_release before mtk_vcodec_dec_release. First, it
182 	 * makes sure the worker thread is not running after vdec_if_deinit.
183 	 * Second, the decoder will be flushed and all the buffers will be
184 	 * returned in stop_streaming.
185 	 */
186 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
187 	mtk_vcodec_dec_release(ctx);
188 
189 	if (v4l2_fh_is_singular(&ctx->fh))
190 		mtk_vcodec_dec_pw_off(&dev->pm);
191 	v4l2_fh_del(&ctx->fh);
192 	v4l2_fh_exit(&ctx->fh);
193 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
194 
195 	list_del_init(&ctx->list);
196 	kfree(ctx->empty_flush_buf);
197 	kfree(ctx);
198 	mutex_unlock(&dev->dev_mutex);
199 	return 0;
200 }
201 
202 static const struct v4l2_file_operations mtk_vcodec_fops = {
203 	.owner		= THIS_MODULE,
204 	.open		= fops_vcodec_open,
205 	.release	= fops_vcodec_release,
206 	.poll		= v4l2_m2m_fop_poll,
207 	.unlocked_ioctl	= video_ioctl2,
208 	.mmap		= v4l2_m2m_fop_mmap,
209 };
210 
mtk_vcodec_probe(struct platform_device * pdev)211 static int mtk_vcodec_probe(struct platform_device *pdev)
212 {
213 	struct mtk_vcodec_dev *dev;
214 	struct video_device *vfd_dec;
215 	struct resource *res;
216 	phandle rproc_phandle;
217 	enum mtk_vcodec_fw_type fw_type;
218 	int i, ret;
219 
220 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
221 	if (!dev)
222 		return -ENOMEM;
223 
224 	INIT_LIST_HEAD(&dev->ctx_list);
225 	dev->plat_dev = pdev;
226 
227 	if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vpu",
228 				  &rproc_phandle)) {
229 		fw_type = VPU;
230 	} else if (!of_property_read_u32(pdev->dev.of_node, "mediatek,scp",
231 					 &rproc_phandle)) {
232 		fw_type = SCP;
233 	} else {
234 		mtk_v4l2_err("Could not get vdec IPI device");
235 		return -ENODEV;
236 	}
237 	if (!pdev->dev.dma_parms) {
238 		pdev->dev.dma_parms = devm_kzalloc(&pdev->dev,
239 						sizeof(*pdev->dev.dma_parms),
240 						GFP_KERNEL);
241 		if (!pdev->dev.dma_parms)
242 			return -ENOMEM;
243 	}
244 	dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
245 
246 	dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, DECODER);
247 	if (IS_ERR(dev->fw_handler))
248 		return PTR_ERR(dev->fw_handler);
249 
250 	ret = mtk_vcodec_init_dec_pm(dev);
251 	if (ret < 0) {
252 		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
253 		goto err_dec_pm;
254 	}
255 
256 	for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) {
257 		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
258 		if (IS_ERR((__force void *)dev->reg_base[i])) {
259 			ret = PTR_ERR((__force void *)dev->reg_base[i]);
260 			goto err_res;
261 		}
262 		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
263 	}
264 
265 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
266 	if (res == NULL) {
267 		dev_err(&pdev->dev, "failed to get irq resource");
268 		ret = -ENOENT;
269 		goto err_res;
270 	}
271 
272 	dev->dec_irq = platform_get_irq(pdev, 0);
273 	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
274 	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
275 			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
276 	if (ret) {
277 		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
278 			dev->dec_irq,
279 			ret);
280 		goto err_res;
281 	}
282 
283 	mutex_init(&dev->dec_mutex);
284 	mutex_init(&dev->dev_mutex);
285 	spin_lock_init(&dev->irqlock);
286 
287 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
288 		"[/MTK_V4L2_VDEC]");
289 
290 	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
291 	if (ret) {
292 		mtk_v4l2_err("v4l2_device_register err=%d", ret);
293 		goto err_res;
294 	}
295 
296 	init_waitqueue_head(&dev->queue);
297 
298 	vfd_dec = video_device_alloc();
299 	if (!vfd_dec) {
300 		mtk_v4l2_err("Failed to allocate video device");
301 		ret = -ENOMEM;
302 		goto err_dec_alloc;
303 	}
304 	vfd_dec->fops		= &mtk_vcodec_fops;
305 	vfd_dec->ioctl_ops	= &mtk_vdec_ioctl_ops;
306 	vfd_dec->release	= video_device_release;
307 	vfd_dec->lock		= &dev->dev_mutex;
308 	vfd_dec->v4l2_dev	= &dev->v4l2_dev;
309 	vfd_dec->vfl_dir	= VFL_DIR_M2M;
310 	vfd_dec->device_caps	= V4L2_CAP_VIDEO_M2M_MPLANE |
311 			V4L2_CAP_STREAMING;
312 
313 	snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s",
314 		MTK_VCODEC_DEC_NAME);
315 	video_set_drvdata(vfd_dec, dev);
316 	dev->vfd_dec = vfd_dec;
317 	platform_set_drvdata(pdev, dev);
318 
319 	dev->m2m_dev_dec = v4l2_m2m_init(&mtk_vdec_m2m_ops);
320 	if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
321 		mtk_v4l2_err("Failed to init mem2mem dec device");
322 		ret = PTR_ERR((__force void *)dev->m2m_dev_dec);
323 		goto err_dec_mem_init;
324 	}
325 
326 	dev->decode_workqueue =
327 		alloc_ordered_workqueue(MTK_VCODEC_DEC_NAME,
328 			WQ_MEM_RECLAIM | WQ_FREEZABLE);
329 	if (!dev->decode_workqueue) {
330 		mtk_v4l2_err("Failed to create decode workqueue");
331 		ret = -EINVAL;
332 		goto err_event_workq;
333 	}
334 
335 	ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 0);
336 	if (ret) {
337 		mtk_v4l2_err("Failed to register video device");
338 		goto err_dec_reg;
339 	}
340 
341 	mtk_v4l2_debug(0, "decoder registered as /dev/video%d",
342 		vfd_dec->num);
343 
344 	return 0;
345 
346 err_dec_reg:
347 	destroy_workqueue(dev->decode_workqueue);
348 err_event_workq:
349 	v4l2_m2m_release(dev->m2m_dev_dec);
350 err_dec_mem_init:
351 	video_unregister_device(vfd_dec);
352 err_dec_alloc:
353 	v4l2_device_unregister(&dev->v4l2_dev);
354 err_res:
355 	mtk_vcodec_release_dec_pm(dev);
356 err_dec_pm:
357 	mtk_vcodec_fw_release(dev->fw_handler);
358 	return ret;
359 }
360 
361 static const struct of_device_id mtk_vcodec_match[] = {
362 	{.compatible = "mediatek,mt8173-vcodec-dec",},
363 	{},
364 };
365 
366 MODULE_DEVICE_TABLE(of, mtk_vcodec_match);
367 
mtk_vcodec_dec_remove(struct platform_device * pdev)368 static int mtk_vcodec_dec_remove(struct platform_device *pdev)
369 {
370 	struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev);
371 
372 	flush_workqueue(dev->decode_workqueue);
373 	destroy_workqueue(dev->decode_workqueue);
374 	if (dev->m2m_dev_dec)
375 		v4l2_m2m_release(dev->m2m_dev_dec);
376 
377 	if (dev->vfd_dec)
378 		video_unregister_device(dev->vfd_dec);
379 
380 	v4l2_device_unregister(&dev->v4l2_dev);
381 	mtk_vcodec_release_dec_pm(dev);
382 	mtk_vcodec_fw_release(dev->fw_handler);
383 	return 0;
384 }
385 
386 static struct platform_driver mtk_vcodec_dec_driver = {
387 	.probe	= mtk_vcodec_probe,
388 	.remove	= mtk_vcodec_dec_remove,
389 	.driver	= {
390 		.name	= MTK_VCODEC_DEC_NAME,
391 		.of_match_table = mtk_vcodec_match,
392 	},
393 };
394 
395 module_platform_driver(mtk_vcodec_dec_driver);
396 
397 MODULE_LICENSE("GPL v2");
398 MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");
399