File Index
Files and directories
Sign in
FILE

iris_hfi_gen2_command.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
   4 */
   5
   6#include <linux/bitfield.h>
   7
   8#include "iris_hfi_gen2.h"
   9#include "iris_hfi_gen2_packet.h"
  10
  11#define UNSPECIFIED_COLOR_FORMAT 5
  12#define NUM_SYS_INIT_PACKETS 8
  13
  14#define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \
  15	NUM_SYS_INIT_PACKETS * (sizeof(struct iris_hfi_packet) + sizeof(u32)))
  16
  17#define SYS_IFPC_PKT_SIZE (sizeof(struct iris_hfi_header) + \
  18	sizeof(struct iris_hfi_packet) + sizeof(u32))
  19
  20#define SYS_NO_PAYLOAD_PKT_SIZE (sizeof(struct iris_hfi_header) + \
  21	sizeof(struct iris_hfi_packet))
  22
  23static int iris_hfi_gen2_sys_init(struct iris_core *core)
  24{
  25	struct iris_hfi_header *hdr;
  26	int ret;
  27
  28	hdr = kzalloc(SYS_INIT_PKT_SIZE, GFP_KERNEL);
  29	if (!hdr)
  30		return -ENOMEM;
  31
  32	iris_hfi_gen2_packet_sys_init(core, hdr);
  33	ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
  34
  35	kfree(hdr);
  36
  37	return ret;
  38}
  39
  40static int iris_hfi_gen2_sys_image_version(struct iris_core *core)
  41{
  42	struct iris_hfi_header *hdr;
  43	int ret;
  44
  45	hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL);
  46	if (!hdr)
  47		return -ENOMEM;
  48
  49	iris_hfi_gen2_packet_image_version(core, hdr);
  50	ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
  51
  52	kfree(hdr);
  53
  54	return ret;
  55}
  56
  57static int iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core *core)
  58{
  59	struct iris_hfi_header *hdr;
  60	int ret;
  61
  62	hdr = kzalloc(SYS_IFPC_PKT_SIZE, GFP_KERNEL);
  63	if (!hdr)
  64		return -ENOMEM;
  65
  66	iris_hfi_gen2_packet_sys_interframe_powercollapse(core, hdr);
  67	ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
  68
  69	kfree(hdr);
  70
  71	return ret;
  72}
  73
  74static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core)
  75{
  76	struct iris_hfi_header *hdr;
  77	int ret;
  78
  79	hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL);
  80	if (!hdr)
  81		return -ENOMEM;
  82
  83	iris_hfi_gen2_packet_sys_pc_prep(core, hdr);
  84	ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
  85
  86	kfree(hdr);
  87
  88	return ret;
  89}
  90
  91static u32 iris_hfi_gen2_get_port(struct iris_inst *inst, u32 plane)
  92{
  93	if (inst->domain == DECODER) {
  94		switch (plane) {
  95		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  96			return HFI_PORT_BITSTREAM;
  97		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  98			return HFI_PORT_RAW;
  99		default:
 100			return HFI_PORT_NONE;
 101		}
 102	} else {
 103		switch (plane) {
 104		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 105			return HFI_PORT_RAW;
 106		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 107			return HFI_PORT_BITSTREAM;
 108		default:
 109			return HFI_PORT_NONE;
 110		}
 111	}
 112}
 113
 114static u32 iris_hfi_gen2_get_port_from_buf_type(struct iris_inst *inst,
 115						enum iris_buffer_type buffer_type)
 116{
 117	if (inst->domain == DECODER) {
 118		switch (buffer_type) {
 119		case BUF_INPUT:
 120		case BUF_BIN:
 121		case BUF_COMV:
 122		case BUF_NON_COMV:
 123		case BUF_LINE:
 124			return HFI_PORT_BITSTREAM;
 125		case BUF_OUTPUT:
 126		case BUF_DPB:
 127			return HFI_PORT_RAW;
 128		case BUF_PERSIST:
 129		default:
 130			return HFI_PORT_NONE;
 131		}
 132	} else {
 133		switch (buffer_type) {
 134		case BUF_INPUT:
 135		case BUF_VPSS:
 136			return HFI_PORT_RAW;
 137		case BUF_OUTPUT:
 138		case BUF_BIN:
 139		case BUF_COMV:
 140		case BUF_NON_COMV:
 141		case BUF_LINE:
 142		case BUF_SCRATCH_2:
 143			return HFI_PORT_BITSTREAM;
 144		case BUF_ARP:
 145		default:
 146			return HFI_PORT_NONE;
 147		}
 148	}
 149}
 150
 151static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag,
 152					      u32 plane, u32 payload_type, void *payload,
 153					      u32 payload_size)
 154{
 155	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 156
 157	iris_hfi_gen2_packet_session_property(inst,
 158					      packet_type,
 159					      flag,
 160					      plane,
 161					      payload_type,
 162					      payload,
 163					      payload_size);
 164
 165	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
 166					inst_hfi_gen2->packet->size);
 167}
 168
 169static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane)
 170{
 171	u32 resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
 172		inst->fmt_src->fmt.pix_mp.height;
 173	u32 port = iris_hfi_gen2_get_port(inst, plane);
 174
 175	return iris_hfi_gen2_session_set_property(inst,
 176						  HFI_PROP_RAW_RESOLUTION,
 177						  HFI_HOST_FLAGS_NONE,
 178						  port,
 179						  HFI_PAYLOAD_32_PACKED,
 180						  &resolution,
 181						  sizeof(u32));
 182}
 183
 184static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane)
 185{
 186	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 187	u32 port = iris_hfi_gen2_get_port(inst, plane);
 188	enum hfi_packet_payload_info payload_type;
 189	u32 resolution, codec_align;
 190
 191	if (inst->domain == DECODER) {
 192		resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
 193			inst->fmt_src->fmt.pix_mp.height;
 194		inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
 195		payload_type = HFI_PAYLOAD_U32;
 196	} else {
 197		codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
 198		resolution = ALIGN(inst->fmt_dst->fmt.pix_mp.width, codec_align) << 16 |
 199			ALIGN(inst->fmt_dst->fmt.pix_mp.height, codec_align);
 200		inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution;
 201		payload_type = HFI_PAYLOAD_32_PACKED;
 202	}
 203
 204	return iris_hfi_gen2_session_set_property(inst,
 205						  HFI_PROP_BITSTREAM_RESOLUTION,
 206						  HFI_HOST_FLAGS_NONE,
 207						  port,
 208						  payload_type,
 209						  &resolution,
 210						  sizeof(u32));
 211}
 212
 213static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane)
 214{
 215	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 216	u32 port = iris_hfi_gen2_get_port(inst, plane);
 217	u32 bottom_offset, right_offset;
 218	u32 left_offset, top_offset;
 219	u32 payload[2];
 220
 221	if (inst->domain == DECODER) {
 222		if (V4L2_TYPE_IS_OUTPUT(plane)) {
 223			bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
 224			right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
 225			left_offset = inst->crop.left;
 226			top_offset = inst->crop.top;
 227		} else {
 228			bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - inst->compose.height);
 229			right_offset = (inst->fmt_dst->fmt.pix_mp.width - inst->compose.width);
 230			left_offset = inst->compose.left;
 231			top_offset = inst->compose.top;
 232		}
 233	} else {
 234		bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
 235		right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
 236		left_offset = inst->crop.left;
 237		top_offset = inst->crop.top;
 238	}
 239
 240	payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset;
 241	payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset;
 242	inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0];
 243	inst_hfi_gen2->src_subcr_params.crop_offsets[1] = payload[1];
 244
 245	return iris_hfi_gen2_session_set_property(inst,
 246						  HFI_PROP_CROP_OFFSETS,
 247						  HFI_HOST_FLAGS_NONE,
 248						  port,
 249						  HFI_PAYLOAD_64_PACKED,
 250						  &payload,
 251						  sizeof(u64));
 252}
 253
 254static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst, u32 plane)
 255{
 256	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 257	u32 port = iris_hfi_gen2_get_port(inst, plane);
 258	u32 bitdepth = BIT_DEPTH_8;
 259
 260	inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth;
 261
 262	return iris_hfi_gen2_session_set_property(inst,
 263						  HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
 264						  HFI_HOST_FLAGS_NONE,
 265						  port,
 266						  HFI_PAYLOAD_U32,
 267						  &bitdepth,
 268						  sizeof(u32));
 269}
 270
 271static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst, u32 plane)
 272{
 273	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 274	u32 port = iris_hfi_gen2_get_port(inst, plane);
 275	u32 coded_frames = 0;
 276
 277	if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE)
 278		coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
 279	inst_hfi_gen2->src_subcr_params.coded_frames = coded_frames;
 280
 281	return iris_hfi_gen2_session_set_property(inst,
 282						  HFI_PROP_CODED_FRAMES,
 283						  HFI_HOST_FLAGS_NONE,
 284						  port,
 285						  HFI_PAYLOAD_U32,
 286						  &coded_frames,
 287						  sizeof(u32));
 288}
 289
 290static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst, u32 plane)
 291{
 292	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 293	u32 min_output = inst->buffers[BUF_OUTPUT].min_count;
 294	u32 port = iris_hfi_gen2_get_port(inst, plane);
 295
 296	inst_hfi_gen2->src_subcr_params.fw_min_count = min_output;
 297
 298	return iris_hfi_gen2_session_set_property(inst,
 299						  HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
 300						  HFI_HOST_FLAGS_NONE,
 301						  port,
 302						  HFI_PAYLOAD_U32,
 303						  &min_output,
 304						  sizeof(u32));
 305}
 306
 307static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst, u32 plane)
 308{
 309	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 310	u32 port = iris_hfi_gen2_get_port(inst, plane);
 311	u32 poc = 0;
 312
 313	inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc;
 314
 315	return iris_hfi_gen2_session_set_property(inst,
 316						  HFI_PROP_PIC_ORDER_CNT_TYPE,
 317						  HFI_HOST_FLAGS_NONE,
 318						  port,
 319						  HFI_PAYLOAD_U32,
 320						  &poc,
 321						  sizeof(u32));
 322}
 323
 324static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst, u32 plane)
 325{
 326	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 327	struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp;
 328	u32 video_signal_type_present_flag = 0, color_info;
 329	u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
 330	u32 video_format = UNSPECIFIED_COLOR_FORMAT;
 331	u32 full_range = V4L2_QUANTIZATION_DEFAULT;
 332	u32 transfer_char = HFI_TRANSFER_RESERVED;
 333	u32 port = iris_hfi_gen2_get_port(inst, plane);
 334	u32 colour_description_present_flag = 0;
 335	u32 primaries = HFI_PRIMARIES_RESERVED;
 336
 337	if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT ||
 338	    pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT ||
 339	    pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) {
 340		colour_description_present_flag = 1;
 341		video_signal_type_present_flag = 1;
 342		primaries = iris_hfi_gen2_get_color_primaries(pixmp->colorspace);
 343		matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc);
 344		transfer_char = iris_hfi_gen2_get_transfer_char(pixmp->xfer_func);
 345	}
 346
 347	if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) {
 348		video_signal_type_present_flag = 1;
 349		full_range = pixmp->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
 350	}
 351
 352	color_info = iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries,
 353						  colour_description_present_flag, full_range,
 354						  video_format, video_signal_type_present_flag);
 355
 356	inst_hfi_gen2->src_subcr_params.color_info = color_info;
 357
 358	return iris_hfi_gen2_session_set_property(inst,
 359						  HFI_PROP_SIGNAL_COLOR_INFO,
 360						  HFI_HOST_FLAGS_NONE,
 361						  port,
 362						  HFI_PAYLOAD_32_PACKED,
 363						  &color_info,
 364						  sizeof(u32));
 365}
 366
 367static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane)
 368{
 369	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 370	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 371	u32 profile = 0;
 372
 373	switch (inst->codec) {
 374	case V4L2_PIX_FMT_HEVC:
 375		profile = inst->fw_caps[PROFILE_HEVC].value;
 376		break;
 377	case V4L2_PIX_FMT_VP9:
 378		profile = inst->fw_caps[PROFILE_VP9].value;
 379		break;
 380	case V4L2_PIX_FMT_H264:
 381		profile = inst->fw_caps[PROFILE_H264].value;
 382		break;
 383	}
 384
 385	inst_hfi_gen2->src_subcr_params.profile = profile;
 386
 387	return iris_hfi_gen2_session_set_property(inst,
 388						  HFI_PROP_PROFILE,
 389						  HFI_HOST_FLAGS_NONE,
 390						  port,
 391						  HFI_PAYLOAD_U32_ENUM,
 392						  &profile,
 393						  sizeof(u32));
 394}
 395
 396static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane)
 397{
 398	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 399	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 400	u32 level = 0;
 401
 402	switch (inst->codec) {
 403	case V4L2_PIX_FMT_HEVC:
 404		level = inst->fw_caps[LEVEL_HEVC].value;
 405		break;
 406	case V4L2_PIX_FMT_VP9:
 407		level = inst->fw_caps[LEVEL_VP9].value;
 408		break;
 409	case V4L2_PIX_FMT_H264:
 410		level = inst->fw_caps[LEVEL_H264].value;
 411		break;
 412	}
 413
 414	inst_hfi_gen2->src_subcr_params.level = level;
 415
 416	return iris_hfi_gen2_session_set_property(inst,
 417						  HFI_PROP_LEVEL,
 418						  HFI_HOST_FLAGS_NONE,
 419						  port,
 420						  HFI_PAYLOAD_U32_ENUM,
 421						  &level,
 422						  sizeof(u32));
 423}
 424
 425static int iris_hfi_gen2_set_opb_enable(struct iris_inst *inst, u32 plane)
 426{
 427	u32 port = iris_hfi_gen2_get_port(inst, plane);
 428	u32 opb_enable = iris_split_mode_enabled(inst);
 429
 430	return iris_hfi_gen2_session_set_property(inst,
 431						  HFI_PROP_OPB_ENABLE,
 432						  HFI_HOST_FLAGS_NONE,
 433						  port,
 434						  HFI_PAYLOAD_U32,
 435						  &opb_enable,
 436						  sizeof(u32));
 437}
 438
 439static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane)
 440{
 441	u32 port = iris_hfi_gen2_get_port(inst, plane);
 442	u32 hfi_colorformat, pixelformat;
 443
 444	if (inst->domain == DECODER) {
 445		pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
 446		hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
 447			HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
 448	} else {
 449		pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
 450		hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
 451			HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
 452	}
 453
 454	return iris_hfi_gen2_session_set_property(inst,
 455						  HFI_PROP_COLOR_FORMAT,
 456						  HFI_HOST_FLAGS_NONE,
 457						  port,
 458						  HFI_PAYLOAD_U32_ENUM,
 459						  &hfi_colorformat,
 460						  sizeof(u32));
 461}
 462
 463static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 plane)
 464{
 465	u32 pixelformat, stride_y, stride_uv, scanline_y, scanline_uv;
 466	u32 port = iris_hfi_gen2_get_port(inst, plane);
 467	u32 payload[2];
 468
 469	if (inst->domain == DECODER) {
 470		pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
 471		stride_y = inst->fmt_dst->fmt.pix_mp.width;
 472		scanline_y = inst->fmt_dst->fmt.pix_mp.height;
 473	} else {
 474		pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
 475		stride_y = ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
 476		scanline_y = ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
 477	}
 478
 479	stride_uv = stride_y;
 480	scanline_uv = scanline_y / 2;
 481
 482	if (pixelformat != V4L2_PIX_FMT_NV12)
 483		return 0;
 484
 485	payload[0] = stride_y << 16 | scanline_y;
 486	payload[1] = stride_uv << 16 | scanline_uv;
 487
 488	return iris_hfi_gen2_session_set_property(inst,
 489						  HFI_PROP_LINEAR_STRIDE_SCANLINE,
 490						  HFI_HOST_FLAGS_NONE,
 491						  port,
 492						  HFI_PAYLOAD_64_PACKED,
 493						  &payload,
 494						  sizeof(u64));
 495}
 496
 497static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane)
 498{
 499	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 500	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 501	u32 tier = inst->fw_caps[TIER].value;
 502
 503	inst_hfi_gen2->src_subcr_params.tier = tier;
 504
 505	return iris_hfi_gen2_session_set_property(inst,
 506						  HFI_PROP_TIER,
 507						  HFI_HOST_FLAGS_NONE,
 508						  port,
 509						  HFI_PAYLOAD_U32_ENUM,
 510						  &tier,
 511						  sizeof(u32));
 512}
 513
 514static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane)
 515{
 516	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 517	u32 frame_rate = inst->frame_rate << 16;
 518
 519	return iris_hfi_gen2_session_set_property(inst,
 520						  HFI_PROP_FRAME_RATE,
 521						  HFI_HOST_FLAGS_NONE,
 522						  port,
 523						  HFI_PAYLOAD_Q16,
 524						  &frame_rate,
 525						  sizeof(u32));
 526}
 527
 528static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
 529{
 530	const struct iris_platform_data *pdata = inst->core->iris_platform_data;
 531	u32 config_params_size = 0, i, j;
 532	const u32 *config_params = NULL;
 533	int ret;
 534
 535	static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
 536		{HFI_PROP_RAW_RESOLUTION,             iris_hfi_gen2_set_raw_resolution         },
 537		{HFI_PROP_BITSTREAM_RESOLUTION,       iris_hfi_gen2_set_bitstream_resolution   },
 538		{HFI_PROP_CROP_OFFSETS,               iris_hfi_gen2_set_crop_offsets           },
 539		{HFI_PROP_CODED_FRAMES,               iris_hfi_gen2_set_coded_frames           },
 540		{HFI_PROP_LUMA_CHROMA_BIT_DEPTH,      iris_hfi_gen2_set_bit_depth              },
 541		{HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count       },
 542		{HFI_PROP_PIC_ORDER_CNT_TYPE,         iris_hfi_gen2_set_picture_order_count    },
 543		{HFI_PROP_SIGNAL_COLOR_INFO,          iris_hfi_gen2_set_colorspace             },
 544		{HFI_PROP_PROFILE,                    iris_hfi_gen2_set_profile                },
 545		{HFI_PROP_LEVEL,                      iris_hfi_gen2_set_level                  },
 546		{HFI_PROP_OPB_ENABLE,                 iris_hfi_gen2_set_opb_enable             },
 547		{HFI_PROP_COLOR_FORMAT,               iris_hfi_gen2_set_colorformat            },
 548		{HFI_PROP_LINEAR_STRIDE_SCANLINE,     iris_hfi_gen2_set_linear_stride_scanline },
 549		{HFI_PROP_TIER,                       iris_hfi_gen2_set_tier                   },
 550		{HFI_PROP_FRAME_RATE,                 iris_hfi_gen2_set_frame_rate             },
 551	};
 552
 553	if (inst->domain == DECODER) {
 554		if (V4L2_TYPE_IS_OUTPUT(plane)) {
 555			if (inst->codec == V4L2_PIX_FMT_H264) {
 556				config_params = pdata->dec_input_config_params_default;
 557				config_params_size = pdata->dec_input_config_params_default_size;
 558			} else if (inst->codec == V4L2_PIX_FMT_HEVC) {
 559				config_params = pdata->dec_input_config_params_hevc;
 560				config_params_size = pdata->dec_input_config_params_hevc_size;
 561			} else if (inst->codec == V4L2_PIX_FMT_VP9) {
 562				config_params = pdata->dec_input_config_params_vp9;
 563				config_params_size = pdata->dec_input_config_params_vp9_size;
 564			} else {
 565				return -EINVAL;
 566			}
 567		} else {
 568			config_params = pdata->dec_output_config_params;
 569			config_params_size = pdata->dec_output_config_params_size;
 570		}
 571	} else {
 572		if (V4L2_TYPE_IS_OUTPUT(plane)) {
 573			config_params = pdata->enc_input_config_params;
 574			config_params_size = pdata->enc_input_config_params_size;
 575		} else {
 576			config_params = pdata->enc_output_config_params;
 577			config_params_size = pdata->enc_output_config_params_size;
 578		}
 579	}
 580
 581	if (!config_params || !config_params_size)
 582		return -EINVAL;
 583
 584	for (i = 0; i < config_params_size; i++) {
 585		for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
 586			if (prop_type_handle_arr[j].type == config_params[i]) {
 587				ret = prop_type_handle_arr[j].handle(inst, plane);
 588				if (ret)
 589					return ret;
 590				break;
 591			}
 592		}
 593	}
 594
 595	return 0;
 596}
 597
 598static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
 599{
 600	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 601	u32 codec = 0;
 602
 603	switch (inst->codec) {
 604	case V4L2_PIX_FMT_H264:
 605		if (inst->domain == ENCODER)
 606			codec = HFI_CODEC_ENCODE_AVC;
 607		else
 608			codec = HFI_CODEC_DECODE_AVC;
 609		break;
 610	case V4L2_PIX_FMT_HEVC:
 611		if (inst->domain == ENCODER)
 612			codec = HFI_CODEC_ENCODE_HEVC;
 613		else
 614			codec = HFI_CODEC_DECODE_HEVC;
 615		break;
 616	case V4L2_PIX_FMT_VP9:
 617		codec = HFI_CODEC_DECODE_VP9;
 618	}
 619
 620	iris_hfi_gen2_packet_session_property(inst,
 621					      HFI_PROP_CODEC,
 622					      HFI_HOST_FLAGS_NONE,
 623					      HFI_PORT_NONE,
 624					      HFI_PAYLOAD_U32_ENUM,
 625					      &codec,
 626					      sizeof(u32));
 627
 628	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
 629					inst_hfi_gen2->packet->size);
 630}
 631
 632static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst)
 633{
 634	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 635	u32 default_header = false;
 636
 637	iris_hfi_gen2_packet_session_property(inst,
 638					      HFI_PROP_DEC_DEFAULT_HEADER,
 639					      HFI_HOST_FLAGS_NONE,
 640					      HFI_PORT_BITSTREAM,
 641					      HFI_PAYLOAD_U32,
 642					      &default_header,
 643					      sizeof(u32));
 644
 645	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
 646					inst_hfi_gen2->packet->size);
 647}
 648
 649static int iris_hfi_gen2_session_open(struct iris_inst *inst)
 650{
 651	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 652	int ret;
 653
 654	if (inst->state != IRIS_INST_DEINIT)
 655		return -EALREADY;
 656
 657	inst_hfi_gen2->ipsc_properties_set = false;
 658	inst_hfi_gen2->opsc_properties_set = false;
 659
 660	inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL);
 661	if (!inst_hfi_gen2->packet)
 662		return -ENOMEM;
 663
 664	iris_hfi_gen2_packet_session_command(inst,
 665					     HFI_CMD_OPEN,
 666					     HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 667					     HFI_HOST_FLAGS_INTR_REQUIRED,
 668					     HFI_PORT_NONE,
 669					     0,
 670					     HFI_PAYLOAD_U32,
 671					     &inst->session_id,
 672					     sizeof(u32));
 673
 674	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
 675				       inst_hfi_gen2->packet->size);
 676	if (ret)
 677		goto fail_free_packet;
 678
 679	ret = iris_hfi_gen2_session_set_codec(inst);
 680	if (ret)
 681		goto fail_free_packet;
 682
 683	if (inst->domain == DECODER) {
 684		ret = iris_hfi_gen2_session_set_default_header(inst);
 685		if (ret)
 686			goto fail_free_packet;
 687	}
 688
 689	return 0;
 690
 691fail_free_packet:
 692	kfree(inst_hfi_gen2->packet);
 693	inst_hfi_gen2->packet = NULL;
 694
 695	return ret;
 696}
 697
 698static int iris_hfi_gen2_session_close(struct iris_inst *inst)
 699{
 700	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 701	int ret;
 702
 703	if (!inst_hfi_gen2->packet)
 704		return -EINVAL;
 705
 706	iris_hfi_gen2_packet_session_command(inst,
 707					     HFI_CMD_CLOSE,
 708					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 709					     HFI_HOST_FLAGS_INTR_REQUIRED |
 710					     HFI_HOST_FLAGS_NON_DISCARDABLE),
 711					     HFI_PORT_NONE,
 712					     inst->session_id,
 713					     HFI_PAYLOAD_NONE,
 714					     NULL,
 715					     0);
 716
 717	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
 718				       inst_hfi_gen2->packet->size);
 719
 720	kfree(inst_hfi_gen2->packet);
 721	inst_hfi_gen2->packet = NULL;
 722
 723	return ret;
 724}
 725
 726static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
 727						u32 cmd, u32 plane, u32 payload_type,
 728						void *payload, u32 payload_size)
 729{
 730	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 731
 732	iris_hfi_gen2_packet_session_command(inst,
 733					     cmd,
 734					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 735					     HFI_HOST_FLAGS_INTR_REQUIRED),
 736					     iris_hfi_gen2_get_port(inst, plane),
 737					     inst->session_id,
 738					     payload_type,
 739					     payload,
 740					     payload_size);
 741
 742	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
 743					inst_hfi_gen2->packet->size);
 744}
 745
 746static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plane)
 747{
 748	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 749	struct hfi_subscription_params subsc_params;
 750	u32 prop_type, payload_size, payload_type;
 751	struct iris_core *core = inst->core;
 752	const u32 *change_param = NULL;
 753	u32 change_param_size = 0;
 754	u32 payload[32] = {0};
 755	u32 hfi_port = 0, i;
 756	int ret;
 757
 758	if (inst->domain == ENCODER)
 759		return 0;
 760
 761	if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
 762	    (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
 763		dev_err(core->dev, "invalid plane\n");
 764		return 0;
 765	}
 766
 767	switch (inst->codec) {
 768	case V4L2_PIX_FMT_H264:
 769		change_param = core->iris_platform_data->dec_input_config_params_default;
 770		change_param_size =
 771			core->iris_platform_data->dec_input_config_params_default_size;
 772		break;
 773	case V4L2_PIX_FMT_HEVC:
 774		change_param = core->iris_platform_data->dec_input_config_params_hevc;
 775		change_param_size =
 776			core->iris_platform_data->dec_input_config_params_hevc_size;
 777		break;
 778	case V4L2_PIX_FMT_VP9:
 779		change_param = core->iris_platform_data->dec_input_config_params_vp9;
 780		change_param_size =
 781			core->iris_platform_data->dec_input_config_params_vp9_size;
 782		break;
 783	}
 784
 785	payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
 786
 787	for (i = 0; i < change_param_size; i++)
 788		payload[i + 1] = change_param[i];
 789
 790	ret = iris_hfi_gen2_session_subscribe_mode(inst,
 791						   HFI_CMD_SUBSCRIBE_MODE,
 792						   plane,
 793						   HFI_PAYLOAD_U32_ARRAY,
 794						   &payload[0],
 795						   ((change_param_size + 1) * sizeof(u32)));
 796	if (ret)
 797		return ret;
 798
 799	if (V4L2_TYPE_IS_OUTPUT(plane)) {
 800		inst_hfi_gen2->ipsc_properties_set = true;
 801	} else {
 802		hfi_port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 803		memcpy(&inst_hfi_gen2->dst_subcr_params,
 804		       &inst_hfi_gen2->src_subcr_params,
 805		       sizeof(inst_hfi_gen2->src_subcr_params));
 806		subsc_params = inst_hfi_gen2->dst_subcr_params;
 807		for (i = 0; i < change_param_size; i++) {
 808			payload[0] = 0;
 809			payload[1] = 0;
 810			payload_size = 0;
 811			payload_type = 0;
 812			prop_type = change_param[i];
 813			switch (prop_type) {
 814			case HFI_PROP_BITSTREAM_RESOLUTION:
 815				payload[0] = subsc_params.bitstream_resolution;
 816				payload_size = sizeof(u32);
 817				payload_type = HFI_PAYLOAD_U32;
 818				break;
 819			case HFI_PROP_CROP_OFFSETS:
 820				payload[0] = subsc_params.crop_offsets[0];
 821				payload[1] = subsc_params.crop_offsets[1];
 822				payload_size = sizeof(u64);
 823				payload_type = HFI_PAYLOAD_64_PACKED;
 824				break;
 825			case HFI_PROP_CODED_FRAMES:
 826				payload[0] = subsc_params.coded_frames;
 827				payload_size = sizeof(u32);
 828				payload_type = HFI_PAYLOAD_U32;
 829				break;
 830			case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
 831				payload[0] = subsc_params.bit_depth;
 832				payload_size = sizeof(u32);
 833				payload_type = HFI_PAYLOAD_U32;
 834				break;
 835			case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
 836				payload[0] = subsc_params.fw_min_count;
 837				payload_size = sizeof(u32);
 838				payload_type = HFI_PAYLOAD_U32;
 839				break;
 840			case HFI_PROP_PIC_ORDER_CNT_TYPE:
 841				payload[0] = subsc_params.pic_order_cnt;
 842				payload_size = sizeof(u32);
 843				payload_type = HFI_PAYLOAD_U32;
 844				break;
 845			case HFI_PROP_SIGNAL_COLOR_INFO:
 846				payload[0] = subsc_params.color_info;
 847				payload_size = sizeof(u32);
 848				payload_type = HFI_PAYLOAD_U32;
 849				break;
 850			case HFI_PROP_PROFILE:
 851				payload[0] = subsc_params.profile;
 852				payload_size = sizeof(u32);
 853				payload_type = HFI_PAYLOAD_U32;
 854				break;
 855			case HFI_PROP_LEVEL:
 856				payload[0] = subsc_params.level;
 857				payload_size = sizeof(u32);
 858				payload_type = HFI_PAYLOAD_U32;
 859				break;
 860			case HFI_PROP_TIER:
 861				payload[0] = subsc_params.tier;
 862				payload_size = sizeof(u32);
 863				payload_type = HFI_PAYLOAD_U32;
 864				break;
 865			default:
 866				prop_type = 0;
 867				ret = -EINVAL;
 868				break;
 869			}
 870			if (prop_type) {
 871				ret = iris_hfi_gen2_session_set_property(inst,
 872									 prop_type,
 873									 HFI_HOST_FLAGS_NONE,
 874									 hfi_port,
 875									 payload_type,
 876									 &payload,
 877									 payload_size);
 878				if (ret)
 879					return ret;
 880			}
 881		}
 882		inst_hfi_gen2->opsc_properties_set = true;
 883	}
 884
 885	return 0;
 886}
 887
 888static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
 889{
 890	struct iris_core *core = inst->core;
 891	u32 subscribe_prop_size = 0, i;
 892	const u32 *subcribe_prop = NULL;
 893	u32 payload[32] = {0};
 894
 895	payload[0] = HFI_MODE_PROPERTY;
 896
 897	if (inst->domain == ENCODER)
 898		return 0;
 899
 900	if (V4L2_TYPE_IS_OUTPUT(plane)) {
 901		subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
 902		subcribe_prop = core->iris_platform_data->dec_input_prop;
 903	} else {
 904		switch (inst->codec) {
 905		case V4L2_PIX_FMT_H264:
 906			subcribe_prop = core->iris_platform_data->dec_output_prop_avc;
 907			subscribe_prop_size =
 908				core->iris_platform_data->dec_output_prop_avc_size;
 909			break;
 910		case V4L2_PIX_FMT_HEVC:
 911			subcribe_prop = core->iris_platform_data->dec_output_prop_hevc;
 912			subscribe_prop_size =
 913				core->iris_platform_data->dec_output_prop_hevc_size;
 914			break;
 915		case V4L2_PIX_FMT_VP9:
 916			subcribe_prop = core->iris_platform_data->dec_output_prop_vp9;
 917			subscribe_prop_size =
 918				core->iris_platform_data->dec_output_prop_vp9_size;
 919			break;
 920		}
 921	}
 922
 923	for (i = 0; i < subscribe_prop_size; i++)
 924		payload[i + 1] = subcribe_prop[i];
 925
 926	return iris_hfi_gen2_session_subscribe_mode(inst,
 927						    HFI_CMD_SUBSCRIBE_MODE,
 928						    plane,
 929						    HFI_PAYLOAD_U32_ARRAY,
 930						    &payload[0],
 931						    (subscribe_prop_size + 1) * sizeof(u32));
 932}
 933
 934static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
 935{
 936	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 937	int ret = 0;
 938
 939	ret = iris_hfi_gen2_subscribe_change_param(inst, plane);
 940	if (ret)
 941		return ret;
 942
 943	ret = iris_hfi_gen2_subscribe_property(inst, plane);
 944	if (ret)
 945		return ret;
 946
 947	iris_hfi_gen2_packet_session_command(inst,
 948					     HFI_CMD_START,
 949					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 950					     HFI_HOST_FLAGS_INTR_REQUIRED),
 951					     iris_hfi_gen2_get_port(inst, plane),
 952					     inst->session_id,
 953					     HFI_PAYLOAD_NONE,
 954					     NULL,
 955					     0);
 956
 957	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
 958					inst_hfi_gen2->packet->size);
 959}
 960
 961static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
 962{
 963	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 964	int ret = 0;
 965
 966	if (!inst_hfi_gen2->packet)
 967		return -EINVAL;
 968
 969	reinit_completion(&inst->completion);
 970
 971	iris_hfi_gen2_packet_session_command(inst,
 972					     HFI_CMD_STOP,
 973					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 974					     HFI_HOST_FLAGS_INTR_REQUIRED |
 975					     HFI_HOST_FLAGS_NON_DISCARDABLE),
 976					     iris_hfi_gen2_get_port(inst, plane),
 977					     inst->session_id,
 978					     HFI_PAYLOAD_NONE,
 979					     NULL,
 980					     0);
 981
 982	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
 983				       inst_hfi_gen2->packet->size);
 984	if (ret)
 985		return ret;
 986
 987	return iris_wait_for_session_response(inst, false);
 988}
 989
 990static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
 991{
 992	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
 993
 994	iris_hfi_gen2_packet_session_command(inst,
 995					     HFI_CMD_PAUSE,
 996					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 997					     HFI_HOST_FLAGS_INTR_REQUIRED),
 998					     iris_hfi_gen2_get_port(inst, plane),
 999					     inst->session_id,
1000					     HFI_PAYLOAD_NONE,
1001					     NULL,
1002					     0);
1003
1004	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1005					inst_hfi_gen2->packet->size);
1006}
1007
1008static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane)
1009{
1010	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1011	u32 payload = HFI_CMD_SETTINGS_CHANGE;
1012
1013	iris_hfi_gen2_packet_session_command(inst,
1014					     HFI_CMD_RESUME,
1015					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1016					     HFI_HOST_FLAGS_INTR_REQUIRED),
1017					     iris_hfi_gen2_get_port(inst, plane),
1018					     inst->session_id,
1019					     HFI_PAYLOAD_U32,
1020					     &payload,
1021					     sizeof(u32));
1022
1023	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1024					inst_hfi_gen2->packet->size);
1025}
1026
1027static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane)
1028{
1029	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1030	u32 payload = HFI_CMD_DRAIN;
1031
1032	iris_hfi_gen2_packet_session_command(inst,
1033					     HFI_CMD_RESUME,
1034					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1035					     HFI_HOST_FLAGS_INTR_REQUIRED),
1036					     iris_hfi_gen2_get_port(inst, plane),
1037					     inst->session_id,
1038					     HFI_PAYLOAD_U32,
1039					     &payload,
1040					     sizeof(u32));
1041
1042	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1043					inst_hfi_gen2->packet->size);
1044}
1045
1046static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
1047{
1048	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1049
1050	if (!V4L2_TYPE_IS_OUTPUT(plane))
1051		return 0;
1052
1053	iris_hfi_gen2_packet_session_command(inst,
1054					     HFI_CMD_DRAIN,
1055					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1056					     HFI_HOST_FLAGS_INTR_REQUIRED |
1057					     HFI_HOST_FLAGS_NON_DISCARDABLE),
1058					     iris_hfi_gen2_get_port(inst, plane),
1059					     inst->session_id,
1060					     HFI_PAYLOAD_NONE,
1061					     NULL,
1062					     0);
1063
1064	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1065					inst_hfi_gen2->packet->size);
1066}
1067
1068static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type buffer_type)
1069{
1070	switch (buffer_type) {
1071	case BUF_INPUT:
1072		if (domain == DECODER)
1073			return HFI_BUFFER_BITSTREAM;
1074		else
1075			return HFI_BUFFER_RAW;
1076	case BUF_OUTPUT:
1077		if (domain == DECODER)
1078			return HFI_BUFFER_RAW;
1079		else
1080			return HFI_BUFFER_BITSTREAM;
1081	case BUF_BIN:
1082		return HFI_BUFFER_BIN;
1083	case BUF_COMV:
1084		return HFI_BUFFER_COMV;
1085	case BUF_NON_COMV:
1086		return HFI_BUFFER_NON_COMV;
1087	case BUF_LINE:
1088		return HFI_BUFFER_LINE;
1089	case BUF_DPB:
1090	case BUF_SCRATCH_2:
1091		return HFI_BUFFER_DPB;
1092	case BUF_PERSIST:
1093		return HFI_BUFFER_PERSIST;
1094	case BUF_ARP:
1095		return HFI_BUFFER_ARP;
1096	case BUF_VPSS:
1097		return HFI_BUFFER_VPSS;
1098	default:
1099		return 0;
1100	}
1101}
1102
1103static int iris_set_num_comv(struct iris_inst *inst)
1104{
1105	struct platform_inst_caps *caps;
1106	struct iris_core *core = inst->core;
1107	u32 num_comv;
1108
1109	caps = core->iris_platform_data->inst_caps;
1110	num_comv = caps->num_comv;
1111
1112	return core->hfi_ops->session_set_property(inst,
1113						   HFI_PROP_COMV_BUFFER_COUNT,
1114						   HFI_HOST_FLAGS_NONE,
1115						   HFI_PORT_BITSTREAM,
1116						   HFI_PAYLOAD_U32,
1117						   &num_comv, sizeof(u32));
1118}
1119
1120static void iris_hfi_gen2_get_buffer(u32 domain, struct iris_buffer *buffer,
1121				     struct iris_hfi_buffer *buf)
1122{
1123	memset(buf, 0, sizeof(*buf));
1124	buf->type = iris_hfi_gen2_buf_type_from_driver(domain, buffer->type);
1125	buf->index = buffer->index;
1126	buf->base_address = buffer->device_addr;
1127	buf->addr_offset = 0;
1128	buf->buffer_size = buffer->buffer_size;
1129
1130	if (domain == DECODER && buffer->type == BUF_INPUT)
1131		buf->buffer_size = ALIGN(buffer->buffer_size, 256);
1132	buf->data_offset = buffer->data_offset;
1133	buf->data_size = buffer->data_size;
1134	if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
1135		buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
1136	buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
1137	buf->timestamp = buffer->timestamp;
1138}
1139
1140static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1141{
1142	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1143	struct iris_hfi_buffer hfi_buffer;
1144	u32 port;
1145	int ret;
1146
1147	iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
1148	if (buffer->type == BUF_COMV) {
1149		ret = iris_set_num_comv(inst);
1150		if (ret)
1151			return ret;
1152	}
1153
1154	port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
1155	iris_hfi_gen2_packet_session_command(inst,
1156					     HFI_CMD_BUFFER,
1157					     HFI_HOST_FLAGS_INTR_REQUIRED,
1158					     port,
1159					     inst->session_id,
1160					     HFI_PAYLOAD_STRUCTURE,
1161					     &hfi_buffer,
1162					     sizeof(hfi_buffer));
1163
1164	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1165					inst_hfi_gen2->packet->size);
1166}
1167
1168static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1169{
1170	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1171	struct iris_hfi_buffer hfi_buffer;
1172	u32 port;
1173
1174	iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
1175	hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
1176	port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
1177
1178	iris_hfi_gen2_packet_session_command(inst,
1179					     HFI_CMD_BUFFER,
1180					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1181					     HFI_HOST_FLAGS_INTR_REQUIRED),
1182					     port,
1183					     inst->session_id,
1184					     HFI_PAYLOAD_STRUCTURE,
1185					     &hfi_buffer,
1186					     sizeof(hfi_buffer));
1187
1188	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1189					inst_hfi_gen2->packet->size);
1190}
1191
1192static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
1193	.sys_init = iris_hfi_gen2_sys_init,
1194	.sys_image_version = iris_hfi_gen2_sys_image_version,
1195	.sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse,
1196	.sys_pc_prep = iris_hfi_gen2_sys_pc_prep,
1197	.session_open = iris_hfi_gen2_session_open,
1198	.session_set_config_params = iris_hfi_gen2_session_set_config_params,
1199	.session_set_property = iris_hfi_gen2_session_set_property,
1200	.session_start = iris_hfi_gen2_session_start,
1201	.session_queue_buf = iris_hfi_gen2_session_queue_buffer,
1202	.session_release_buf = iris_hfi_gen2_session_release_buffer,
1203	.session_pause = iris_hfi_gen2_session_pause,
1204	.session_resume_drc = iris_hfi_gen2_session_resume_drc,
1205	.session_stop = iris_hfi_gen2_session_stop,
1206	.session_drain = iris_hfi_gen2_session_drain,
1207	.session_resume_drain = iris_hfi_gen2_session_resume_drain,
1208	.session_close = iris_hfi_gen2_session_close,
1209};
1210
1211void iris_hfi_gen2_command_ops_init(struct iris_core *core)
1212{
1213	core->hfi_ops = &iris_hfi_gen2_command_ops;
1214}
1215
1216struct iris_inst *iris_hfi_gen2_get_instance(void)
1217{
1218	return (struct iris_inst *)kzalloc(sizeof(struct iris_inst_hfi_gen2), GFP_KERNEL);
1219}
~/ Read-only file preview.