brintos

brintos / linux-shallow public Read only

0
0
Text · 29.7 KiB · e7d37aa Raw
1181 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 2020-2021 NXP4 */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				256026#define MSG_SIZE				2560027#define WINDSOR_USER_DATA_WORDS			1628#define WINDSOR_MAX_SRC_FRAMES			0x629#define WINDSOR_MAX_REF_FRAMES			0x330#define WINDSOR_BITRATE_UNIT			102431#define WINDSOR_H264_EXTENDED_SAR		25532 33enum {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_RESERVED50};51 52enum {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_RESERVED65};66 67enum {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_FRAME73};74 75struct 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 90struct 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 100struct 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 108struct 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 178struct 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 mode211	u32 dsa_test_mode;              // Automated test mode for the DSA.212	u32 fme_test_mode;              // Automated test mode for the fme213	u32 cbr_row_mode;               //0: FW mode; 1: HW mode214	u32 windsor_mode;               //0: normal mode; 1: intra only mode; 2: intra+0MV mode215	u32 encode_mode;                // H264, VC1, MPEG2, DIVX216	u32 frame_width;                // display width217	u32 frame_height;               // display height218	u32 enc_frame_width;            // encoding width, should be 16-pix align219	u32 enc_frame_height;           // encoding height, should be 16-pix aligned220	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 286struct 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 325struct 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 351struct 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 358enum 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	MEDIAIP_ENC_FMT_SHORT_HEADER,366	MEDIAIP_ENC_FMT_NULL367};368 369enum 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_AP381};382 383enum 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  = 0x00000004387};388 389struct vpu_enc_memory_resource {390	u32 phys;391	u32 virt;392	u32 size;393};394 395struct 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 423struct 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 429struct vpu_enc_encoding_status {430	u32   frame_id;431	u32   error_flag;   //Error type432	u32   mb_y;433	u32   mb_x;434	u32   reserved[12];435 436};437 438struct 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 446struct 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 456struct vpu_enc_host_ctrls {457	struct vpu_enc_ctrl ctrls[VID_API_NUM_STREAMS];458};459 460struct 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	u32 average_qp;503};504 505u32 vpu_windsor_get_data_size(void)506{507	return sizeof(struct vpu_enc_host_ctrls);508}509 510static struct vpu_enc_yuv_desc *get_yuv_desc(struct vpu_shared_addr *shared,511					     u32 instance)512{513	struct vpu_enc_host_ctrls *hcs = shared->priv;514 515	return hcs->ctrls[instance].yuv_desc;516}517 518static struct vpu_enc_mem_pool *get_mem_pool(struct vpu_shared_addr *shared,519					     u32 instance)520{521	struct vpu_enc_host_ctrls *hcs = shared->priv;522 523	return hcs->ctrls[instance].pool;524}525 526static struct vpu_rpc_buffer_desc *get_stream_buf_desc(struct vpu_shared_addr *shared,527						       u32 instance)528{529	struct vpu_enc_host_ctrls *hcs = shared->priv;530 531	return hcs->ctrls[instance].stream_desc;532}533 534static struct vpu_enc_expert_mode_param *get_expert_param(struct vpu_shared_addr *shared,535							  u32 instance)536{537	struct vpu_enc_host_ctrls *hcs = shared->priv;538 539	return hcs->ctrls[instance].expert;540}541 542static struct vpu_enc_param *get_enc_param(struct vpu_shared_addr *shared, u32 instance)543{544	struct vpu_enc_host_ctrls *hcs = shared->priv;545 546	return hcs->ctrls[instance].param;547}548 549static u32 get_ptr(u32 ptr)550{551	return (ptr | 0x80000000);552}553 554void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,555			  struct vpu_buffer *rpc, dma_addr_t boot_addr)556{557	unsigned long base_phy_addr;558	unsigned long phy_addr;559	unsigned long offset;560	struct windsor_iface *iface;561	struct windsor_ctrl_iface *ctrl;562	struct vpu_enc_host_ctrls *hcs;563	unsigned int i;564 565	if (rpc->phys < boot_addr)566		return;567 568	base_phy_addr = rpc->phys - boot_addr;569	iface = rpc->virt;570	shared->iface = iface;571	shared->boot_addr = boot_addr;572	hcs = shared->priv;573 574	iface->exec_base_addr = base_phy_addr;575	iface->exec_area_size = rpc->length;576 577	offset = sizeof(struct windsor_iface);578	phy_addr = base_phy_addr + offset;579	shared->cmd_desc = &iface->cmd_buffer_desc;580	shared->cmd_mem_vir = rpc->virt + offset;581	iface->cmd_buffer_desc.start =582	iface->cmd_buffer_desc.rptr =583	iface->cmd_buffer_desc.wptr = phy_addr;584	iface->cmd_buffer_desc.end = iface->cmd_buffer_desc.start + CMD_SIZE;585 586	offset += CMD_SIZE;587	phy_addr = base_phy_addr + offset;588	shared->msg_desc = &iface->msg_buffer_desc;589	shared->msg_mem_vir = rpc->virt + offset;590	iface->msg_buffer_desc.start =591	iface->msg_buffer_desc.wptr =592	iface->msg_buffer_desc.rptr = phy_addr;593	iface->msg_buffer_desc.end = iface->msg_buffer_desc.start + MSG_SIZE;594 595	offset += MSG_SIZE;596	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {597		iface->ctrl_iface[i] = base_phy_addr + offset;598		offset += sizeof(struct windsor_ctrl_iface);599	}600	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {601		ctrl = rpc->virt + (iface->ctrl_iface[i] - base_phy_addr);602 603		ctrl->enc_yuv_buffer_desc = base_phy_addr + offset;604		hcs->ctrls[i].yuv_desc = rpc->virt + offset;605		offset += sizeof(struct vpu_enc_yuv_desc);606 607		ctrl->enc_stream_buffer_desc = base_phy_addr + offset;608		hcs->ctrls[i].stream_desc = rpc->virt + offset;609		offset += sizeof(struct vpu_rpc_buffer_desc);610 611		ctrl->enc_expert_mode_param = base_phy_addr + offset;612		hcs->ctrls[i].expert = rpc->virt + offset;613		offset += sizeof(struct vpu_enc_expert_mode_param);614 615		ctrl->enc_param = base_phy_addr + offset;616		hcs->ctrls[i].param = rpc->virt + offset;617		offset += sizeof(struct vpu_enc_param);618 619		ctrl->enc_mem_pool = base_phy_addr + offset;620		hcs->ctrls[i].pool = rpc->virt + offset;621		offset += sizeof(struct vpu_enc_mem_pool);622 623		ctrl->enc_encoding_status = base_phy_addr + offset;624		hcs->ctrls[i].status = rpc->virt + offset;625		offset += sizeof(struct vpu_enc_encoding_status);626 627		ctrl->enc_dsa_status = base_phy_addr + offset;628		hcs->ctrls[i].dsa = rpc->virt + offset;629		offset += sizeof(struct vpu_enc_dsa_status);630	}631 632	rpc->bytesused = offset;633}634 635void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared, struct vpu_buffer *log)636{637	struct windsor_iface *iface = shared->iface;638 639	iface->log_buffer_desc.start =640	iface->log_buffer_desc.wptr =641	iface->log_buffer_desc.rptr = log->phys - shared->boot_addr;642	iface->log_buffer_desc.end = iface->log_buffer_desc.start + log->length;643}644 645void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,646				u32 regs_base, void __iomem *regs, u32 core_id)647{648	struct windsor_iface *iface = shared->iface;649	struct vpu_rpc_system_config *config = &iface->system_config;650 651	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);652}653 654int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared)655{656	return 0x300000;657}658 659static struct vpu_pair windsor_cmds[] = {660	{VPU_CMD_ID_NOOP, GTB_ENC_CMD_NOOP},661	{VPU_CMD_ID_CONFIGURE_CODEC, GTB_ENC_CMD_CONFIGURE_CODEC},662	{VPU_CMD_ID_START, GTB_ENC_CMD_STREAM_START},663	{VPU_CMD_ID_STOP, GTB_ENC_CMD_STREAM_STOP},664	{VPU_CMD_ID_FRAME_ENCODE, GTB_ENC_CMD_FRAME_ENCODE},665	{VPU_CMD_ID_SNAPSHOT, GTB_ENC_CMD_SNAPSHOT},666	{VPU_CMD_ID_FIRM_RESET, GTB_ENC_CMD_FIRM_RESET},667	{VPU_CMD_ID_UPDATE_PARAMETER, GTB_ENC_CMD_PARAMETER_UPD},668	{VPU_CMD_ID_DEBUG, GTB_ENC_CMD_FW_STATUS}669};670 671static struct vpu_pair windsor_msgs[] = {672	{VPU_MSG_ID_RESET_DONE, VID_API_ENC_EVENT_RESET_DONE},673	{VPU_MSG_ID_START_DONE, VID_API_ENC_EVENT_START_DONE},674	{VPU_MSG_ID_STOP_DONE, VID_API_ENC_EVENT_STOP_DONE},675	{VPU_MSG_ID_FRAME_INPUT_DONE, VID_API_ENC_EVENT_FRAME_INPUT_DONE},676	{VPU_MSG_ID_ENC_DONE, VID_API_ENC_EVENT_FRAME_DONE},677	{VPU_MSG_ID_FRAME_RELEASE, VID_API_ENC_EVENT_FRAME_RELEASE},678	{VPU_MSG_ID_MEM_REQUEST, VID_API_ENC_EVENT_MEM_REQUEST},679	{VPU_MSG_ID_PARAM_UPD_DONE, VID_API_ENC_EVENT_PARA_UPD_DONE},680	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_ENC_EVENT_FIRMWARE_XCPT},681};682 683int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)684{685	int ret;686 687	ret = vpu_find_dst_by_src(windsor_cmds, ARRAY_SIZE(windsor_cmds), id);688	if (ret < 0)689		return ret;690	pkt->hdr.id = ret;691	pkt->hdr.num = 0;692	pkt->hdr.index = index;693	if (id == VPU_CMD_ID_FRAME_ENCODE) {694		s64 timestamp = *(s64 *)data;695		struct timespec64 ts = ns_to_timespec64(timestamp);696 697		pkt->hdr.num = 2;698		pkt->data[0] = ts.tv_sec;699		pkt->data[1] = ts.tv_nsec;700	}701 702	return 0;703}704 705int vpu_windsor_convert_msg_id(u32 id)706{707	return vpu_find_src_by_dst(windsor_msgs, ARRAY_SIZE(windsor_msgs), id);708}709 710static void vpu_windsor_unpack_pic_info(struct vpu_rpc_event *pkt, void *data)711{712	struct vpu_enc_pic_info *info = data;713	struct windsor_pic_info *windsor = (struct windsor_pic_info *)pkt->data;714	struct timespec64 ts = { windsor->tv_s, windsor->tv_ns };715 716	info->frame_id = windsor->frame_id;717	switch (windsor->pic_type) {718	case MEDIAIP_ENC_PIC_TYPE_I_FRAME:719	case MEDIAIP_ENC_PIC_TYPE_IDR_FRAME:720		info->pic_type = V4L2_BUF_FLAG_KEYFRAME;721		break;722	case MEDIAIP_ENC_PIC_TYPE_P_FRAME:723		info->pic_type = V4L2_BUF_FLAG_PFRAME;724		break;725	case MEDIAIP_ENC_PIC_TYPE_B_FRAME:726		info->pic_type = V4L2_BUF_FLAG_BFRAME;727		break;728	default:729		break;730	}731	info->skipped_frame = windsor->skipped_frame;732	info->error_flag = windsor->error_flag;733	info->psnr = windsor->psnr;734	info->frame_size = windsor->frame_size;735	info->wptr = get_ptr(windsor->str_buff_wptr);736	info->crc = windsor->frame_crc;737	info->timestamp = timespec64_to_ns(&ts);738	info->average_qp = windsor->average_qp;739}740 741static void vpu_windsor_unpack_mem_req(struct vpu_rpc_event *pkt, void *data)742{743	struct vpu_pkt_mem_req_data *req_data = data;744 745	req_data->enc_frame_size = pkt->data[0];746	req_data->enc_frame_num = pkt->data[1];747	req_data->ref_frame_size = pkt->data[2];748	req_data->ref_frame_num = pkt->data[3];749	req_data->act_buf_size = pkt->data[4];750	req_data->act_buf_num = 1;751}752 753int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)754{755	if (!pkt || !data)756		return -EINVAL;757 758	switch (pkt->hdr.id) {759	case VID_API_ENC_EVENT_FRAME_DONE:760		vpu_windsor_unpack_pic_info(pkt, data);761		break;762	case VID_API_ENC_EVENT_MEM_REQUEST:763		vpu_windsor_unpack_mem_req(pkt, data);764		break;765	case VID_API_ENC_EVENT_FRAME_RELEASE:766		*(u32 *)data = pkt->data[0];767		break;768	default:769		break;770	}771 772	return 0;773}774 775static int vpu_windsor_fill_yuv_frame(struct vpu_shared_addr *shared,776				      u32 instance,777				      struct vb2_buffer *vb)778{779	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);780	struct vpu_format *out_fmt;781	struct vpu_enc_yuv_desc *desc;782	struct vb2_v4l2_buffer *vbuf;783 784	if (instance >= VID_API_NUM_STREAMS)785		return -EINVAL;786 787	desc = get_yuv_desc(shared, instance);788	out_fmt = vpu_get_format(inst, vb->type);789 790	vbuf = to_vb2_v4l2_buffer(vb);791	desc->frame_id = vbuf->sequence;792	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)793		desc->key_frame = 1;794	else795		desc->key_frame = 0;796	desc->luma_base = vpu_get_vb_phy_addr(vb, 0);797	if (vb->num_planes > 1)798		desc->chroma_base = vpu_get_vb_phy_addr(vb, 1);799	else800		desc->chroma_base = desc->luma_base + out_fmt->sizeimage[0];801 802	return 0;803}804 805int vpu_windsor_input_frame(struct vpu_shared_addr *shared,806			    struct vpu_inst *inst, struct vb2_buffer *vb)807{808	vpu_windsor_fill_yuv_frame(shared, inst->id, vb);809	return vpu_session_encode_frame(inst, vb->timestamp);810}811 812int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,813				       u32 instance,814				       u32 type,815				       u32 index,816				       struct vpu_buffer *buf)817{818	struct vpu_enc_mem_pool *pool;819	struct vpu_enc_memory_resource *res;820 821	if (instance >= VID_API_NUM_STREAMS)822		return -EINVAL;823 824	pool = get_mem_pool(shared, instance);825 826	switch (type) {827	case MEM_RES_ENC:828		if (index >= ARRAY_SIZE(pool->enc_frames))829			return -EINVAL;830		res = &pool->enc_frames[index];831		break;832	case MEM_RES_REF:833		if (index >= ARRAY_SIZE(pool->ref_frames))834			return -EINVAL;835		res = &pool->ref_frames[index];836		break;837	case MEM_RES_ACT:838		if (index)839			return -EINVAL;840		res = &pool->act_frame;841		break;842	default:843		return -EINVAL;844	}845 846	res->phys = buf->phys;847	res->virt = buf->phys - shared->boot_addr;848	res->size = buf->length;849 850	return 0;851}852 853int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,854				     u32 instance,855				     struct vpu_buffer *buf)856{857	struct vpu_rpc_buffer_desc *desc;858	struct vpu_enc_expert_mode_param *expert;859 860	desc = get_stream_buf_desc(shared, instance);861	expert = get_expert_param(shared, instance);862 863	desc->start = buf->phys;864	desc->wptr = buf->phys;865	desc->rptr = buf->phys;866	desc->end = buf->phys + buf->length;867 868	expert->calib_param.mem_chunk_phys_addr = 0;869	expert->calib_param.mem_chunk_virt_addr = 0;870	expert->calib_param.mem_chunk_size = 0;871	expert->calib_param.cb_base = buf->phys;872	expert->calib_param.cb_size = buf->length;873 874	return 0;875}876 877int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,878				     u32 instance, u32 ptr, bool write)879{880	struct vpu_rpc_buffer_desc *desc;881 882	desc = get_stream_buf_desc(shared, instance);883 884	/*update wptr/rptr after data is written or read*/885	mb();886	if (write)887		desc->wptr = ptr;888	else889		desc->rptr = ptr;890 891	return 0;892}893 894int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,895				       u32 instance, struct vpu_rpc_buffer_desc *desc)896{897	struct vpu_rpc_buffer_desc *rpc_desc;898 899	rpc_desc = get_stream_buf_desc(shared, instance);900	if (desc) {901		desc->wptr = get_ptr(rpc_desc->wptr);902		desc->rptr = get_ptr(rpc_desc->rptr);903		desc->start = get_ptr(rpc_desc->start);904		desc->end = get_ptr(rpc_desc->end);905	}906 907	return 0;908}909 910u32 vpu_windsor_get_version(struct vpu_shared_addr *shared)911{912	struct windsor_iface *iface = shared->iface;913 914	return iface->fw_version;915}916 917static int vpu_windsor_set_frame_rate(struct vpu_enc_expert_mode_param *expert,918				      struct vpu_encode_params *params)919{920	expert->config_param.frame_rate_num = params->frame_rate.numerator;921	expert->config_param.frame_rate_den = params->frame_rate.denominator;922 923	return 0;924}925 926static int vpu_windsor_set_format(struct vpu_enc_param *param, u32 pixelformat)927{928	switch (pixelformat) {929	case V4L2_PIX_FMT_H264:930		param->codec_mode = MEDIAIP_ENC_FMT_H264;931		break;932	default:933		return -EINVAL;934	}935 936	return 0;937}938 939static int vpu_windsor_set_profile(struct vpu_enc_param *param, u32 profile)940{941	switch (profile) {942	case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:943		param->profile = MEDIAIP_ENC_PROF_H264_BP;944		break;945	case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:946		param->profile = MEDIAIP_ENC_PROF_H264_MP;947		break;948	case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:949		param->profile = MEDIAIP_ENC_PROF_H264_HP;950		break;951	default:952		return -EINVAL;953	}954 955	return 0;956}957 958static const u32 h264_level[] = {959	[V4L2_MPEG_VIDEO_H264_LEVEL_1_0] = 10,960	[V4L2_MPEG_VIDEO_H264_LEVEL_1B]  = 14,961	[V4L2_MPEG_VIDEO_H264_LEVEL_1_1] = 11,962	[V4L2_MPEG_VIDEO_H264_LEVEL_1_2] = 12,963	[V4L2_MPEG_VIDEO_H264_LEVEL_1_3] = 13,964	[V4L2_MPEG_VIDEO_H264_LEVEL_2_0] = 20,965	[V4L2_MPEG_VIDEO_H264_LEVEL_2_1] = 21,966	[V4L2_MPEG_VIDEO_H264_LEVEL_2_2] = 22,967	[V4L2_MPEG_VIDEO_H264_LEVEL_3_0] = 30,968	[V4L2_MPEG_VIDEO_H264_LEVEL_3_1] = 31,969	[V4L2_MPEG_VIDEO_H264_LEVEL_3_2] = 32,970	[V4L2_MPEG_VIDEO_H264_LEVEL_4_0] = 40,971	[V4L2_MPEG_VIDEO_H264_LEVEL_4_1] = 41,972	[V4L2_MPEG_VIDEO_H264_LEVEL_4_2] = 42,973	[V4L2_MPEG_VIDEO_H264_LEVEL_5_0] = 50,974	[V4L2_MPEG_VIDEO_H264_LEVEL_5_1] = 51975};976 977static int vpu_windsor_set_level(struct vpu_enc_param *param, u32 level)978{979	if (level >= ARRAY_SIZE(h264_level))980		return -EINVAL;981 982	param->level = h264_level[level];983 984	return 0;985}986 987static int vpu_windsor_set_size(struct vpu_enc_param *windsor,988				struct vpu_encode_params *params)989{990	windsor->src_stride = params->src_stride;991	windsor->src_width = params->src_width;992	windsor->src_height = params->src_height;993	windsor->src_offset_x = params->crop.left;994	windsor->src_offset_y = params->crop.top;995	windsor->src_crop_width = params->crop.width;996	windsor->src_crop_height = params->crop.height;997	windsor->out_width = params->out_width;998	windsor->out_height = params->out_height;999 1000	return 0;1001}1002 1003static int vpu_windsor_set_gop(struct vpu_enc_param *param, u32 gop)1004{1005	param->iframe_interval = gop;1006 1007	return 0;1008}1009 1010static int vpu_windsor_set_bframes(struct vpu_enc_param *param, u32 bframes)1011{1012	if (bframes) {1013		param->low_latency_mode = 0;1014		param->bframes = bframes;1015	} else {1016		param->low_latency_mode = 1;1017		param->bframes = 0;1018	}1019 1020	return 0;1021}1022 1023static int vpu_windsor_set_bitrate_mode(struct vpu_enc_param *param, u32 rc_enable, u32 mode)1024{1025	if (!rc_enable)1026		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP;1027	else if (mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)1028		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_VBR;1029	else1030		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CBR;1031 1032	return 0;1033}1034 1035static u32 vpu_windsor_bitrate(u32 bitrate)1036{1037	return DIV_ROUND_CLOSEST(bitrate, WINDSOR_BITRATE_UNIT);1038}1039 1040static int vpu_windsor_set_bitrate(struct vpu_enc_param *windsor,1041				   struct vpu_encode_params *params)1042{1043	windsor->target_bitrate = vpu_windsor_bitrate(params->bitrate);1044	windsor->min_bitrate = vpu_windsor_bitrate(params->bitrate_min);1045	windsor->max_bitrate = vpu_windsor_bitrate(params->bitrate_max);1046 1047	return 0;1048}1049 1050static int vpu_windsor_set_qp(struct vpu_enc_expert_mode_param *expert,1051			      struct vpu_encode_params *params)1052{1053	expert->static_param.rate_control_islice_qp = params->i_frame_qp;1054	expert->static_param.rate_control_pslice_qp = params->p_frame_qp;1055	expert->static_param.rate_control_bslice_qp = params->b_frame_qp;1056 1057	return 0;1058}1059 1060static int vpu_windsor_set_sar(struct vpu_enc_expert_mode_param *expert,1061			       struct vpu_encode_params *params)1062{1063	expert->config_param.h264_aspect_ratio_present = params->sar.enable;1064	if (params->sar.idc == V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED)1065		expert->config_param.aspect_ratio = WINDSOR_H264_EXTENDED_SAR;1066	else1067		expert->config_param.aspect_ratio = params->sar.idc;1068	expert->config_param.h264_aspect_ratio_sar_width = params->sar.width;1069	expert->config_param.h264_aspect_ratio_sar_height = params->sar.height;1070 1071	return 0;1072}1073 1074static int vpu_windsor_set_color(struct vpu_enc_expert_mode_param *expert,1075				 struct vpu_encode_params *params)1076{1077	expert->config_param.h264_video_type_present = 1;1078	expert->config_param.h264_video_format = 5;1079	expert->config_param.h264_video_colour_descriptor = 1;1080	expert->config_param.h264_video_colour_primaries =1081		vpu_color_cvrt_primaries_v2i(params->color.primaries);1082	expert->config_param.h264_video_transfer_char =1083		vpu_color_cvrt_transfers_v2i(params->color.transfer);1084	expert->config_param.h264_video_matrix_coeff =1085		vpu_color_cvrt_matrix_v2i(params->color.matrix);1086	expert->config_param.h264_video_full_range =1087		vpu_color_cvrt_full_range_v2i(params->color.full_range);1088	return 0;1089}1090 1091static int vpu_windsor_update_bitrate(struct vpu_shared_addr *shared,1092				      u32 instance, struct vpu_encode_params *params)1093{1094	struct vpu_enc_param *windsor;1095	struct vpu_enc_expert_mode_param *expert;1096 1097	windsor = get_enc_param(shared, instance);1098	expert = get_expert_param(shared, instance);1099 1100	if (windsor->bitrate_mode != MEDIAIP_ENC_BITRATE_MODE_CBR)1101		return 0;1102	if (!params->rc_enable)1103		return 0;1104	if (vpu_windsor_bitrate(params->bitrate) == windsor->target_bitrate)1105		return 0;1106 1107	vpu_windsor_set_bitrate(windsor, params);1108	expert->static_param.rate_control_bitrate = windsor->target_bitrate;1109	expert->static_param.rate_control_bitrate_min = windsor->min_bitrate;1110	expert->static_param.rate_control_bitrate_max = windsor->max_bitrate;1111 1112	return 0;1113}1114 1115static int vpu_windsor_set_params(struct vpu_shared_addr *shared,1116				  u32 instance, struct vpu_encode_params *params)1117{1118	struct vpu_enc_param *windsor;1119	int ret;1120 1121	windsor = get_enc_param(shared, instance);1122 1123	if (params->input_format != V4L2_PIX_FMT_NV12 &&1124	    params->input_format != V4L2_PIX_FMT_NV12M)1125		return -EINVAL;1126 1127	ret = vpu_windsor_set_format(windsor, params->codec_format);1128	if (ret)1129		return ret;1130	vpu_windsor_set_profile(windsor, params->profile);1131	vpu_windsor_set_level(windsor, params->level);1132	vpu_windsor_set_size(windsor, params);1133	vpu_windsor_set_gop(windsor, params->gop_length);1134	vpu_windsor_set_bframes(windsor, params->bframes);1135	vpu_windsor_set_bitrate_mode(windsor, params->rc_enable, params->rc_mode);1136	vpu_windsor_set_bitrate(windsor, params);1137	windsor->init_slice_qp = params->i_frame_qp;1138 1139	if (!params->frame_rate.numerator)1140		return -EINVAL;1141	windsor->frame_rate = params->frame_rate.denominator / params->frame_rate.numerator;1142 1143	return 0;1144}1145 1146static int vpu_windsor_update_params(struct vpu_shared_addr *shared,1147				     u32 instance, struct vpu_encode_params *params)1148{1149	struct vpu_enc_expert_mode_param *expert;1150 1151	expert = get_expert_param(shared, instance);1152 1153	vpu_windsor_set_frame_rate(expert, params);1154	vpu_windsor_set_qp(expert, params);1155	vpu_windsor_set_sar(expert, params);1156	vpu_windsor_set_color(expert, params);1157	vpu_windsor_update_bitrate(shared, instance, params);1158	/*expert->config_param.iac_sc_threshold = 0;*/1159 1160	return 0;1161}1162 1163int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,1164				  u32 instance, struct vpu_encode_params *params, u32 update)1165{1166	if (!params)1167		return -EINVAL;1168 1169	if (!update)1170		return vpu_windsor_set_params(shared, instance, params);1171	else1172		return vpu_windsor_update_params(shared, instance, params);1173}1174 1175u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared)1176{1177	struct windsor_iface *iface = shared->iface;1178 1179	return iface->max_streams;1180}1181