xref: /linux/drivers/media/platform/qcom/venus/core.c (revision 197789c60a11eaf18b4a2e5d2dbf8d490e10395e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
4  * Copyright (C) 2017 Linaro Ltd.
5  */
6 #include <linux/init.h>
7 #include <linux/interconnect.h>
8 #include <linux/io.h>
9 #include <linux/ioctl.h>
10 #include <linux/delay.h>
11 #include <linux/devcoredump.h>
12 #include <linux/list.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_platform.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
18 #include <linux/types.h>
19 #include <linux/pm_domain.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/videodev2.h>
22 #include <media/videobuf2-v4l2.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-mem2mem.h>
25 #include <media/v4l2-ioctl.h>
26 
27 #include "core.h"
28 #include "firmware.h"
29 #include "pm_helpers.h"
30 #include "hfi_venus_io.h"
31 
32 static void venus_coredump(struct venus_core *core)
33 {
34 	struct device *dev;
35 	phys_addr_t mem_phys;
36 	size_t mem_size;
37 	void *mem_va;
38 	void *data;
39 
40 	dev = core->dev;
41 	mem_phys = core->fw.mem_phys;
42 	mem_size = core->fw.mem_size;
43 
44 	mem_va = memremap(mem_phys, mem_size, MEMREMAP_WC);
45 	if (!mem_va)
46 		return;
47 
48 	data = vmalloc(mem_size);
49 	if (!data) {
50 		memunmap(mem_va);
51 		return;
52 	}
53 
54 	memcpy(data, mem_va, mem_size);
55 	memunmap(mem_va);
56 	dev_coredumpv(dev, data, mem_size, GFP_KERNEL);
57 }
58 
59 static void venus_event_notify(struct venus_core *core, u32 event)
60 {
61 	struct venus_inst *inst;
62 
63 	switch (event) {
64 	case EVT_SYS_WATCHDOG_TIMEOUT:
65 	case EVT_SYS_ERROR:
66 		break;
67 	default:
68 		return;
69 	}
70 
71 	mutex_lock(&core->lock);
72 	set_bit(0, &core->sys_error);
73 	set_bit(0, &core->dump_core);
74 	list_for_each_entry(inst, &core->instances, list)
75 		inst->ops->event_notify(inst, EVT_SESSION_ERROR, NULL);
76 	mutex_unlock(&core->lock);
77 
78 	disable_irq_nosync(core->irq);
79 	schedule_delayed_work(&core->work, msecs_to_jiffies(10));
80 }
81 
82 static const struct hfi_core_ops venus_core_ops = {
83 	.event_notify = venus_event_notify,
84 };
85 
86 #define RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS 10
87 
88 static void venus_sys_error_handler(struct work_struct *work)
89 {
90 	struct venus_core *core =
91 			container_of(work, struct venus_core, work.work);
92 	int ret, i, max_attempts = RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS;
93 	const char *err_msg = "";
94 	bool failed = false;
95 
96 	ret = pm_runtime_get_sync(core->dev);
97 	if (ret < 0) {
98 		err_msg = "resume runtime PM";
99 		max_attempts = 0;
100 		failed = true;
101 	}
102 
103 	core->ops->core_deinit(core);
104 	core->state = CORE_UNINIT;
105 
106 	for (i = 0; i < max_attempts; i++) {
107 		if (!pm_runtime_active(core->dev_dec) && !pm_runtime_active(core->dev_enc))
108 			break;
109 		msleep(10);
110 	}
111 
112 	mutex_lock(&core->lock);
113 
114 	venus_shutdown(core);
115 
116 	if (test_bit(0, &core->dump_core)) {
117 		venus_coredump(core);
118 		clear_bit(0, &core->dump_core);
119 	}
120 
121 	pm_runtime_put_sync(core->dev);
122 
123 	for (i = 0; i < max_attempts; i++) {
124 		if (!core->pmdomains ||
125 		    !pm_runtime_active(core->pmdomains->pd_devs[0]))
126 			break;
127 		usleep_range(1000, 1500);
128 	}
129 
130 	hfi_reinit(core);
131 
132 	ret = pm_runtime_get_sync(core->dev);
133 	if (ret < 0) {
134 		err_msg = "resume runtime PM";
135 		failed = true;
136 	}
137 
138 	ret = venus_boot(core);
139 	if (ret && !failed) {
140 		err_msg = "boot Venus";
141 		failed = true;
142 	}
143 
144 	ret = hfi_core_resume(core, true);
145 	if (ret && !failed) {
146 		err_msg = "resume HFI";
147 		failed = true;
148 	}
149 
150 	enable_irq(core->irq);
151 
152 	mutex_unlock(&core->lock);
153 
154 	ret = hfi_core_init(core);
155 	if (ret && !failed) {
156 		err_msg = "init HFI";
157 		failed = true;
158 	}
159 
160 	pm_runtime_put_sync(core->dev);
161 
162 	if (failed) {
163 		disable_irq_nosync(core->irq);
164 		dev_warn_ratelimited(core->dev,
165 				     "System error has occurred, recovery failed to %s\n",
166 				     err_msg);
167 		schedule_delayed_work(&core->work, msecs_to_jiffies(10));
168 		return;
169 	}
170 
171 	dev_warn(core->dev, "system error has occurred (recovered)\n");
172 
173 	mutex_lock(&core->lock);
174 	clear_bit(0, &core->sys_error);
175 	wake_up_all(&core->sys_err_done);
176 	mutex_unlock(&core->lock);
177 }
178 
179 static u32 to_v4l2_codec_type(u32 codec)
180 {
181 	switch (codec) {
182 	case HFI_VIDEO_CODEC_HEVC:
183 		return V4L2_PIX_FMT_HEVC;
184 	case HFI_VIDEO_CODEC_H264:
185 		return V4L2_PIX_FMT_H264;
186 	case HFI_VIDEO_CODEC_H263:
187 		return V4L2_PIX_FMT_H263;
188 	case HFI_VIDEO_CODEC_MPEG1:
189 		return V4L2_PIX_FMT_MPEG1;
190 	case HFI_VIDEO_CODEC_MPEG2:
191 		return V4L2_PIX_FMT_MPEG2;
192 	case HFI_VIDEO_CODEC_MPEG4:
193 		return V4L2_PIX_FMT_MPEG4;
194 	case HFI_VIDEO_CODEC_VC1:
195 		return V4L2_PIX_FMT_VC1_ANNEX_G;
196 	case HFI_VIDEO_CODEC_VP8:
197 		return V4L2_PIX_FMT_VP8;
198 	case HFI_VIDEO_CODEC_VP9:
199 		return V4L2_PIX_FMT_VP9;
200 	case HFI_VIDEO_CODEC_DIVX:
201 	case HFI_VIDEO_CODEC_DIVX_311:
202 		return V4L2_PIX_FMT_XVID;
203 	default:
204 		return 0;
205 	}
206 }
207 
208 static int venus_enumerate_codecs(struct venus_core *core, u32 type)
209 {
210 	const struct hfi_inst_ops dummy_ops = {};
211 	struct venus_inst *inst;
212 	u32 codec, codecs;
213 	unsigned int i;
214 	int ret;
215 
216 	if (core->res->hfi_version != HFI_VERSION_1XX)
217 		return 0;
218 
219 	inst = kzalloc_obj(*inst);
220 	if (!inst)
221 		return -ENOMEM;
222 
223 	mutex_init(&inst->lock);
224 	inst->core = core;
225 	inst->session_type = type;
226 	if (type == VIDC_SESSION_TYPE_DEC)
227 		codecs = core->dec_codecs;
228 	else
229 		codecs = core->enc_codecs;
230 
231 	ret = hfi_session_create(inst, &dummy_ops);
232 	if (ret)
233 		goto err;
234 
235 	for (i = 0; i < MAX_CODEC_NUM; i++) {
236 		codec = (1UL << i) & codecs;
237 		if (!codec)
238 			continue;
239 
240 		ret = hfi_session_init(inst, to_v4l2_codec_type(codec));
241 		if (ret)
242 			goto done;
243 
244 		ret = hfi_session_deinit(inst);
245 		if (ret)
246 			goto done;
247 	}
248 
249 done:
250 	hfi_session_destroy(inst);
251 err:
252 	mutex_destroy(&inst->lock);
253 	kfree(inst);
254 
255 	return ret;
256 }
257 
258 static void venus_assign_register_offsets(struct venus_core *core)
259 {
260 	if (IS_IRIS2(core) || IS_IRIS2_1(core) || IS_AR50_LITE(core)) {
261 		core->cpu_base = core->base + CPU_BASE_V6;
262 		core->cpu_cs_base = core->base + CPU_CS_BASE_V6;
263 		core->cpu_ic_base = core->base + CPU_IC_BASE_V6;
264 		core->wrapper_base = core->base + WRAPPER_BASE_V6;
265 		core->wrapper_tz_base = core->base + WRAPPER_TZ_BASE_V6;
266 		if (IS_AR50_LITE(core)) {
267 			core->vbif_base = NULL;
268 			core->aon_base = NULL;
269 		} else {
270 			core->vbif_base = core->base + VBIF_BASE;
271 			core->aon_base = core->base + AON_BASE_V6;
272 		}
273 	} else {
274 		core->vbif_base = core->base + VBIF_BASE;
275 		core->cpu_base = core->base + CPU_BASE;
276 		core->cpu_cs_base = core->base + CPU_CS_BASE;
277 		core->cpu_ic_base = core->base + CPU_IC_BASE;
278 		core->wrapper_base = core->base + WRAPPER_BASE;
279 		core->wrapper_tz_base = NULL;
280 		core->aon_base = NULL;
281 	}
282 }
283 
284 static irqreturn_t venus_isr_thread(int irq, void *dev_id)
285 {
286 	struct venus_core *core = dev_id;
287 	irqreturn_t ret;
288 
289 	ret = hfi_isr_thread(irq, dev_id);
290 
291 	if (ret == IRQ_HANDLED && venus_fault_inject_ssr())
292 		hfi_core_trigger_ssr(core, HFI_TEST_SSR_SW_ERR_FATAL);
293 
294 	return ret;
295 }
296 
297 #if defined(CONFIG_OF_DYNAMIC)
298 static int venus_add_video_core(struct venus_core *core, const char *node_name,
299 				const char *compat)
300 {
301 	struct of_changeset *ocs = core->ocs;
302 	struct device *dev = core->dev;
303 	struct device_node *np, *enp;
304 	int ret;
305 
306 	if (!node_name)
307 		return 0;
308 
309 	enp = of_find_node_by_name(dev->of_node, node_name);
310 	if (enp) {
311 		of_node_put(enp);
312 		return 0;
313 	}
314 
315 	np = of_changeset_create_node(ocs, dev->of_node, node_name);
316 	if (!np) {
317 		dev_err(dev, "Unable to create new node\n");
318 		return -ENODEV;
319 	}
320 
321 	ret = of_changeset_add_prop_string(ocs, np, "compatible", compat);
322 	if (ret)
323 		dev_err(dev, "unable to add %s\n", compat);
324 
325 	of_node_put(np);
326 
327 	return ret;
328 }
329 
330 static int venus_add_dynamic_nodes(struct venus_core *core)
331 {
332 	struct device *dev = core->dev;
333 	int ret;
334 
335 	core->ocs = kmalloc_obj(*core->ocs);
336 	if (!core->ocs)
337 		return -ENOMEM;
338 
339 	of_changeset_init(core->ocs);
340 
341 	ret = venus_add_video_core(core, core->res->dec_nodename, "venus-decoder");
342 	if (ret)
343 		goto err;
344 
345 	ret = venus_add_video_core(core, core->res->enc_nodename, "venus-encoder");
346 	if (ret)
347 		goto err;
348 
349 	ret = of_changeset_apply(core->ocs);
350 	if (ret) {
351 		dev_err(dev, "applying changeset fail ret %d\n", ret);
352 		goto err;
353 	}
354 
355 	return 0;
356 err:
357 	of_changeset_destroy(core->ocs);
358 	kfree(core->ocs);
359 	core->ocs = NULL;
360 	return ret;
361 }
362 
363 static void venus_remove_dynamic_nodes(struct venus_core *core)
364 {
365 	if (core->ocs) {
366 		of_changeset_revert(core->ocs);
367 		of_changeset_destroy(core->ocs);
368 		kfree(core->ocs);
369 	}
370 }
371 #else
372 static int venus_add_dynamic_nodes(struct venus_core *core)
373 {
374 	return 0;
375 }
376 
377 static void venus_remove_dynamic_nodes(struct venus_core *core) {}
378 #endif
379 
380 static int venus_probe(struct platform_device *pdev)
381 {
382 	struct device *dev = &pdev->dev;
383 	struct venus_core *core;
384 	int ret;
385 
386 	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
387 	if (!core)
388 		return -ENOMEM;
389 
390 	core->dev = dev;
391 
392 	core->base = devm_platform_ioremap_resource(pdev, 0);
393 	if (IS_ERR(core->base))
394 		return PTR_ERR(core->base);
395 
396 	core->video_path = devm_of_icc_get(dev, "video-mem");
397 	if (IS_ERR(core->video_path))
398 		return PTR_ERR(core->video_path);
399 
400 	core->cpucfg_path = devm_of_icc_get(dev, "cpu-cfg");
401 	if (IS_ERR(core->cpucfg_path))
402 		return PTR_ERR(core->cpucfg_path);
403 
404 	core->irq = platform_get_irq(pdev, 0);
405 	if (core->irq < 0)
406 		return core->irq;
407 
408 	core->res = of_device_get_match_data(dev);
409 	if (!core->res)
410 		return -ENODEV;
411 
412 	mutex_init(&core->pm_lock);
413 
414 	core->pm_ops = venus_pm_get(core->res->hfi_version);
415 	if (!core->pm_ops)
416 		return -ENODEV;
417 
418 	if (core->pm_ops->core_get) {
419 		ret = core->pm_ops->core_get(core);
420 		if (ret)
421 			return ret;
422 	}
423 
424 	ret = dma_set_mask_and_coherent(dev, core->res->dma_mask);
425 	if (ret)
426 		goto err_core_put;
427 
428 	dma_set_max_seg_size(dev, UINT_MAX);
429 
430 	INIT_LIST_HEAD(&core->instances);
431 	mutex_init(&core->lock);
432 	INIT_DELAYED_WORK(&core->work, venus_sys_error_handler);
433 	init_waitqueue_head(&core->sys_err_done);
434 
435 	ret = hfi_create(core, &venus_core_ops);
436 	if (ret)
437 		goto err_core_put;
438 
439 	ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, venus_isr_thread,
440 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
441 					"venus", core);
442 	if (ret)
443 		goto err_core_put;
444 
445 	venus_assign_register_offsets(core);
446 
447 	ret = v4l2_device_register(dev, &core->v4l2_dev);
448 	if (ret)
449 		goto err_hfi_destroy;
450 
451 	platform_set_drvdata(pdev, core);
452 
453 	pm_runtime_enable(dev);
454 
455 	ret = pm_runtime_get_sync(dev);
456 	if (ret < 0)
457 		goto err_runtime_disable;
458 
459 	ret = venus_firmware_init(core);
460 	if (ret)
461 		goto err_runtime_disable;
462 
463 	ret = venus_boot(core);
464 	if (ret)
465 		goto err_firmware_deinit;
466 
467 	ret = venus_firmware_cfg(core);
468 	if (ret)
469 		goto err_venus_shutdown;
470 
471 	ret = hfi_core_resume(core, true);
472 	if (ret)
473 		goto err_venus_shutdown;
474 
475 	ret = hfi_core_init(core);
476 	if (ret)
477 		goto err_venus_shutdown;
478 
479 	ret = venus_firmware_check(core);
480 	if (ret)
481 		goto err_core_deinit;
482 
483 	if (core->res->dec_nodename || core->res->enc_nodename) {
484 		ret = venus_add_dynamic_nodes(core);
485 		if (ret)
486 			goto err_core_deinit;
487 	}
488 
489 	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
490 	if (ret)
491 		goto err_remove_dynamic_nodes;
492 
493 	ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
494 	if (ret)
495 		goto err_of_depopulate;
496 
497 	ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC);
498 	if (ret)
499 		goto err_of_depopulate;
500 
501 	ret = pm_runtime_put_sync(dev);
502 	if (ret) {
503 		pm_runtime_get_noresume(dev);
504 		goto err_of_depopulate;
505 	}
506 
507 	venus_dbgfs_init(core);
508 
509 	return 0;
510 
511 err_of_depopulate:
512 	of_platform_depopulate(dev);
513 err_remove_dynamic_nodes:
514 	venus_remove_dynamic_nodes(core);
515 err_core_deinit:
516 	hfi_core_deinit(core, false);
517 err_venus_shutdown:
518 	venus_shutdown(core);
519 err_firmware_deinit:
520 	venus_firmware_deinit(core);
521 err_runtime_disable:
522 	pm_runtime_put_noidle(dev);
523 	pm_runtime_disable(dev);
524 	pm_runtime_set_suspended(dev);
525 	v4l2_device_unregister(&core->v4l2_dev);
526 err_hfi_destroy:
527 	hfi_destroy(core);
528 err_core_put:
529 	if (core->pm_ops->core_put)
530 		core->pm_ops->core_put(core);
531 	return ret;
532 }
533 
534 static void venus_remove(struct platform_device *pdev)
535 {
536 	struct venus_core *core = platform_get_drvdata(pdev);
537 	const struct venus_pm_ops *pm_ops = core->pm_ops;
538 	struct device *dev = core->dev;
539 	int ret;
540 
541 	cancel_delayed_work_sync(&core->work);
542 	ret = pm_runtime_get_sync(dev);
543 	WARN_ON(ret < 0);
544 
545 	ret = hfi_core_deinit(core, true);
546 	WARN_ON(ret);
547 
548 	venus_shutdown(core);
549 	of_platform_depopulate(dev);
550 
551 	venus_firmware_deinit(core);
552 
553 	venus_remove_dynamic_nodes(core);
554 
555 	pm_runtime_put_sync(dev);
556 	pm_runtime_disable(dev);
557 
558 	if (pm_ops->core_put)
559 		pm_ops->core_put(core);
560 
561 	v4l2_device_unregister(&core->v4l2_dev);
562 
563 	hfi_destroy(core);
564 
565 	mutex_destroy(&core->pm_lock);
566 	mutex_destroy(&core->lock);
567 	venus_dbgfs_deinit(core);
568 }
569 
570 static void venus_core_shutdown(struct platform_device *pdev)
571 {
572 	struct venus_core *core = platform_get_drvdata(pdev);
573 
574 	pm_runtime_get_sync(core->dev);
575 	venus_shutdown(core);
576 	venus_firmware_deinit(core);
577 	pm_runtime_put_sync(core->dev);
578 }
579 
580 static __maybe_unused int venus_runtime_suspend(struct device *dev)
581 {
582 	struct venus_core *core = dev_get_drvdata(dev);
583 	const struct venus_pm_ops *pm_ops = core->pm_ops;
584 	int ret;
585 
586 	ret = hfi_core_suspend(core);
587 	if (ret)
588 		return ret;
589 
590 	if (pm_ops->core_power) {
591 		ret = pm_ops->core_power(core, POWER_OFF);
592 		if (ret)
593 			return ret;
594 	}
595 
596 	ret = icc_set_bw(core->cpucfg_path, 0, 0);
597 	if (ret)
598 		goto err_cpucfg_path;
599 
600 	ret = icc_set_bw(core->video_path, 0, 0);
601 	if (ret)
602 		goto err_video_path;
603 
604 	return ret;
605 
606 err_video_path:
607 	icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0);
608 err_cpucfg_path:
609 	if (pm_ops->core_power)
610 		pm_ops->core_power(core, POWER_ON);
611 
612 	return ret;
613 }
614 
615 void venus_close_common(struct venus_inst *inst, struct file *filp)
616 {
617 	/*
618 	 * Make sure we don't have IRQ/IRQ-thread currently running
619 	 * or pending execution, which would race with the inst destruction.
620 	 */
621 	synchronize_irq(inst->core->irq);
622 
623 	v4l2_m2m_ctx_release(inst->m2m_ctx);
624 	v4l2_m2m_release(inst->m2m_dev);
625 	hfi_session_destroy(inst);
626 	v4l2_fh_del(&inst->fh, filp);
627 	v4l2_fh_exit(&inst->fh);
628 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
629 
630 	mutex_destroy(&inst->lock);
631 	mutex_destroy(&inst->ctx_q_lock);
632 }
633 EXPORT_SYMBOL_GPL(venus_close_common);
634 
635 static __maybe_unused int venus_runtime_resume(struct device *dev)
636 {
637 	struct venus_core *core = dev_get_drvdata(dev);
638 	const struct venus_pm_ops *pm_ops = core->pm_ops;
639 	int ret;
640 
641 	ret = icc_set_bw(core->video_path, kbps_to_icc(20000), 0);
642 	if (ret)
643 		return ret;
644 
645 	ret = icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0);
646 	if (ret)
647 		return ret;
648 
649 	if (pm_ops->core_power) {
650 		ret = pm_ops->core_power(core, POWER_ON);
651 		if (ret)
652 			return ret;
653 	}
654 
655 	return hfi_core_resume(core, false);
656 }
657 
658 static const struct dev_pm_ops venus_pm_ops = {
659 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
660 				pm_runtime_force_resume)
661 	SET_RUNTIME_PM_OPS(venus_runtime_suspend, venus_runtime_resume, NULL)
662 };
663 
664 static const struct freq_tbl msm8916_freq_table[] = {
665 	{ 352800, 228570000 },	/* 1920x1088 @ 30 + 1280x720 @ 30 */
666 	{ 244800, 160000000 },	/* 1920x1088 @ 30 */
667 	{ 108000, 100000000 },	/* 1280x720 @ 30 */
668 };
669 
670 static const struct reg_val msm8916_reg_preset[] = {
671 	{ 0xe0020, 0x05555556 },
672 	{ 0xe0024, 0x05555556 },
673 	{ 0x80124, 0x00000003 },
674 };
675 
676 static const struct venus_resources msm8916_res = {
677 	.freq_tbl = msm8916_freq_table,
678 	.freq_tbl_size = ARRAY_SIZE(msm8916_freq_table),
679 	.reg_tbl = msm8916_reg_preset,
680 	.reg_tbl_size = ARRAY_SIZE(msm8916_reg_preset),
681 	.clks = { "core", "iface", "bus", },
682 	.clks_num = 3,
683 	.max_load = 352800, /* 720p@30 + 1080p@30 */
684 	.hfi_version = HFI_VERSION_1XX,
685 	.vmem_id = VIDC_RESOURCE_NONE,
686 	.vmem_size = 0,
687 	.vmem_addr = 0,
688 	.dma_mask = 0xddc00000 - 1,
689 	.fwname = "qcom/venus-1.8/venus.mbn",
690 	.dec_codec_blacklist = HFI_VIDEO_CODEC_HEVC | HFI_VIDEO_CODEC_SPARK,
691 	.enc_codec_blacklist = HFI_VIDEO_CODEC_HEVC,
692 	.dec_nodename = "video-decoder",
693 	.enc_nodename = "video-encoder",
694 };
695 
696 static const struct freq_tbl msm8939_freq_table[] = {
697 	{ 489600, 266670000 },	/* 1080p @ 60 */
698 	{ 244800, 133330000 },	/* 1080p @ 30 */
699 	{ 220800, 133330000 },	/* 720p @ 60 */
700 	{ 108000, 133330000 },	/* 720p @ 30 */
701 	{ 72000, 133330000 },	/* VGA @ 60 */
702 	{ 36000, 133330000 },	/* VGA @ 30 */
703 };
704 
705 static const struct reg_val msm8939_reg_preset[] = {
706 	{ 0xe0020, 0x0aaaaaaa },
707 	{ 0xe0024, 0x0aaaaaaa },
708 	{ 0x80124, 0x00000003 },
709 };
710 
711 static const struct venus_resources msm8939_res = {
712 	.freq_tbl = msm8939_freq_table,
713 	.freq_tbl_size = ARRAY_SIZE(msm8939_freq_table),
714 	.reg_tbl = msm8939_reg_preset,
715 	.reg_tbl_size = ARRAY_SIZE(msm8939_reg_preset),
716 	.clks = { "core", "iface", "bus", },
717 	.clks_num = 3,
718 	.vcodec_clks = { "vcodec0_core", "vcodec1_core" },
719 	.vcodec_clks_num = 2,
720 	.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0", "vcodec1" },
721 	.vcodec_pmdomains_num = 3,
722 	.max_load = 489600, /* 1080p@30 + 1080p@30 */
723 	.hfi_version = HFI_VERSION_1XX,
724 	.vmem_id = VIDC_RESOURCE_NONE,
725 	.vmem_size = 0,
726 	.vmem_addr = 0,
727 	.dma_mask = 0xddc00000 - 1,
728 	.fwname = "qcom/venus-1.8/venus.mbn",
729 	.dec_codec_blacklist = HFI_VIDEO_CODEC_SPARK,
730 	.enc_codec_blacklist = HFI_VIDEO_CODEC_HEVC,
731 	.dec_nodename = "video-decoder",
732 	.enc_nodename = "video-encoder",
733 };
734 
735 static const struct freq_tbl msm8996_freq_table[] = {
736 	{ 1944000, 520000000 },	/* 4k UHD @ 60 (decode only) */
737 	{  972000, 520000000 },	/* 4k UHD @ 30 */
738 	{  489600, 346666667 },	/* 1080p @ 60 */
739 	{  244800, 150000000 },	/* 1080p @ 30 */
740 	{  108000,  75000000 },	/* 720p @ 30 */
741 };
742 
743 static const struct reg_val msm8996_reg_preset[] = {
744 	{ 0x80010, 0xffffffff },
745 	{ 0x80018, 0x00001556 },
746 	{ 0x8001C, 0x00001556 },
747 };
748 
749 static const struct venus_resources msm8996_res = {
750 	.freq_tbl = msm8996_freq_table,
751 	.freq_tbl_size = ARRAY_SIZE(msm8996_freq_table),
752 	.reg_tbl = msm8996_reg_preset,
753 	.reg_tbl_size = ARRAY_SIZE(msm8996_reg_preset),
754 	.clks = {"core", "iface", "bus", "mbus" },
755 	.clks_num = 4,
756 	.vcodec0_clks = { "core" },
757 	.vcodec1_clks = { "core" },
758 	.vcodec_clks_num = 1,
759 	.max_load = 2563200,
760 	.hfi_version = HFI_VERSION_3XX,
761 	.vmem_id = VIDC_RESOURCE_NONE,
762 	.vmem_size = 0,
763 	.vmem_addr = 0,
764 	.dma_mask = 0xddc00000 - 1,
765 	.fwname = "qcom/venus-4.2/venus.mbn",
766 };
767 
768 static const struct freq_tbl msm8998_freq_table[] = {
769 	{ 1728000, 533000000 },	/* 4k UHD @ 60 (decode only) */
770 	{ 1036800, 444000000 },	/* 2k @ 120 */
771 	{  829440, 355200000 },	/* 4k @ 44 */
772 	{  489600, 269330000 },/* 4k @ 30 */
773 	{  108000, 200000000 },	/* 1080p @ 60 */
774 };
775 
776 static const struct reg_val msm8998_reg_preset[] = {
777 	{ 0x80124, 0x00000003 },
778 	{ 0x80550, 0x01111111 },
779 	{ 0x80560, 0x01111111 },
780 	{ 0x80568, 0x01111111 },
781 	{ 0x80570, 0x01111111 },
782 	{ 0x80580, 0x01111111 },
783 	{ 0x80588, 0x01111111 },
784 	{ 0xe2010, 0x00000000 },
785 };
786 
787 static const struct venus_resources msm8998_res = {
788 	.freq_tbl = msm8998_freq_table,
789 	.freq_tbl_size = ARRAY_SIZE(msm8998_freq_table),
790 	.reg_tbl = msm8998_reg_preset,
791 	.reg_tbl_size = ARRAY_SIZE(msm8998_reg_preset),
792 	.clks = { "core", "iface", "bus", "mbus" },
793 	.clks_num = 4,
794 	.vcodec0_clks = { "core" },
795 	.vcodec1_clks = { "core" },
796 	.vcodec_clks_num = 1,
797 	.max_load = 2563200,
798 	.hfi_version = HFI_VERSION_3XX,
799 	.vmem_id = VIDC_RESOURCE_NONE,
800 	.vmem_size = 0,
801 	.vmem_addr = 0,
802 	.dma_mask = 0xddc00000 - 1,
803 	.fwname = "qcom/venus-4.4/venus.mbn",
804 };
805 
806 static const struct freq_tbl sdm660_freq_table[] = {
807 	{ 979200, 518400000 },
808 	{ 489600, 441600000 },
809 	{ 432000, 404000000 },
810 	{ 244800, 320000000 },
811 	{ 216000, 269330000 },
812 	{ 108000, 133330000 },
813 };
814 
815 static const struct reg_val sdm660_reg_preset[] = {
816 	{ 0x80010, 0x001f001f },
817 	{ 0x80018, 0x00000156 },
818 	{ 0x8001c, 0x00000156 },
819 };
820 
821 static const struct bw_tbl sdm660_bw_table_enc[] = {
822 	{  979200,  1044000, 0, 2446336, 0 },	/* 4k UHD @ 30 */
823 	{  864000,   887000, 0, 2108416, 0 },	/* 720p @ 240 */
824 	{  489600,   666000, 0, 1207296, 0 },	/* 1080p @ 60 */
825 	{  432000,   578000, 0, 1058816, 0 },	/* 720p @ 120 */
826 	{  244800,   346000, 0,  616448, 0 },	/* 1080p @ 30 */
827 	{  216000,   293000, 0,  534528, 0 },	/* 720p @ 60 */
828 	{  108000,   151000, 0,  271360, 0 },	/* 720p @ 30 */
829 };
830 
831 static const struct bw_tbl sdm660_bw_table_dec[] = {
832 	{  979200,  2365000, 0, 1892000, 0 },	/* 4k UHD @ 30 */
833 	{  864000,  1978000, 0, 1554000, 0 },	/* 720p @ 240 */
834 	{  489600,  1133000, 0,  895000, 0 },	/* 1080p @ 60 */
835 	{  432000,   994000, 0,  781000, 0 },	/* 720p @ 120 */
836 	{  244800,   580000, 0,  460000, 0 },	/* 1080p @ 30 */
837 	{  216000,   501000, 0,  301000, 0 },	/* 720p @ 60 */
838 	{  108000,   255000, 0,  202000, 0 },	/* 720p @ 30 */
839 };
840 
841 static const struct venus_resources sdm660_res = {
842 	.freq_tbl = sdm660_freq_table,
843 	.freq_tbl_size = ARRAY_SIZE(sdm660_freq_table),
844 	.reg_tbl = sdm660_reg_preset,
845 	.reg_tbl_size = ARRAY_SIZE(sdm660_reg_preset),
846 	.bw_tbl_enc = sdm660_bw_table_enc,
847 	.bw_tbl_enc_size = ARRAY_SIZE(sdm660_bw_table_enc),
848 	.bw_tbl_dec = sdm660_bw_table_dec,
849 	.bw_tbl_dec_size = ARRAY_SIZE(sdm660_bw_table_dec),
850 	.clks = {"core", "iface", "bus", "bus_throttle" },
851 	.clks_num = 4,
852 	.vcodec0_clks = { "vcodec0_core" },
853 	.vcodec1_clks = { "vcodec0_core" },
854 	.vcodec_clks_num = 1,
855 	.vcodec_num = 1,
856 	.max_load = 1036800,
857 	.hfi_version = HFI_VERSION_3XX,
858 	.vmem_id = VIDC_RESOURCE_NONE,
859 	.vmem_size = 0,
860 	.vmem_addr = 0,
861 	.cp_start = 0,
862 	.cp_size = 0x79000000,
863 	.cp_nonpixel_start = 0x1000000,
864 	.cp_nonpixel_size = 0x28000000,
865 	.dma_mask = 0xd9000000 - 1,
866 	.fwname = "qcom/venus-4.4/venus.mdt",
867 };
868 
869 static const struct freq_tbl sdm845_freq_table[] = {
870 	{ 3110400, 533000000 },	/* 4096x2160@90 */
871 	{ 2073600, 444000000 },	/* 4096x2160@60 */
872 	{ 1944000, 404000000 },	/* 3840x2160@60 */
873 	{  972000, 330000000 },	/* 3840x2160@30 */
874 	{  489600, 200000000 },	/* 1920x1080@60 */
875 	{  244800, 100000000 },	/* 1920x1080@30 */
876 };
877 
878 static const struct bw_tbl sdm845_bw_table_enc[] = {
879 	{ 1944000, 1612000, 0, 2416000, 0 },	/* 3840x2160@60 */
880 	{  972000,  951000, 0, 1434000, 0 },	/* 3840x2160@30 */
881 	{  489600,  723000, 0,  973000, 0 },	/* 1920x1080@60 */
882 	{  244800,  370000, 0,	495000, 0 },	/* 1920x1080@30 */
883 };
884 
885 static const struct bw_tbl sdm845_bw_table_dec[] = {
886 	{ 2073600, 3929000, 0, 5551000, 0 },	/* 4096x2160@60 */
887 	{ 1036800, 1987000, 0, 2797000, 0 },	/* 4096x2160@30 */
888 	{  489600, 1040000, 0, 1298000, 0 },	/* 1920x1080@60 */
889 	{  244800,  530000, 0,  659000, 0 },	/* 1920x1080@30 */
890 };
891 
892 static const struct venus_resources sdm845_res = {
893 	.freq_tbl = sdm845_freq_table,
894 	.freq_tbl_size = ARRAY_SIZE(sdm845_freq_table),
895 	.bw_tbl_enc = sdm845_bw_table_enc,
896 	.bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
897 	.bw_tbl_dec = sdm845_bw_table_dec,
898 	.bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
899 	.clks = {"core", "iface", "bus" },
900 	.clks_num = 3,
901 	.vcodec0_clks = { "core", "bus" },
902 	.vcodec1_clks = { "core", "bus" },
903 	.vcodec_clks_num = 2,
904 	.max_load = 3110400,	/* 4096x2160@90 */
905 	.hfi_version = HFI_VERSION_4XX,
906 	.vpu_version = VPU_VERSION_AR50,
907 	.vmem_id = VIDC_RESOURCE_NONE,
908 	.vmem_size = 0,
909 	.vmem_addr = 0,
910 	.dma_mask = 0xe0000000 - 1,
911 	.fwname = "qcom/venus-5.2/venus.mbn",
912 };
913 
914 static const struct venus_resources sdm845_res_v2 = {
915 	.freq_tbl = sdm845_freq_table,
916 	.freq_tbl_size = ARRAY_SIZE(sdm845_freq_table),
917 	.bw_tbl_enc = sdm845_bw_table_enc,
918 	.bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
919 	.bw_tbl_dec = sdm845_bw_table_dec,
920 	.bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
921 	.clks = {"core", "iface", "bus" },
922 	.clks_num = 3,
923 	.vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
924 	.vcodec1_clks = { "vcodec1_core", "vcodec1_bus" },
925 	.vcodec_clks_num = 2,
926 	.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0", "vcodec1" },
927 	.vcodec_pmdomains_num = 3,
928 	.opp_pmdomain = (const char *[]) { "cx" },
929 	.opp_pmdomain_num = 1,
930 	.vcodec_num = 2,
931 	.max_load = 3110400,	/* 4096x2160@90 */
932 	.hfi_version = HFI_VERSION_4XX,
933 	.vpu_version = VPU_VERSION_AR50,
934 	.vmem_id = VIDC_RESOURCE_NONE,
935 	.vmem_size = 0,
936 	.vmem_addr = 0,
937 	.dma_mask = 0xe0000000 - 1,
938 	.cp_start = 0,
939 	.cp_size = 0x70800000,
940 	.cp_nonpixel_start = 0x1000000,
941 	.cp_nonpixel_size = 0x24800000,
942 	.fwname = "qcom/venus-5.2/venus.mbn",
943 	.dec_nodename = "video-core0",
944 	.enc_nodename = "video-core1",
945 };
946 
947 static const struct freq_tbl sc7180_freq_table[] = {
948 	{  0, 500000000 },
949 	{  0, 434000000 },
950 	{  0, 340000000 },
951 	{  0, 270000000 },
952 	{  0, 150000000 },
953 };
954 
955 static const struct bw_tbl sc7180_bw_table_enc[] = {
956 	{  972000,  750000, 0, 0, 0 },	/* 3840x2160@30 */
957 	{  489600,  451000, 0, 0, 0 },	/* 1920x1080@60 */
958 	{  244800,  234000, 0, 0, 0 },	/* 1920x1080@30 */
959 };
960 
961 static const struct bw_tbl sc7180_bw_table_dec[] = {
962 	{ 1036800, 1386000, 0, 1875000, 0 },	/* 4096x2160@30 */
963 	{  489600,  865000, 0, 1146000, 0 },	/* 1920x1080@60 */
964 	{  244800,  530000, 0,  583000, 0 },	/* 1920x1080@30 */
965 };
966 
967 static const struct venus_resources sc7180_res = {
968 	.freq_tbl = sc7180_freq_table,
969 	.freq_tbl_size = ARRAY_SIZE(sc7180_freq_table),
970 	.bw_tbl_enc = sc7180_bw_table_enc,
971 	.bw_tbl_enc_size = ARRAY_SIZE(sc7180_bw_table_enc),
972 	.bw_tbl_dec = sc7180_bw_table_dec,
973 	.bw_tbl_dec_size = ARRAY_SIZE(sc7180_bw_table_dec),
974 	.clks = {"core", "iface", "bus" },
975 	.clks_num = 3,
976 	.vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
977 	.vcodec_clks_num = 2,
978 	.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
979 	.vcodec_pmdomains_num = 2,
980 	.opp_pmdomain = (const char *[]) { "cx" },
981 	.opp_pmdomain_num = 1,
982 	.vcodec_num = 1,
983 	.hfi_version = HFI_VERSION_4XX,
984 	.vpu_version = VPU_VERSION_AR50,
985 	.vmem_id = VIDC_RESOURCE_NONE,
986 	.vmem_size = 0,
987 	.vmem_addr = 0,
988 	.dma_mask = 0xe0000000 - 1,
989 	.cp_start = 0,
990 	.cp_size = 0x70800000,
991 	.cp_nonpixel_start = 0x1000000,
992 	.cp_nonpixel_size = 0x24800000,
993 	.fwname = "qcom/venus-5.4/venus.mbn",
994 	.dec_nodename = "video-decoder",
995 	.enc_nodename = "video-encoder",
996 };
997 
998 #if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS))
999 static const struct freq_tbl sm8250_freq_table[] = {
1000 	{ 0, 444000000 },
1001 	{ 0, 366000000 },
1002 	{ 0, 338000000 },
1003 	{ 0, 240000000 },
1004 };
1005 
1006 static const struct bw_tbl sm8250_bw_table_enc[] = {
1007 	{ 1944000, 1954000, 0, 3711000, 0 },	/* 3840x2160@60 */
1008 	{  972000,  996000, 0, 1905000, 0 },	/* 3840x2160@30 */
1009 	{  489600,  645000, 0,  977000, 0 },	/* 1920x1080@60 */
1010 	{  244800,  332000, 0,	498000, 0 },	/* 1920x1080@30 */
1011 };
1012 
1013 static const struct bw_tbl sm8250_bw_table_dec[] = {
1014 	{ 2073600, 2403000, 0, 4113000, 0 },	/* 4096x2160@60 */
1015 	{ 1036800, 1224000, 0, 2079000, 0 },	/* 4096x2160@30 */
1016 	{  489600,  812000, 0,  998000, 0 },	/* 1920x1080@60 */
1017 	{  244800,  416000, 0,  509000, 0 },	/* 1920x1080@30 */
1018 };
1019 
1020 static const struct reg_val sm8250_reg_preset[] = {
1021 	{ 0xb0088, 0 },
1022 };
1023 
1024 static const struct venus_resources sm8250_res = {
1025 	.freq_tbl = sm8250_freq_table,
1026 	.freq_tbl_size = ARRAY_SIZE(sm8250_freq_table),
1027 	.reg_tbl = sm8250_reg_preset,
1028 	.reg_tbl_size = ARRAY_SIZE(sm8250_reg_preset),
1029 	.bw_tbl_enc = sm8250_bw_table_enc,
1030 	.bw_tbl_enc_size = ARRAY_SIZE(sm8250_bw_table_enc),
1031 	.bw_tbl_dec = sm8250_bw_table_dec,
1032 	.bw_tbl_dec_size = ARRAY_SIZE(sm8250_bw_table_dec),
1033 	.clks = {"core", "iface"},
1034 	.clks_num = 2,
1035 	.resets = { "bus", "core" },
1036 	.resets_num = 2,
1037 	.vcodec0_clks = { "vcodec0_core" },
1038 	.vcodec_clks_num = 1,
1039 	.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
1040 	.vcodec_pmdomains_num = 2,
1041 	.opp_pmdomain = (const char *[]) { "mx", "mmcx" },
1042 	.opp_pmdomain_num = 2,
1043 	.vcodec_num = 1,
1044 	.max_load = 7833600,
1045 	.hfi_version = HFI_VERSION_6XX,
1046 	.vpu_version = VPU_VERSION_IRIS2,
1047 	.num_vpp_pipes = 4,
1048 	.vmem_id = VIDC_RESOURCE_NONE,
1049 	.vmem_size = 0,
1050 	.vmem_addr = 0,
1051 	.dma_mask = 0xe0000000 - 1,
1052 	.fwname = "qcom/vpu-1.0/venus.mbn",
1053 	.dec_nodename = "video-decoder",
1054 	.enc_nodename = "video-encoder",
1055 };
1056 
1057 static const struct freq_tbl sc7280_freq_table[] = {
1058 	{ 0, 460000000 },
1059 	{ 0, 424000000 },
1060 	{ 0, 335000000 },
1061 	{ 0, 240000000 },
1062 	{ 0, 133333333 },
1063 };
1064 
1065 static const struct bw_tbl sc7280_bw_table_enc[] = {
1066 	{ 1944000, 1896000, 0, 3657000, 0 },	/* 3840x2160@60 */
1067 	{  972000,  968000, 0, 1848000, 0 },	/* 3840x2160@30 */
1068 	{  489600,  618000, 0,  941000, 0 },	/* 1920x1080@60 */
1069 	{  244800,  318000, 0,	480000, 0 },	/* 1920x1080@30 */
1070 };
1071 
1072 static const struct bw_tbl sc7280_bw_table_dec[] = {
1073 	{ 2073600, 2128000, 0, 3831000, 0 },	/* 4096x2160@60 */
1074 	{ 1036800, 1085000, 0, 1937000, 0 },	/* 4096x2160@30 */
1075 	{  489600,  779000, 0,  998000, 0 },	/* 1920x1080@60 */
1076 	{  244800,  400000, 0,  509000, 0 },	/* 1920x1080@30 */
1077 };
1078 
1079 static const struct reg_val sm7280_reg_preset[] = {
1080 	{ 0xb0088, 0 },
1081 };
1082 
1083 static const struct hfi_ubwc_config sc7280_ubwc_config = {
1084 	0, 0, {1, 1, 1, 0, 0, 0}, 8, 32, 14, 0, 0, {0, 0}
1085 };
1086 
1087 static const struct venus_resources sc7280_res = {
1088 	.freq_tbl = sc7280_freq_table,
1089 	.freq_tbl_size = ARRAY_SIZE(sc7280_freq_table),
1090 	.reg_tbl = sm7280_reg_preset,
1091 	.reg_tbl_size = ARRAY_SIZE(sm7280_reg_preset),
1092 	.bw_tbl_enc = sc7280_bw_table_enc,
1093 	.bw_tbl_enc_size = ARRAY_SIZE(sc7280_bw_table_enc),
1094 	.bw_tbl_dec = sc7280_bw_table_dec,
1095 	.bw_tbl_dec_size = ARRAY_SIZE(sc7280_bw_table_dec),
1096 	.ubwc_conf = &sc7280_ubwc_config,
1097 	.clks = {"core", "bus", "iface"},
1098 	.clks_num = 3,
1099 	.vcodec0_clks = {"vcodec_core", "vcodec_bus"},
1100 	.vcodec_clks_num = 2,
1101 	.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
1102 	.vcodec_pmdomains_num = 2,
1103 	.opp_pmdomain = (const char *[]) { "cx" },
1104 	.opp_pmdomain_num = 1,
1105 	.vcodec_num = 1,
1106 	.hfi_version = HFI_VERSION_6XX,
1107 	.vpu_version = VPU_VERSION_IRIS2_1,
1108 	.num_vpp_pipes = 1,
1109 	.vmem_id = VIDC_RESOURCE_NONE,
1110 	.vmem_size = 0,
1111 	.vmem_addr = 0,
1112 	.dma_mask = 0xe0000000 - 1,
1113 	.cp_start = 0,
1114 	.cp_size = 0x25800000,
1115 	.cp_nonpixel_start = 0x1000000,
1116 	.cp_nonpixel_size = 0x24800000,
1117 	.fwname = "qcom/vpu-2.0/venus.mbn",
1118 	.dec_nodename = "video-decoder",
1119 	.enc_nodename = "video-encoder",
1120 };
1121 #endif
1122 
1123 static const struct bw_tbl qcm2290_bw_table_dec[] = {
1124 	{ 352800, 597000, 0, 746000, 0 }, /* 1080p@30 + 720p@30 */
1125 	{ 244800, 413000, 0, 516000, 0 }, /* 1080p@30 */
1126 	{ 216000, 364000, 0, 454000, 0 }, /* 720p@60  */
1127 	{ 108000, 182000, 0, 227000, 0 }, /* 720p@30  */
1128 };
1129 
1130 static const struct bw_tbl qcm2290_bw_table_enc[] = {
1131 	{ 352800, 396000, 0, 0, 0 }, /* 1080p@30 + 720p@30 */
1132 	{ 244800, 275000, 0, 0, 0 }, /* 1080p@30 */
1133 	{ 216000, 242000, 0, 0, 0 }, /* 720p@60  */
1134 	{ 108000, 121000, 0, 0, 0 }, /* 720p@30  */
1135 };
1136 
1137 static const struct firmware_version min_fw = {
1138 	.major = 6, .minor = 0, .rev = 55,
1139 };
1140 
1141 static const struct venus_resources qcm2290_res = {
1142 	.bw_tbl_dec = qcm2290_bw_table_dec,
1143 	.bw_tbl_dec_size = ARRAY_SIZE(qcm2290_bw_table_dec),
1144 	.bw_tbl_enc = qcm2290_bw_table_enc,
1145 	.bw_tbl_enc_size = ARRAY_SIZE(qcm2290_bw_table_enc),
1146 	.clks = { "core", "iface", "bus", "throttle" },
1147 	.clks_num = 4,
1148 	.vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
1149 	.vcodec_clks_num = 2,
1150 	.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
1151 	.vcodec_pmdomains_num = 2,
1152 	.opp_pmdomain = (const char *[]) { "cx" },
1153 	.opp_pmdomain_num = 1,
1154 	.vcodec_num = 1,
1155 	.hfi_version = HFI_VERSION_4XX,
1156 	.vpu_version = VPU_VERSION_AR50_LITE,
1157 	.max_load = 352800,
1158 	.num_vpp_pipes = 1,
1159 	.vmem_id = VIDC_RESOURCE_NONE,
1160 	.vmem_size = 0,
1161 	.vmem_addr = 0,
1162 	.cp_start = 0,
1163 	.cp_size = 0x70800000,
1164 	.cp_nonpixel_start = 0x1000000,
1165 	.cp_nonpixel_size = 0x24800000,
1166 	.dma_mask = 0xe0000000 - 1,
1167 	.fwname = "qcom/venus-6.0/venus.mbn",
1168 	.dec_nodename = "video-decoder",
1169 	.enc_nodename = "video-encoder",
1170 	.min_fw = &min_fw,
1171 };
1172 
1173 static const struct of_device_id venus_dt_match[] = {
1174 	{ .compatible = "qcom,msm8916-venus", .data = &msm8916_res, },
1175 	{ .compatible = "qcom,msm8939-venus", .data = &msm8939_res, },
1176 	{ .compatible = "qcom,msm8996-venus", .data = &msm8996_res, },
1177 	{ .compatible = "qcom,msm8998-venus", .data = &msm8998_res, },
1178 	{ .compatible = "qcom,qcm2290-venus", .data = &qcm2290_res, },
1179 	{ .compatible = "qcom,sc7180-venus", .data = &sc7180_res, },
1180 	{ .compatible = "qcom,sdm660-venus", .data = &sdm660_res, },
1181 	{ .compatible = "qcom,sdm845-venus", .data = &sdm845_res, },
1182 	{ .compatible = "qcom,sdm845-venus-v2", .data = &sdm845_res_v2, },
1183 #if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS))
1184 	{ .compatible = "qcom,sc7280-venus", .data = &sc7280_res, },
1185 	{ .compatible = "qcom,sm8250-venus", .data = &sm8250_res, },
1186 #endif
1187 	{ }
1188 };
1189 MODULE_DEVICE_TABLE(of, venus_dt_match);
1190 
1191 static struct platform_driver qcom_venus_driver = {
1192 	.probe = venus_probe,
1193 	.remove = venus_remove,
1194 	.driver = {
1195 		.name = "qcom-venus",
1196 		.of_match_table = venus_dt_match,
1197 		.pm = &venus_pm_ops,
1198 	},
1199 	.shutdown = venus_core_shutdown,
1200 };
1201 module_platform_driver(qcom_venus_driver);
1202 
1203 MODULE_DESCRIPTION("Qualcomm Venus video encoder and decoder driver");
1204 MODULE_LICENSE("GPL v2");
1205