diff mbox series

[21/33] iris: vidc: hfi: Add packetization layer

Message ID 1690550624-14642-22-git-send-email-quic_vgarodia@quicinc.com (mailing list archive)
State Not Applicable
Headers show
Series Qualcomm video decoder/encoder driver | expand

Commit Message

Vikash Garodia July 28, 2023, 1:23 p.m. UTC
This implements hfi packets used to communicate the info
to/from firmware.

Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
---
 .../platform/qcom/iris/vidc/inc/hfi_command.h      | 190 ++++++
 .../media/platform/qcom/iris/vidc/inc/hfi_packet.h |  52 ++
 .../media/platform/qcom/iris/vidc/src/hfi_packet.c | 657 +++++++++++++++++++++
 3 files changed, 899 insertions(+)
 create mode 100644 drivers/media/platform/qcom/iris/vidc/inc/hfi_command.h
 create mode 100644 drivers/media/platform/qcom/iris/vidc/inc/hfi_packet.h
 create mode 100644 drivers/media/platform/qcom/iris/vidc/src/hfi_packet.c
diff mbox series

Patch

diff --git a/drivers/media/platform/qcom/iris/vidc/inc/hfi_command.h b/drivers/media/platform/qcom/iris/vidc/inc/hfi_command.h
new file mode 100644
index 0000000..5542e56
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/vidc/inc/hfi_command.h
@@ -0,0 +1,190 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __H_HFI_COMMAND_H__
+#define __H_HFI_COMMAND_H__
+
+//todo: DP: remove below headers
+#include <linux/bits.h>
+#include <linux/types.h>
+
+#define HFI_VIDEO_ARCH_LX               0x1
+
+struct hfi_header {
+	u32 size;
+	u32 session_id;
+	u32 header_id;
+	u32 reserved[4];
+	u32 num_packets;
+};
+
+struct hfi_packet {
+	u32 size;
+	u32 type;
+	u32 flags;
+	u32 payload_info;
+	u32 port;
+	u32 packet_id;
+	u32 reserved[2];
+};
+
+struct hfi_buffer {
+	u32 type;
+	u32 index;
+	u64 base_address;
+	u32 addr_offset;
+	u32 buffer_size;
+	u32 data_offset;
+	u32 data_size;
+	u64 timestamp;
+	u32 flags;
+	u32 reserved[5];
+};
+
+enum hfi_packet_host_flags {
+	HFI_HOST_FLAGS_NONE                = 0x00000000,
+	HFI_HOST_FLAGS_INTR_REQUIRED       = 0x00000001,
+	HFI_HOST_FLAGS_RESPONSE_REQUIRED   = 0x00000002,
+	HFI_HOST_FLAGS_NON_DISCARDABLE     = 0x00000004,
+	HFI_HOST_FLAGS_GET_PROPERTY        = 0x00000008,
+};
+
+enum hfi_packet_firmware_flags {
+	HFI_FW_FLAGS_NONE          = 0x00000000,
+	HFI_FW_FLAGS_SUCCESS       = 0x00000001,
+	HFI_FW_FLAGS_INFORMATION   = 0x00000002,
+	HFI_FW_FLAGS_SESSION_ERROR = 0x00000004,
+	HFI_FW_FLAGS_SYSTEM_ERROR  = 0x00000008,
+};
+
+enum hfi_packet_payload_info {
+	HFI_PAYLOAD_NONE      = 0x00000000,
+	HFI_PAYLOAD_U32       = 0x00000001,
+	HFI_PAYLOAD_S32       = 0x00000002,
+	HFI_PAYLOAD_U64       = 0x00000003,
+	HFI_PAYLOAD_S64       = 0x00000004,
+	HFI_PAYLOAD_STRUCTURE = 0x00000005,
+	HFI_PAYLOAD_BLOB      = 0x00000006,
+	HFI_PAYLOAD_STRING    = 0x00000007,
+	HFI_PAYLOAD_Q16       = 0x00000008,
+	HFI_PAYLOAD_U32_ENUM  = 0x00000009,
+	HFI_PAYLOAD_32_PACKED = 0x0000000a,
+	HFI_PAYLOAD_U32_ARRAY = 0x0000000b,
+	HFI_PAYLOAD_S32_ARRAY = 0x0000000c,
+	HFI_PAYLOAD_64_PACKED = 0x0000000d,
+};
+
+enum hfi_packet_port_type {
+	HFI_PORT_NONE      = 0x00000000,
+	HFI_PORT_BITSTREAM = 0x00000001,
+	HFI_PORT_RAW       = 0x00000002,
+};
+
+enum hfi_buffer_type {
+	HFI_BUFFER_BITSTREAM      = 0x00000001,
+	HFI_BUFFER_RAW            = 0x00000002,
+	HFI_BUFFER_METADATA       = 0x00000003,
+	HFI_BUFFER_SUBCACHE       = 0x00000004,
+	HFI_BUFFER_PARTIAL_DATA   = 0x00000005,
+	HFI_BUFFER_DPB            = 0x00000006,
+	HFI_BUFFER_BIN            = 0x00000007,
+	HFI_BUFFER_LINE           = 0x00000008,
+	HFI_BUFFER_ARP            = 0x00000009,
+	HFI_BUFFER_COMV           = 0x0000000A,
+	HFI_BUFFER_NON_COMV       = 0x0000000B,
+	HFI_BUFFER_PERSIST        = 0x0000000C,
+	HFI_BUFFER_VPSS           = 0x0000000D,
+};
+
+enum hfi_buffer_host_flags {
+	HFI_BUF_HOST_FLAG_NONE               = 0x00000000,
+	HFI_BUF_HOST_FLAG_RELEASE            = 0x00000001,
+	HFI_BUF_HOST_FLAG_READONLY           = 0x00000010,
+	HFI_BUF_HOST_FLAG_CODEC_CONFIG       = 0x00000100,
+	HFI_BUF_HOST_FLAGS_CB_NON_SECURE       = 0x00000200,
+	HFI_BUF_HOST_FLAGS_CB_SECURE_PIXEL     = 0x00000400,
+	HFI_BUF_HOST_FLAGS_CB_SECURE_BITSTREAM = 0x00000800,
+	HFI_BUF_HOST_FLAGS_CB_SECURE_NON_PIXEL = 0x00001000,
+	HFI_BUF_HOST_FLAGS_CB_NON_SECURE_PIXEL = 0x00002000,
+};
+
+enum hfi_buffer_firmware_flags {
+	HFI_BUF_FW_FLAG_NONE            = 0x00000000,
+	HFI_BUF_FW_FLAG_RELEASE_DONE    = 0x00000001,
+	HFI_BUF_FW_FLAG_READONLY        = 0x00000010,
+	HFI_BUF_FW_FLAG_CODEC_CONFIG    = 0x00000100,
+	HFI_BUF_FW_FLAG_LAST            = 0x10000000,
+	HFI_BUF_FW_FLAG_PSC_LAST        = 0x20000000,
+};
+
+enum hfi_metapayload_header_flags {
+	HFI_METADATA_FLAGS_NONE         = 0x00000000,
+	HFI_METADATA_FLAGS_TOP_FIELD    = 0x00000001,
+	HFI_METADATA_FLAGS_BOTTOM_FIELD = 0x00000002,
+};
+
+struct metabuf_header {
+	u32 count;
+	u32 size;
+	u32 version;
+	u32 reserved[5];
+};
+
+struct metapayload_header {
+	u32 type;
+	u32 size;
+	u32 version;
+	u32 offset;
+	u32 flags;
+	u32 reserved[3];
+};
+
+enum hfi_property_mode_type {
+	HFI_MODE_NONE                 = 0x00000000,
+	HFI_MODE_PORT_SETTINGS_CHANGE = 0x00000001,
+	HFI_MODE_PROPERTY             = 0x00000002,
+	HFI_MODE_METADATA             = 0x00000004,
+	HFI_MODE_DYNAMIC_METADATA     = 0x00000005,
+};
+
+enum hfi_reserve_type {
+	HFI_RESERVE_START = 0x1,
+	HFI_RESERVE_STOP  = 0x2,
+};
+
+#define HFI_CMD_BEGIN                                           0x01000000
+#define HFI_CMD_INIT                                            0x01000001
+#define HFI_CMD_POWER_COLLAPSE                                  0x01000002
+#define HFI_CMD_OPEN                                            0x01000003
+#define HFI_CMD_CLOSE                                           0x01000004
+#define HFI_CMD_START                                           0x01000005
+#define HFI_CMD_STOP                                            0x01000006
+#define HFI_CMD_DRAIN                                           0x01000007
+#define HFI_CMD_RESUME                                          0x01000008
+#define HFI_CMD_BUFFER                                          0x01000009
+#define HFI_CMD_DELIVERY_MODE                                   0x0100000A
+#define HFI_CMD_SUBSCRIBE_MODE                                  0x0100000B
+#define HFI_CMD_SETTINGS_CHANGE                                 0x0100000C
+
+#define HFI_SSR_TYPE_SW_ERR_FATAL       0x1
+#define HFI_SSR_TYPE_SW_DIV_BY_ZERO     0x2
+#define HFI_SSR_TYPE_CPU_WDOG_IRQ       0x3
+#define HFI_SSR_TYPE_NOC_ERROR          0x4
+#define HFI_BITMASK_HW_CLIENT_ID                        0x000000f0
+#define HFI_BITMASK_SSR_TYPE                            0x0000000f
+#define HFI_CMD_SSR                                             0x0100000D
+
+#define HFI_STABILITY_TYPE_VCODEC_HUNG        0x1
+#define HFI_STABILITY_TYPE_ENC_BUFFER_FULL    0x2
+#define HFI_BITMASK_STABILITY_TYPE                      0x0000000f
+#define HFI_CMD_STABILITY                                       0x0100000E
+
+#define HFI_CMD_RESERVE                                         0x0100000F
+#define HFI_CMD_FLUSH                                           0x01000010
+#define HFI_CMD_PAUSE                                           0x01000011
+#define HFI_CMD_END                                             0x01FFFFFF
+
+#endif //__H_HFI_COMMAND_H__
diff --git a/drivers/media/platform/qcom/iris/vidc/inc/hfi_packet.h b/drivers/media/platform/qcom/iris/vidc/inc/hfi_packet.h
new file mode 100644
index 0000000..dc19c85
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/vidc/inc/hfi_packet.h
@@ -0,0 +1,52 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _HFI_PACKET_H_
+#define _HFI_PACKET_H_
+
+#include "hfi_command.h"
+#include "hfi_property.h"
+#include "msm_vidc_core.h"
+#include "msm_vidc_inst.h"
+#include "msm_vidc_internal.h"
+
+u32 get_hfi_port(struct msm_vidc_inst *inst,
+		 enum msm_vidc_port_type port);
+u32 get_hfi_port_from_buffer_type(struct msm_vidc_inst *inst,
+				  enum msm_vidc_buffer_type buffer_type);
+u32 hfi_buf_type_from_driver(enum msm_vidc_domain_type domain,
+			     enum msm_vidc_buffer_type buffer_type);
+u32 hfi_buf_type_to_driver(enum msm_vidc_domain_type domain,
+			   enum hfi_buffer_type buffer_type,
+			   enum hfi_packet_port_type port_type);
+u32 get_hfi_codec(struct msm_vidc_inst *inst);
+u32 get_hfi_colorformat(struct msm_vidc_inst *inst,
+			enum msm_vidc_colorformat_type colorformat);
+int get_hfi_buffer(struct msm_vidc_inst *inst,
+		   struct msm_vidc_buffer *buffer, struct hfi_buffer *buf);
+int hfi_create_header(u8 *packet, u32 packet_size,
+		      u32 session_id, u32 header_id);
+int hfi_create_packet(u8 *packet, u32 packet_size,
+		      u32 pkt_type, u32 pkt_flags, u32 payload_type, u32 port,
+		      u32 packet_id, void *payload, u32 payload_size);
+int hfi_create_buffer(u8 *packet, u32 packet_size, u32 *offset,
+		      enum msm_vidc_domain_type domain,
+		      struct msm_vidc_buffer *data);
+int hfi_packet_sys_init(struct msm_vidc_core *core,
+			u8 *pkt, u32 pkt_size);
+int hfi_packet_image_version(struct msm_vidc_core *core,
+			     u8 *pkt, u32 pkt_size);
+int hfi_packet_sys_pc_prep(struct msm_vidc_core *core,
+			   u8 *pkt, u32 pkt_size);
+int hfi_packet_sys_debug_config(struct msm_vidc_core *core, u8 *pkt,
+				u32 pkt_size, u32 debug_config);
+int hfi_packet_session_command(struct msm_vidc_inst *inst, u32 pkt_type,
+			       u32 flags, u32 port, u32 session_id,
+			       u32 payload_type, void *payload, u32 payload_size);
+int hfi_packet_sys_intraframe_powercollapse(struct msm_vidc_core *core, u8 *pkt,
+					    u32 pkt_size, u32 enable);
+
+#endif // _HFI_PACKET_H_
diff --git a/drivers/media/platform/qcom/iris/vidc/src/hfi_packet.c b/drivers/media/platform/qcom/iris/vidc/src/hfi_packet.c
new file mode 100644
index 0000000..2cf777c
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/vidc/src/hfi_packet.c
@@ -0,0 +1,657 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "hfi_packet.h"
+#include "msm_vidc_core.h"
+#include "msm_vidc_debug.h"
+#include "msm_vidc_driver.h"
+#include "msm_vidc_inst.h"
+#include "msm_vidc_platform.h"
+
+u32 get_hfi_port(struct msm_vidc_inst *inst,
+		 enum msm_vidc_port_type port)
+{
+	u32 hfi_port = HFI_PORT_NONE;
+
+	if (is_decode_session(inst)) {
+		switch (port) {
+		case INPUT_PORT:
+			hfi_port = HFI_PORT_BITSTREAM;
+			break;
+		case OUTPUT_PORT:
+			hfi_port = HFI_PORT_RAW;
+			break;
+		default:
+			i_vpr_e(inst, "%s: invalid port type %d\n",
+				__func__, port);
+			break;
+		}
+	} else if (is_encode_session(inst)) {
+		switch (port) {
+		case INPUT_PORT:
+			hfi_port = HFI_PORT_RAW;
+			break;
+		case OUTPUT_PORT:
+			hfi_port = HFI_PORT_BITSTREAM;
+			break;
+		default:
+			i_vpr_e(inst, "%s: invalid port type %d\n",
+				__func__, port);
+			break;
+		}
+	} else {
+		i_vpr_e(inst, "%s: invalid domain %#x\n",
+			__func__, inst->domain);
+	}
+
+	return hfi_port;
+}
+
+u32 get_hfi_port_from_buffer_type(struct msm_vidc_inst *inst,
+				  enum msm_vidc_buffer_type buffer_type)
+{
+	u32 hfi_port = HFI_PORT_NONE;
+
+	if (is_decode_session(inst)) {
+		switch (buffer_type) {
+		case MSM_VIDC_BUF_INPUT:
+		case MSM_VIDC_BUF_BIN:
+		case MSM_VIDC_BUF_COMV:
+		case MSM_VIDC_BUF_NON_COMV:
+		case MSM_VIDC_BUF_LINE:
+			hfi_port = HFI_PORT_BITSTREAM;
+			break;
+		case MSM_VIDC_BUF_OUTPUT:
+		case MSM_VIDC_BUF_DPB:
+			hfi_port = HFI_PORT_RAW;
+			break;
+		case MSM_VIDC_BUF_PERSIST:
+			hfi_port = HFI_PORT_NONE;
+			break;
+		default:
+			i_vpr_e(inst, "%s: invalid buffer type %d\n",
+				__func__, buffer_type);
+			break;
+		}
+	} else if (is_encode_session(inst)) {
+		switch (buffer_type) {
+		case MSM_VIDC_BUF_INPUT:
+		case MSM_VIDC_BUF_VPSS:
+			hfi_port = HFI_PORT_RAW;
+			break;
+		case MSM_VIDC_BUF_OUTPUT:
+		case MSM_VIDC_BUF_BIN:
+		case MSM_VIDC_BUF_COMV:
+		case MSM_VIDC_BUF_NON_COMV:
+		case MSM_VIDC_BUF_LINE:
+		case MSM_VIDC_BUF_DPB:
+			hfi_port = HFI_PORT_BITSTREAM;
+			break;
+		case MSM_VIDC_BUF_ARP:
+			hfi_port = HFI_PORT_NONE;
+			break;
+		default:
+			i_vpr_e(inst, "%s: invalid buffer type %d\n",
+				__func__, buffer_type);
+			break;
+		}
+	} else {
+		i_vpr_e(inst, "%s: invalid domain %#x\n",
+			__func__, inst->domain);
+	}
+
+	return hfi_port;
+}
+
+u32 hfi_buf_type_from_driver(enum msm_vidc_domain_type domain,
+			     enum msm_vidc_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case MSM_VIDC_BUF_INPUT:
+		if (domain == MSM_VIDC_DECODER)
+			return HFI_BUFFER_BITSTREAM;
+		else
+			return HFI_BUFFER_RAW;
+	case MSM_VIDC_BUF_OUTPUT:
+		if (domain == MSM_VIDC_DECODER)
+			return HFI_BUFFER_RAW;
+		else
+			return HFI_BUFFER_BITSTREAM;
+	case MSM_VIDC_BUF_BIN:
+		return HFI_BUFFER_BIN;
+	case MSM_VIDC_BUF_ARP:
+		return HFI_BUFFER_ARP;
+	case MSM_VIDC_BUF_COMV:
+		return HFI_BUFFER_COMV;
+	case MSM_VIDC_BUF_NON_COMV:
+		return HFI_BUFFER_NON_COMV;
+	case MSM_VIDC_BUF_LINE:
+		return HFI_BUFFER_LINE;
+	case MSM_VIDC_BUF_DPB:
+		return HFI_BUFFER_DPB;
+	case MSM_VIDC_BUF_PERSIST:
+		return HFI_BUFFER_PERSIST;
+	case MSM_VIDC_BUF_VPSS:
+		return HFI_BUFFER_VPSS;
+	default:
+		d_vpr_e("invalid buffer type %d\n",
+			buffer_type);
+		return 0;
+	}
+}
+
+u32 hfi_buf_type_to_driver(enum msm_vidc_domain_type domain,
+			   enum hfi_buffer_type buffer_type,
+			   enum hfi_packet_port_type port_type)
+{
+	switch (buffer_type) {
+	case HFI_BUFFER_BITSTREAM:
+		if (domain == MSM_VIDC_DECODER)
+			return MSM_VIDC_BUF_INPUT;
+		else
+			return MSM_VIDC_BUF_OUTPUT;
+	case HFI_BUFFER_RAW:
+		if (domain == MSM_VIDC_DECODER)
+			return MSM_VIDC_BUF_OUTPUT;
+		else
+			return MSM_VIDC_BUF_INPUT;
+	case HFI_BUFFER_BIN:
+		return MSM_VIDC_BUF_BIN;
+	case HFI_BUFFER_ARP:
+		return MSM_VIDC_BUF_ARP;
+	case HFI_BUFFER_COMV:
+		return MSM_VIDC_BUF_COMV;
+	case HFI_BUFFER_NON_COMV:
+		return MSM_VIDC_BUF_NON_COMV;
+	case HFI_BUFFER_LINE:
+		return MSM_VIDC_BUF_LINE;
+	case HFI_BUFFER_DPB:
+		return MSM_VIDC_BUF_DPB;
+	case HFI_BUFFER_PERSIST:
+		return MSM_VIDC_BUF_PERSIST;
+	case HFI_BUFFER_VPSS:
+		return MSM_VIDC_BUF_VPSS;
+	default:
+		d_vpr_e("invalid buffer type %d\n",
+			buffer_type);
+		return 0;
+	}
+}
+
+u32 get_hfi_codec(struct msm_vidc_inst *inst)
+{
+	switch (inst->codec) {
+	case MSM_VIDC_H264:
+		if (is_encode_session(inst))
+			return HFI_CODEC_ENCODE_AVC;
+		else
+			return HFI_CODEC_DECODE_AVC;
+	case MSM_VIDC_HEVC:
+		if (is_encode_session(inst))
+			return HFI_CODEC_ENCODE_HEVC;
+		else
+			return HFI_CODEC_DECODE_HEVC;
+	case MSM_VIDC_VP9:
+		return HFI_CODEC_DECODE_VP9;
+	default:
+		i_vpr_e(inst, "invalid codec %d, domain %d\n",
+			inst->codec, inst->domain);
+		return 0;
+	}
+}
+
+u32 get_hfi_colorformat(struct msm_vidc_inst *inst,
+			enum msm_vidc_colorformat_type colorformat)
+{
+	u32 hfi_colorformat = HFI_COLOR_FMT_NV12_UBWC;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12:
+		hfi_colorformat = HFI_COLOR_FMT_NV12;
+		break;
+	case MSM_VIDC_FMT_NV12C:
+		hfi_colorformat = HFI_COLOR_FMT_NV12_UBWC;
+		break;
+	case MSM_VIDC_FMT_P010:
+		hfi_colorformat = HFI_COLOR_FMT_P010;
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		hfi_colorformat = HFI_COLOR_FMT_TP10_UBWC;
+		break;
+	case MSM_VIDC_FMT_RGBA8888:
+		hfi_colorformat = HFI_COLOR_FMT_RGBA8888;
+		break;
+	case MSM_VIDC_FMT_RGBA8888C:
+		hfi_colorformat = HFI_COLOR_FMT_RGBA8888_UBWC;
+		break;
+	case MSM_VIDC_FMT_NV21:
+		hfi_colorformat = HFI_COLOR_FMT_NV21;
+		break;
+	default:
+		i_vpr_e(inst, "%s: invalid colorformat %d\n",
+			__func__, colorformat);
+		break;
+	}
+
+	return hfi_colorformat;
+}
+
+static u32 get_hfi_region_flag(enum msm_vidc_buffer_region region)
+{
+	switch (region) {
+	case MSM_VIDC_NON_SECURE:
+		return HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
+	case MSM_VIDC_NON_SECURE_PIXEL:
+		return HFI_BUF_HOST_FLAGS_CB_NON_SECURE_PIXEL;
+	case MSM_VIDC_SECURE_PIXEL:
+		return HFI_BUF_HOST_FLAGS_CB_SECURE_PIXEL;
+	case MSM_VIDC_SECURE_NONPIXEL:
+		return HFI_BUF_HOST_FLAGS_CB_SECURE_NON_PIXEL;
+	case MSM_VIDC_SECURE_BITSTREAM:
+		return HFI_BUF_HOST_FLAGS_CB_SECURE_BITSTREAM;
+	case MSM_VIDC_REGION_MAX:
+	case MSM_VIDC_REGION_NONE:
+	default:
+		return HFI_BUF_HOST_FLAG_NONE;
+	}
+}
+
+int get_hfi_buffer(struct msm_vidc_inst *inst,
+		   struct msm_vidc_buffer *buffer, struct hfi_buffer *buf)
+{
+	memset(buf, 0, sizeof(struct hfi_buffer));
+	buf->type = hfi_buf_type_from_driver(inst->domain, buffer->type);
+	buf->index = buffer->index;
+	buf->base_address = buffer->device_addr;
+	buf->addr_offset = 0;
+	buf->buffer_size = buffer->buffer_size;
+	/*
+	 * for decoder input buffers, firmware (BSE HW) needs 256 aligned
+	 * buffer size otherwise it will truncate or ignore the data after 256
+	 * aligned size which may lead to error concealment
+	 */
+	if (is_decode_session(inst) && is_input_buffer(buffer->type))
+		buf->buffer_size = ALIGN(buffer->buffer_size, 256);
+	buf->data_offset = buffer->data_offset;
+	buf->data_size = buffer->data_size;
+	if (buffer->attr & MSM_VIDC_ATTR_READ_ONLY)
+		buf->flags |= HFI_BUF_HOST_FLAG_READONLY;
+	if (buffer->attr & MSM_VIDC_ATTR_PENDING_RELEASE)
+		buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
+	buf->flags |= get_hfi_region_flag(buffer->region);
+	buf->timestamp = buffer->timestamp;
+
+	return 0;
+}
+
+int hfi_create_header(u8 *packet, u32 packet_size, u32 session_id,
+		      u32 header_id)
+{
+	struct hfi_header *hdr = (struct hfi_header *)packet;
+
+	if (!packet || packet_size < sizeof(struct hfi_header)) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(hdr, 0, sizeof(struct hfi_header));
+
+	hdr->size = sizeof(struct hfi_header);
+	hdr->session_id = session_id;
+	hdr->header_id = header_id;
+	hdr->num_packets = 0;
+	return 0;
+}
+
+int hfi_create_packet(u8 *packet, u32 packet_size, u32 pkt_type,
+		      u32 pkt_flags, u32 payload_type, u32 port,
+		      u32 packet_id, void *payload, u32 payload_size)
+{
+	struct hfi_header *hdr;
+	struct hfi_packet *pkt;
+	u32 pkt_size;
+
+	if (!packet) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	hdr = (struct hfi_header *)packet;
+	if (hdr->size < sizeof(struct hfi_header)) {
+		d_vpr_e("%s: invalid hdr size %d\n", __func__, hdr->size);
+		return -EINVAL;
+	}
+	pkt = (struct hfi_packet *)(packet + hdr->size);
+	pkt_size = sizeof(struct hfi_packet) + payload_size;
+	if (packet_size < hdr->size  + pkt_size) {
+		d_vpr_e("%s: invalid packet_size %d, %d %d\n",
+			__func__, packet_size, hdr->size, pkt_size);
+		return -EINVAL;
+	}
+	memset(pkt, 0, pkt_size);
+	pkt->size = pkt_size;
+	pkt->type = pkt_type;
+	pkt->flags = pkt_flags;
+	pkt->payload_info = payload_type;
+	pkt->port = port;
+	pkt->packet_id = packet_id;
+	if (payload_size)
+		memcpy((u8 *)pkt + sizeof(struct hfi_packet),
+		       payload, payload_size);
+
+	hdr->num_packets++;
+	hdr->size += pkt->size;
+	return 0;
+}
+
+int hfi_packet_sys_init(struct msm_vidc_core *core,
+			u8 *pkt, u32 pkt_size)
+{
+	int rc = 0;
+	u32 payload = 0;
+
+	rc = hfi_create_header(pkt, pkt_size,
+			       0 /*session_id*/,
+			       core->header_id++);
+	if (rc)
+		goto err_sys_init;
+
+	/* HFI_CMD_SYSTEM_INIT */
+	payload = HFI_VIDEO_ARCH_LX;
+	d_vpr_h("%s: arch %d\n", __func__, payload);
+	core->sys_init_id = core->packet_id++;
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_CMD_INIT,
+			       (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+			       HFI_HOST_FLAGS_INTR_REQUIRED |
+			       HFI_HOST_FLAGS_NON_DISCARDABLE),
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->sys_init_id,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_sys_init;
+
+	/* HFI_PROP_UBWC_MAX_CHANNELS */
+	payload = core->platform->data.ubwc_config->max_channels;
+	d_vpr_h("%s: ubwc max channels %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_UBWC_MAX_CHANNELS,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_sys_init;
+
+	/* HFI_PROP_UBWC_MAL_LENGTH */
+	payload = core->platform->data.ubwc_config->mal_length;
+	d_vpr_h("%s: ubwc mal length %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_UBWC_MAL_LENGTH,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_sys_init;
+
+	/* HFI_PROP_UBWC_HBB */
+	payload = core->platform->data.ubwc_config->highest_bank_bit;
+	d_vpr_h("%s: ubwc hbb %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_UBWC_HBB,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_sys_init;
+
+	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL1 */
+	payload = core->platform->data.ubwc_config->bank_swzl_level;
+	d_vpr_h("%s: ubwc swzl1 %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_UBWC_BANK_SWZL_LEVEL1,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_sys_init;
+
+	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL2 */
+	payload = core->platform->data.ubwc_config->bank_swz2_level;
+	d_vpr_h("%s: ubwc swzl2 %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_UBWC_BANK_SWZL_LEVEL2,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_sys_init;
+
+	/* HFI_PROP_UBWC_BANK_SWZL_LEVEL3 */
+	payload = core->platform->data.ubwc_config->bank_swz3_level;
+	d_vpr_h("%s: ubwc swzl3 %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_UBWC_BANK_SWZL_LEVEL3,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_sys_init;
+
+	/* HFI_PROP_UBWC_BANK_SPREADING */
+	payload = core->platform->data.ubwc_config->bank_spreading;
+	d_vpr_h("%s: ubwc bank spreading %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_UBWC_BANK_SPREADING,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_sys_init;
+
+	d_vpr_h("System init packet created\n");
+	return rc;
+
+err_sys_init:
+	d_vpr_e("%s: create packet failed\n", __func__);
+	return rc;
+}
+
+int hfi_packet_image_version(struct msm_vidc_core *core,
+			     u8 *pkt, u32 pkt_size)
+{
+	int rc = 0;
+
+	rc = hfi_create_header(pkt, pkt_size,
+			       0 /*session_id*/,
+			       core->header_id++);
+	if (rc)
+		goto err_img_version;
+
+	/* HFI_PROP_IMAGE_VERSION */
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_IMAGE_VERSION,
+			       (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+			       HFI_HOST_FLAGS_INTR_REQUIRED |
+			       HFI_HOST_FLAGS_GET_PROPERTY),
+			       HFI_PAYLOAD_NONE,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       NULL, 0);
+	if (rc)
+		goto err_img_version;
+
+	d_vpr_h("Image version packet created\n");
+	return rc;
+
+err_img_version:
+	d_vpr_e("%s: create packet failed\n", __func__);
+	return rc;
+}
+
+int hfi_packet_sys_pc_prep(struct msm_vidc_core *core,
+			   u8 *pkt, u32 pkt_size)
+{
+	int rc = 0;
+
+	rc = hfi_create_header(pkt, pkt_size,
+			       0 /*session_id*/,
+			       core->header_id++);
+	if (rc)
+		goto err_sys_pc;
+
+	/* HFI_CMD_POWER_COLLAPSE */
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_CMD_POWER_COLLAPSE,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_NONE,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       NULL, 0);
+	if (rc)
+		goto err_sys_pc;
+
+	d_vpr_h("Power collapse packet created\n");
+	return rc;
+
+err_sys_pc:
+	d_vpr_e("%s: create packet failed\n", __func__);
+	return rc;
+}
+
+int hfi_packet_sys_debug_config(struct msm_vidc_core *core,
+				u8 *pkt, u32 pkt_size, u32 debug_config)
+{
+	int rc = 0;
+	u32 payload = 0;
+
+	rc = hfi_create_header(pkt, pkt_size,
+			       0 /*session_id*/,
+			       core->header_id++);
+	if (rc)
+		goto err_debug;
+
+	/* HFI_PROP_DEBUG_CONFIG */
+	payload = 0; /*TODO:Change later*/
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_DEBUG_CONFIG,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32_ENUM,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_debug;
+
+	/* HFI_PROP_DEBUG_LOG_LEVEL */
+	payload = debug_config; /*TODO:Change later*/
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_DEBUG_LOG_LEVEL,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32_ENUM,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err_debug;
+
+err_debug:
+	if (rc)
+		d_vpr_e("%s: create packet failed\n", __func__);
+
+	return rc;
+}
+
+int hfi_packet_session_command(struct msm_vidc_inst *inst, u32 pkt_type,
+			       u32 flags, u32 port, u32 session_id,
+			       u32 payload_type, void *payload, u32 payload_size)
+{
+	int rc = 0;
+	struct msm_vidc_core *core;
+
+	core = inst->core;
+
+	rc = hfi_create_header(inst->packet, inst->packet_size,
+			       session_id, core->header_id++);
+	if (rc)
+		goto err_cmd;
+
+	rc = hfi_create_packet(inst->packet,
+			       inst->packet_size,
+			       pkt_type,
+			       flags,
+			       payload_type,
+			       port,
+			       core->packet_id++,
+			       payload,
+			       payload_size);
+	if (rc)
+		goto err_cmd;
+
+	i_vpr_h(inst, "Command packet 0x%x created\n", pkt_type);
+	return rc;
+
+err_cmd:
+	i_vpr_e(inst, "%s: create packet failed\n", __func__);
+	return rc;
+}
+
+int hfi_packet_sys_intraframe_powercollapse(struct msm_vidc_core *core,
+					    u8 *pkt, u32 pkt_size, u32 enable)
+{
+	int rc = 0;
+	u32 payload = 0;
+
+	rc = hfi_create_header(pkt, pkt_size,
+			       0 /*session_id*/,
+			       core->header_id++);
+	if (rc)
+		goto err;
+
+	/* HFI_PROP_INTRA_FRAME_POWER_COLLAPSE */
+	payload = enable;
+	d_vpr_h("%s: intra frame power collapse %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+			       HFI_PROP_INTRA_FRAME_POWER_COLLAPSE,
+			       HFI_HOST_FLAGS_NONE,
+			       HFI_PAYLOAD_U32,
+			       HFI_PORT_NONE,
+			       core->packet_id++,
+			       &payload,
+			       sizeof(u32));
+	if (rc)
+		goto err;
+
+	d_vpr_h("IFPC packet created\n");
+	return rc;
+
+err:
+	d_vpr_e("%s: create packet failed\n", __func__);
+	return rc;
+}