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 #include <linux/pm_runtime.h>
18 
19 #include "mtk_vcodec_drv.h"
20 #include "mtk_vcodec_enc.h"
21 #include "mtk_vcodec_enc_pm.h"
22 #include "mtk_vcodec_intr.h"
23 #include "mtk_vcodec_util.h"
24 #include "mtk_vcodec_fw.h"
25 
26 module_param(mtk_v4l2_dbg_level, int, S_IRUGO | S_IWUSR);
27 module_param(mtk_vcodec_dbg, bool, S_IRUGO | S_IWUSR);
28 
29 static const struct mtk_video_fmt mtk_video_formats_output_mt8173[] = {
30 	{
31 		.fourcc = V4L2_PIX_FMT_NV12M,
32 		.type = MTK_FMT_FRAME,
33 		.num_planes = 2,
34 	},
35 	{
36 		.fourcc = V4L2_PIX_FMT_NV21M,
37 		.type = MTK_FMT_FRAME,
38 		.num_planes = 2,
39 	},
40 	{
41 		.fourcc = V4L2_PIX_FMT_YUV420M,
42 		.type = MTK_FMT_FRAME,
43 		.num_planes = 3,
44 	},
45 	{
46 		.fourcc = V4L2_PIX_FMT_YVU420M,
47 		.type = MTK_FMT_FRAME,
48 		.num_planes = 3,
49 	},
50 };
51 
52 static const struct mtk_video_fmt mtk_video_formats_capture_mt8173[] =  {
53 	{
54 		.fourcc = V4L2_PIX_FMT_H264,
55 		.type = MTK_FMT_ENC,
56 		.num_planes = 1,
57 	},
58 	{
59 		.fourcc = V4L2_PIX_FMT_VP8,
60 		.type = MTK_FMT_ENC,
61 		.num_planes = 1,
62 	},
63 };
64 
65 static const struct mtk_video_fmt mtk_video_formats_capture_mt8183[] =  {
66 	{
67 		.fourcc = V4L2_PIX_FMT_H264,
68 		.type = MTK_FMT_ENC,
69 		.num_planes = 1,
70 	},
71 };
72 
73 /* Wake up context wait_queue */
wake_up_ctx(struct mtk_vcodec_ctx * ctx,unsigned int reason)74 static void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
75 {
76 	ctx->int_cond = 1;
77 	ctx->int_type = reason;
78 	wake_up_interruptible(&ctx->queue);
79 }
80 
clean_irq_status(unsigned int irq_status,void __iomem * addr)81 static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
82 {
83 	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
84 		writel(MTK_VENC_IRQ_STATUS_PAUSE, addr);
85 
86 	if (irq_status & MTK_VENC_IRQ_STATUS_SWITCH)
87 		writel(MTK_VENC_IRQ_STATUS_SWITCH, addr);
88 
89 	if (irq_status & MTK_VENC_IRQ_STATUS_DRAM)
90 		writel(MTK_VENC_IRQ_STATUS_DRAM, addr);
91 
92 	if (irq_status & MTK_VENC_IRQ_STATUS_SPS)
93 		writel(MTK_VENC_IRQ_STATUS_SPS, addr);
94 
95 	if (irq_status & MTK_VENC_IRQ_STATUS_PPS)
96 		writel(MTK_VENC_IRQ_STATUS_PPS, addr);
97 
98 	if (irq_status & MTK_VENC_IRQ_STATUS_FRM)
99 		writel(MTK_VENC_IRQ_STATUS_FRM, addr);
100 
101 }
mtk_vcodec_enc_irq_handler(int irq,void * priv)102 static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
103 {
104 	struct mtk_vcodec_dev *dev = priv;
105 	struct mtk_vcodec_ctx *ctx;
106 	unsigned long flags;
107 	void __iomem *addr;
108 
109 	spin_lock_irqsave(&dev->irqlock, flags);
110 	ctx = dev->curr_ctx;
111 	spin_unlock_irqrestore(&dev->irqlock, flags);
112 
113 	mtk_v4l2_debug(1, "id=%d", ctx->id);
114 	addr = dev->reg_base[VENC_SYS] + MTK_VENC_IRQ_ACK_OFFSET;
115 
116 	ctx->irq_status = readl(dev->reg_base[VENC_SYS] +
117 				(MTK_VENC_IRQ_STATUS_OFFSET));
118 
119 	clean_irq_status(ctx->irq_status, addr);
120 
121 	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
122 	return IRQ_HANDLED;
123 }
124 
mtk_vcodec_enc_lt_irq_handler(int irq,void * priv)125 static irqreturn_t mtk_vcodec_enc_lt_irq_handler(int irq, void *priv)
126 {
127 	struct mtk_vcodec_dev *dev = priv;
128 	struct mtk_vcodec_ctx *ctx;
129 	unsigned long flags;
130 	void __iomem *addr;
131 
132 	spin_lock_irqsave(&dev->irqlock, flags);
133 	ctx = dev->curr_ctx;
134 	spin_unlock_irqrestore(&dev->irqlock, flags);
135 
136 	mtk_v4l2_debug(1, "id=%d", ctx->id);
137 	ctx->irq_status = readl(dev->reg_base[VENC_LT_SYS] +
138 				(MTK_VENC_IRQ_STATUS_OFFSET));
139 
140 	addr = dev->reg_base[VENC_LT_SYS] + MTK_VENC_IRQ_ACK_OFFSET;
141 
142 	clean_irq_status(ctx->irq_status, addr);
143 
144 	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
145 	return IRQ_HANDLED;
146 }
147 
fops_vcodec_open(struct file * file)148 static int fops_vcodec_open(struct file *file)
149 {
150 	struct mtk_vcodec_dev *dev = video_drvdata(file);
151 	struct mtk_vcodec_ctx *ctx = NULL;
152 	int ret = 0;
153 
154 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
155 	if (!ctx)
156 		return -ENOMEM;
157 
158 	mutex_lock(&dev->dev_mutex);
159 	/*
160 	 * Use simple counter to uniquely identify this context. Only
161 	 * used for logging.
162 	 */
163 	ctx->id = dev->id_counter++;
164 	v4l2_fh_init(&ctx->fh, video_devdata(file));
165 	file->private_data = &ctx->fh;
166 	v4l2_fh_add(&ctx->fh);
167 	INIT_LIST_HEAD(&ctx->list);
168 	ctx->dev = dev;
169 	init_waitqueue_head(&ctx->queue);
170 
171 	ctx->type = MTK_INST_ENCODER;
172 	ret = mtk_vcodec_enc_ctrls_setup(ctx);
173 	if (ret) {
174 		mtk_v4l2_err("Failed to setup controls() (%d)",
175 				ret);
176 		goto err_ctrls_setup;
177 	}
178 	ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_enc, ctx,
179 				&mtk_vcodec_enc_queue_init);
180 	if (IS_ERR((__force void *)ctx->m2m_ctx)) {
181 		ret = PTR_ERR((__force void *)ctx->m2m_ctx);
182 		mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)",
183 				ret);
184 		goto err_m2m_ctx_init;
185 	}
186 	mtk_vcodec_enc_set_default_params(ctx);
187 
188 	if (v4l2_fh_is_singular(&ctx->fh)) {
189 		/*
190 		 * load fireware to checks if it was loaded already and
191 		 * does nothing in that case
192 		 */
193 		ret = mtk_vcodec_fw_load_firmware(dev->fw_handler);
194 		if (ret < 0) {
195 			/*
196 			 * Return 0 if downloading firmware successfully,
197 			 * otherwise it is failed
198 			 */
199 			mtk_v4l2_err("vpu_load_firmware failed!");
200 			goto err_load_fw;
201 		}
202 
203 		dev->enc_capability =
204 			mtk_vcodec_fw_get_venc_capa(dev->fw_handler);
205 		mtk_v4l2_debug(0, "encoder capability %x", dev->enc_capability);
206 	}
207 
208 	mtk_v4l2_debug(2, "Create instance [%d]@%p m2m_ctx=%p ",
209 			ctx->id, ctx, ctx->m2m_ctx);
210 
211 	list_add(&ctx->list, &dev->ctx_list);
212 
213 	mutex_unlock(&dev->dev_mutex);
214 	mtk_v4l2_debug(0, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
215 			ctx->id);
216 	return ret;
217 
218 	/* Deinit when failure occurred */
219 err_load_fw:
220 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
221 err_m2m_ctx_init:
222 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
223 err_ctrls_setup:
224 	v4l2_fh_del(&ctx->fh);
225 	v4l2_fh_exit(&ctx->fh);
226 	kfree(ctx);
227 	mutex_unlock(&dev->dev_mutex);
228 
229 	return ret;
230 }
231 
fops_vcodec_release(struct file * file)232 static int fops_vcodec_release(struct file *file)
233 {
234 	struct mtk_vcodec_dev *dev = video_drvdata(file);
235 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
236 
237 	mtk_v4l2_debug(1, "[%d] encoder", ctx->id);
238 	mutex_lock(&dev->dev_mutex);
239 
240 	mtk_vcodec_enc_release(ctx);
241 	v4l2_fh_del(&ctx->fh);
242 	v4l2_fh_exit(&ctx->fh);
243 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
244 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
245 
246 	list_del_init(&ctx->list);
247 	kfree(ctx);
248 	mutex_unlock(&dev->dev_mutex);
249 	return 0;
250 }
251 
252 static const struct v4l2_file_operations mtk_vcodec_fops = {
253 	.owner		= THIS_MODULE,
254 	.open		= fops_vcodec_open,
255 	.release	= fops_vcodec_release,
256 	.poll		= v4l2_m2m_fop_poll,
257 	.unlocked_ioctl	= video_ioctl2,
258 	.mmap		= v4l2_m2m_fop_mmap,
259 };
260 
mtk_vcodec_probe(struct platform_device * pdev)261 static int mtk_vcodec_probe(struct platform_device *pdev)
262 {
263 	struct mtk_vcodec_dev *dev;
264 	struct video_device *vfd_enc;
265 	struct resource *res;
266 	phandle rproc_phandle;
267 	enum mtk_vcodec_fw_type fw_type;
268 	int ret;
269 
270 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
271 	if (!dev)
272 		return -ENOMEM;
273 
274 	INIT_LIST_HEAD(&dev->ctx_list);
275 	dev->plat_dev = pdev;
276 
277 	if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vpu",
278 				  &rproc_phandle)) {
279 		fw_type = VPU;
280 	} else if (!of_property_read_u32(pdev->dev.of_node, "mediatek,scp",
281 					 &rproc_phandle)) {
282 		fw_type = SCP;
283 	} else {
284 		mtk_v4l2_err("Could not get venc IPI device");
285 		return -ENODEV;
286 	}
287 	if (!pdev->dev.dma_parms) {
288 		pdev->dev.dma_parms = devm_kzalloc(&pdev->dev,
289 						sizeof(*pdev->dev.dma_parms),
290 						GFP_KERNEL);
291 		if (!pdev->dev.dma_parms)
292 			return -ENOMEM;
293 	}
294 	dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
295 
296 	dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, ENCODER);
297 	if (IS_ERR(dev->fw_handler))
298 		return PTR_ERR(dev->fw_handler);
299 
300 	dev->venc_pdata = of_device_get_match_data(&pdev->dev);
301 	ret = mtk_vcodec_init_enc_pm(dev);
302 	if (ret < 0) {
303 		dev_err(&pdev->dev, "Failed to get mt vcodec clock source!");
304 		goto err_enc_pm;
305 	}
306 
307 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
308 	dev->reg_base[VENC_SYS] = devm_ioremap_resource(&pdev->dev, res);
309 	if (IS_ERR((__force void *)dev->reg_base[VENC_SYS])) {
310 		ret = PTR_ERR((__force void *)dev->reg_base[VENC_SYS]);
311 		goto err_res;
312 	}
313 	mtk_v4l2_debug(2, "reg[%d] base=0x%p", i, dev->reg_base[VENC_SYS]);
314 
315 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
316 	if (res == NULL) {
317 		dev_err(&pdev->dev, "failed to get irq resource");
318 		ret = -ENOENT;
319 		goto err_res;
320 	}
321 
322 	dev->enc_irq = platform_get_irq(pdev, 0);
323 	irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
324 	ret = devm_request_irq(&pdev->dev, dev->enc_irq,
325 			       mtk_vcodec_enc_irq_handler,
326 			       0, pdev->name, dev);
327 	if (ret) {
328 		dev_err(&pdev->dev, "Failed to install dev->enc_irq %d (%d)",
329 			dev->enc_irq,
330 			ret);
331 		ret = -EINVAL;
332 		goto err_res;
333 	}
334 
335 	if (dev->venc_pdata->has_lt_irq) {
336 		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
337 		dev->reg_base[VENC_LT_SYS] = devm_ioremap_resource(&pdev->dev, res);
338 		if (IS_ERR((__force void *)dev->reg_base[VENC_LT_SYS])) {
339 			ret = PTR_ERR((__force void *)dev->reg_base[VENC_LT_SYS]);
340 			goto err_res;
341 		}
342 		mtk_v4l2_debug(2, "reg[%d] base=0x%p", i, dev->reg_base[VENC_LT_SYS]);
343 
344 		dev->enc_lt_irq = platform_get_irq(pdev, 1);
345 		irq_set_status_flags(dev->enc_lt_irq, IRQ_NOAUTOEN);
346 		ret = devm_request_irq(&pdev->dev,
347 				       dev->enc_lt_irq,
348 				       mtk_vcodec_enc_lt_irq_handler,
349 				       0, pdev->name, dev);
350 		if (ret) {
351 			dev_err(&pdev->dev,
352 				"Failed to install dev->enc_lt_irq %d (%d)",
353 				dev->enc_lt_irq, ret);
354 			ret = -EINVAL;
355 			goto err_res;
356 		}
357 	}
358 
359 	mutex_init(&dev->enc_mutex);
360 	mutex_init(&dev->dev_mutex);
361 	spin_lock_init(&dev->irqlock);
362 
363 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
364 		 "[MTK_V4L2_VENC]");
365 
366 	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
367 	if (ret) {
368 		mtk_v4l2_err("v4l2_device_register err=%d", ret);
369 		goto err_res;
370 	}
371 
372 	init_waitqueue_head(&dev->queue);
373 
374 	/* allocate video device for encoder and register it */
375 	vfd_enc = video_device_alloc();
376 	if (!vfd_enc) {
377 		mtk_v4l2_err("Failed to allocate video device");
378 		ret = -ENOMEM;
379 		goto err_enc_alloc;
380 	}
381 	vfd_enc->fops           = &mtk_vcodec_fops;
382 	vfd_enc->ioctl_ops      = &mtk_venc_ioctl_ops;
383 	vfd_enc->release        = video_device_release;
384 	vfd_enc->lock           = &dev->dev_mutex;
385 	vfd_enc->v4l2_dev       = &dev->v4l2_dev;
386 	vfd_enc->vfl_dir        = VFL_DIR_M2M;
387 	vfd_enc->device_caps	= V4L2_CAP_VIDEO_M2M_MPLANE |
388 					V4L2_CAP_STREAMING;
389 
390 	snprintf(vfd_enc->name, sizeof(vfd_enc->name), "%s",
391 		 MTK_VCODEC_ENC_NAME);
392 	video_set_drvdata(vfd_enc, dev);
393 	dev->vfd_enc = vfd_enc;
394 	platform_set_drvdata(pdev, dev);
395 
396 	dev->m2m_dev_enc = v4l2_m2m_init(&mtk_venc_m2m_ops);
397 	if (IS_ERR((__force void *)dev->m2m_dev_enc)) {
398 		mtk_v4l2_err("Failed to init mem2mem enc device");
399 		ret = PTR_ERR((__force void *)dev->m2m_dev_enc);
400 		goto err_enc_mem_init;
401 	}
402 
403 	dev->encode_workqueue =
404 			alloc_ordered_workqueue(MTK_VCODEC_ENC_NAME,
405 						WQ_MEM_RECLAIM |
406 						WQ_FREEZABLE);
407 	if (!dev->encode_workqueue) {
408 		mtk_v4l2_err("Failed to create encode workqueue");
409 		ret = -EINVAL;
410 		goto err_event_workq;
411 	}
412 
413 	ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, 1);
414 	if (ret) {
415 		mtk_v4l2_err("Failed to register video device");
416 		goto err_enc_reg;
417 	}
418 
419 	mtk_v4l2_debug(0, "encoder registered as /dev/video%d",
420 			vfd_enc->num);
421 
422 	return 0;
423 
424 err_enc_reg:
425 	destroy_workqueue(dev->encode_workqueue);
426 err_event_workq:
427 	v4l2_m2m_release(dev->m2m_dev_enc);
428 err_enc_mem_init:
429 	video_unregister_device(vfd_enc);
430 err_enc_alloc:
431 	v4l2_device_unregister(&dev->v4l2_dev);
432 err_res:
433 	mtk_vcodec_release_enc_pm(dev);
434 err_enc_pm:
435 	mtk_vcodec_fw_release(dev->fw_handler);
436 	return ret;
437 }
438 
439 static const struct mtk_vcodec_enc_pdata mt8173_pdata = {
440 	.chip = MTK_MT8173,
441 	.has_lt_irq = true,
442 	.capture_formats = mtk_video_formats_capture_mt8173,
443 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_mt8173),
444 	.output_formats = mtk_video_formats_output_mt8173,
445 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output_mt8173),
446 	.min_bitrate = 1,
447 	.max_bitrate = 4000000,
448 };
449 
450 static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
451 	.chip = MTK_MT8183,
452 	.has_lt_irq = false,
453 	.uses_ext = true,
454 	.capture_formats = mtk_video_formats_capture_mt8183,
455 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_mt8183),
456 	/* MT8183 supports the same output formats as MT8173 */
457 	.output_formats = mtk_video_formats_output_mt8173,
458 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output_mt8173),
459 	.min_bitrate = 64,
460 	.max_bitrate = 40000000,
461 };
462 
463 static const struct of_device_id mtk_vcodec_enc_match[] = {
464 	{.compatible = "mediatek,mt8173-vcodec-enc", .data = &mt8173_pdata},
465 	{.compatible = "mediatek,mt8183-vcodec-enc", .data = &mt8183_pdata},
466 	{},
467 };
468 MODULE_DEVICE_TABLE(of, mtk_vcodec_enc_match);
469 
mtk_vcodec_enc_remove(struct platform_device * pdev)470 static int mtk_vcodec_enc_remove(struct platform_device *pdev)
471 {
472 	struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev);
473 
474 	mtk_v4l2_debug_enter();
475 	flush_workqueue(dev->encode_workqueue);
476 	destroy_workqueue(dev->encode_workqueue);
477 	if (dev->m2m_dev_enc)
478 		v4l2_m2m_release(dev->m2m_dev_enc);
479 
480 	if (dev->vfd_enc)
481 		video_unregister_device(dev->vfd_enc);
482 
483 	v4l2_device_unregister(&dev->v4l2_dev);
484 	mtk_vcodec_release_enc_pm(dev);
485 	mtk_vcodec_fw_release(dev->fw_handler);
486 	return 0;
487 }
488 
489 static struct platform_driver mtk_vcodec_enc_driver = {
490 	.probe	= mtk_vcodec_probe,
491 	.remove	= mtk_vcodec_enc_remove,
492 	.driver	= {
493 		.name	= MTK_VCODEC_ENC_NAME,
494 		.of_match_table = mtk_vcodec_enc_match,
495 	},
496 };
497 
498 module_platform_driver(mtk_vcodec_enc_driver);
499 
500 
501 MODULE_LICENSE("GPL v2");
502 MODULE_DESCRIPTION("Mediatek video codec V4L2 encoder driver");
503