File Index
Files and directories
Sign in
FILE

wave5-vpuapi.c

File preview with syntax highlighting.

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