1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2/*
3 * Wave5 series multi-standard codec IP - helper functions
4 *
5 * Copyright (C) 2021-2023 CHIPS&MEDIA INC
6 */
7
8#include <linux/bug.h>
9#include "wave5-vpuapi.h"
10#include "wave5-regdefine.h"
11#include "wave5.h"
12
13#define DECODE_ALL_TEMPORAL_LAYERS 0
14#define DECODE_ALL_SPATIAL_LAYERS 0
15
16static int wave5_initialize_vpu(struct device *dev, u8 *code, size_t size)
17{
18 int ret;
19 struct vpu_device *vpu_dev = dev_get_drvdata(dev);
20
21 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
22 if (ret)
23 return ret;
24
25 if (wave5_vpu_is_init(vpu_dev)) {
26 wave5_vpu_re_init(dev, fw: (void *)code, size);
27 ret = -EBUSY;
28 goto err_out;
29 }
30
31 ret = wave5_vpu_reset(dev, reset_mode: SW_RESET_ON_BOOT);
32 if (ret)
33 goto err_out;
34
35 ret = wave5_vpu_init(dev, fw: (void *)code, size);
36
37err_out:
38 mutex_unlock(lock: &vpu_dev->hw_lock);
39 return ret;
40}
41
42int wave5_vpu_init_with_bitcode(struct device *dev, u8 *bitcode, size_t size)
43{
44 if (!bitcode || size == 0)
45 return -EINVAL;
46
47 return wave5_initialize_vpu(dev, code: bitcode, size);
48}
49
50int wave5_vpu_flush_instance(struct vpu_instance *inst)
51{
52 int ret = 0;
53 int retry = 0;
54
55 ret = mutex_lock_interruptible(&inst->dev->hw_lock);
56 if (ret)
57 return ret;
58 do {
59 /*
60 * Repeat the FLUSH command until the firmware reports that the
61 * VPU isn't running anymore
62 */
63 ret = wave5_vpu_hw_flush_instance(inst);
64 if (ret < 0 && ret != -EBUSY) {
65 dev_warn(inst->dev->dev, "Flush of %s instance with id: %d fail: %d\n",
66 inst->type == VPU_INST_TYPE_DEC ? "DECODER" : "ENCODER", inst->id,
67 ret);
68 mutex_unlock(lock: &inst->dev->hw_lock);
69 return ret;
70 }
71 if (ret == -EBUSY && retry++ >= MAX_FIRMWARE_CALL_RETRY) {
72 dev_warn(inst->dev->dev, "Flush of %s instance with id: %d timed out!\n",
73 inst->type == VPU_INST_TYPE_DEC ? "DECODER" : "ENCODER", inst->id);
74 mutex_unlock(lock: &inst->dev->hw_lock);
75 return -ETIMEDOUT;
76 }
77 } while (ret != 0);
78 mutex_unlock(lock: &inst->dev->hw_lock);
79
80 return ret;
81}
82
83int wave5_vpu_get_version_info(struct device *dev, u32 *revision, unsigned int *product_id)
84{
85 int ret;
86 struct vpu_device *vpu_dev = dev_get_drvdata(dev);
87
88 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
89 if (ret)
90 return ret;
91
92 if (!wave5_vpu_is_init(vpu_dev)) {
93 ret = -EINVAL;
94 goto err_out;
95 }
96
97 if (product_id)
98 *product_id = vpu_dev->product;
99 ret = wave5_vpu_get_version(vpu_dev, revision);
100
101err_out:
102 mutex_unlock(lock: &vpu_dev->hw_lock);
103 return ret;
104}
105
106static int wave5_check_dec_open_param(struct vpu_instance *inst, struct dec_open_param *param)
107{
108 if (inst->id >= MAX_NUM_INSTANCE) {
109 dev_err(inst->dev->dev, "Too many simultaneous instances: %d (max: %u)\n",
110 inst->id, MAX_NUM_INSTANCE);
111 return -EOPNOTSUPP;
112 }
113
114 if (param->bitstream_buffer % 8) {
115 dev_err(inst->dev->dev,
116 "Bitstream buffer must be aligned to a multiple of 8\n");
117 return -EINVAL;
118 }
119
120 if (param->bitstream_buffer_size % 1024 ||
121 param->bitstream_buffer_size < MIN_BITSTREAM_BUFFER_SIZE) {
122 dev_err(inst->dev->dev,
123 "Bitstream buffer size must be aligned to a multiple of 1024 and have a minimum size of %d\n",
124 MIN_BITSTREAM_BUFFER_SIZE);
125 return -EINVAL;
126 }
127
128 return 0;
129}
130
131int wave5_vpu_dec_open(struct vpu_instance *inst, struct dec_open_param *open_param)
132{
133 struct dec_info *p_dec_info;
134 int ret;
135 struct vpu_device *vpu_dev = inst->dev;
136 dma_addr_t buffer_addr;
137 size_t buffer_size;
138
139 ret = wave5_check_dec_open_param(inst, param: open_param);
140 if (ret)
141 return ret;
142
143 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
144 if (ret)
145 return ret;
146
147 if (!wave5_vpu_is_init(vpu_dev)) {
148 mutex_unlock(lock: &vpu_dev->hw_lock);
149 return -ENODEV;
150 }
151
152 p_dec_info = &inst->codec_info->dec_info;
153 memcpy(&p_dec_info->open_param, open_param, sizeof(struct dec_open_param));
154
155 buffer_addr = open_param->bitstream_buffer;
156 buffer_size = open_param->bitstream_buffer_size;
157 p_dec_info->stream_wr_ptr = buffer_addr;
158 p_dec_info->stream_rd_ptr = buffer_addr;
159 p_dec_info->stream_buf_start_addr = buffer_addr;
160 p_dec_info->stream_buf_size = buffer_size;
161 p_dec_info->stream_buf_end_addr = buffer_addr + buffer_size;
162 p_dec_info->reorder_enable = TRUE;
163 p_dec_info->temp_id_select_mode = TEMPORAL_ID_MODE_ABSOLUTE;
164 p_dec_info->target_temp_id = DECODE_ALL_TEMPORAL_LAYERS;
165 p_dec_info->target_spatial_id = DECODE_ALL_SPATIAL_LAYERS;
166
167 ret = wave5_vpu_build_up_dec_param(inst, param: open_param);
168 mutex_unlock(lock: &vpu_dev->hw_lock);
169
170 return ret;
171}
172
173static int reset_auxiliary_buffers(struct vpu_instance *inst, unsigned int index)
174{
175 struct dec_info *p_dec_info = &inst->codec_info->dec_info;
176
177 if (index >= MAX_REG_FRAME)
178 return 1;
179
180 if (p_dec_info->vb_mv[index].size == 0 && p_dec_info->vb_fbc_y_tbl[index].size == 0 &&
181 p_dec_info->vb_fbc_c_tbl[index].size == 0)
182 return 1;
183
184 wave5_vdi_free_dma_memory(vpu_dev: inst->dev, vb: &p_dec_info->vb_mv[index]);
185 wave5_vdi_free_dma_memory(vpu_dev: inst->dev, vb: &p_dec_info->vb_fbc_y_tbl[index]);
186 wave5_vdi_free_dma_memory(vpu_dev: inst->dev, vb: &p_dec_info->vb_fbc_c_tbl[index]);
187
188 return 0;
189}
190
191int wave5_vpu_dec_close(struct vpu_instance *inst, u32 *fail_res)
192{
193 struct dec_info *p_dec_info = &inst->codec_info->dec_info;
194 int ret;
195 int retry = 0;
196 struct vpu_device *vpu_dev = inst->dev;
197 int i;
198
199 *fail_res = 0;
200 if (!inst->codec_info)
201 return -EINVAL;
202
203 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
204 if (ret)
205 return ret;
206
207 do {
208 ret = wave5_vpu_dec_finish_seq(inst, fail_res);
209 if (ret < 0 && *fail_res != WAVE5_SYSERR_VPU_STILL_RUNNING) {
210 dev_warn(inst->dev->dev, "dec_finish_seq timed out\n");
211 goto unlock_and_return;
212 }
213
214 if (*fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING &&
215 retry++ >= MAX_FIRMWARE_CALL_RETRY) {
216 ret = -ETIMEDOUT;
217 goto unlock_and_return;
218 }
219 } while (ret != 0);
220
221 dev_dbg(inst->dev->dev, "%s: dec_finish_seq complete\n", __func__);
222
223 wave5_vdi_free_dma_memory(vpu_dev, vb: &p_dec_info->vb_work);
224
225 for (i = 0 ; i < MAX_REG_FRAME; i++) {
226 ret = reset_auxiliary_buffers(inst, index: i);
227 if (ret) {
228 ret = 0;
229 break;
230 }
231 }
232
233 wave5_vdi_free_dma_memory(vpu_dev, vb: &p_dec_info->vb_task);
234
235unlock_and_return:
236 mutex_unlock(lock: &vpu_dev->hw_lock);
237
238 return ret;
239}
240
241int wave5_vpu_dec_issue_seq_init(struct vpu_instance *inst)
242{
243 int ret;
244 struct vpu_device *vpu_dev = inst->dev;
245
246 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
247 if (ret)
248 return ret;
249
250 ret = wave5_vpu_dec_init_seq(inst);
251
252 mutex_unlock(lock: &vpu_dev->hw_lock);
253
254 return ret;
255}
256
257int wave5_vpu_dec_complete_seq_init(struct vpu_instance *inst, struct dec_initial_info *info)
258{
259 struct dec_info *p_dec_info = &inst->codec_info->dec_info;
260 int ret;
261 struct vpu_device *vpu_dev = inst->dev;
262
263 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
264 if (ret)
265 return ret;
266
267 ret = wave5_vpu_dec_get_seq_info(inst, info);
268 if (!ret)
269 p_dec_info->initial_info_obtained = true;
270
271 info->rd_ptr = wave5_dec_get_rd_ptr(inst);
272 info->wr_ptr = p_dec_info->stream_wr_ptr;
273
274 p_dec_info->initial_info = *info;
275
276 mutex_unlock(lock: &vpu_dev->hw_lock);
277
278 return ret;
279}
280
281int wave5_vpu_dec_register_frame_buffer_ex(struct vpu_instance *inst, int num_of_decoding_fbs,
282 int num_of_display_fbs, int stride, int height)
283{
284 struct dec_info *p_dec_info;
285 int ret;
286 struct vpu_device *vpu_dev = inst->dev;
287 struct frame_buffer *fb;
288
289 if (num_of_decoding_fbs >= WAVE5_MAX_FBS || num_of_display_fbs >= WAVE5_MAX_FBS)
290 return -EINVAL;
291
292 p_dec_info = &inst->codec_info->dec_info;
293 p_dec_info->num_of_decoding_fbs = num_of_decoding_fbs;
294 p_dec_info->num_of_display_fbs = num_of_display_fbs;
295 p_dec_info->stride = stride;
296
297 if (!p_dec_info->initial_info_obtained)
298 return -EINVAL;
299
300 if (stride < p_dec_info->initial_info.pic_width || (stride % 8 != 0) ||
301 height < p_dec_info->initial_info.pic_height)
302 return -EINVAL;
303
304 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
305 if (ret)
306 return ret;
307
308 fb = inst->frame_buf;
309 ret = wave5_vpu_dec_register_framebuffer(inst, fb_arr: &fb[p_dec_info->num_of_decoding_fbs],
310 map_type: LINEAR_FRAME_MAP, count: p_dec_info->num_of_display_fbs);
311 if (ret)
312 goto err_out;
313
314 ret = wave5_vpu_dec_register_framebuffer(inst, fb_arr: &fb[0], map_type: COMPRESSED_FRAME_MAP,
315 count: p_dec_info->num_of_decoding_fbs);
316
317err_out:
318 mutex_unlock(lock: &vpu_dev->hw_lock);
319
320 return ret;
321}
322
323int wave5_vpu_dec_get_bitstream_buffer(struct vpu_instance *inst, dma_addr_t *prd_ptr,
324 dma_addr_t *pwr_ptr, size_t *size)
325{
326 struct dec_info *p_dec_info;
327 dma_addr_t rd_ptr;
328 dma_addr_t wr_ptr;
329 int room;
330 struct vpu_device *vpu_dev = inst->dev;
331 int ret;
332
333 p_dec_info = &inst->codec_info->dec_info;
334
335 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
336 if (ret)
337 return ret;
338 rd_ptr = wave5_dec_get_rd_ptr(inst);
339 mutex_unlock(lock: &vpu_dev->hw_lock);
340
341 wr_ptr = p_dec_info->stream_wr_ptr;
342
343 if (wr_ptr < rd_ptr)
344 room = rd_ptr - wr_ptr;
345 else
346 room = (p_dec_info->stream_buf_end_addr - wr_ptr) +
347 (rd_ptr - p_dec_info->stream_buf_start_addr);
348 room--;
349
350 if (prd_ptr)
351 *prd_ptr = rd_ptr;
352 if (pwr_ptr)
353 *pwr_ptr = wr_ptr;
354 if (size)
355 *size = room;
356
357 return 0;
358}
359
360int wave5_vpu_dec_update_bitstream_buffer(struct vpu_instance *inst, size_t size)
361{
362 struct dec_info *p_dec_info;
363 dma_addr_t wr_ptr;
364 dma_addr_t rd_ptr;
365 int ret;
366 struct vpu_device *vpu_dev = inst->dev;
367
368 if (!inst->codec_info)
369 return -EINVAL;
370
371 p_dec_info = &inst->codec_info->dec_info;
372 wr_ptr = p_dec_info->stream_wr_ptr;
373 rd_ptr = p_dec_info->stream_rd_ptr;
374
375 if (size > 0) {
376 if (wr_ptr < rd_ptr && rd_ptr <= wr_ptr + size)
377 return -EINVAL;
378
379 wr_ptr += size;
380
381 if (wr_ptr > p_dec_info->stream_buf_end_addr) {
382 u32 room = wr_ptr - p_dec_info->stream_buf_end_addr;
383
384 wr_ptr = p_dec_info->stream_buf_start_addr;
385 wr_ptr += room;
386 } else if (wr_ptr == p_dec_info->stream_buf_end_addr) {
387 wr_ptr = p_dec_info->stream_buf_start_addr;
388 }
389
390 p_dec_info->stream_wr_ptr = wr_ptr;
391 p_dec_info->stream_rd_ptr = rd_ptr;
392 }
393
394 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
395 if (ret)
396 return ret;
397 ret = wave5_vpu_dec_set_bitstream_flag(inst, eos: (size == 0));
398 mutex_unlock(lock: &vpu_dev->hw_lock);
399
400 return ret;
401}
402
403int wave5_vpu_dec_start_one_frame(struct vpu_instance *inst, u32 *res_fail)
404{
405 struct dec_info *p_dec_info = &inst->codec_info->dec_info;
406 int ret;
407 struct vpu_device *vpu_dev = inst->dev;
408
409 if (p_dec_info->stride == 0) /* this means frame buffers have not been registered. */
410 return -EINVAL;
411
412 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
413 if (ret)
414 return ret;
415
416 ret = wave5_vpu_decode(inst, fail_res: res_fail);
417
418 mutex_unlock(lock: &vpu_dev->hw_lock);
419
420 return ret;
421}
422
423int wave5_vpu_dec_set_rd_ptr(struct vpu_instance *inst, dma_addr_t addr, int update_wr_ptr)
424{
425 struct dec_info *p_dec_info = &inst->codec_info->dec_info;
426 int ret;
427 struct vpu_device *vpu_dev = inst->dev;
428
429 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
430 if (ret)
431 return ret;
432
433 ret = wave5_dec_set_rd_ptr(inst, addr);
434
435 p_dec_info->stream_rd_ptr = addr;
436 if (update_wr_ptr)
437 p_dec_info->stream_wr_ptr = addr;
438
439 mutex_unlock(lock: &vpu_dev->hw_lock);
440
441 return ret;
442}
443
444dma_addr_t wave5_vpu_dec_get_rd_ptr(struct vpu_instance *inst)
445{
446 int ret;
447 dma_addr_t rd_ptr;
448
449 ret = mutex_lock_interruptible(&inst->dev->hw_lock);
450 if (ret)
451 return ret;
452
453 rd_ptr = wave5_dec_get_rd_ptr(inst);
454
455 mutex_unlock(lock: &inst->dev->hw_lock);
456
457 return rd_ptr;
458}
459
460int wave5_vpu_dec_get_output_info(struct vpu_instance *inst, struct dec_output_info *info)
461{
462 struct dec_info *p_dec_info;
463 int ret;
464 struct vpu_rect rect_info;
465 u32 val;
466 u32 decoded_index;
467 u32 disp_idx;
468 u32 max_dec_index;
469 struct vpu_device *vpu_dev = inst->dev;
470 struct dec_output_info *disp_info;
471
472 if (!info)
473 return -EINVAL;
474
475 p_dec_info = &inst->codec_info->dec_info;
476
477 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
478 if (ret)
479 return ret;
480
481 memset(info, 0, sizeof(*info));
482
483 ret = wave5_vpu_dec_get_result(inst, result: info);
484 if (ret) {
485 info->rd_ptr = p_dec_info->stream_rd_ptr;
486 info->wr_ptr = p_dec_info->stream_wr_ptr;
487 goto err_out;
488 }
489
490 decoded_index = info->index_frame_decoded;
491
492 /* calculate display frame region */
493 val = 0;
494 rect_info.left = 0;
495 rect_info.right = 0;
496 rect_info.top = 0;
497 rect_info.bottom = 0;
498
499 if (decoded_index < WAVE5_MAX_FBS) {
500 if (inst->std == W_HEVC_DEC || inst->std == W_AVC_DEC)
501 rect_info = p_dec_info->initial_info.pic_crop_rect;
502
503 if (inst->std == W_HEVC_DEC)
504 p_dec_info->dec_out_info[decoded_index].decoded_poc = info->decoded_poc;
505
506 p_dec_info->dec_out_info[decoded_index].rc_decoded = rect_info;
507 }
508 info->rc_decoded = rect_info;
509
510 disp_idx = info->index_frame_display;
511 if (info->index_frame_display >= 0 && info->index_frame_display < WAVE5_MAX_FBS) {
512 disp_info = &p_dec_info->dec_out_info[disp_idx];
513 if (info->index_frame_display != info->index_frame_decoded) {
514 /*
515 * when index_frame_decoded < 0, and index_frame_display >= 0
516 * info->dec_pic_width and info->dec_pic_height are still valid
517 * but those of p_dec_info->dec_out_info[disp_idx] are invalid in VP9
518 */
519 info->disp_pic_width = disp_info->dec_pic_width;
520 info->disp_pic_height = disp_info->dec_pic_height;
521 } else {
522 info->disp_pic_width = info->dec_pic_width;
523 info->disp_pic_height = info->dec_pic_height;
524 }
525
526 info->rc_display = disp_info->rc_decoded;
527
528 } else {
529 info->rc_display.left = 0;
530 info->rc_display.right = 0;
531 info->rc_display.top = 0;
532 info->rc_display.bottom = 0;
533 info->disp_pic_width = 0;
534 info->disp_pic_height = 0;
535 }
536
537 p_dec_info->stream_rd_ptr = wave5_dec_get_rd_ptr(inst);
538 p_dec_info->frame_display_flag = vpu_read_reg(vpu_dev, W5_RET_DEC_DISP_IDC);
539
540 val = p_dec_info->num_of_decoding_fbs; //fb_offset
541
542 max_dec_index = (p_dec_info->num_of_decoding_fbs > p_dec_info->num_of_display_fbs) ?
543 p_dec_info->num_of_decoding_fbs : p_dec_info->num_of_display_fbs;
544
545 if (info->index_frame_display >= 0 &&
546 info->index_frame_display < (int)max_dec_index)
547 info->disp_frame = inst->frame_buf[val + info->index_frame_display];
548
549 info->rd_ptr = p_dec_info->stream_rd_ptr;
550 info->wr_ptr = p_dec_info->stream_wr_ptr;
551 info->frame_display_flag = p_dec_info->frame_display_flag;
552
553 info->sequence_no = p_dec_info->initial_info.sequence_no;
554 if (decoded_index < WAVE5_MAX_FBS)
555 p_dec_info->dec_out_info[decoded_index] = *info;
556
557 if (disp_idx < WAVE5_MAX_FBS)
558 info->disp_frame.sequence_no = info->sequence_no;
559
560 if (info->sequence_changed) {
561 memcpy((void *)&p_dec_info->initial_info, (void *)&p_dec_info->new_seq_info,
562 sizeof(struct dec_initial_info));
563 p_dec_info->initial_info.sequence_no++;
564 }
565
566err_out:
567 mutex_unlock(lock: &vpu_dev->hw_lock);
568
569 return ret;
570}
571
572int wave5_vpu_dec_clr_disp_flag(struct vpu_instance *inst, int index)
573{
574 struct dec_info *p_dec_info = &inst->codec_info->dec_info;
575 int ret;
576 struct vpu_device *vpu_dev = inst->dev;
577
578 if (index >= p_dec_info->num_of_display_fbs)
579 return -EINVAL;
580
581 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
582 if (ret)
583 return ret;
584 ret = wave5_dec_clr_disp_flag(inst, index);
585 mutex_unlock(lock: &vpu_dev->hw_lock);
586
587 return ret;
588}
589
590int wave5_vpu_dec_set_disp_flag(struct vpu_instance *inst, int index)
591{
592 struct dec_info *p_dec_info = &inst->codec_info->dec_info;
593 int ret = 0;
594 struct vpu_device *vpu_dev = inst->dev;
595
596 if (index >= p_dec_info->num_of_display_fbs)
597 return -EINVAL;
598
599 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
600 if (ret)
601 return ret;
602 ret = wave5_dec_set_disp_flag(inst, index);
603 mutex_unlock(lock: &vpu_dev->hw_lock);
604
605 return ret;
606}
607
608int wave5_vpu_dec_reset_framebuffer(struct vpu_instance *inst, unsigned int index)
609{
610 if (index >= MAX_REG_FRAME)
611 return -EINVAL;
612
613 if (inst->frame_vbuf[index].size == 0)
614 return -EINVAL;
615
616 wave5_vdi_free_dma_memory(vpu_dev: inst->dev, vb: &inst->frame_vbuf[index]);
617
618 return 0;
619}
620
621int wave5_vpu_dec_give_command(struct vpu_instance *inst, enum codec_command cmd, void *parameter)
622{
623 struct dec_info *p_dec_info = &inst->codec_info->dec_info;
624 int ret = 0;
625
626 switch (cmd) {
627 case DEC_GET_QUEUE_STATUS: {
628 struct queue_status_info *queue_info = parameter;
629
630 queue_info->instance_queue_count = p_dec_info->instance_queue_count;
631 queue_info->report_queue_count = p_dec_info->report_queue_count;
632 break;
633 }
634 case DEC_RESET_FRAMEBUF_INFO: {
635 int i;
636
637 for (i = 0; i < MAX_REG_FRAME; i++) {
638 ret = wave5_vpu_dec_reset_framebuffer(inst, index: i);
639 if (ret)
640 break;
641 }
642
643 for (i = 0; i < MAX_REG_FRAME; i++) {
644 ret = reset_auxiliary_buffers(inst, index: i);
645 if (ret)
646 break;
647 }
648
649 wave5_vdi_free_dma_memory(vpu_dev: inst->dev, vb: &p_dec_info->vb_task);
650 break;
651 }
652 case DEC_GET_SEQ_INFO: {
653 struct dec_initial_info *seq_info = parameter;
654
655 *seq_info = p_dec_info->initial_info;
656 break;
657 }
658
659 default:
660 return -EINVAL;
661 }
662
663 return ret;
664}
665
666int wave5_vpu_enc_open(struct vpu_instance *inst, struct enc_open_param *open_param)
667{
668 struct enc_info *p_enc_info;
669 int ret;
670 struct vpu_device *vpu_dev = inst->dev;
671
672 ret = wave5_vpu_enc_check_open_param(inst, open_param);
673 if (ret)
674 return ret;
675
676 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
677 if (ret)
678 return ret;
679
680 if (!wave5_vpu_is_init(vpu_dev)) {
681 mutex_unlock(lock: &vpu_dev->hw_lock);
682 return -ENODEV;
683 }
684
685 p_enc_info = &inst->codec_info->enc_info;
686 p_enc_info->open_param = *open_param;
687
688 ret = wave5_vpu_build_up_enc_param(dev: vpu_dev->dev, inst, open_param);
689 mutex_unlock(lock: &vpu_dev->hw_lock);
690
691 return ret;
692}
693
694int wave5_vpu_enc_close(struct vpu_instance *inst, u32 *fail_res)
695{
696 struct enc_info *p_enc_info = &inst->codec_info->enc_info;
697 int ret;
698 int retry = 0;
699 struct vpu_device *vpu_dev = inst->dev;
700
701 *fail_res = 0;
702 if (!inst->codec_info)
703 return -EINVAL;
704
705 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
706 if (ret)
707 return ret;
708
709 do {
710 ret = wave5_vpu_enc_finish_seq(inst, fail_res);
711 if (ret < 0 && *fail_res != WAVE5_SYSERR_VPU_STILL_RUNNING) {
712 dev_warn(inst->dev->dev, "enc_finish_seq timed out\n");
713 mutex_unlock(lock: &vpu_dev->hw_lock);
714 return ret;
715 }
716
717 if (*fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING &&
718 retry++ >= MAX_FIRMWARE_CALL_RETRY) {
719 mutex_unlock(lock: &vpu_dev->hw_lock);
720 return -ETIMEDOUT;
721 }
722 } while (ret != 0);
723
724 dev_dbg(inst->dev->dev, "%s: enc_finish_seq complete\n", __func__);
725
726 wave5_vdi_free_dma_memory(vpu_dev, vb: &p_enc_info->vb_work);
727
728 if (inst->std == W_HEVC_ENC || inst->std == W_AVC_ENC) {
729 wave5_vdi_free_dma_memory(vpu_dev, vb: &p_enc_info->vb_sub_sam_buf);
730 wave5_vdi_free_dma_memory(vpu_dev, vb: &p_enc_info->vb_mv);
731 wave5_vdi_free_dma_memory(vpu_dev, vb: &p_enc_info->vb_fbc_y_tbl);
732 wave5_vdi_free_dma_memory(vpu_dev, vb: &p_enc_info->vb_fbc_c_tbl);
733 }
734
735 wave5_vdi_free_dma_memory(vpu_dev, vb: &p_enc_info->vb_task);
736
737 mutex_unlock(lock: &vpu_dev->hw_lock);
738
739 return 0;
740}
741
742int wave5_vpu_enc_register_frame_buffer(struct vpu_instance *inst, unsigned int num,
743 unsigned int stride, int height,
744 enum tiled_map_type map_type)
745{
746 struct enc_info *p_enc_info = &inst->codec_info->enc_info;
747 int ret;
748 struct vpu_device *vpu_dev = inst->dev;
749 unsigned int size_luma, size_chroma;
750 int i;
751
752 if (p_enc_info->stride)
753 return -EINVAL;
754
755 if (!p_enc_info->initial_info_obtained)
756 return -EINVAL;
757
758 if (num < p_enc_info->initial_info.min_frame_buffer_count)
759 return -EINVAL;
760
761 if (stride == 0 || stride % 8 != 0)
762 return -EINVAL;
763
764 if (height <= 0)
765 return -EINVAL;
766
767 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
768 if (ret)
769 return ret;
770
771 p_enc_info->num_frame_buffers = num;
772 p_enc_info->stride = stride;
773
774 size_luma = stride * height;
775 size_chroma = ALIGN(stride / 2, 16) * height;
776
777 for (i = 0; i < num; i++) {
778 if (!inst->frame_buf[i].update_fb_info)
779 continue;
780
781 inst->frame_buf[i].update_fb_info = false;
782 inst->frame_buf[i].stride = stride;
783 inst->frame_buf[i].height = height;
784 inst->frame_buf[i].map_type = COMPRESSED_FRAME_MAP;
785 inst->frame_buf[i].buf_y_size = size_luma;
786 inst->frame_buf[i].buf_cb = inst->frame_buf[i].buf_y + size_luma;
787 inst->frame_buf[i].buf_cb_size = size_chroma;
788 inst->frame_buf[i].buf_cr_size = 0;
789 }
790
791 ret = wave5_vpu_enc_register_framebuffer(dev: inst->dev->dev, inst, fb_arr: &inst->frame_buf[0],
792 map_type: COMPRESSED_FRAME_MAP,
793 count: p_enc_info->num_frame_buffers);
794
795 mutex_unlock(lock: &vpu_dev->hw_lock);
796
797 return ret;
798}
799
800static int wave5_check_enc_param(struct vpu_instance *inst, struct enc_param *param)
801{
802 struct enc_info *p_enc_info = &inst->codec_info->enc_info;
803
804 if (!param)
805 return -EINVAL;
806
807 if (!param->source_frame)
808 return -EINVAL;
809
810 if (p_enc_info->open_param.bit_rate == 0 && inst->std == W_HEVC_ENC) {
811 if (param->pic_stream_buffer_addr % 16 || param->pic_stream_buffer_size == 0)
812 return -EINVAL;
813 }
814 if (param->pic_stream_buffer_addr % 8 || param->pic_stream_buffer_size == 0)
815 return -EINVAL;
816
817 return 0;
818}
819
820int wave5_vpu_enc_start_one_frame(struct vpu_instance *inst, struct enc_param *param, u32 *fail_res)
821{
822 struct enc_info *p_enc_info = &inst->codec_info->enc_info;
823 int ret;
824 struct vpu_device *vpu_dev = inst->dev;
825
826 *fail_res = 0;
827
828 if (p_enc_info->stride == 0) /* this means frame buffers have not been registered. */
829 return -EINVAL;
830
831 ret = wave5_check_enc_param(inst, param);
832 if (ret)
833 return ret;
834
835 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
836 if (ret)
837 return ret;
838
839 p_enc_info->pts_map[param->src_idx] = param->pts;
840
841 ret = wave5_vpu_encode(inst, option: param, fail_res);
842
843 mutex_unlock(lock: &vpu_dev->hw_lock);
844
845 return ret;
846}
847
848int wave5_vpu_enc_get_output_info(struct vpu_instance *inst, struct enc_output_info *info)
849{
850 struct enc_info *p_enc_info = &inst->codec_info->enc_info;
851 int ret;
852 struct vpu_device *vpu_dev = inst->dev;
853
854 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
855 if (ret)
856 return ret;
857
858 ret = wave5_vpu_enc_get_result(inst, result: info);
859 if (ret) {
860 info->pts = 0;
861 goto unlock;
862 }
863
864 if (info->recon_frame_index >= 0)
865 info->pts = p_enc_info->pts_map[info->enc_src_idx];
866
867unlock:
868 mutex_unlock(lock: &vpu_dev->hw_lock);
869
870 return ret;
871}
872
873int wave5_vpu_enc_give_command(struct vpu_instance *inst, enum codec_command cmd, void *parameter)
874{
875 struct enc_info *p_enc_info = &inst->codec_info->enc_info;
876
877 switch (cmd) {
878 case ENABLE_ROTATION:
879 p_enc_info->rotation_enable = true;
880 break;
881 case ENABLE_MIRRORING:
882 p_enc_info->mirror_enable = true;
883 break;
884 case SET_MIRROR_DIRECTION: {
885 enum mirror_direction mir_dir;
886
887 mir_dir = *(enum mirror_direction *)parameter;
888 if (mir_dir != MIRDIR_NONE && mir_dir != MIRDIR_HOR &&
889 mir_dir != MIRDIR_VER && mir_dir != MIRDIR_HOR_VER)
890 return -EINVAL;
891 p_enc_info->mirror_direction = mir_dir;
892 break;
893 }
894 case SET_ROTATION_ANGLE: {
895 int angle;
896
897 angle = *(int *)parameter;
898 if (angle && angle != 90 && angle != 180 && angle != 270)
899 return -EINVAL;
900 if (p_enc_info->initial_info_obtained && (angle == 90 || angle == 270))
901 return -EINVAL;
902 p_enc_info->rotation_angle = angle;
903 break;
904 }
905 case ENC_GET_QUEUE_STATUS: {
906 struct queue_status_info *queue_info = parameter;
907
908 queue_info->instance_queue_count = p_enc_info->instance_queue_count;
909 queue_info->report_queue_count = p_enc_info->report_queue_count;
910 break;
911 }
912 default:
913 return -EINVAL;
914 }
915 return 0;
916}
917
918int wave5_vpu_enc_issue_seq_init(struct vpu_instance *inst)
919{
920 int ret;
921 struct vpu_device *vpu_dev = inst->dev;
922
923 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
924 if (ret)
925 return ret;
926
927 ret = wave5_vpu_enc_init_seq(inst);
928
929 mutex_unlock(lock: &vpu_dev->hw_lock);
930
931 return ret;
932}
933
934int wave5_vpu_enc_complete_seq_init(struct vpu_instance *inst, struct enc_initial_info *info)
935{
936 struct enc_info *p_enc_info = &inst->codec_info->enc_info;
937 int ret;
938 struct vpu_device *vpu_dev = inst->dev;
939
940 if (!info)
941 return -EINVAL;
942
943 ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
944 if (ret)
945 return ret;
946
947 ret = wave5_vpu_enc_get_seq_info(inst, info);
948 if (ret) {
949 p_enc_info->initial_info_obtained = false;
950 mutex_unlock(lock: &vpu_dev->hw_lock);
951 return ret;
952 }
953
954 p_enc_info->initial_info_obtained = true;
955 p_enc_info->initial_info = *info;
956
957 mutex_unlock(lock: &vpu_dev->hw_lock);
958
959 return 0;
960}
961

source code of linux/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c