1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright 2020-2021 NXP |
4 | */ |
5 | |
6 | #include <linux/init.h> |
7 | #include <linux/interconnect.h> |
8 | #include <linux/ioctl.h> |
9 | #include <linux/list.h> |
10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> |
12 | #include <linux/platform_device.h> |
13 | #include <linux/time64.h> |
14 | #include <media/videobuf2-v4l2.h> |
15 | #include <media/videobuf2-dma-contig.h> |
16 | #include "vpu.h" |
17 | #include "vpu_rpc.h" |
18 | #include "vpu_defs.h" |
19 | #include "vpu_helpers.h" |
20 | #include "vpu_cmds.h" |
21 | #include "vpu_v4l2.h" |
22 | #include "vpu_imx8q.h" |
23 | #include "vpu_windsor.h" |
24 | |
25 | #define CMD_SIZE 2560 |
26 | #define MSG_SIZE 25600 |
27 | #define WINDSOR_USER_DATA_WORDS 16 |
28 | #define WINDSOR_MAX_SRC_FRAMES 0x6 |
29 | #define WINDSOR_MAX_REF_FRAMES 0x3 |
30 | #define WINDSOR_BITRATE_UNIT 1024 |
31 | #define WINDSOR_H264_EXTENDED_SAR 255 |
32 | |
33 | enum { |
34 | GTB_ENC_CMD_NOOP = 0x0, |
35 | GTB_ENC_CMD_STREAM_START, |
36 | GTB_ENC_CMD_FRAME_ENCODE, |
37 | GTB_ENC_CMD_FRAME_SKIP, |
38 | GTB_ENC_CMD_STREAM_STOP, |
39 | GTB_ENC_CMD_PARAMETER_UPD, |
40 | GTB_ENC_CMD_TERMINATE, |
41 | GTB_ENC_CMD_SNAPSHOT, |
42 | GTB_ENC_CMD_ROLL_SNAPSHOT, |
43 | GTB_ENC_CMD_LOCK_SCHEDULER, |
44 | GTB_ENC_CMD_UNLOCK_SCHEDULER, |
45 | GTB_ENC_CMD_CONFIGURE_CODEC, |
46 | GTB_ENC_CMD_DEAD_MARK, |
47 | GTB_ENC_CMD_FIRM_RESET, |
48 | GTB_ENC_CMD_FW_STATUS, |
49 | GTB_ENC_CMD_RESERVED |
50 | }; |
51 | |
52 | enum { |
53 | VID_API_EVENT_UNDEFINED = 0x0, |
54 | VID_API_ENC_EVENT_RESET_DONE = 0x1, |
55 | VID_API_ENC_EVENT_START_DONE, |
56 | VID_API_ENC_EVENT_STOP_DONE, |
57 | VID_API_ENC_EVENT_TERMINATE_DONE, |
58 | VID_API_ENC_EVENT_FRAME_INPUT_DONE, |
59 | VID_API_ENC_EVENT_FRAME_DONE, |
60 | VID_API_ENC_EVENT_FRAME_RELEASE, |
61 | VID_API_ENC_EVENT_PARA_UPD_DONE, |
62 | VID_API_ENC_EVENT_MEM_REQUEST, |
63 | VID_API_ENC_EVENT_FIRMWARE_XCPT, |
64 | VID_API_ENC_EVENT_RESERVED |
65 | }; |
66 | |
67 | enum { |
68 | MEDIAIP_ENC_PIC_TYPE_B_FRAME = 0, |
69 | MEDIAIP_ENC_PIC_TYPE_P_FRAME, |
70 | MEDIAIP_ENC_PIC_TYPE_I_FRAME, |
71 | MEDIAIP_ENC_PIC_TYPE_IDR_FRAME, |
72 | MEDIAIP_ENC_PIC_TYPE_BI_FRAME |
73 | }; |
74 | |
75 | struct windsor_iface { |
76 | u32 exec_base_addr; |
77 | u32 exec_area_size; |
78 | struct vpu_rpc_buffer_desc cmd_buffer_desc; |
79 | struct vpu_rpc_buffer_desc msg_buffer_desc; |
80 | u32 cmd_int_enable[VID_API_NUM_STREAMS]; |
81 | u32 fw_version; |
82 | u32 mvd_fw_offset; |
83 | u32 max_streams; |
84 | u32 ctrl_iface[VID_API_NUM_STREAMS]; |
85 | struct vpu_rpc_system_config system_config; |
86 | u32 api_version; |
87 | struct vpu_rpc_buffer_desc log_buffer_desc; |
88 | }; |
89 | |
90 | struct windsor_ctrl_iface { |
91 | u32 enc_yuv_buffer_desc; |
92 | u32 enc_stream_buffer_desc; |
93 | u32 enc_expert_mode_param; |
94 | u32 enc_param; |
95 | u32 enc_mem_pool; |
96 | u32 enc_encoding_status; |
97 | u32 enc_dsa_status; |
98 | }; |
99 | |
100 | struct vpu_enc_yuv_desc { |
101 | u32 frame_id; |
102 | u32 luma_base; |
103 | u32 chroma_base; |
104 | u32 param_idx; |
105 | u32 key_frame; |
106 | }; |
107 | |
108 | struct vpu_enc_calib_params { |
109 | u32 use_ame; |
110 | |
111 | u32 cme_mvx_max; |
112 | u32 cme_mvy_max; |
113 | u32 ame_prefresh_y0; |
114 | u32 ame_prefresh_y1; |
115 | u32 fme_min_sad; |
116 | u32 cme_min_sad; |
117 | |
118 | u32 fme_pred_int_weight; |
119 | u32 fme_pred_hp_weight; |
120 | u32 fme_pred_qp_weight; |
121 | u32 fme_cost_weight; |
122 | u32 fme_act_thold; |
123 | u32 fme_sad_thold; |
124 | u32 fme_zero_sad_thold; |
125 | |
126 | u32 fme_lrg_mvx_lmt; |
127 | u32 fme_lrg_mvy_lmt; |
128 | u32 fme_force_mode; |
129 | u32 fme_force4mvcost; |
130 | u32 fme_force2mvcost; |
131 | |
132 | u32 h264_inter_thrd; |
133 | |
134 | u32 i16x16_mode_cost; |
135 | u32 i4x4_mode_lambda; |
136 | u32 i8x8_mode_lambda; |
137 | |
138 | u32 inter_mod_mult; |
139 | u32 inter_sel_mult; |
140 | u32 inter_bid_cost; |
141 | u32 inter_bwd_cost; |
142 | u32 inter_4mv_cost; |
143 | s32 one_mv_i16_cost; |
144 | s32 one_mv_i4x4_cost; |
145 | s32 one_mv_i8x8_cost; |
146 | s32 two_mv_i16_cost; |
147 | s32 two_mv_i4x4_cost; |
148 | s32 two_mv_i8x8_cost; |
149 | s32 four_mv_i16_cost; |
150 | s32 four_mv_i4x4_cost; |
151 | s32 four_mv_i8x8_cost; |
152 | |
153 | u32 intra_pred_enab; |
154 | u32 intra_chr_pred; |
155 | u32 intra16_pred; |
156 | u32 intra4x4_pred; |
157 | u32 intra8x8_pred; |
158 | |
159 | u32 cb_base; |
160 | u32 cb_size; |
161 | u32 cb_head_room; |
162 | |
163 | u32 mem_page_width; |
164 | u32 mem_page_height; |
165 | u32 mem_total_size; |
166 | u32 mem_chunk_phys_addr; |
167 | u32 mem_chunk_virt_addr; |
168 | u32 mem_chunk_size; |
169 | u32 mem_y_stride; |
170 | u32 mem_uv_stride; |
171 | |
172 | u32 split_wr_enab; |
173 | u32 split_wr_req_size; |
174 | u32 split_rd_enab; |
175 | u32 split_rd_req_size; |
176 | }; |
177 | |
178 | struct vpu_enc_config_params { |
179 | u32 param_change; |
180 | u32 start_frame; |
181 | u32 end_frame; |
182 | u32 userdata_enable; |
183 | u32 userdata_id[4]; |
184 | u32 userdata_message[WINDSOR_USER_DATA_WORDS]; |
185 | u32 userdata_length; |
186 | u32 h264_profile_idc; |
187 | u32 h264_level_idc; |
188 | u32 h264_au_delimiter; |
189 | u32 h264_seq_end_code; |
190 | u32 h264_recovery_points; |
191 | u32 h264_vui_parameters; |
192 | u32 h264_aspect_ratio_present; |
193 | u32 h264_aspect_ratio_sar_width; |
194 | u32 h264_aspect_ratio_sar_height; |
195 | u32 h264_overscan_present; |
196 | u32 h264_video_type_present; |
197 | u32 h264_video_format; |
198 | u32 h264_video_full_range; |
199 | u32 h264_video_colour_descriptor; |
200 | u32 h264_video_colour_primaries; |
201 | u32 h264_video_transfer_char; |
202 | u32 h264_video_matrix_coeff; |
203 | u32 h264_chroma_loc_info_present; |
204 | u32 h264_chroma_loc_type_top; |
205 | u32 h264_chroma_loc_type_bot; |
206 | u32 h264_timing_info_present; |
207 | u32 h264_buffering_period_present; |
208 | u32 h264_low_delay_hrd_flag; |
209 | u32 aspect_ratio; |
210 | u32 test_mode; // Automated firmware test mode |
211 | u32 dsa_test_mode; // Automated test mode for the DSA. |
212 | u32 fme_test_mode; // Automated test mode for the fme |
213 | u32 cbr_row_mode; //0: FW mode; 1: HW mode |
214 | u32 windsor_mode; //0: normal mode; 1: intra only mode; 2: intra+0MV mode |
215 | u32 encode_mode; // H264, VC1, MPEG2, DIVX |
216 | u32 frame_width; // display width |
217 | u32 frame_height; // display height |
218 | u32 enc_frame_width; // encoding width, should be 16-pix align |
219 | u32 enc_frame_height; // encoding height, should be 16-pix aligned |
220 | u32 frame_rate_num; |
221 | u32 frame_rate_den; |
222 | u32 vi_field_source; |
223 | u32 vi_frame_width; |
224 | u32 vi_frame_height; |
225 | u32 crop_frame_width; |
226 | u32 crop_frame_height; |
227 | u32 crop_x_start_posn; |
228 | u32 crop_y_start_posn; |
229 | u32 mode422; |
230 | u32 mode_yuy2; |
231 | u32 dsa_luma_en; |
232 | u32 dsa_chroma_en; |
233 | u32 dsa_ext_hfilt_en; |
234 | u32 dsa_di_en; |
235 | u32 dsa_di_top_ref; |
236 | u32 dsa_vertf_disable; |
237 | u32 dsa_disable_pwb; |
238 | u32 dsa_hor_phase; |
239 | u32 dsa_ver_phase; |
240 | u32 dsa_iac_enable; |
241 | u32 iac_sc_threshold; |
242 | u32 iac_vm_threshold; |
243 | u32 iac_skip_mode; |
244 | u32 iac_grp_width; |
245 | u32 iac_grp_height; |
246 | u32 rate_control_mode; |
247 | u32 rate_control_resolution; |
248 | u32 buffer_size; |
249 | u32 buffer_level_init; |
250 | u32 buffer_I_bit_budget; |
251 | u32 top_field_first; |
252 | u32 intra_lum_qoffset; |
253 | u32 intra_chr_qoffset; |
254 | u32 inter_lum_qoffset; |
255 | u32 inter_chr_qoffset; |
256 | u32 use_def_scaling_mtx; |
257 | u32 inter_8x8_enab; |
258 | u32 inter_4x4_enab; |
259 | u32 fme_enable_qpel; |
260 | u32 fme_enable_hpel; |
261 | u32 fme_nozeromv; |
262 | u32 fme_predmv_en; |
263 | u32 fme_pred_2mv4mv; |
264 | u32 fme_smallsadthresh; |
265 | u32 ame_en_lmvc; |
266 | u32 ame_x_mult; |
267 | u32 cme_enable_4mv; |
268 | u32 cme_enable_1mv; |
269 | u32 hme_enable_16x8mv; |
270 | u32 hme_enable_8x16mv; |
271 | u32 cme_mv_weight; |
272 | u32 cme_mv_cost; |
273 | u32 ame_mult_mv; |
274 | u32 ame_shift_mv; |
275 | u32 hme_forceto1mv_en; |
276 | u32 hme_2mv_cost; |
277 | u32 hme_pred_mode; |
278 | u32 hme_sc_rnge; |
279 | u32 hme_sw_rnge; |
280 | u32 output_format; |
281 | u32 timestamp_enab; |
282 | u32 initial_pts_enab; |
283 | u32 initial_pts; |
284 | }; |
285 | |
286 | struct vpu_enc_static_params { |
287 | u32 param_change; |
288 | u32 gop_length; |
289 | u32 rate_control_bitrate; |
290 | u32 rate_control_bitrate_min; |
291 | u32 rate_control_bitrate_max; |
292 | u32 rate_control_content_models; |
293 | u32 rate_control_iframe_maxsize; |
294 | u32 rate_control_qp_init; |
295 | u32 rate_control_islice_qp; |
296 | u32 rate_control_pslice_qp; |
297 | u32 rate_control_bslice_qp; |
298 | u32 adaptive_quantization; |
299 | u32 aq_variance; |
300 | u32 cost_optimization; |
301 | u32 fdlp_mode; |
302 | u32 enable_isegbframes; |
303 | u32 enable_adaptive_keyratio; |
304 | u32 keyratio_imin; |
305 | u32 keyratio_imax; |
306 | u32 keyratio_pmin; |
307 | u32 keyratio_pmax; |
308 | u32 keyratio_bmin; |
309 | u32 keyratio_bmax; |
310 | s32 keyratio_istep; |
311 | s32 keyratio_pstep; |
312 | s32 keyratio_bstep; |
313 | u32 enable_paff; |
314 | u32 enable_b_frame_ref; |
315 | u32 enable_adaptive_gop; |
316 | u32 enable_closed_gop; |
317 | u32 open_gop_refresh_freq; |
318 | u32 enable_adaptive_sc; |
319 | u32 enable_fade_detection; |
320 | s32 fade_detection_threshold; |
321 | u32 enable_repeat_b; |
322 | u32 enable_low_delay_b; |
323 | }; |
324 | |
325 | struct vpu_enc_dynamic_params { |
326 | u32 param_change; |
327 | u32 rows_per_slice; |
328 | u32 mbaff_enable; |
329 | u32 dbf_enable; |
330 | u32 field_source; |
331 | u32 gop_b_length; |
332 | u32 mb_group_size; |
333 | u32 cbr_rows_per_group; |
334 | u32 skip_enable; |
335 | u32 pts_bits_0_to_31; |
336 | u32 pts_bit_32; |
337 | u32 rm_expsv_cff; |
338 | u32 const_ipred; |
339 | s32 chr_qp_offset; |
340 | u32 intra_mb_qp_offset; |
341 | u32 h264_cabac_init_method; |
342 | u32 h264_cabac_init_idc; |
343 | u32 h264_cabac_enable; |
344 | s32 alpha_c0_offset_div2; |
345 | s32 beta_offset_div2; |
346 | u32 intra_prefresh_y0; |
347 | u32 intra_prefresh_y1; |
348 | u32 dbg_dump_rec_src; |
349 | }; |
350 | |
351 | struct vpu_enc_expert_mode_param { |
352 | struct vpu_enc_calib_params calib_param; |
353 | struct vpu_enc_config_params config_param; |
354 | struct vpu_enc_static_params static_param; |
355 | struct vpu_enc_dynamic_params dynamic_param; |
356 | }; |
357 | |
358 | enum MEDIAIP_ENC_FMT { |
359 | MEDIAIP_ENC_FMT_H264 = 0, |
360 | MEDIAIP_ENC_FMT_VC1, |
361 | MEDIAIP_ENC_FMT_MPEG2, |
362 | MEDIAIP_ENC_FMT_MPEG4SP, |
363 | MEDIAIP_ENC_FMT_H263, |
364 | MEDIAIP_ENC_FMT_MPEG1, |
365 | , |
366 | MEDIAIP_ENC_FMT_NULL |
367 | }; |
368 | |
369 | enum MEDIAIP_ENC_PROFILE { |
370 | MEDIAIP_ENC_PROF_MPEG2_SP = 0, |
371 | MEDIAIP_ENC_PROF_MPEG2_MP, |
372 | MEDIAIP_ENC_PROF_MPEG2_HP, |
373 | MEDIAIP_ENC_PROF_H264_BP, |
374 | MEDIAIP_ENC_PROF_H264_MP, |
375 | MEDIAIP_ENC_PROF_H264_HP, |
376 | MEDIAIP_ENC_PROF_MPEG4_SP, |
377 | MEDIAIP_ENC_PROF_MPEG4_ASP, |
378 | MEDIAIP_ENC_PROF_VC1_SP, |
379 | MEDIAIP_ENC_PROF_VC1_MP, |
380 | MEDIAIP_ENC_PROF_VC1_AP |
381 | }; |
382 | |
383 | enum MEDIAIP_ENC_BITRATE_MODE { |
384 | MEDIAIP_ENC_BITRATE_MODE_VBR = 0x00000001, |
385 | MEDIAIP_ENC_BITRATE_MODE_CBR = 0x00000002, |
386 | MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP = 0x00000004 |
387 | }; |
388 | |
389 | struct vpu_enc_memory_resource { |
390 | u32 phys; |
391 | u32 virt; |
392 | u32 size; |
393 | }; |
394 | |
395 | struct vpu_enc_param { |
396 | enum MEDIAIP_ENC_FMT codec_mode; |
397 | enum MEDIAIP_ENC_PROFILE profile; |
398 | u32 level; |
399 | |
400 | struct vpu_enc_memory_resource enc_mem_desc; |
401 | |
402 | u32 frame_rate; |
403 | u32 src_stride; |
404 | u32 src_width; |
405 | u32 src_height; |
406 | u32 src_offset_x; |
407 | u32 src_offset_y; |
408 | u32 src_crop_width; |
409 | u32 src_crop_height; |
410 | u32 out_width; |
411 | u32 out_height; |
412 | u32 iframe_interval; |
413 | u32 bframes; |
414 | u32 low_latency_mode; |
415 | |
416 | enum MEDIAIP_ENC_BITRATE_MODE bitrate_mode; |
417 | u32 target_bitrate; |
418 | u32 max_bitrate; |
419 | u32 min_bitrate; |
420 | u32 init_slice_qp; |
421 | }; |
422 | |
423 | struct vpu_enc_mem_pool { |
424 | struct vpu_enc_memory_resource enc_frames[WINDSOR_MAX_SRC_FRAMES]; |
425 | struct vpu_enc_memory_resource ref_frames[WINDSOR_MAX_REF_FRAMES]; |
426 | struct vpu_enc_memory_resource act_frame; |
427 | }; |
428 | |
429 | struct vpu_enc_encoding_status { |
430 | u32 frame_id; |
431 | u32 error_flag; //Error type |
432 | u32 mb_y; |
433 | u32 mb_x; |
434 | u32 reserved[12]; |
435 | |
436 | }; |
437 | |
438 | struct vpu_enc_dsa_status { |
439 | u32 frame_id; |
440 | u32 dsa_cyle; |
441 | u32 mb_y; |
442 | u32 mb_x; |
443 | u32 reserved[4]; |
444 | }; |
445 | |
446 | struct vpu_enc_ctrl { |
447 | struct vpu_enc_yuv_desc *yuv_desc; |
448 | struct vpu_rpc_buffer_desc *stream_desc; |
449 | struct vpu_enc_expert_mode_param *expert; |
450 | struct vpu_enc_param *param; |
451 | struct vpu_enc_mem_pool *pool; |
452 | struct vpu_enc_encoding_status *status; |
453 | struct vpu_enc_dsa_status *dsa; |
454 | }; |
455 | |
456 | struct vpu_enc_host_ctrls { |
457 | struct vpu_enc_ctrl ctrls[VID_API_NUM_STREAMS]; |
458 | }; |
459 | |
460 | struct windsor_pic_info { |
461 | u32 frame_id; |
462 | u32 pic_encod_done; |
463 | u32 pic_type; |
464 | u32 skipped_frame; |
465 | u32 error_flag; |
466 | u32 psnr; |
467 | u32 flush_done; |
468 | u32 mb_y; |
469 | u32 mb_x; |
470 | u32 frame_size; |
471 | u32 frame_enc_ttl_cycles; |
472 | u32 frame_enc_ttl_frm_cycles; |
473 | u32 frame_enc_ttl_slc_cycles; |
474 | u32 frame_enc_ttl_enc_cycles; |
475 | u32 frame_enc_ttl_hme_cycles; |
476 | u32 frame_enc_ttl_dsa_cycles; |
477 | u32 frame_enc_fw_cycles; |
478 | u32 frame_crc; |
479 | u32 num_interrupts_1; |
480 | u32 num_interrupts_2; |
481 | u32 poc; |
482 | u32 ref_info; |
483 | u32 pic_num; |
484 | u32 pic_activity; |
485 | u32 scene_change; |
486 | u32 mb_stats; |
487 | u32 enc_cache_count0; |
488 | u32 enc_cache_count1; |
489 | u32 mtl_wr_strb_cnt; |
490 | u32 mtl_rd_strb_cnt; |
491 | u32 str_buff_wptr; |
492 | u32 diagnosticEvents; |
493 | u32 proc_iacc_tot_rd_cnt; |
494 | u32 proc_dacc_tot_rd_cnt; |
495 | u32 proc_dacc_tot_wr_cnt; |
496 | u32 proc_dacc_reg_rd_cnt; |
497 | u32 proc_dacc_reg_wr_cnt; |
498 | u32 proc_dacc_rng_rd_cnt; |
499 | u32 proc_dacc_rng_wr_cnt; |
500 | s32 tv_s; |
501 | u32 tv_ns; |
502 | }; |
503 | |
504 | u32 vpu_windsor_get_data_size(void) |
505 | { |
506 | return sizeof(struct vpu_enc_host_ctrls); |
507 | } |
508 | |
509 | static struct vpu_enc_yuv_desc *get_yuv_desc(struct vpu_shared_addr *shared, |
510 | u32 instance) |
511 | { |
512 | struct vpu_enc_host_ctrls *hcs = shared->priv; |
513 | |
514 | return hcs->ctrls[instance].yuv_desc; |
515 | } |
516 | |
517 | static struct vpu_enc_mem_pool *get_mem_pool(struct vpu_shared_addr *shared, |
518 | u32 instance) |
519 | { |
520 | struct vpu_enc_host_ctrls *hcs = shared->priv; |
521 | |
522 | return hcs->ctrls[instance].pool; |
523 | } |
524 | |
525 | static struct vpu_rpc_buffer_desc *get_stream_buf_desc(struct vpu_shared_addr *shared, |
526 | u32 instance) |
527 | { |
528 | struct vpu_enc_host_ctrls *hcs = shared->priv; |
529 | |
530 | return hcs->ctrls[instance].stream_desc; |
531 | } |
532 | |
533 | static struct vpu_enc_expert_mode_param *get_expert_param(struct vpu_shared_addr *shared, |
534 | u32 instance) |
535 | { |
536 | struct vpu_enc_host_ctrls *hcs = shared->priv; |
537 | |
538 | return hcs->ctrls[instance].expert; |
539 | } |
540 | |
541 | static struct vpu_enc_param *get_enc_param(struct vpu_shared_addr *shared, u32 instance) |
542 | { |
543 | struct vpu_enc_host_ctrls *hcs = shared->priv; |
544 | |
545 | return hcs->ctrls[instance].param; |
546 | } |
547 | |
548 | static u32 get_ptr(u32 ptr) |
549 | { |
550 | return (ptr | 0x80000000); |
551 | } |
552 | |
553 | void vpu_windsor_init_rpc(struct vpu_shared_addr *shared, |
554 | struct vpu_buffer *rpc, dma_addr_t boot_addr) |
555 | { |
556 | unsigned long base_phy_addr; |
557 | unsigned long phy_addr; |
558 | unsigned long offset; |
559 | struct windsor_iface *iface; |
560 | struct windsor_ctrl_iface *ctrl; |
561 | struct vpu_enc_host_ctrls *hcs; |
562 | unsigned int i; |
563 | |
564 | if (rpc->phys < boot_addr) |
565 | return; |
566 | |
567 | base_phy_addr = rpc->phys - boot_addr; |
568 | iface = rpc->virt; |
569 | shared->iface = iface; |
570 | shared->boot_addr = boot_addr; |
571 | hcs = shared->priv; |
572 | |
573 | iface->exec_base_addr = base_phy_addr; |
574 | iface->exec_area_size = rpc->length; |
575 | |
576 | offset = sizeof(struct windsor_iface); |
577 | phy_addr = base_phy_addr + offset; |
578 | shared->cmd_desc = &iface->cmd_buffer_desc; |
579 | shared->cmd_mem_vir = rpc->virt + offset; |
580 | iface->cmd_buffer_desc.start = |
581 | iface->cmd_buffer_desc.rptr = |
582 | iface->cmd_buffer_desc.wptr = phy_addr; |
583 | iface->cmd_buffer_desc.end = iface->cmd_buffer_desc.start + CMD_SIZE; |
584 | |
585 | offset += CMD_SIZE; |
586 | phy_addr = base_phy_addr + offset; |
587 | shared->msg_desc = &iface->msg_buffer_desc; |
588 | shared->msg_mem_vir = rpc->virt + offset; |
589 | iface->msg_buffer_desc.start = |
590 | iface->msg_buffer_desc.wptr = |
591 | iface->msg_buffer_desc.rptr = phy_addr; |
592 | iface->msg_buffer_desc.end = iface->msg_buffer_desc.start + MSG_SIZE; |
593 | |
594 | offset += MSG_SIZE; |
595 | for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) { |
596 | iface->ctrl_iface[i] = base_phy_addr + offset; |
597 | offset += sizeof(struct windsor_ctrl_iface); |
598 | } |
599 | for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) { |
600 | ctrl = rpc->virt + (iface->ctrl_iface[i] - base_phy_addr); |
601 | |
602 | ctrl->enc_yuv_buffer_desc = base_phy_addr + offset; |
603 | hcs->ctrls[i].yuv_desc = rpc->virt + offset; |
604 | offset += sizeof(struct vpu_enc_yuv_desc); |
605 | |
606 | ctrl->enc_stream_buffer_desc = base_phy_addr + offset; |
607 | hcs->ctrls[i].stream_desc = rpc->virt + offset; |
608 | offset += sizeof(struct vpu_rpc_buffer_desc); |
609 | |
610 | ctrl->enc_expert_mode_param = base_phy_addr + offset; |
611 | hcs->ctrls[i].expert = rpc->virt + offset; |
612 | offset += sizeof(struct vpu_enc_expert_mode_param); |
613 | |
614 | ctrl->enc_param = base_phy_addr + offset; |
615 | hcs->ctrls[i].param = rpc->virt + offset; |
616 | offset += sizeof(struct vpu_enc_param); |
617 | |
618 | ctrl->enc_mem_pool = base_phy_addr + offset; |
619 | hcs->ctrls[i].pool = rpc->virt + offset; |
620 | offset += sizeof(struct vpu_enc_mem_pool); |
621 | |
622 | ctrl->enc_encoding_status = base_phy_addr + offset; |
623 | hcs->ctrls[i].status = rpc->virt + offset; |
624 | offset += sizeof(struct vpu_enc_encoding_status); |
625 | |
626 | ctrl->enc_dsa_status = base_phy_addr + offset; |
627 | hcs->ctrls[i].dsa = rpc->virt + offset; |
628 | offset += sizeof(struct vpu_enc_dsa_status); |
629 | } |
630 | |
631 | rpc->bytesused = offset; |
632 | } |
633 | |
634 | void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared, struct vpu_buffer *log) |
635 | { |
636 | struct windsor_iface *iface = shared->iface; |
637 | |
638 | iface->log_buffer_desc.start = |
639 | iface->log_buffer_desc.wptr = |
640 | iface->log_buffer_desc.rptr = log->phys - shared->boot_addr; |
641 | iface->log_buffer_desc.end = iface->log_buffer_desc.start + log->length; |
642 | } |
643 | |
644 | void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared, |
645 | u32 regs_base, void __iomem *regs, u32 core_id) |
646 | { |
647 | struct windsor_iface *iface = shared->iface; |
648 | struct vpu_rpc_system_config *config = &iface->system_config; |
649 | |
650 | vpu_imx8q_set_system_cfg_common(config, regs: regs_base, core_id); |
651 | } |
652 | |
653 | int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared) |
654 | { |
655 | return 0x300000; |
656 | } |
657 | |
658 | static struct vpu_pair windsor_cmds[] = { |
659 | {VPU_CMD_ID_NOOP, GTB_ENC_CMD_NOOP}, |
660 | {VPU_CMD_ID_CONFIGURE_CODEC, GTB_ENC_CMD_CONFIGURE_CODEC}, |
661 | {VPU_CMD_ID_START, GTB_ENC_CMD_STREAM_START}, |
662 | {VPU_CMD_ID_STOP, GTB_ENC_CMD_STREAM_STOP}, |
663 | {VPU_CMD_ID_FRAME_ENCODE, GTB_ENC_CMD_FRAME_ENCODE}, |
664 | {VPU_CMD_ID_SNAPSHOT, GTB_ENC_CMD_SNAPSHOT}, |
665 | {VPU_CMD_ID_FIRM_RESET, GTB_ENC_CMD_FIRM_RESET}, |
666 | {VPU_CMD_ID_UPDATE_PARAMETER, GTB_ENC_CMD_PARAMETER_UPD}, |
667 | {VPU_CMD_ID_DEBUG, GTB_ENC_CMD_FW_STATUS} |
668 | }; |
669 | |
670 | static struct vpu_pair windsor_msgs[] = { |
671 | {VPU_MSG_ID_RESET_DONE, VID_API_ENC_EVENT_RESET_DONE}, |
672 | {VPU_MSG_ID_START_DONE, VID_API_ENC_EVENT_START_DONE}, |
673 | {VPU_MSG_ID_STOP_DONE, VID_API_ENC_EVENT_STOP_DONE}, |
674 | {VPU_MSG_ID_FRAME_INPUT_DONE, VID_API_ENC_EVENT_FRAME_INPUT_DONE}, |
675 | {VPU_MSG_ID_ENC_DONE, VID_API_ENC_EVENT_FRAME_DONE}, |
676 | {VPU_MSG_ID_FRAME_RELEASE, VID_API_ENC_EVENT_FRAME_RELEASE}, |
677 | {VPU_MSG_ID_MEM_REQUEST, VID_API_ENC_EVENT_MEM_REQUEST}, |
678 | {VPU_MSG_ID_PARAM_UPD_DONE, VID_API_ENC_EVENT_PARA_UPD_DONE}, |
679 | {VPU_MSG_ID_FIRMWARE_XCPT, VID_API_ENC_EVENT_FIRMWARE_XCPT}, |
680 | }; |
681 | |
682 | int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data) |
683 | { |
684 | int ret; |
685 | |
686 | ret = vpu_find_dst_by_src(pairs: windsor_cmds, ARRAY_SIZE(windsor_cmds), src: id); |
687 | if (ret < 0) |
688 | return ret; |
689 | pkt->hdr.id = ret; |
690 | pkt->hdr.num = 0; |
691 | pkt->hdr.index = index; |
692 | if (id == VPU_CMD_ID_FRAME_ENCODE) { |
693 | s64 timestamp = *(s64 *)data; |
694 | struct timespec64 ts = ns_to_timespec64(nsec: timestamp); |
695 | |
696 | pkt->hdr.num = 2; |
697 | pkt->data[0] = ts.tv_sec; |
698 | pkt->data[1] = ts.tv_nsec; |
699 | } |
700 | |
701 | return 0; |
702 | } |
703 | |
704 | int vpu_windsor_convert_msg_id(u32 id) |
705 | { |
706 | return vpu_find_src_by_dst(pairs: windsor_msgs, ARRAY_SIZE(windsor_msgs), dst: id); |
707 | } |
708 | |
709 | static void vpu_windsor_unpack_pic_info(struct vpu_rpc_event *pkt, void *data) |
710 | { |
711 | struct vpu_enc_pic_info *info = data; |
712 | struct windsor_pic_info *windsor = (struct windsor_pic_info *)pkt->data; |
713 | struct timespec64 ts = { windsor->tv_s, windsor->tv_ns }; |
714 | |
715 | info->frame_id = windsor->frame_id; |
716 | switch (windsor->pic_type) { |
717 | case MEDIAIP_ENC_PIC_TYPE_I_FRAME: |
718 | case MEDIAIP_ENC_PIC_TYPE_IDR_FRAME: |
719 | info->pic_type = V4L2_BUF_FLAG_KEYFRAME; |
720 | break; |
721 | case MEDIAIP_ENC_PIC_TYPE_P_FRAME: |
722 | info->pic_type = V4L2_BUF_FLAG_PFRAME; |
723 | break; |
724 | case MEDIAIP_ENC_PIC_TYPE_B_FRAME: |
725 | info->pic_type = V4L2_BUF_FLAG_BFRAME; |
726 | break; |
727 | default: |
728 | break; |
729 | } |
730 | info->skipped_frame = windsor->skipped_frame; |
731 | info->error_flag = windsor->error_flag; |
732 | info->psnr = windsor->psnr; |
733 | info->frame_size = windsor->frame_size; |
734 | info->wptr = get_ptr(ptr: windsor->str_buff_wptr); |
735 | info->crc = windsor->frame_crc; |
736 | info->timestamp = timespec64_to_ns(ts: &ts); |
737 | } |
738 | |
739 | static void vpu_windsor_unpack_mem_req(struct vpu_rpc_event *pkt, void *data) |
740 | { |
741 | struct vpu_pkt_mem_req_data *req_data = data; |
742 | |
743 | req_data->enc_frame_size = pkt->data[0]; |
744 | req_data->enc_frame_num = pkt->data[1]; |
745 | req_data->ref_frame_size = pkt->data[2]; |
746 | req_data->ref_frame_num = pkt->data[3]; |
747 | req_data->act_buf_size = pkt->data[4]; |
748 | req_data->act_buf_num = 1; |
749 | } |
750 | |
751 | int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data) |
752 | { |
753 | if (!pkt || !data) |
754 | return -EINVAL; |
755 | |
756 | switch (pkt->hdr.id) { |
757 | case VID_API_ENC_EVENT_FRAME_DONE: |
758 | vpu_windsor_unpack_pic_info(pkt, data); |
759 | break; |
760 | case VID_API_ENC_EVENT_MEM_REQUEST: |
761 | vpu_windsor_unpack_mem_req(pkt, data); |
762 | break; |
763 | case VID_API_ENC_EVENT_FRAME_RELEASE: |
764 | *(u32 *)data = pkt->data[0]; |
765 | break; |
766 | default: |
767 | break; |
768 | } |
769 | |
770 | return 0; |
771 | } |
772 | |
773 | static int vpu_windsor_fill_yuv_frame(struct vpu_shared_addr *shared, |
774 | u32 instance, |
775 | struct vb2_buffer *vb) |
776 | { |
777 | struct vpu_inst *inst = vb2_get_drv_priv(q: vb->vb2_queue); |
778 | struct vpu_format *out_fmt; |
779 | struct vpu_enc_yuv_desc *desc; |
780 | struct vb2_v4l2_buffer *vbuf; |
781 | |
782 | if (instance >= VID_API_NUM_STREAMS) |
783 | return -EINVAL; |
784 | |
785 | desc = get_yuv_desc(shared, instance); |
786 | out_fmt = vpu_get_format(inst, type: vb->type); |
787 | |
788 | vbuf = to_vb2_v4l2_buffer(vb); |
789 | desc->frame_id = vbuf->sequence; |
790 | if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME) |
791 | desc->key_frame = 1; |
792 | else |
793 | desc->key_frame = 0; |
794 | desc->luma_base = vpu_get_vb_phy_addr(vb, plane_no: 0); |
795 | if (vb->num_planes > 1) |
796 | desc->chroma_base = vpu_get_vb_phy_addr(vb, plane_no: 1); |
797 | else |
798 | desc->chroma_base = desc->luma_base + out_fmt->sizeimage[0]; |
799 | |
800 | return 0; |
801 | } |
802 | |
803 | int vpu_windsor_input_frame(struct vpu_shared_addr *shared, |
804 | struct vpu_inst *inst, struct vb2_buffer *vb) |
805 | { |
806 | vpu_windsor_fill_yuv_frame(shared, instance: inst->id, vb); |
807 | return vpu_session_encode_frame(inst, timestamp: vb->timestamp); |
808 | } |
809 | |
810 | int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared, |
811 | u32 instance, |
812 | u32 type, |
813 | u32 index, |
814 | struct vpu_buffer *buf) |
815 | { |
816 | struct vpu_enc_mem_pool *pool; |
817 | struct vpu_enc_memory_resource *res; |
818 | |
819 | if (instance >= VID_API_NUM_STREAMS) |
820 | return -EINVAL; |
821 | |
822 | pool = get_mem_pool(shared, instance); |
823 | |
824 | switch (type) { |
825 | case MEM_RES_ENC: |
826 | if (index >= ARRAY_SIZE(pool->enc_frames)) |
827 | return -EINVAL; |
828 | res = &pool->enc_frames[index]; |
829 | break; |
830 | case MEM_RES_REF: |
831 | if (index >= ARRAY_SIZE(pool->ref_frames)) |
832 | return -EINVAL; |
833 | res = &pool->ref_frames[index]; |
834 | break; |
835 | case MEM_RES_ACT: |
836 | if (index) |
837 | return -EINVAL; |
838 | res = &pool->act_frame; |
839 | break; |
840 | default: |
841 | return -EINVAL; |
842 | } |
843 | |
844 | res->phys = buf->phys; |
845 | res->virt = buf->phys - shared->boot_addr; |
846 | res->size = buf->length; |
847 | |
848 | return 0; |
849 | } |
850 | |
851 | int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared, |
852 | u32 instance, |
853 | struct vpu_buffer *buf) |
854 | { |
855 | struct vpu_rpc_buffer_desc *desc; |
856 | struct vpu_enc_expert_mode_param *expert; |
857 | |
858 | desc = get_stream_buf_desc(shared, instance); |
859 | expert = get_expert_param(shared, instance); |
860 | |
861 | desc->start = buf->phys; |
862 | desc->wptr = buf->phys; |
863 | desc->rptr = buf->phys; |
864 | desc->end = buf->phys + buf->length; |
865 | |
866 | expert->calib_param.mem_chunk_phys_addr = 0; |
867 | expert->calib_param.mem_chunk_virt_addr = 0; |
868 | expert->calib_param.mem_chunk_size = 0; |
869 | expert->calib_param.cb_base = buf->phys; |
870 | expert->calib_param.cb_size = buf->length; |
871 | |
872 | return 0; |
873 | } |
874 | |
875 | int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared, |
876 | u32 instance, u32 ptr, bool write) |
877 | { |
878 | struct vpu_rpc_buffer_desc *desc; |
879 | |
880 | desc = get_stream_buf_desc(shared, instance); |
881 | |
882 | /*update wptr/rptr after data is written or read*/ |
883 | mb(); |
884 | if (write) |
885 | desc->wptr = ptr; |
886 | else |
887 | desc->rptr = ptr; |
888 | |
889 | return 0; |
890 | } |
891 | |
892 | int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared, |
893 | u32 instance, struct vpu_rpc_buffer_desc *desc) |
894 | { |
895 | struct vpu_rpc_buffer_desc *rpc_desc; |
896 | |
897 | rpc_desc = get_stream_buf_desc(shared, instance); |
898 | if (desc) { |
899 | desc->wptr = get_ptr(ptr: rpc_desc->wptr); |
900 | desc->rptr = get_ptr(ptr: rpc_desc->rptr); |
901 | desc->start = get_ptr(ptr: rpc_desc->start); |
902 | desc->end = get_ptr(ptr: rpc_desc->end); |
903 | } |
904 | |
905 | return 0; |
906 | } |
907 | |
908 | u32 vpu_windsor_get_version(struct vpu_shared_addr *shared) |
909 | { |
910 | struct windsor_iface *iface = shared->iface; |
911 | |
912 | return iface->fw_version; |
913 | } |
914 | |
915 | static int vpu_windsor_set_frame_rate(struct vpu_enc_expert_mode_param *expert, |
916 | struct vpu_encode_params *params) |
917 | { |
918 | expert->config_param.frame_rate_num = params->frame_rate.numerator; |
919 | expert->config_param.frame_rate_den = params->frame_rate.denominator; |
920 | |
921 | return 0; |
922 | } |
923 | |
924 | static int vpu_windsor_set_format(struct vpu_enc_param *param, u32 pixelformat) |
925 | { |
926 | switch (pixelformat) { |
927 | case V4L2_PIX_FMT_H264: |
928 | param->codec_mode = MEDIAIP_ENC_FMT_H264; |
929 | break; |
930 | default: |
931 | return -EINVAL; |
932 | } |
933 | |
934 | return 0; |
935 | } |
936 | |
937 | static int vpu_windsor_set_profile(struct vpu_enc_param *param, u32 profile) |
938 | { |
939 | switch (profile) { |
940 | case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: |
941 | param->profile = MEDIAIP_ENC_PROF_H264_BP; |
942 | break; |
943 | case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: |
944 | param->profile = MEDIAIP_ENC_PROF_H264_MP; |
945 | break; |
946 | case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: |
947 | param->profile = MEDIAIP_ENC_PROF_H264_HP; |
948 | break; |
949 | default: |
950 | return -EINVAL; |
951 | } |
952 | |
953 | return 0; |
954 | } |
955 | |
956 | static const u32 h264_level[] = { |
957 | [V4L2_MPEG_VIDEO_H264_LEVEL_1_0] = 10, |
958 | [V4L2_MPEG_VIDEO_H264_LEVEL_1B] = 14, |
959 | [V4L2_MPEG_VIDEO_H264_LEVEL_1_1] = 11, |
960 | [V4L2_MPEG_VIDEO_H264_LEVEL_1_2] = 12, |
961 | [V4L2_MPEG_VIDEO_H264_LEVEL_1_3] = 13, |
962 | [V4L2_MPEG_VIDEO_H264_LEVEL_2_0] = 20, |
963 | [V4L2_MPEG_VIDEO_H264_LEVEL_2_1] = 21, |
964 | [V4L2_MPEG_VIDEO_H264_LEVEL_2_2] = 22, |
965 | [V4L2_MPEG_VIDEO_H264_LEVEL_3_0] = 30, |
966 | [V4L2_MPEG_VIDEO_H264_LEVEL_3_1] = 31, |
967 | [V4L2_MPEG_VIDEO_H264_LEVEL_3_2] = 32, |
968 | [V4L2_MPEG_VIDEO_H264_LEVEL_4_0] = 40, |
969 | [V4L2_MPEG_VIDEO_H264_LEVEL_4_1] = 41, |
970 | [V4L2_MPEG_VIDEO_H264_LEVEL_4_2] = 42, |
971 | [V4L2_MPEG_VIDEO_H264_LEVEL_5_0] = 50, |
972 | [V4L2_MPEG_VIDEO_H264_LEVEL_5_1] = 51 |
973 | }; |
974 | |
975 | static int vpu_windsor_set_level(struct vpu_enc_param *param, u32 level) |
976 | { |
977 | if (level >= ARRAY_SIZE(h264_level)) |
978 | return -EINVAL; |
979 | |
980 | param->level = h264_level[level]; |
981 | |
982 | return 0; |
983 | } |
984 | |
985 | static int vpu_windsor_set_size(struct vpu_enc_param *windsor, |
986 | struct vpu_encode_params *params) |
987 | { |
988 | windsor->src_stride = params->src_stride; |
989 | windsor->src_width = params->src_width; |
990 | windsor->src_height = params->src_height; |
991 | windsor->src_offset_x = params->crop.left; |
992 | windsor->src_offset_y = params->crop.top; |
993 | windsor->src_crop_width = params->crop.width; |
994 | windsor->src_crop_height = params->crop.height; |
995 | windsor->out_width = params->out_width; |
996 | windsor->out_height = params->out_height; |
997 | |
998 | return 0; |
999 | } |
1000 | |
1001 | static int vpu_windsor_set_gop(struct vpu_enc_param *param, u32 gop) |
1002 | { |
1003 | param->iframe_interval = gop; |
1004 | |
1005 | return 0; |
1006 | } |
1007 | |
1008 | static int vpu_windsor_set_bframes(struct vpu_enc_param *param, u32 bframes) |
1009 | { |
1010 | if (bframes) { |
1011 | param->low_latency_mode = 0; |
1012 | param->bframes = bframes; |
1013 | } else { |
1014 | param->low_latency_mode = 1; |
1015 | param->bframes = 0; |
1016 | } |
1017 | |
1018 | return 0; |
1019 | } |
1020 | |
1021 | static int vpu_windsor_set_bitrate_mode(struct vpu_enc_param *param, u32 rc_enable, u32 mode) |
1022 | { |
1023 | if (!rc_enable) |
1024 | param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP; |
1025 | else if (mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
1026 | param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_VBR; |
1027 | else |
1028 | param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CBR; |
1029 | |
1030 | return 0; |
1031 | } |
1032 | |
1033 | static u32 vpu_windsor_bitrate(u32 bitrate) |
1034 | { |
1035 | return DIV_ROUND_CLOSEST(bitrate, WINDSOR_BITRATE_UNIT); |
1036 | } |
1037 | |
1038 | static int vpu_windsor_set_bitrate(struct vpu_enc_param *windsor, |
1039 | struct vpu_encode_params *params) |
1040 | { |
1041 | windsor->target_bitrate = vpu_windsor_bitrate(bitrate: params->bitrate); |
1042 | windsor->min_bitrate = vpu_windsor_bitrate(bitrate: params->bitrate_min); |
1043 | windsor->max_bitrate = vpu_windsor_bitrate(bitrate: params->bitrate_max); |
1044 | |
1045 | return 0; |
1046 | } |
1047 | |
1048 | static int vpu_windsor_set_qp(struct vpu_enc_expert_mode_param *expert, |
1049 | struct vpu_encode_params *params) |
1050 | { |
1051 | expert->static_param.rate_control_islice_qp = params->i_frame_qp; |
1052 | expert->static_param.rate_control_pslice_qp = params->p_frame_qp; |
1053 | expert->static_param.rate_control_bslice_qp = params->b_frame_qp; |
1054 | |
1055 | return 0; |
1056 | } |
1057 | |
1058 | static int vpu_windsor_set_sar(struct vpu_enc_expert_mode_param *expert, |
1059 | struct vpu_encode_params *params) |
1060 | { |
1061 | expert->config_param.h264_aspect_ratio_present = params->sar.enable; |
1062 | if (params->sar.idc == V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED) |
1063 | expert->config_param.aspect_ratio = WINDSOR_H264_EXTENDED_SAR; |
1064 | else |
1065 | expert->config_param.aspect_ratio = params->sar.idc; |
1066 | expert->config_param.h264_aspect_ratio_sar_width = params->sar.width; |
1067 | expert->config_param.h264_aspect_ratio_sar_height = params->sar.height; |
1068 | |
1069 | return 0; |
1070 | } |
1071 | |
1072 | static int vpu_windsor_set_color(struct vpu_enc_expert_mode_param *expert, |
1073 | struct vpu_encode_params *params) |
1074 | { |
1075 | expert->config_param.h264_video_type_present = 1; |
1076 | expert->config_param.h264_video_format = 5; |
1077 | expert->config_param.h264_video_colour_descriptor = 1; |
1078 | expert->config_param.h264_video_colour_primaries = |
1079 | vpu_color_cvrt_primaries_v2i(primaries: params->color.primaries); |
1080 | expert->config_param.h264_video_transfer_char = |
1081 | vpu_color_cvrt_transfers_v2i(transfers: params->color.transfer); |
1082 | expert->config_param.h264_video_matrix_coeff = |
1083 | vpu_color_cvrt_matrix_v2i(matrix: params->color.matrix); |
1084 | expert->config_param.h264_video_full_range = |
1085 | vpu_color_cvrt_full_range_v2i(full_range: params->color.full_range); |
1086 | return 0; |
1087 | } |
1088 | |
1089 | static int vpu_windsor_update_bitrate(struct vpu_shared_addr *shared, |
1090 | u32 instance, struct vpu_encode_params *params) |
1091 | { |
1092 | struct vpu_enc_param *windsor; |
1093 | struct vpu_enc_expert_mode_param *expert; |
1094 | |
1095 | windsor = get_enc_param(shared, instance); |
1096 | expert = get_expert_param(shared, instance); |
1097 | |
1098 | if (windsor->bitrate_mode != MEDIAIP_ENC_BITRATE_MODE_CBR) |
1099 | return 0; |
1100 | if (!params->rc_enable) |
1101 | return 0; |
1102 | if (vpu_windsor_bitrate(bitrate: params->bitrate) == windsor->target_bitrate) |
1103 | return 0; |
1104 | |
1105 | vpu_windsor_set_bitrate(windsor, params); |
1106 | expert->static_param.rate_control_bitrate = windsor->target_bitrate; |
1107 | expert->static_param.rate_control_bitrate_min = windsor->min_bitrate; |
1108 | expert->static_param.rate_control_bitrate_max = windsor->max_bitrate; |
1109 | |
1110 | return 0; |
1111 | } |
1112 | |
1113 | static int vpu_windsor_set_params(struct vpu_shared_addr *shared, |
1114 | u32 instance, struct vpu_encode_params *params) |
1115 | { |
1116 | struct vpu_enc_param *windsor; |
1117 | int ret; |
1118 | |
1119 | windsor = get_enc_param(shared, instance); |
1120 | |
1121 | if (params->input_format != V4L2_PIX_FMT_NV12 && |
1122 | params->input_format != V4L2_PIX_FMT_NV12M) |
1123 | return -EINVAL; |
1124 | |
1125 | ret = vpu_windsor_set_format(param: windsor, pixelformat: params->codec_format); |
1126 | if (ret) |
1127 | return ret; |
1128 | vpu_windsor_set_profile(param: windsor, profile: params->profile); |
1129 | vpu_windsor_set_level(param: windsor, level: params->level); |
1130 | vpu_windsor_set_size(windsor, params); |
1131 | vpu_windsor_set_gop(param: windsor, gop: params->gop_length); |
1132 | vpu_windsor_set_bframes(param: windsor, bframes: params->bframes); |
1133 | vpu_windsor_set_bitrate_mode(param: windsor, rc_enable: params->rc_enable, mode: params->rc_mode); |
1134 | vpu_windsor_set_bitrate(windsor, params); |
1135 | windsor->init_slice_qp = params->i_frame_qp; |
1136 | |
1137 | if (!params->frame_rate.numerator) |
1138 | return -EINVAL; |
1139 | windsor->frame_rate = params->frame_rate.denominator / params->frame_rate.numerator; |
1140 | |
1141 | return 0; |
1142 | } |
1143 | |
1144 | static int vpu_windsor_update_params(struct vpu_shared_addr *shared, |
1145 | u32 instance, struct vpu_encode_params *params) |
1146 | { |
1147 | struct vpu_enc_expert_mode_param *expert; |
1148 | |
1149 | expert = get_expert_param(shared, instance); |
1150 | |
1151 | vpu_windsor_set_frame_rate(expert, params); |
1152 | vpu_windsor_set_qp(expert, params); |
1153 | vpu_windsor_set_sar(expert, params); |
1154 | vpu_windsor_set_color(expert, params); |
1155 | vpu_windsor_update_bitrate(shared, instance, params); |
1156 | /*expert->config_param.iac_sc_threshold = 0;*/ |
1157 | |
1158 | return 0; |
1159 | } |
1160 | |
1161 | int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared, |
1162 | u32 instance, struct vpu_encode_params *params, u32 update) |
1163 | { |
1164 | if (!params) |
1165 | return -EINVAL; |
1166 | |
1167 | if (!update) |
1168 | return vpu_windsor_set_params(shared, instance, params); |
1169 | else |
1170 | return vpu_windsor_update_params(shared, instance, params); |
1171 | } |
1172 | |
1173 | u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared) |
1174 | { |
1175 | struct windsor_iface *iface = shared->iface; |
1176 | |
1177 | return iface->max_streams; |
1178 | } |
1179 | |