1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019 Linaro Ltd.
4  *
5  * Author: Stanimir Varbanov <stanimir.varbanov@linaro.org>
6  */
7 #include <linux/clk.h>
8 #include <linux/interconnect.h>
9 #include <linux/iopoll.h>
10 #include <linux/kernel.h>
11 #include <linux/pm_domain.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/types.h>
14 #include <media/v4l2-mem2mem.h>
15 
16 #include "core.h"
17 #include "hfi_parser.h"
18 #include "hfi_venus_io.h"
19 #include "pm_helpers.h"
20 
21 static bool legacy_binding;
22 
23 static int core_clks_get(struct venus_core *core)
24 {
25 	const struct venus_resources *res = core->res;
26 	struct device *dev = core->dev;
27 	unsigned int i;
28 
29 	for (i = 0; i < res->clks_num; i++) {
30 		core->clks[i] = devm_clk_get(dev, res->clks[i]);
31 		if (IS_ERR(core->clks[i]))
32 			return PTR_ERR(core->clks[i]);
33 	}
34 
35 	return 0;
36 }
37 
38 static int core_clks_enable(struct venus_core *core)
39 {
40 	const struct venus_resources *res = core->res;
41 	unsigned int i;
42 	int ret;
43 
44 	for (i = 0; i < res->clks_num; i++) {
45 		ret = clk_prepare_enable(core->clks[i]);
46 		if (ret)
47 			goto err;
48 	}
49 
50 	return 0;
51 err:
52 	while (i--)
53 		clk_disable_unprepare(core->clks[i]);
54 
55 	return ret;
56 }
57 
58 static void core_clks_disable(struct venus_core *core)
59 {
60 	const struct venus_resources *res = core->res;
61 	unsigned int i = res->clks_num;
62 
63 	while (i--)
64 		clk_disable_unprepare(core->clks[i]);
65 }
66 
67 static int core_clks_set_rate(struct venus_core *core, unsigned long freq)
68 {
69 	struct clk *clk = core->clks[0];
70 	int ret;
71 
72 	ret = clk_set_rate(clk, freq);
73 	if (ret)
74 		return ret;
75 
76 	ret = clk_set_rate(core->vcodec0_clks[0], freq);
77 	if (ret)
78 		return ret;
79 
80 	ret = clk_set_rate(core->vcodec1_clks[0], freq);
81 	if (ret)
82 		return ret;
83 
84 	return 0;
85 }
86 
87 static int vcodec_clks_get(struct venus_core *core, struct device *dev,
88 			   struct clk **clks, const char * const *id)
89 {
90 	const struct venus_resources *res = core->res;
91 	unsigned int i;
92 
93 	for (i = 0; i < res->vcodec_clks_num; i++) {
94 		if (!id[i])
95 			continue;
96 		clks[i] = devm_clk_get(dev, id[i]);
97 		if (IS_ERR(clks[i]))
98 			return PTR_ERR(clks[i]);
99 	}
100 
101 	return 0;
102 }
103 
104 static int vcodec_clks_enable(struct venus_core *core, struct clk **clks)
105 {
106 	const struct venus_resources *res = core->res;
107 	unsigned int i;
108 	int ret;
109 
110 	for (i = 0; i < res->vcodec_clks_num; i++) {
111 		ret = clk_prepare_enable(clks[i]);
112 		if (ret)
113 			goto err;
114 	}
115 
116 	return 0;
117 err:
118 	while (i--)
119 		clk_disable_unprepare(clks[i]);
120 
121 	return ret;
122 }
123 
124 static void vcodec_clks_disable(struct venus_core *core, struct clk **clks)
125 {
126 	const struct venus_resources *res = core->res;
127 	unsigned int i = res->vcodec_clks_num;
128 
129 	while (i--)
130 		clk_disable_unprepare(clks[i]);
131 }
132 
133 static u32 load_per_instance(struct venus_inst *inst)
134 {
135 	u32 mbs;
136 
137 	if (!inst || !(inst->state >= INST_INIT && inst->state < INST_STOP))
138 		return 0;
139 
140 	mbs = (ALIGN(inst->width, 16) / 16) * (ALIGN(inst->height, 16) / 16);
141 
142 	return mbs * inst->fps;
143 }
144 
145 static u32 load_per_type(struct venus_core *core, u32 session_type)
146 {
147 	struct venus_inst *inst = NULL;
148 	u32 mbs_per_sec = 0;
149 
150 	mutex_lock(&core->lock);
151 	list_for_each_entry(inst, &core->instances, list) {
152 		if (inst->session_type != session_type)
153 			continue;
154 
155 		mbs_per_sec += load_per_instance(inst);
156 	}
157 	mutex_unlock(&core->lock);
158 
159 	return mbs_per_sec;
160 }
161 
162 static void mbs_to_bw(struct venus_inst *inst, u32 mbs, u32 *avg, u32 *peak)
163 {
164 	const struct venus_resources *res = inst->core->res;
165 	const struct bw_tbl *bw_tbl;
166 	unsigned int num_rows, i;
167 
168 	*avg = 0;
169 	*peak = 0;
170 
171 	if (mbs == 0)
172 		return;
173 
174 	if (inst->session_type == VIDC_SESSION_TYPE_ENC) {
175 		num_rows = res->bw_tbl_enc_size;
176 		bw_tbl = res->bw_tbl_enc;
177 	} else if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
178 		num_rows = res->bw_tbl_dec_size;
179 		bw_tbl = res->bw_tbl_dec;
180 	} else {
181 		return;
182 	}
183 
184 	if (!bw_tbl || num_rows == 0)
185 		return;
186 
187 	for (i = 0; i < num_rows; i++) {
188 		if (mbs > bw_tbl[i].mbs_per_sec)
189 			break;
190 
191 		if (inst->dpb_fmt & HFI_COLOR_FORMAT_10_BIT_BASE) {
192 			*avg = bw_tbl[i].avg_10bit;
193 			*peak = bw_tbl[i].peak_10bit;
194 		} else {
195 			*avg = bw_tbl[i].avg;
196 			*peak = bw_tbl[i].peak;
197 		}
198 	}
199 }
200 
201 static int load_scale_bw(struct venus_core *core)
202 {
203 	struct venus_inst *inst = NULL;
204 	u32 mbs_per_sec, avg, peak, total_avg = 0, total_peak = 0;
205 
206 	mutex_lock(&core->lock);
207 	list_for_each_entry(inst, &core->instances, list) {
208 		mbs_per_sec = load_per_instance(inst);
209 		mbs_to_bw(inst, mbs_per_sec, &avg, &peak);
210 		total_avg += avg;
211 		total_peak += peak;
212 	}
213 	mutex_unlock(&core->lock);
214 
215 	dev_dbg(core->dev, "total: avg_bw: %u, peak_bw: %u\n",
216 		total_avg, total_peak);
217 
218 	return icc_set_bw(core->video_path, total_avg, total_peak);
219 }
220 
221 static int load_scale_v1(struct venus_inst *inst)
222 {
223 	struct venus_core *core = inst->core;
224 	const struct freq_tbl *table = core->res->freq_tbl;
225 	unsigned int num_rows = core->res->freq_tbl_size;
226 	unsigned long freq = table[0].freq;
227 	struct device *dev = core->dev;
228 	u32 mbs_per_sec;
229 	unsigned int i;
230 	int ret;
231 
232 	mbs_per_sec = load_per_type(core, VIDC_SESSION_TYPE_ENC) +
233 		      load_per_type(core, VIDC_SESSION_TYPE_DEC);
234 
235 	if (mbs_per_sec > core->res->max_load)
236 		dev_warn(dev, "HW is overloaded, needed: %d max: %d\n",
237 			 mbs_per_sec, core->res->max_load);
238 
239 	if (!mbs_per_sec && num_rows > 1) {
240 		freq = table[num_rows - 1].freq;
241 		goto set_freq;
242 	}
243 
244 	for (i = 0; i < num_rows; i++) {
245 		if (mbs_per_sec > table[i].load)
246 			break;
247 		freq = table[i].freq;
248 	}
249 
250 set_freq:
251 
252 	ret = core_clks_set_rate(core, freq);
253 	if (ret) {
254 		dev_err(dev, "failed to set clock rate %lu (%d)\n",
255 			freq, ret);
256 		return ret;
257 	}
258 
259 	ret = load_scale_bw(core);
260 	if (ret) {
261 		dev_err(dev, "failed to set bandwidth (%d)\n",
262 			ret);
263 		return ret;
264 	}
265 
266 	return 0;
267 }
268 
269 static int core_get_v1(struct device *dev)
270 {
271 	struct venus_core *core = dev_get_drvdata(dev);
272 
273 	return core_clks_get(core);
274 }
275 
276 static int core_power_v1(struct device *dev, int on)
277 {
278 	struct venus_core *core = dev_get_drvdata(dev);
279 	int ret = 0;
280 
281 	if (on == POWER_ON)
282 		ret = core_clks_enable(core);
283 	else
284 		core_clks_disable(core);
285 
286 	return ret;
287 }
288 
289 static const struct venus_pm_ops pm_ops_v1 = {
290 	.core_get = core_get_v1,
291 	.core_power = core_power_v1,
292 	.load_scale = load_scale_v1,
293 };
294 
295 static void
296 vcodec_control_v3(struct venus_core *core, u32 session_type, bool enable)
297 {
298 	void __iomem *ctrl;
299 
300 	if (session_type == VIDC_SESSION_TYPE_DEC)
301 		ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
302 	else
303 		ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
304 
305 	if (enable)
306 		writel(0, ctrl);
307 	else
308 		writel(1, ctrl);
309 }
310 
311 static int vdec_get_v3(struct device *dev)
312 {
313 	struct venus_core *core = dev_get_drvdata(dev);
314 
315 	return vcodec_clks_get(core, dev, core->vcodec0_clks,
316 			       core->res->vcodec0_clks);
317 }
318 
319 static int vdec_power_v3(struct device *dev, int on)
320 {
321 	struct venus_core *core = dev_get_drvdata(dev);
322 	int ret = 0;
323 
324 	vcodec_control_v3(core, VIDC_SESSION_TYPE_DEC, true);
325 
326 	if (on == POWER_ON)
327 		ret = vcodec_clks_enable(core, core->vcodec0_clks);
328 	else
329 		vcodec_clks_disable(core, core->vcodec0_clks);
330 
331 	vcodec_control_v3(core, VIDC_SESSION_TYPE_DEC, false);
332 
333 	return ret;
334 }
335 
336 static int venc_get_v3(struct device *dev)
337 {
338 	struct venus_core *core = dev_get_drvdata(dev);
339 
340 	return vcodec_clks_get(core, dev, core->vcodec1_clks,
341 			       core->res->vcodec1_clks);
342 }
343 
344 static int venc_power_v3(struct device *dev, int on)
345 {
346 	struct venus_core *core = dev_get_drvdata(dev);
347 	int ret = 0;
348 
349 	vcodec_control_v3(core, VIDC_SESSION_TYPE_ENC, true);
350 
351 	if (on == POWER_ON)
352 		ret = vcodec_clks_enable(core, core->vcodec1_clks);
353 	else
354 		vcodec_clks_disable(core, core->vcodec1_clks);
355 
356 	vcodec_control_v3(core, VIDC_SESSION_TYPE_ENC, false);
357 
358 	return ret;
359 }
360 
361 static const struct venus_pm_ops pm_ops_v3 = {
362 	.core_get = core_get_v1,
363 	.core_power = core_power_v1,
364 	.vdec_get = vdec_get_v3,
365 	.vdec_power = vdec_power_v3,
366 	.venc_get = venc_get_v3,
367 	.venc_power = venc_power_v3,
368 	.load_scale = load_scale_v1,
369 };
370 
371 static int vcodec_control_v4(struct venus_core *core, u32 coreid, bool enable)
372 {
373 	void __iomem *ctrl, *stat;
374 	u32 val;
375 	int ret;
376 
377 	if (coreid == VIDC_CORE_ID_1) {
378 		ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
379 		stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
380 	} else {
381 		ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
382 		stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
383 	}
384 
385 	if (enable) {
386 		writel(0, ctrl);
387 
388 		ret = readl_poll_timeout(stat, val, val & BIT(1), 1, 100);
389 		if (ret)
390 			return ret;
391 	} else {
392 		writel(1, ctrl);
393 
394 		ret = readl_poll_timeout(stat, val, !(val & BIT(1)), 1, 100);
395 		if (ret)
396 			return ret;
397 	}
398 
399 	return 0;
400 }
401 
402 static int poweroff_coreid(struct venus_core *core, unsigned int coreid_mask)
403 {
404 	int ret;
405 
406 	if (coreid_mask & VIDC_CORE_ID_1) {
407 		ret = vcodec_control_v4(core, VIDC_CORE_ID_1, true);
408 		if (ret)
409 			return ret;
410 
411 		vcodec_clks_disable(core, core->vcodec0_clks);
412 
413 		ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
414 		if (ret)
415 			return ret;
416 
417 		ret = pm_runtime_put_sync(core->pmdomains[1]);
418 		if (ret < 0)
419 			return ret;
420 	}
421 
422 	if (coreid_mask & VIDC_CORE_ID_2) {
423 		ret = vcodec_control_v4(core, VIDC_CORE_ID_2, true);
424 		if (ret)
425 			return ret;
426 
427 		vcodec_clks_disable(core, core->vcodec1_clks);
428 
429 		ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
430 		if (ret)
431 			return ret;
432 
433 		ret = pm_runtime_put_sync(core->pmdomains[2]);
434 		if (ret < 0)
435 			return ret;
436 	}
437 
438 	return 0;
439 }
440 
441 static int poweron_coreid(struct venus_core *core, unsigned int coreid_mask)
442 {
443 	int ret;
444 
445 	if (coreid_mask & VIDC_CORE_ID_1) {
446 		ret = pm_runtime_get_sync(core->pmdomains[1]);
447 		if (ret < 0)
448 			return ret;
449 
450 		ret = vcodec_control_v4(core, VIDC_CORE_ID_1, true);
451 		if (ret)
452 			return ret;
453 
454 		ret = vcodec_clks_enable(core, core->vcodec0_clks);
455 		if (ret)
456 			return ret;
457 
458 		ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
459 		if (ret < 0)
460 			return ret;
461 	}
462 
463 	if (coreid_mask & VIDC_CORE_ID_2) {
464 		ret = pm_runtime_get_sync(core->pmdomains[2]);
465 		if (ret < 0)
466 			return ret;
467 
468 		ret = vcodec_control_v4(core, VIDC_CORE_ID_2, true);
469 		if (ret)
470 			return ret;
471 
472 		ret = vcodec_clks_enable(core, core->vcodec1_clks);
473 		if (ret)
474 			return ret;
475 
476 		ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
477 		if (ret < 0)
478 			return ret;
479 	}
480 
481 	return 0;
482 }
483 
484 static void
485 min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load)
486 {
487 	u32 mbs_per_sec, load, core1_load = 0, core2_load = 0;
488 	u32 cores_max = core_num_max(inst);
489 	struct venus_core *core = inst->core;
490 	struct venus_inst *inst_pos;
491 	unsigned long vpp_freq;
492 	u32 coreid;
493 
494 	mutex_lock(&core->lock);
495 
496 	list_for_each_entry(inst_pos, &core->instances, list) {
497 		if (inst_pos == inst)
498 			continue;
499 		vpp_freq = inst_pos->clk_data.codec_freq_data->vpp_freq;
500 		coreid = inst_pos->clk_data.core_id;
501 
502 		mbs_per_sec = load_per_instance(inst_pos);
503 		load = mbs_per_sec * vpp_freq;
504 
505 		if ((coreid & VIDC_CORE_ID_3) == VIDC_CORE_ID_3) {
506 			core1_load += load / 2;
507 			core2_load += load / 2;
508 		} else if (coreid & VIDC_CORE_ID_1) {
509 			core1_load += load;
510 		} else if (coreid & VIDC_CORE_ID_2) {
511 			core2_load += load;
512 		}
513 	}
514 
515 	*min_coreid = core1_load <= core2_load ?
516 			VIDC_CORE_ID_1 : VIDC_CORE_ID_2;
517 	*min_load = min(core1_load, core2_load);
518 
519 	if (cores_max < VIDC_CORE_ID_2 || core->res->vcodec_num < 2) {
520 		*min_coreid = VIDC_CORE_ID_1;
521 		*min_load = core1_load;
522 	}
523 
524 	mutex_unlock(&core->lock);
525 }
526 
527 static int decide_core(struct venus_inst *inst)
528 {
529 	const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
530 	struct venus_core *core = inst->core;
531 	u32 min_coreid, min_load, inst_load;
532 	struct hfi_videocores_usage_type cu;
533 	unsigned long max_freq;
534 
535 	if (legacy_binding) {
536 		if (inst->session_type == VIDC_SESSION_TYPE_DEC)
537 			cu.video_core_enable_mask = VIDC_CORE_ID_1;
538 		else
539 			cu.video_core_enable_mask = VIDC_CORE_ID_2;
540 
541 		goto done;
542 	}
543 
544 	if (inst->clk_data.core_id != VIDC_CORE_ID_DEFAULT)
545 		return 0;
546 
547 	inst_load = load_per_instance(inst);
548 	inst_load *= inst->clk_data.codec_freq_data->vpp_freq;
549 	max_freq = core->res->freq_tbl[0].freq;
550 
551 	min_loaded_core(inst, &min_coreid, &min_load);
552 
553 	if ((inst_load + min_load) > max_freq) {
554 		dev_warn(core->dev, "HW is overloaded, needed: %u max: %lu\n",
555 			 inst_load, max_freq);
556 		return -EINVAL;
557 	}
558 
559 	inst->clk_data.core_id = min_coreid;
560 	cu.video_core_enable_mask = min_coreid;
561 
562 done:
563 	return hfi_session_set_property(inst, ptype, &cu);
564 }
565 
566 static int acquire_core(struct venus_inst *inst)
567 {
568 	struct venus_core *core = inst->core;
569 	unsigned int coreid_mask = 0;
570 
571 	if (inst->core_acquired)
572 		return 0;
573 
574 	inst->core_acquired = true;
575 
576 	if (inst->clk_data.core_id & VIDC_CORE_ID_1) {
577 		if (core->core0_usage_count++)
578 			return 0;
579 
580 		coreid_mask = VIDC_CORE_ID_1;
581 	}
582 
583 	if (inst->clk_data.core_id & VIDC_CORE_ID_2) {
584 		if (core->core1_usage_count++)
585 			return 0;
586 
587 		coreid_mask |= VIDC_CORE_ID_2;
588 	}
589 
590 	return poweron_coreid(core, coreid_mask);
591 }
592 
593 static int release_core(struct venus_inst *inst)
594 {
595 	struct venus_core *core = inst->core;
596 	unsigned int coreid_mask = 0;
597 	int ret;
598 
599 	if (!inst->core_acquired)
600 		return 0;
601 
602 	if (inst->clk_data.core_id & VIDC_CORE_ID_1) {
603 		if (--core->core0_usage_count)
604 			goto done;
605 
606 		coreid_mask = VIDC_CORE_ID_1;
607 	}
608 
609 	if (inst->clk_data.core_id & VIDC_CORE_ID_2) {
610 		if (--core->core1_usage_count)
611 			goto done;
612 
613 		coreid_mask |= VIDC_CORE_ID_2;
614 	}
615 
616 	ret = poweroff_coreid(core, coreid_mask);
617 	if (ret)
618 		return ret;
619 
620 done:
621 	inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
622 	inst->core_acquired = false;
623 	return 0;
624 }
625 
626 static int coreid_power_v4(struct venus_inst *inst, int on)
627 {
628 	struct venus_core *core = inst->core;
629 	int ret;
630 
631 	if (legacy_binding)
632 		return 0;
633 
634 	if (on == POWER_ON) {
635 		ret = decide_core(inst);
636 		if (ret)
637 			return ret;
638 
639 		mutex_lock(&core->lock);
640 		ret = acquire_core(inst);
641 		mutex_unlock(&core->lock);
642 	} else {
643 		mutex_lock(&core->lock);
644 		ret = release_core(inst);
645 		mutex_unlock(&core->lock);
646 	}
647 
648 	return ret;
649 }
650 
651 static int vdec_get_v4(struct device *dev)
652 {
653 	struct venus_core *core = dev_get_drvdata(dev);
654 
655 	if (!legacy_binding)
656 		return 0;
657 
658 	return vcodec_clks_get(core, dev, core->vcodec0_clks,
659 			       core->res->vcodec0_clks);
660 }
661 
662 static void vdec_put_v4(struct device *dev)
663 {
664 	struct venus_core *core = dev_get_drvdata(dev);
665 	unsigned int i;
666 
667 	if (!legacy_binding)
668 		return;
669 
670 	for (i = 0; i < core->res->vcodec_clks_num; i++)
671 		core->vcodec0_clks[i] = NULL;
672 }
673 
674 static int vdec_power_v4(struct device *dev, int on)
675 {
676 	struct venus_core *core = dev_get_drvdata(dev);
677 	int ret;
678 
679 	if (!legacy_binding)
680 		return 0;
681 
682 	ret = vcodec_control_v4(core, VIDC_CORE_ID_1, true);
683 	if (ret)
684 		return ret;
685 
686 	if (on == POWER_ON)
687 		ret = vcodec_clks_enable(core, core->vcodec0_clks);
688 	else
689 		vcodec_clks_disable(core, core->vcodec0_clks);
690 
691 	vcodec_control_v4(core, VIDC_CORE_ID_1, false);
692 
693 	return ret;
694 }
695 
696 static int venc_get_v4(struct device *dev)
697 {
698 	struct venus_core *core = dev_get_drvdata(dev);
699 
700 	if (!legacy_binding)
701 		return 0;
702 
703 	return vcodec_clks_get(core, dev, core->vcodec1_clks,
704 			       core->res->vcodec1_clks);
705 }
706 
707 static void venc_put_v4(struct device *dev)
708 {
709 	struct venus_core *core = dev_get_drvdata(dev);
710 	unsigned int i;
711 
712 	if (!legacy_binding)
713 		return;
714 
715 	for (i = 0; i < core->res->vcodec_clks_num; i++)
716 		core->vcodec1_clks[i] = NULL;
717 }
718 
719 static int venc_power_v4(struct device *dev, int on)
720 {
721 	struct venus_core *core = dev_get_drvdata(dev);
722 	int ret;
723 
724 	if (!legacy_binding)
725 		return 0;
726 
727 	ret = vcodec_control_v4(core, VIDC_CORE_ID_2, true);
728 	if (ret)
729 		return ret;
730 
731 	if (on == POWER_ON)
732 		ret = vcodec_clks_enable(core, core->vcodec1_clks);
733 	else
734 		vcodec_clks_disable(core, core->vcodec1_clks);
735 
736 	vcodec_control_v4(core, VIDC_CORE_ID_2, false);
737 
738 	return ret;
739 }
740 
741 static int vcodec_domains_get(struct device *dev)
742 {
743 	struct venus_core *core = dev_get_drvdata(dev);
744 	const struct venus_resources *res = core->res;
745 	struct device *pd;
746 	unsigned int i;
747 
748 	if (!res->vcodec_pmdomains_num)
749 		return -ENODEV;
750 
751 	for (i = 0; i < res->vcodec_pmdomains_num; i++) {
752 		pd = dev_pm_domain_attach_by_name(dev,
753 						  res->vcodec_pmdomains[i]);
754 		if (IS_ERR(pd))
755 			return PTR_ERR(pd);
756 		core->pmdomains[i] = pd;
757 	}
758 
759 	core->pd_dl_venus = device_link_add(dev, core->pmdomains[0],
760 					    DL_FLAG_PM_RUNTIME |
761 					    DL_FLAG_STATELESS |
762 					    DL_FLAG_RPM_ACTIVE);
763 	if (!core->pd_dl_venus)
764 		return -ENODEV;
765 
766 	return 0;
767 }
768 
769 static void vcodec_domains_put(struct device *dev)
770 {
771 	struct venus_core *core = dev_get_drvdata(dev);
772 	const struct venus_resources *res = core->res;
773 	unsigned int i;
774 
775 	if (!res->vcodec_pmdomains_num)
776 		return;
777 
778 	if (core->pd_dl_venus)
779 		device_link_del(core->pd_dl_venus);
780 
781 	for (i = 0; i < res->vcodec_pmdomains_num; i++) {
782 		if (IS_ERR_OR_NULL(core->pmdomains[i]))
783 			continue;
784 		dev_pm_domain_detach(core->pmdomains[i], true);
785 	}
786 }
787 
788 static int core_get_v4(struct device *dev)
789 {
790 	struct venus_core *core = dev_get_drvdata(dev);
791 	const struct venus_resources *res = core->res;
792 	int ret;
793 
794 	ret = core_clks_get(core);
795 	if (ret)
796 		return ret;
797 
798 	if (!res->vcodec_pmdomains_num)
799 		legacy_binding = true;
800 
801 	dev_info(dev, "%s legacy binding\n", legacy_binding ? "" : "non");
802 
803 	ret = vcodec_clks_get(core, dev, core->vcodec0_clks, res->vcodec0_clks);
804 	if (ret)
805 		return ret;
806 
807 	ret = vcodec_clks_get(core, dev, core->vcodec1_clks, res->vcodec1_clks);
808 	if (ret)
809 		return ret;
810 
811 	if (legacy_binding)
812 		return 0;
813 
814 	ret = vcodec_domains_get(dev);
815 	if (ret)
816 		return ret;
817 
818 	return 0;
819 }
820 
821 static void core_put_v4(struct device *dev)
822 {
823 	if (legacy_binding)
824 		return;
825 
826 	vcodec_domains_put(dev);
827 }
828 
829 static int core_power_v4(struct device *dev, int on)
830 {
831 	struct venus_core *core = dev_get_drvdata(dev);
832 	int ret = 0;
833 
834 	if (on == POWER_ON)
835 		ret = core_clks_enable(core);
836 	else
837 		core_clks_disable(core);
838 
839 	return ret;
840 }
841 
842 static unsigned long calculate_inst_freq(struct venus_inst *inst,
843 					 unsigned long filled_len)
844 {
845 	unsigned long vpp_freq = 0, vsp_freq = 0;
846 	u32 fps = (u32)inst->fps;
847 	u32 mbs_per_sec;
848 
849 	mbs_per_sec = load_per_instance(inst) / fps;
850 
851 	vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
852 	/* 21 / 20 is overhead factor */
853 	vpp_freq += vpp_freq / 20;
854 	vsp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vsp_freq;
855 
856 	/* 10 / 7 is overhead factor */
857 	if (inst->session_type == VIDC_SESSION_TYPE_ENC)
858 		vsp_freq += (inst->controls.enc.bitrate * 10) / 7;
859 	else
860 		vsp_freq += ((fps * filled_len * 8) * 10) / 7;
861 
862 	return max(vpp_freq, vsp_freq);
863 }
864 
865 static int load_scale_v4(struct venus_inst *inst)
866 {
867 	struct venus_core *core = inst->core;
868 	const struct freq_tbl *table = core->res->freq_tbl;
869 	unsigned int num_rows = core->res->freq_tbl_size;
870 	struct device *dev = core->dev;
871 	unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
872 	unsigned long filled_len = 0;
873 	int i, ret;
874 
875 	for (i = 0; i < inst->num_input_bufs; i++)
876 		filled_len = max(filled_len, inst->payloads[i]);
877 
878 	if (inst->session_type == VIDC_SESSION_TYPE_DEC && !filled_len)
879 		return 0;
880 
881 	freq = calculate_inst_freq(inst, filled_len);
882 	inst->clk_data.freq = freq;
883 
884 	mutex_lock(&core->lock);
885 	list_for_each_entry(inst, &core->instances, list) {
886 		if (inst->clk_data.core_id == VIDC_CORE_ID_1) {
887 			freq_core1 += inst->clk_data.freq;
888 		} else if (inst->clk_data.core_id == VIDC_CORE_ID_2) {
889 			freq_core2 += inst->clk_data.freq;
890 		} else if (inst->clk_data.core_id == VIDC_CORE_ID_3) {
891 			freq_core1 += inst->clk_data.freq;
892 			freq_core2 += inst->clk_data.freq;
893 		}
894 	}
895 	mutex_unlock(&core->lock);
896 
897 	freq = max(freq_core1, freq_core2);
898 
899 	if (freq >= table[0].freq) {
900 		freq = table[0].freq;
901 		dev_warn(dev, "HW is overloaded, needed: %lu max: %lu\n",
902 			 freq, table[0].freq);
903 		goto set_freq;
904 	}
905 
906 	for (i = num_rows - 1 ; i >= 0; i--) {
907 		if (freq <= table[i].freq) {
908 			freq = table[i].freq;
909 			break;
910 		}
911 	}
912 
913 set_freq:
914 
915 	ret = core_clks_set_rate(core, freq);
916 	if (ret) {
917 		dev_err(dev, "failed to set clock rate %lu (%d)\n",
918 			freq, ret);
919 		return ret;
920 	}
921 
922 	ret = load_scale_bw(core);
923 	if (ret) {
924 		dev_err(dev, "failed to set bandwidth (%d)\n",
925 			ret);
926 		return ret;
927 	}
928 
929 	return 0;
930 }
931 
932 static const struct venus_pm_ops pm_ops_v4 = {
933 	.core_get = core_get_v4,
934 	.core_put = core_put_v4,
935 	.core_power = core_power_v4,
936 	.vdec_get = vdec_get_v4,
937 	.vdec_put = vdec_put_v4,
938 	.vdec_power = vdec_power_v4,
939 	.venc_get = venc_get_v4,
940 	.venc_put = venc_put_v4,
941 	.venc_power = venc_power_v4,
942 	.coreid_power = coreid_power_v4,
943 	.load_scale = load_scale_v4,
944 };
945 
946 const struct venus_pm_ops *venus_pm_get(enum hfi_version version)
947 {
948 	switch (version) {
949 	case HFI_VERSION_1XX:
950 	default:
951 		return &pm_ops_v1;
952 	case HFI_VERSION_3XX:
953 		return &pm_ops_v3;
954 	case HFI_VERSION_4XX:
955 		return &pm_ops_v4;
956 	}
957 
958 	return NULL;
959 }
960