File Index
Files and directories
Sign in
FILE

vpu_windsor.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/platform/amphion/vpu_windsor.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright 2020-2021 NXP
   4 */
   5
   6#include <linux/init.h>
   7#include <linux/interconnect.h>
   8#include <linux/ioctl.h>
   9#include <linux/list.h>
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/platform_device.h>
  13#include <linux/time64.h>
  14#include <media/videobuf2-v4l2.h>
  15#include <media/videobuf2-dma-contig.h>
  16#include "vpu.h"
  17#include "vpu_rpc.h"
  18#include "vpu_defs.h"
  19#include "vpu_helpers.h"
  20#include "vpu_cmds.h"
  21#include "vpu_v4l2.h"
  22#include "vpu_imx8q.h"
  23#include "vpu_windsor.h"
  24
  25#define CMD_SIZE				2560
  26#define MSG_SIZE				25600
  27#define WINDSOR_USER_DATA_WORDS			16
  28#define WINDSOR_MAX_SRC_FRAMES			0x6
  29#define WINDSOR_MAX_REF_FRAMES			0x3
  30#define WINDSOR_BITRATE_UNIT			1024
  31#define WINDSOR_H264_EXTENDED_SAR		255
  32
  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_RESERVED
  50};
  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_RESERVED
  65};
  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_FRAME
  73};
  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 mode
 211	u32 dsa_test_mode;              // Automated test mode for the DSA.
 212	u32 fme_test_mode;              // Automated test mode for the fme
 213	u32 cbr_row_mode;               //0: FW mode; 1: HW mode
 214	u32 windsor_mode;               //0: normal mode; 1: intra only mode; 2: intra+0MV mode
 215	u32 encode_mode;                // H264, VC1, MPEG2, DIVX
 216	u32 frame_width;                // display width
 217	u32 frame_height;               // display height
 218	u32 enc_frame_width;            // encoding width, should be 16-pix align
 219	u32 enc_frame_height;           // encoding height, should be 16-pix aligned
 220	u32 frame_rate_num;
 221	u32 frame_rate_den;
 222	u32 vi_field_source;
 223	u32 vi_frame_width;
 224	u32 vi_frame_height;
 225	u32 crop_frame_width;
 226	u32 crop_frame_height;
 227	u32 crop_x_start_posn;
 228	u32 crop_y_start_posn;
 229	u32 mode422;
 230	u32 mode_yuy2;
 231	u32 dsa_luma_en;
 232	u32 dsa_chroma_en;
 233	u32 dsa_ext_hfilt_en;
 234	u32 dsa_di_en;
 235	u32 dsa_di_top_ref;
 236	u32 dsa_vertf_disable;
 237	u32 dsa_disable_pwb;
 238	u32 dsa_hor_phase;
 239	u32 dsa_ver_phase;
 240	u32 dsa_iac_enable;
 241	u32 iac_sc_threshold;
 242	u32 iac_vm_threshold;
 243	u32 iac_skip_mode;
 244	u32 iac_grp_width;
 245	u32 iac_grp_height;
 246	u32 rate_control_mode;
 247	u32 rate_control_resolution;
 248	u32 buffer_size;
 249	u32 buffer_level_init;
 250	u32 buffer_I_bit_budget;
 251	u32 top_field_first;
 252	u32 intra_lum_qoffset;
 253	u32 intra_chr_qoffset;
 254	u32 inter_lum_qoffset;
 255	u32 inter_chr_qoffset;
 256	u32 use_def_scaling_mtx;
 257	u32 inter_8x8_enab;
 258	u32 inter_4x4_enab;
 259	u32 fme_enable_qpel;
 260	u32 fme_enable_hpel;
 261	u32 fme_nozeromv;
 262	u32 fme_predmv_en;
 263	u32 fme_pred_2mv4mv;
 264	u32 fme_smallsadthresh;
 265	u32 ame_en_lmvc;
 266	u32 ame_x_mult;
 267	u32 cme_enable_4mv;
 268	u32 cme_enable_1mv;
 269	u32 hme_enable_16x8mv;
 270	u32 hme_enable_8x16mv;
 271	u32 cme_mv_weight;
 272	u32 cme_mv_cost;
 273	u32 ame_mult_mv;
 274	u32 ame_shift_mv;
 275	u32 hme_forceto1mv_en;
 276	u32 hme_2mv_cost;
 277	u32 hme_pred_mode;
 278	u32 hme_sc_rnge;
 279	u32 hme_sw_rnge;
 280	u32 output_format;
 281	u32 timestamp_enab;
 282	u32 initial_pts_enab;
 283	u32 initial_pts;
 284};
 285
 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_NULL
 367};
 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_AP
 381};
 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  = 0x00000004
 387};
 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 type
 432	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	else
 795		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	else
 800		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	else
 889		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] = 51
 975};
 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	else
1030		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	else
1067		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	else
1172		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}
~/ Read-only file preview.