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