diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index ba04c8a19a..7de13f1e0f 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -58,6 +58,7 @@ static struct msm_platform_core_capability core_data_waipio[] = { {MAX_MBPS_HQ, 489600}, /* ((1920x1088)/256)@60fps */ {MAX_MBPF_B_FRAME, 32640}, /* 3840x2176/256 */ {MAX_MBPS_B_FRAME, 1958400}, /* 3840x2176/256 MBs@60fps */ + {NUM_VPP_PIPE, 4}, {SW_PC, 1}, {SW_PC_DELAY, 1500}, /* 1500 ms */ {FW_UNLOAD, 0}, @@ -97,17 +98,15 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { {FRAME_HEIGHT, ENC|DEC, CODECS_ALL, 128, 8192, 1, 1080}, {PIX_FMTS, ENC, CODECS_ALL, MSM_VIDC_FMT_NV12, - MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, + MSM_VIDC_FMT_NV12_TP10_UBWC, MSM_VIDC_FMT_NV12 | MSM_VIDC_FMT_NV21 | MSM_VIDC_FMT_NV12_UBWC | - MSM_VIDC_FMT_NV12_P010_UBWC | MSM_VIDC_FMT_NV12_TP10_UBWC | - MSM_VIDC_FMT_RGBA8888_UBWC | MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, + MSM_VIDC_FMT_NV12_P010 | MSM_VIDC_FMT_NV12_TP10_UBWC, MSM_VIDC_FMT_NV12_UBWC}, {PIX_FMTS, DEC, CODECS_ALL, MSM_VIDC_FMT_NV12, - MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, + MSM_VIDC_FMT_NV12_TP10_UBWC, MSM_VIDC_FMT_NV12 | MSM_VIDC_FMT_NV21 | MSM_VIDC_FMT_NV12_UBWC | - MSM_VIDC_FMT_NV12_P010_UBWC | MSM_VIDC_FMT_NV12_TP10_UBWC | - MSM_VIDC_FMT_RGBA8888_UBWC | MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, + MSM_VIDC_FMT_NV12_P010 | MSM_VIDC_FMT_NV12_TP10_UBWC, MSM_VIDC_FMT_NV12_UBWC}, {MIN_BUFFERS_INPUT, ENC|DEC, CODECS_ALL, 0, 64, 1, 4, V4L2_CID_MIN_BUFFERS_FOR_OUTPUT}, diff --git a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c index 7218968bd8..427f2184b7 100644 --- a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c @@ -8,6 +8,7 @@ #include "msm_vidc_buffer.h" #include "msm_vidc_inst.h" #include "msm_vidc_core.h" +#include "msm_vidc_platform.h" #include "msm_vidc_driver.h" #include "msm_vidc_debug.h" @@ -1001,27 +1002,36 @@ static u32 calculate_mpeg2d_persist1_size(void) return QMATRIX_SIZE + MP2D_QPDUMP_SIZE; } -/* encoder internal buffers */ +/* decoder internal buffers */ u32 msm_vidc_decoder_scratch_size_iris2(struct msm_vidc_inst *inst) { + struct msm_vidc_core *core; u32 size = 0; u32 width, height, num_vpp_pipes; struct v4l2_format *f; bool is_interlaced; u32 vpp_delay; - d_vpr_h("%s()\n", __func__); - if (!inst) { + if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return size; } + core = inst->core; - num_vpp_pipes = 0; - vpp_delay = 0; + if (!core->capabilities) { + d_vpr_e("%s: invalid capabilities\n", __func__); + return size; + } + + num_vpp_pipes = core->capabilities[NUM_VPP_PIPE].value; + if (inst->decode_vpp_delay.enable) + vpp_delay = inst->decode_vpp_delay.size; + else + vpp_delay = DEFAULT_BSE_VPP_DELAY; is_interlaced = false; //(inst->pic_struct == MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED); f = &inst->fmts[INPUT_PORT]; - width = f->fmt.pix.width; - height = f->fmt.pix.height; + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; if (inst->codec == MSM_VIDC_H264) { size = calculate_h264d_scratch_size(inst, width, height, @@ -1042,22 +1052,31 @@ u32 msm_vidc_decoder_scratch_size_iris2(struct msm_vidc_inst *inst) u32 msm_vidc_decoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) { + struct msm_vidc_core *core; u32 size = 0; u32 width, height, out_min_count, num_vpp_pipes; struct v4l2_format *f; u32 vpp_delay; - d_vpr_h("%s()\n", __func__); - if (!inst) { + if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return size; } + core = inst->core; - num_vpp_pipes = 0; - vpp_delay = 0; + if (!core->capabilities) { + d_vpr_e("%s: invalid capabilities\n", __func__); + return size; + } + + num_vpp_pipes = core->capabilities[NUM_VPP_PIPE].value; + if (inst->decode_vpp_delay.enable) + vpp_delay = inst->decode_vpp_delay.size; + else + vpp_delay = DEFAULT_BSE_VPP_DELAY; f = &inst->fmts[INPUT_PORT]; - width = f->fmt.pix.width; - height = f->fmt.pix.height; + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; out_min_count = inst->buffers.output.min_count; out_min_count = max(vpp_delay + 1, out_min_count); @@ -1108,6 +1127,7 @@ u32 msm_vidc_decoder_persist_1_size_iris2(struct msm_vidc_inst *inst) /* encoder internal buffers */ u32 msm_vidc_encoder_scratch_size_iris2(struct msm_vidc_inst *inst) { + struct msm_vidc_core *core; u32 size = 0; u32 width, height, num_vpp_pipes; struct v4l2_format *f; @@ -1116,11 +1136,17 @@ u32 msm_vidc_encoder_scratch_size_iris2(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params\n", __func__); return size; } + core = inst->core; - num_vpp_pipes = 4; //inst->core->platform_data->num_vpp_pipes; + if (!core->capabilities) { + d_vpr_e("%s: invalid capabilities\n", __func__); + return size; + } + + num_vpp_pipes = core->capabilities[NUM_VPP_PIPE].value; f = &inst->fmts[OUTPUT_PORT]; - width = f->fmt.pix.width; - height = f->fmt.pix.height; + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; if (inst->codec == MSM_VIDC_H264) { size = calculate_h264e_scratch_size(inst, width, height, @@ -1137,6 +1163,7 @@ u32 msm_vidc_encoder_scratch_size_iris2(struct msm_vidc_inst *inst) u32 msm_vidc_encoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) { + struct msm_vidc_core *core; u32 size = 0; u32 width, height, num_ref, num_vpp_pipes; bool is_tenbit = false; @@ -1146,11 +1173,17 @@ u32 msm_vidc_encoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) d_vpr_e("%s: Instance is null!", __func__); return size; } + core = inst->core; - num_vpp_pipes = 4; //inst->core->platform_data->num_vpp_pipes; + if (!core->capabilities) { + d_vpr_e("%s: invalid capabilities\n", __func__); + return size; + } + + num_vpp_pipes = core->capabilities[NUM_VPP_PIPE].value; f = &inst->fmts[OUTPUT_PORT]; - width = f->fmt.pix.width; - height = f->fmt.pix.height; + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; num_ref = 4; //msm_vidc_get_num_ref_frames(inst); is_tenbit = false; //(inst->bit_depth == MSM_VIDC_BIT_DEPTH_10); @@ -1177,8 +1210,8 @@ u32 msm_vidc_encoder_scratch_2_size_iris2(struct msm_vidc_inst *inst) } f = &inst->fmts[OUTPUT_PORT]; - width = f->fmt.pix.width; - height = f->fmt.pix.height; + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; num_ref = 4; //msm_vidc_get_num_ref_frames(inst); is_tenbit = false; //(inst->bit_depth == MSM_VIDC_BIT_DEPTH_10); diff --git a/driver/vidc/inc/hfi_command.h b/driver/vidc/inc/hfi_command.h index a5246bef5a..3eb5621572 100644 --- a/driver/vidc/inc/hfi_command.h +++ b/driver/vidc/inc/hfi_command.h @@ -102,6 +102,11 @@ enum hfi_buffer_firmware_flags { HFI_BUF_FW_FLAG_LAST = BIT(0), HFI_BUF_FW_FLAG_READONLY = BIT(1), HFI_BUF_FW_FLAG_CODEC_CONFIG = BIT(2), + // TODO + HFI_BUF_FW_FLAG_SUBFRAME = BIT(3), + HFI_BUF_FW_FLAG_KEYFRAME = BIT(4), + HFI_BUF_FW_FLAG_CORRUPT = BIT(28), + HFI_BUF_FW_FLAG_UNSUPPORTED = BIT(29), }; enum hfi_metapayload_header_flags { diff --git a/driver/vidc/inc/hfi_packet.h b/driver/vidc/inc/hfi_packet.h index fb867d6e5a..843806b727 100644 --- a/driver/vidc/inc/hfi_packet.h +++ b/driver/vidc/inc/hfi_packet.h @@ -20,6 +20,8 @@ u32 get_hfi_port_from_buffer_type(struct msm_vidc_inst *inst, u32 get_hfi_buffer_type(enum msm_vidc_domain_type domain, enum msm_vidc_buffer_type buffer_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, @@ -41,7 +43,4 @@ int hfi_packet_sys_debug_config(struct msm_vidc_core *core, 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_session_property(struct msm_vidc_inst *inst, - u32 pkt_type, u32 flags, u32 port, - u32 payload_type, void *payload, u32 payload_size); #endif // _HFI_PACKET_H_ diff --git a/driver/vidc/inc/msm_vidc_bus.h b/driver/vidc/inc/msm_vidc_bus.h index 28d7b4c8de..91005e0464 100644 --- a/driver/vidc/inc/msm_vidc_bus.h +++ b/driver/vidc/inc/msm_vidc_bus.h @@ -236,7 +236,7 @@ static inline int __bpp(enum msm_vidc_colorformat_type f) case MSM_VIDC_FMT_NV12_UBWC: case MSM_VIDC_FMT_RGBA8888_UBWC: return 8; - case MSM_VIDC_FMT_NV12_P010_UBWC: + case MSM_VIDC_FMT_NV12_P010: case MSM_VIDC_FMT_NV12_TP10_UBWC: return 10; default: diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index a508f419a3..e950655c0e 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -70,11 +70,16 @@ void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, struct msm_vidc_buffer *vbuf); void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst, struct vb2_buffer *vb2); -enum msm_vidc_codec_type v4l2_codec_to_driver(u32 v4l2_codec); -u32 v4l2_codec_from_driver(enum msm_vidc_codec_type codec); -u32 v4l2_colorformat_to_media(u32 v4l2_fmt); -enum msm_vidc_colorformat_type v4l2_colorformat_to_driver(u32 colorformat); -u32 v4l2_colorformat_from_driver(enum msm_vidc_colorformat_type colorformat); +enum msm_vidc_codec_type v4l2_codec_to_driver(u32 v4l2_codec, + const char *func); +u32 v4l2_codec_from_driver(enum msm_vidc_codec_type codec, + const char *func); +u32 v4l2_colorformat_to_media(u32 v4l2_fmt, + const char *func); +enum msm_vidc_colorformat_type v4l2_colorformat_to_driver(u32 colorformat, + const char *func); +u32 v4l2_colorformat_from_driver(enum msm_vidc_colorformat_type colorformat, + const char *func); int v4l2_type_to_driver_port(struct msm_vidc_inst *inst, u32 type, const char *func); int msm_vidc_change_inst_state(struct msm_vidc_inst *inst, @@ -85,6 +90,9 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type); int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type); +int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf); +int msm_vidc_remove_session(struct msm_vidc_inst *inst); int msm_vidc_add_session(struct msm_vidc_inst *inst); int msm_vidc_session_open(struct msm_vidc_inst *inst); int msm_vidc_session_set_codec(struct msm_vidc_inst *inst); diff --git a/driver/vidc/inc/msm_vidc_dt.h b/driver/vidc/inc/msm_vidc_dt.h index efee355ecb..823116923d 100644 --- a/driver/vidc/inc/msm_vidc_dt.h +++ b/driver/vidc/inc/msm_vidc_dt.h @@ -138,6 +138,7 @@ struct clock_info { u32 count; bool has_scaling; bool has_mem_retention; + u64 prev; }; struct clock_set { diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index b548a7bb3d..4294bfc9f1 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -95,6 +95,8 @@ struct msm_vidc_inst { struct vb2_queue vb2q[MAX_PORT]; struct msm_vidc_crop crop; struct msm_vidc_properties prop; + enum msm_vidc_stage_type stage; + enum msm_vidc_pipe_type pipe; struct msm_vidc_power power; struct msm_vidc_buffers_info buffers; struct msm_vidc_mappings_info mappings; diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index 7f1d27ca32..88788dbe48 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -46,8 +46,8 @@ #define COLOR_RANGE_UNSPECIFIED (-1) #define V4L2_EVENT_VIDC_BASE 10 -#define INPUT_PLANE V4L2_BUF_TYPE_VIDEO_OUTPUT -#define OUTPUT_PLANE V4L2_BUF_TYPE_VIDEO_CAPTURE +#define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE +#define OUTPUT_MPLANE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE #define INPUT_META_PLANE V4L2_BUF_TYPE_META_OUTPUT #define OUTPUT_META_PLANE V4L2_BUF_TYPE_META_CAPTURE @@ -92,26 +92,40 @@ enum msm_vidc_codec_type { }; enum msm_vidc_colorformat_type { - MSM_VIDC_FMT_NV12 = BIT(0), - MSM_VIDC_FMT_NV21 = BIT(1), - MSM_VIDC_FMT_NV12_UBWC = BIT(2), - MSM_VIDC_FMT_NV12_P010_UBWC = BIT(3), - MSM_VIDC_FMT_NV12_TP10_UBWC = BIT(4), - MSM_VIDC_FMT_RGBA8888_UBWC = BIT(5), - MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS = BIT(6), + MSM_VIDC_FMT_NONE = 0, + MSM_VIDC_FMT_NV12, + MSM_VIDC_FMT_NV21, + MSM_VIDC_FMT_NV12_UBWC, + MSM_VIDC_FMT_NV12_P010, + MSM_VIDC_FMT_NV12_TP10_UBWC, + MSM_VIDC_FMT_RGBA8888, + MSM_VIDC_FMT_RGBA8888_UBWC, }; enum msm_vidc_buffer_type { - MSM_VIDC_BUF_QUEUE = BIT(0), - MSM_VIDC_BUF_INPUT = BIT(1), - MSM_VIDC_BUF_OUTPUT = BIT(2), - MSM_VIDC_BUF_INPUT_META = BIT(3), - MSM_VIDC_BUF_OUTPUT_META = BIT(4), - MSM_VIDC_BUF_SCRATCH = BIT(5), - MSM_VIDC_BUF_SCRATCH_1 = BIT(6), - MSM_VIDC_BUF_SCRATCH_2 = BIT(7), - MSM_VIDC_BUF_PERSIST = BIT(8), - MSM_VIDC_BUF_PERSIST_1 = BIT(9), + MSM_VIDC_BUF_NONE = 0, + MSM_VIDC_BUF_INPUT, + MSM_VIDC_BUF_OUTPUT, + MSM_VIDC_BUF_INPUT_META, + MSM_VIDC_BUF_OUTPUT_META, + MSM_VIDC_BUF_QUEUE, + MSM_VIDC_BUF_SCRATCH, + MSM_VIDC_BUF_SCRATCH_1, + MSM_VIDC_BUF_SCRATCH_2, + MSM_VIDC_BUF_PERSIST, + MSM_VIDC_BUF_PERSIST_1, +}; + +/* always match with v4l2 flags V4L2_BUF_FLAG_* */ +enum msm_vidc_buffer_flags { + MSM_VIDC_BUF_FLAG_KEYFRAME = 0x00000008, + MSM_VIDC_BUF_FLAG_PFRAME = 0x00000010, + MSM_VIDC_BUF_FLAG_BFRAME = 0x00000020, + MSM_VIDC_BUF_FLAG_ERROR = 0x00000040, + MSM_VIDC_BUF_FLAG_LAST = 0x00100000, + // TODO: remove below flags + MSM_VIDC_BUF_FLAG_CODECCONFIG = 0x01000000, + MSM_VIDC_BUF_FLAG_SUBFRAME = 0x02000000, }; enum msm_vidc_buffer_attributes { @@ -122,10 +136,11 @@ enum msm_vidc_buffer_attributes { }; enum msm_vidc_buffer_region { - MSM_VIDC_NON_SECURE = BIT(0), - MSM_VIDC_SECURE_PIXEL = BIT(1), - MSM_VIDC_SECURE_NONPIXEL = BIT(2), - MSM_VIDC_SECURE_BITSTREAM = BIT(3), + MSM_VIDC_REGION_NONE = 0, + MSM_VIDC_NON_SECURE, + MSM_VIDC_SECURE_PIXEL, + MSM_VIDC_SECURE_NONPIXEL, + MSM_VIDC_SECURE_BITSTREAM, }; enum msm_vidc_port_type { @@ -136,6 +151,19 @@ enum msm_vidc_port_type { MAX_PORT, }; +enum msm_vidc_stage_type { + MSM_VIDC_STAGE_NONE = 0, + MSM_VIDC_STAGE_1 = 1, + MSM_VIDC_STAGE_2 = 2, +}; + +enum msm_vidc_pipe_type { + MSM_VIDC_PIPE_NONE = 0, + MSM_VIDC_PIPE_1 = 1, + MSM_VIDC_PIPE_2 = 2, + MSM_VIDC_PIPE_4 = 4, +}; + enum msm_vidc_core_capability_type { CORE_CAP_NONE = 0, ENC_CODECS, @@ -149,6 +177,7 @@ enum msm_vidc_core_capability_type { MAX_MBPS_HQ, MAX_MBPF_B_FRAME, MAX_MBPS_B_FRAME, + NUM_VPP_PIPE, SW_PC, SW_PC_DELAY, FW_UNLOAD, diff --git a/driver/vidc/inc/venus_hfi.h b/driver/vidc/inc/venus_hfi.h index d50e8baf51..97eda798f9 100644 --- a/driver/vidc/inc/venus_hfi.h +++ b/driver/vidc/inc/venus_hfi.h @@ -35,7 +35,7 @@ struct vidc_buffer_addr_info { u32 extradata_size; u32 response_required; }; - +#if 0 struct hfi_resource_subcache_type { u32 size; u32 sc_id; @@ -45,7 +45,10 @@ struct hfi_resource_syscache_info_type { u32 num_entries; struct hfi_resource_subcache_type rg_subcache_entries[1]; }; - +#endif +int venus_hfi_session_property(struct msm_vidc_inst *inst, + u32 pkt_type, u32 flags, u32 port, + u32 payload_type, void *payload, u32 payload_size); int venus_hfi_queue_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buffer, struct msm_vidc_buffer *metabuf); int venus_hfi_release_buffer(struct msm_vidc_inst *inst, @@ -64,6 +67,10 @@ void venus_hfi_pm_work_handler(struct work_struct *work); void __write_register(struct msm_vidc_core *core, u32 reg, u32 value); int __read_register(struct msm_vidc_core *core, u32 reg); +int __iface_cmdq_write(struct msm_vidc_core *core, + void *pkt); +int __iface_msgq_read(struct msm_vidc_core *core, void *pkt); +int __iface_dbgq_read(struct msm_vidc_core *core, void *pkt); void __disable_unprepare_clks(struct msm_vidc_core *core); int __disable_regulators(struct msm_vidc_core *core); int __unvote_buses(struct msm_vidc_core *core); diff --git a/driver/vidc/src/hfi_packet.c b/driver/vidc/src/hfi_packet.c index afe81e3ca8..eb0c20a05d 100644 --- a/driver/vidc/src/hfi_packet.c +++ b/driver/vidc/src/hfi_packet.c @@ -154,6 +154,42 @@ u32 get_hfi_codec(struct msm_vidc_inst *inst) } } +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_NV12_UBWC: + hfi_colorformat = HFI_COLOR_FMT_NV12_UBWC; + break; + case MSM_VIDC_FMT_NV12_P010: + hfi_colorformat = HFI_COLOR_FMT_P010; + break; + case MSM_VIDC_FMT_NV12_TP10_UBWC: + hfi_colorformat = HFI_COLOR_FMT_TP10_UBWC; + break; + case MSM_VIDC_FMT_RGBA8888: + hfi_colorformat = HFI_COLOR_FMT_RGBA8888; + break; + case MSM_VIDC_FMT_RGBA8888_UBWC: + hfi_colorformat = HFI_COLOR_FMT_RGBA8888_UBWC; + break; + case MSM_VIDC_FMT_NV21: + hfi_colorformat = HFI_COLOR_FMT_NV21; + break; + default: + s_vpr_e(inst->sid, "%s: invalid colorformat %d\n", + __func__, colorformat); + break; + } + + return hfi_colorformat; +} + int get_hfi_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buffer, struct hfi_buffer *buf) { @@ -543,40 +579,3 @@ err_cmd: d_vpr_e("%s: create packet failed\n", __func__); return rc; } - -int hfi_packet_session_property(struct msm_vidc_inst *inst, - u32 pkt_type, u32 flags, u32 port, u32 payload_type, - void *payload, u32 payload_size) -{ - int rc = 0; - struct msm_vidc_core *core; - - if (!inst || !inst->core || !inst->packet) { - d_vpr_e("%s: Invalid params\n", __func__); - return -EINVAL; - } - core = inst->core; - - rc = hfi_create_header(inst->packet, inst->packet_size, - inst->session_id, core->header_id++); - if (rc) - goto err_prop; - - 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_prop; - - d_vpr_h("Property packet 0x%x created\n", pkt_type); - return rc; - -err_prop: - d_vpr_e("%s: create packet failed\n", __func__); - return rc; -} \ No newline at end of file diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index 412041348d..00851bf514 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -16,20 +16,363 @@ #include "venus_hfi.h" #include "hfi_packet.h" +u32 msm_vdec_subscribe_for_port_settings_change[] = { + HFI_PROP_ALIGN_RESOLUTION, + HFI_PROP_CROP_COORDINATE_TOP_LEFT, + HFI_PROP_CROP_RESOLUTION, + HFI_PROP_LUMA_CHROMA_BIT_DEPTH, + HFI_PROP_CABAC_SESSION, + HFI_PROP_CODED_FRAMES, + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, + HFI_PROP_PIC_ORDER_CNT_TYPE, + HFI_PROP_SIGNAL_COLOR_INFO, +}; + +u32 msm_vdec_subscribe_for_properties[] = { + HFI_PROP_TAG_NOT_PROPAGATED_TO_OUTPUT, +}; + +u32 msm_vdec_subscribe_for_metadata[] = { + HFI_PROP_TAG_NOT_PROPAGATED_TO_OUTPUT, +}; + +u32 msm_vdec_deliver_as_metadata[] = { + HFI_PROP_BUFFER_TAG, +}; + static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec) { int rc = 0; d_vpr_h("%s()\n", __func__); - inst->codec = v4l2_codec_to_driver(codec); + inst->codec = v4l2_codec_to_driver(codec, __func__); rc = msm_vidc_get_inst_capability(inst); - return rc; + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_resolution(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 resolution; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + resolution = inst->fmts[port].fmt.pix_mp.width << 16 | + inst->fmts[port].fmt.pix_mp.height; + rc = venus_hfi_session_property(inst, + HFI_PROP_ALIGN_RESOLUTION, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &resolution, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_crop_top_left(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 crop_top_left; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + crop_top_left = 0; + rc = venus_hfi_session_property(inst, + HFI_PROP_CROP_COORDINATE_TOP_LEFT, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &crop_top_left, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_crop_resolution(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 crop; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + /* output buffer resolution is nothing but crop */ + crop = inst->fmts[OUTPUT_PORT].fmt.pix_mp.width << 16 | + inst->fmts[OUTPUT_PORT].fmt.pix_mp.height; + rc = venus_hfi_session_property(inst, + HFI_PROP_CROP_RESOLUTION, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &crop, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_bit_depth(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 colorformat; + u32 bitdepth = 8 << 16 | 8; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + colorformat = inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat; + if (colorformat == V4L2_PIX_FMT_NV12_P010 || + colorformat == V4L2_PIX_FMT_NV12_TP10_UBWC) + bitdepth = 10 << 16 | 10; + rc = venus_hfi_session_property(inst, + HFI_PROP_LUMA_CHROMA_BIT_DEPTH, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &bitdepth, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_cabac(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 cabac = 0; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + rc = venus_hfi_session_property(inst, + HFI_PROP_CABAC_SESSION, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &cabac, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_coded_frames(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 coded_frames; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + /* (mb_adaptive_frame_field_flag << 1) | frame_mbs_only_flag */ + coded_frames = 1; + rc = venus_hfi_session_property(inst, + HFI_PROP_CODED_FRAMES, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &coded_frames, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_min_output_count(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 min_output; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + min_output = inst->buffers.output.min_count; + rc = venus_hfi_session_property(inst, + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &min_output, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_picture_order_count(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 poc = 1; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + rc = venus_hfi_session_property(inst, + HFI_PROP_PIC_ORDER_CNT_TYPE, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &poc, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_colorspace(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 colorspace; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + colorspace = inst->fmts[OUTPUT_PORT].fmt.pix_mp.colorspace; + rc = venus_hfi_session_property(inst, + HFI_PROP_SIGNAL_COLOR_INFO, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &colorspace, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_colorformat(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + u32 pixelformat; + enum msm_vidc_colorformat_type colorformat; + u32 hfi_colorformat; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + pixelformat = inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat; + if (pixelformat != V4L2_PIX_FMT_NV12_UBWC && + pixelformat != V4L2_PIX_FMT_NV12_TP10_UBWC) { + s_vpr_e(inst->sid, "%s: invalid pixelformat %#x\n", + __func__, pixelformat); + return -EINVAL; + } + colorformat = v4l2_colorformat_to_driver(pixelformat, __func__); + hfi_colorformat = get_hfi_colorformat(inst, colorformat); + rc = venus_hfi_session_property(inst, + HFI_PROP_COLOR_FORMAT, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &hfi_colorformat, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_stage(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + struct msm_vidc_core *core = inst->core; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + rc = call_session_op(core, decide_work_mode, inst); + if (rc) { + s_vpr_e(inst->sid, "%s: decide_work_mode failed %d\n", + __func__, port); + return -EINVAL; + } + + rc = venus_hfi_session_property(inst, + HFI_PROP_STAGE, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &inst->stage, + sizeof(u32)); + if (rc) + return rc; + return 0; +} + +static int msm_vdec_set_pipe(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + struct msm_vidc_core *core = inst->core; + + if (port != INPUT_PORT && port != OUTPUT_PORT) { + s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port); + return -EINVAL; + } + + rc = call_session_op(core, decide_work_route, inst); + if (rc) { + s_vpr_e(inst->sid, "%s: decide_work_route failed %d\n", + __func__, port); + return -EINVAL; + } + + rc = venus_hfi_session_property(inst, + HFI_PROP_PIPE, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, port), + HFI_PAYLOAD_U32, + &inst->pipe, + sizeof(u32)); + if (rc) + return rc; + return 0; } static int msm_vdec_set_input_properties(struct msm_vidc_inst *inst) { int rc = 0; + int i = 0; d_vpr_h("%s()\n", __func__); if (!inst) { @@ -37,6 +380,108 @@ static int msm_vdec_set_input_properties(struct msm_vidc_inst *inst) return -EINVAL; } + for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change); + i++) { + switch (msm_vdec_subscribe_for_port_settings_change[i]) { + case HFI_PROP_ALIGN_RESOLUTION: + rc = msm_vdec_set_resolution(inst, INPUT_PORT); + break; + case HFI_PROP_CROP_COORDINATE_TOP_LEFT: + rc = msm_vdec_set_crop_top_left(inst, INPUT_PORT); + break; + case HFI_PROP_CROP_RESOLUTION: + rc = msm_vdec_set_crop_resolution(inst, INPUT_PORT); + break; + case HFI_PROP_LUMA_CHROMA_BIT_DEPTH: + rc = msm_vdec_set_bit_depth(inst, INPUT_PORT); + break; + case HFI_PROP_CABAC_SESSION: + rc = msm_vdec_set_cabac(inst, INPUT_PORT); + break; + case HFI_PROP_CODED_FRAMES: + rc = msm_vdec_set_coded_frames(inst, INPUT_PORT); + break; + case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT: + rc = msm_vdec_set_min_output_count(inst, INPUT_PORT); + break; + case HFI_PROP_PIC_ORDER_CNT_TYPE: + rc = msm_vdec_set_picture_order_count(inst, INPUT_PORT); + break; + case HFI_PROP_SIGNAL_COLOR_INFO: + rc = msm_vdec_set_colorspace(inst, INPUT_PORT); + break; + default: + d_vpr_e("%s: unknown property %#x\n", __func__, + msm_vdec_subscribe_for_port_settings_change[i]); + rc = -EINVAL; + break; + } + } + + return rc; +} + +static int msm_vdec_set_output_properties(struct msm_vidc_inst *inst) +{ + int rc = 0; + int i = 0; + + d_vpr_h("%s()\n", __func__); + if (!inst) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + rc = msm_vdec_set_colorformat(inst, OUTPUT_PORT); + if (rc) + return rc; + + rc = msm_vdec_set_stage(inst, OUTPUT_PORT); + if (rc) + return rc; + + rc = msm_vdec_set_pipe(inst, OUTPUT_PORT); + if (rc) + return rc; + + for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change); + i++) { + switch (msm_vdec_subscribe_for_port_settings_change[i]) { + case HFI_PROP_ALIGN_RESOLUTION: + rc = msm_vdec_set_resolution(inst, OUTPUT_PORT); + break; + case HFI_PROP_CROP_COORDINATE_TOP_LEFT: + rc = msm_vdec_set_crop_top_left(inst, OUTPUT_PORT); + break; + case HFI_PROP_CROP_RESOLUTION: + rc = msm_vdec_set_crop_resolution(inst, OUTPUT_PORT); + break; + case HFI_PROP_LUMA_CHROMA_BIT_DEPTH: + rc = msm_vdec_set_bit_depth(inst, OUTPUT_PORT); + break; + case HFI_PROP_CABAC_SESSION: + rc = msm_vdec_set_cabac(inst, OUTPUT_PORT); + break; + case HFI_PROP_CODED_FRAMES: + rc = msm_vdec_set_coded_frames(inst, OUTPUT_PORT); + break; + case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT: + rc = msm_vdec_set_min_output_count(inst, OUTPUT_PORT); + break; + case HFI_PROP_PIC_ORDER_CNT_TYPE: + rc = msm_vdec_set_picture_order_count(inst, OUTPUT_PORT); + break; + case HFI_PROP_SIGNAL_COLOR_INFO: + rc = msm_vdec_set_colorspace(inst, OUTPUT_PORT); + break; + default: + d_vpr_e("%s: unknown property %#x\n", __func__, + msm_vdec_subscribe_for_port_settings_change[i]); + rc = -EINVAL; + break; + } + } + return rc; } @@ -156,17 +601,6 @@ static int msm_vdec_port_settings_subscription(struct msm_vidc_inst *inst, struct msm_vidc_core *core; u32 payload[32] = {0}; u32 i; - u32 subscribe_psc[] = { - HFI_PROP_ALIGN_RESOLUTION, - HFI_PROP_CROP_RESOLUTION, - HFI_PROP_CROP_COORDINATE_TOP_LEFT, - HFI_PROP_LUMA_CHROMA_BIT_DEPTH, - HFI_PROP_CABAC_SESSION, - HFI_PROP_CODED_FRAMES, - HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, - HFI_PROP_PIC_ORDER_CNT_TYPE, - HFI_PROP_SIGNAL_COLOR_INFO, - }; if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); @@ -176,24 +610,26 @@ static int msm_vdec_port_settings_subscription(struct msm_vidc_inst *inst, d_vpr_h("%s()\n", __func__); payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE; - for (i = 0; i < ARRAY_SIZE(subscribe_psc); i++) - payload[i + 1] = subscribe_psc[i]; + for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change); + i++) + payload[i + 1] = msm_vdec_subscribe_for_port_settings_change[i]; rc = hfi_create_header(inst->packet, inst->packet_size, - inst->session_id, - core->header_id++); + inst->session_id, + core->header_id++); if (rc) return rc; rc = hfi_create_packet(inst->packet, inst->packet_size, - HFI_CMD_SUBSCRIBE_MODE, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), - HFI_PAYLOAD_U32_ARRAY, - get_hfi_port(inst, port), - core->packet_id++, - &payload[0], - (ARRAY_SIZE(subscribe_psc) + 1) * sizeof(u32)); + HFI_CMD_SUBSCRIBE_MODE, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + HFI_PAYLOAD_U32_ARRAY, + get_hfi_port(inst, port), + core->packet_id++, + &payload[0], + (ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change) + 1) * + sizeof(u32)); if (rc) return rc; @@ -207,9 +643,6 @@ static int msm_vdec_property_subscription(struct msm_vidc_inst *inst, struct msm_vidc_core *core; u32 payload[32] = {0}; u32 i; - u32 subscribe_properties[] = { - HFI_PROP_TAG_NOT_PROPAGATED_TO_OUTPUT, - }; if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); @@ -219,8 +652,8 @@ static int msm_vdec_property_subscription(struct msm_vidc_inst *inst, d_vpr_h("%s()\n", __func__); payload[0] = HFI_MODE_PROPERTY; - for (i = 0; i < ARRAY_SIZE(subscribe_properties); i++) - payload[i + 1] = subscribe_properties[i]; + for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_properties); i++) + payload[i + 1] = msm_vdec_subscribe_for_properties[i]; rc = hfi_create_header(inst->packet, inst->packet_size, inst->session_id, @@ -236,7 +669,49 @@ static int msm_vdec_property_subscription(struct msm_vidc_inst *inst, get_hfi_port(inst, port), core->packet_id++, &payload[0], - (ARRAY_SIZE(subscribe_properties) + 1) * sizeof(u32)); + (ARRAY_SIZE(msm_vdec_subscribe_for_properties) + 1) * + sizeof(u32)); + if (rc) + return rc; + + return rc; +} + +static int msm_vdec_metadata_subscription(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + struct msm_vidc_core *core; + u32 payload[32] = {0}; + u32 i; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + d_vpr_h("%s()\n", __func__); + + payload[0] = HFI_MODE_METADATA; + for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_metadata); i++) + payload[i + 1] = msm_vdec_subscribe_for_metadata[i]; + + rc = hfi_create_header(inst->packet, inst->packet_size, + inst->session_id, + core->header_id++); + if (rc) + return rc; + + rc = hfi_create_packet(inst->packet, inst->packet_size, + HFI_CMD_SUBSCRIBE_MODE, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + HFI_PAYLOAD_U32_ARRAY, + get_hfi_port(inst, port), + core->packet_id++, + &payload[0], + (ARRAY_SIZE(msm_vdec_subscribe_for_metadata) + 1) * + sizeof(u32)); if (rc) return rc; @@ -250,9 +725,6 @@ static int msm_vdec_metadata_delivery(struct msm_vidc_inst *inst, struct msm_vidc_core *core; u32 payload[32] = {0}; u32 i; - u32 metadata_delivery[] = { - HFI_PROP_BUFFER_TAG, - }; if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); @@ -262,24 +734,54 @@ static int msm_vdec_metadata_delivery(struct msm_vidc_inst *inst, d_vpr_h("%s()\n", __func__); payload[0] = HFI_MODE_METADATA; - for (i = 0; i < ARRAY_SIZE(metadata_delivery); i++) - payload[i + 1] = metadata_delivery[i]; + for (i = 0; i < ARRAY_SIZE(msm_vdec_deliver_as_metadata); i++) + payload[i + 1] = msm_vdec_deliver_as_metadata[i]; rc = hfi_create_header(inst->packet, inst->packet_size, - inst->session_id, - core->header_id++); + inst->session_id, + core->header_id++); if (rc) return rc; rc = hfi_create_packet(inst->packet, inst->packet_size, - HFI_CMD_DELIVERY_MODE, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), - HFI_PAYLOAD_U32_ARRAY, - get_hfi_port(inst, port), - core->packet_id++, - &payload[0], - (ARRAY_SIZE(metadata_delivery) + 1) * sizeof(u32)); + HFI_CMD_DELIVERY_MODE, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + HFI_PAYLOAD_U32_ARRAY, + get_hfi_port(inst, port), + core->packet_id++, + &payload[0], + (ARRAY_SIZE(msm_vdec_deliver_as_metadata) + 1) * sizeof(u32)); + if (rc) + return rc; + + return rc; +} + +static int msm_vdec_subscription(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + + rc = msm_vdec_port_settings_subscription(inst, port); + if (rc) + return rc; + rc = msm_vdec_property_subscription(inst, port); + if (rc) + return rc; + rc = msm_vdec_metadata_subscription(inst, port); + if (rc) + return rc; + + return rc; +} + +static int msm_vdec_deliveries(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + + rc = msm_vdec_metadata_delivery(inst, port); if (rc) return rc; @@ -290,7 +792,7 @@ int msm_vdec_stop_input(struct msm_vidc_inst *inst) { int rc = 0; - if (!inst) { + if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -317,10 +819,8 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst) //rc = msm_vidc_check_scaling_supported(inst); if (rc) goto error; - rc = call_session_op(core, decide_work_mode, inst); - if (rc) - goto error; - rc = call_session_op(core, decide_work_route, inst); + + rc = msm_vdec_set_input_properties(inst); if (rc) goto error; @@ -339,10 +839,6 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst) //msm_vidc_update_batching(inst); //msm_vidc_scale_power(inst); - rc = msm_vdec_set_input_properties(inst); - rc = 0; // TODO - if (rc) - goto error; rc = msm_vdec_create_input_internal_buffers(inst); rc = 0; // TODO if (rc) @@ -352,18 +848,11 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst) if (rc) goto error; - rc = msm_vdec_port_settings_subscription(inst, INPUT_PORT); - rc = 0; // TODO + rc = msm_vdec_subscription(inst, INPUT_PORT); if (rc) goto error; - rc = msm_vdec_property_subscription(inst, INPUT_PORT); - rc = 0; // TODO - if (rc) - goto error; - - rc = msm_vdec_metadata_delivery(inst, INPUT_PORT); - rc = 0; // TODO + rc = msm_vdec_deliveries(inst, INPUT_PORT); if (rc) goto error; @@ -385,7 +874,7 @@ int msm_vdec_stop_output(struct msm_vidc_inst *inst) int rc = 0; d_vpr_h("%s()\n", __func__); - if (!inst) { + if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -398,16 +887,20 @@ int msm_vdec_start_output(struct msm_vidc_inst *inst) int rc = 0; d_vpr_h("%s()\n", __func__); - if (!inst) { + if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - rc = msm_vdec_port_settings_subscription(inst, OUTPUT_PORT); + rc = msm_vdec_set_output_properties(inst); if (rc) goto error; - rc = msm_vdec_metadata_delivery(inst, OUTPUT_PORT); + rc = msm_vdec_subscription(inst, OUTPUT_PORT); + if (rc) + goto error; + + rc = msm_vdec_deliveries(inst, OUTPUT_PORT); if (rc) goto error; @@ -467,33 +960,34 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) return -EINVAL; } - if (f->type == INPUT_PLANE) { + if (f->type == INPUT_MPLANE) { if (inst->state == MSM_VIDC_START_INPUT) { d_vpr_e("%s: invalid state %d\n", __func__, inst->state); return -EINVAL; } - if (inst->fmts[INPUT_PORT].fmt.pix.pixelformat != - f->fmt.pix.pixelformat) { + if (inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat != + f->fmt.pix_mp.pixelformat) { s_vpr_e(inst->sid, "%s: codec changed from %#x to %#x\n", __func__, - inst->fmts[INPUT_PORT].fmt.pix.pixelformat, - f->fmt.pix.pixelformat); - rc = msm_vdec_codec_change(inst, f->fmt.pix.pixelformat); + inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat, + f->fmt.pix_mp.pixelformat); + rc = msm_vdec_codec_change(inst, f->fmt.pix_mp.pixelformat); if (rc) goto err_invalid_fmt; } fmt = &inst->fmts[INPUT_PORT]; - fmt->type = INPUT_PLANE; - fmt->fmt.pix.width = ALIGN(f->fmt.pix.width, 16); - fmt->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); - fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat; - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_INPUT); - inst->buffers.input.min_count = - call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT); - inst->buffers.input.extra_count = - call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT); + fmt->type = INPUT_MPLANE; + fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 16); + fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16); + fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; + fmt->fmt.pix_mp.num_planes = 1; + fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; + fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core, + buffer_size, inst, MSM_VIDC_BUF_INPUT); + inst->buffers.input.min_count = call_session_op(core, + min_count, inst, MSM_VIDC_BUF_INPUT); + inst->buffers.input.extra_count = call_session_op(core, + extra_count, inst, MSM_VIDC_BUF_INPUT); if (inst->buffers.input.actual_count < inst->buffers.input.min_count + inst->buffers.input.extra_count) { @@ -501,12 +995,13 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) inst->buffers.input.min_count + inst->buffers.input.extra_count; } - inst->buffers.input.size = fmt->fmt.pix.sizeimage; + inst->buffers.input.size = + fmt->fmt.pix_mp.plane_fmt[0].sizeimage; /* update crop dimensions */ inst->crop.x = inst->crop.y = 0; - inst->crop.width = f->fmt.pix.width; - inst->crop.height = f->fmt.pix.height; + inst->crop.width = f->fmt.pix_mp.width; + inst->crop.height = f->fmt.pix_mp.height; //rc = msm_vidc_check_session_supported(inst); if (rc) @@ -515,8 +1010,9 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) // mplane->pixelformat); s_vpr_h(inst->sid, "%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n", - __func__, f->fmt.pix.pixelformat, f->fmt.pix.width, - f->fmt.pix.height, fmt->fmt.pix.sizeimage, + __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, + f->fmt.pix_mp.height, + fmt->fmt.pix_mp.plane_fmt[0].sizeimage, inst->buffers.input.min_count, inst->buffers.input.extra_count); @@ -545,27 +1041,31 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) __func__, fmt->fmt.meta.buffersize, inst->buffers.input_meta.min_count, inst->buffers.input_meta.extra_count); - } else if (f->type == OUTPUT_PLANE) { + } else if (f->type == OUTPUT_MPLANE) { if (inst->state == MSM_VIDC_START_OUTPUT) { d_vpr_e("%s: invalid state %d\n", __func__, inst->state); return -EINVAL; } fmt = &inst->fmts[OUTPUT_PORT]; - fmt->type = OUTPUT_PLANE; - fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat; - fmt->fmt.pix.width = VENUS_Y_STRIDE( - v4l2_colorformat_to_media(fmt->fmt.pix.pixelformat), - f->fmt.pix.width); - fmt->fmt.pix.height = VENUS_Y_SCANLINES( - v4l2_colorformat_to_media(fmt->fmt.pix.pixelformat), - f->fmt.pix.height); - fmt->fmt.pix.bytesperline = fmt->fmt.pix.width; - fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_OUTPUT); - inst->buffers.output.min_count = - call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT); - inst->buffers.output.extra_count = - call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT); + fmt->type = OUTPUT_MPLANE; + fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; + fmt->fmt.pix_mp.width = VENUS_Y_STRIDE( + v4l2_colorformat_to_media( + fmt->fmt.pix_mp.pixelformat, __func__), + f->fmt.pix_mp.width); + fmt->fmt.pix_mp.height = VENUS_Y_SCANLINES( + v4l2_colorformat_to_media( + fmt->fmt.pix_mp.pixelformat, __func__), + f->fmt.pix_mp.height); + fmt->fmt.pix_mp.num_planes = 1; + fmt->fmt.pix_mp.plane_fmt[0].bytesperline = + fmt->fmt.pix_mp.width; + fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core, + buffer_size, inst, MSM_VIDC_BUF_OUTPUT); + inst->buffers.output.min_count = call_session_op(core, + min_count, inst, MSM_VIDC_BUF_OUTPUT); + inst->buffers.output.extra_count = call_session_op(core, + extra_count, inst, MSM_VIDC_BUF_OUTPUT); if (inst->buffers.output.actual_count < inst->buffers.output.min_count + inst->buffers.output.extra_count) { @@ -573,15 +1073,17 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) inst->buffers.output.min_count + inst->buffers.output.extra_count; } - inst->buffers.output.size = fmt->fmt.pix.sizeimage; + inst->buffers.output.size = + fmt->fmt.pix_mp.plane_fmt[0].sizeimage; //rc = msm_vidc_check_session_supported(inst); if (rc) goto err_invalid_fmt; s_vpr_h(inst->sid, "%s: output: format %#x width %d height %d size %d min_count %d extra_count %d\n", - __func__, fmt->fmt.pix.pixelformat, fmt->fmt.pix.width, - fmt->fmt.pix.height, fmt->fmt.pix.sizeimage, + __func__, fmt->fmt.pix_mp.pixelformat, fmt->fmt.pix_mp.width, + fmt->fmt.pix_mp.height, + fmt->fmt.pix_mp.plane_fmt[0].sizeimage, inst->buffers.output.min_count, inst->buffers.output.extra_count); } else if (f->type == OUTPUT_META_PLANE) { @@ -649,7 +1151,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) } core = inst->core; - if (f->type == INPUT_PLANE) { + if (f->type == INPUT_MPLANE) { u32 codecs = core->capabilities[DEC_CODECS].value; while (codecs) { @@ -662,12 +1164,13 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) i++; codecs >>= 1; } - f->pixelformat = v4l2_codec_from_driver(array[f->index]); + f->pixelformat = v4l2_codec_from_driver(array[f->index], + __func__); if (!f->pixelformat) return -EINVAL; f->flags = V4L2_FMT_FLAG_COMPRESSED; strlcpy(f->description, "codec", sizeof(f->description)); - } else if (f->type == OUTPUT_PLANE) { + } else if (f->type == OUTPUT_MPLANE) { u32 formats = inst->capabilities->cap[PIX_FMTS].step_or_mask; while (formats) { @@ -680,7 +1183,8 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) i++; formats >>= 1; } - f->pixelformat = v4l2_colorformat_from_driver(array[f->index]); + f->pixelformat = v4l2_colorformat_from_driver(array[f->index], + __func__); if (!f->pixelformat) return -EINVAL; strlcpy(f->description, "colorformat", sizeof(f->description)); @@ -715,25 +1219,26 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) INIT_DELAYED_WORK(&inst->decode_batch.work, msm_vidc_batch_handler); f = &inst->fmts[INPUT_PORT]; - f->type = INPUT_PLANE; - f->fmt.pix.width = DEFAULT_WIDTH; - f->fmt.pix.height = DEFAULT_HEIGHT; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_INPUT); - inst->buffers.input.min_count = - call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT); - inst->buffers.input.extra_count = - call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT); + f->type = INPUT_MPLANE; + f->fmt.pix_mp.width = DEFAULT_WIDTH; + f->fmt.pix_mp.height = DEFAULT_HEIGHT; + f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + f->fmt.pix_mp.num_planes = 1; + f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; + f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core, + buffer_size, inst, MSM_VIDC_BUF_INPUT); + inst->buffers.input.min_count = call_session_op(core, + min_count, inst, MSM_VIDC_BUF_INPUT); + inst->buffers.input.extra_count = call_session_op(core, + extra_count, inst, MSM_VIDC_BUF_INPUT); inst->buffers.input.actual_count = inst->buffers.input.min_count + inst->buffers.input.extra_count; - inst->buffers.input.size = f->fmt.pix.sizeimage; + inst->buffers.input.size = f->fmt.pix_mp.plane_fmt[0].sizeimage; inst->crop.x = inst->crop.y = 0; - inst->crop.width = f->fmt.pix.width; - inst->crop.height = f->fmt.pix.height; + inst->crop.width = f->fmt.pix_mp.width; + inst->crop.height = f->fmt.pix_mp.height; f = &inst->fmts[INPUT_META_PORT]; f->type = INPUT_META_PLANE; @@ -746,23 +1251,26 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) inst->buffers.input_meta.size = f->fmt.meta.buffersize; f = &inst->fmts[OUTPUT_PORT]; - f->type = OUTPUT_PLANE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12_UBWC; - f->fmt.pix.width = VENUS_Y_STRIDE( - v4l2_colorformat_to_media(f->fmt.pix.pixelformat), DEFAULT_WIDTH); - f->fmt.pix.height = VENUS_Y_SCANLINES( - v4l2_colorformat_to_media(f->fmt.pix.pixelformat), DEFAULT_HEIGHT); - f->fmt.pix.bytesperline = f->fmt.pix.width; - f->fmt.pix.sizeimage = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_OUTPUT); - inst->buffers.output.min_count = - call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT); - inst->buffers.output.extra_count = - call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT); + f->type = OUTPUT_MPLANE; + f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_UBWC; + f->fmt.pix_mp.width = VENUS_Y_STRIDE( + v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__), + DEFAULT_WIDTH); + f->fmt.pix_mp.height = VENUS_Y_SCANLINES( + v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__), + DEFAULT_HEIGHT); + f->fmt.pix_mp.num_planes = 1; + f->fmt.pix_mp.plane_fmt[0].bytesperline = f->fmt.pix_mp.width; + f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core, + buffer_size, inst, MSM_VIDC_BUF_OUTPUT); + inst->buffers.output.min_count = call_session_op(core, + min_count, inst, MSM_VIDC_BUF_OUTPUT); + inst->buffers.output.extra_count = call_session_op(core, + extra_count, inst, MSM_VIDC_BUF_OUTPUT); inst->buffers.output.actual_count = inst->buffers.output.min_count + inst->buffers.output.extra_count; - inst->buffers.output.size = f->fmt.pix.sizeimage; + inst->buffers.output.size = f->fmt.pix_mp.plane_fmt[0].sizeimage; f = &inst->fmts[OUTPUT_META_PORT]; f->type = OUTPUT_META_PLANE; @@ -776,9 +1284,11 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) inst->prop.frame_rate = DEFAULT_FPS << 16; inst->prop.operating_rate = DEFAULT_FPS << 16; + inst->stage = MSM_VIDC_STAGE_2; + inst->pipe = MSM_VIDC_PIPE_4; rc = msm_vdec_codec_change(inst, - inst->fmts[INPUT_PORT].fmt.pix.pixelformat); + inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat); return rc; } diff --git a/driver/vidc/src/msm_venc.c b/driver/vidc/src/msm_venc.c index e991e63b69..feb948f034 100644 --- a/driver/vidc/src/msm_venc.c +++ b/driver/vidc/src/msm_venc.c @@ -20,7 +20,7 @@ static int msm_venc_codec_change(struct msm_vidc_inst *inst, u32 codec) d_vpr_h("%s()\n", __func__); - inst->codec = v4l2_codec_to_driver(codec); + inst->codec = v4l2_codec_to_driver(codec, __func__); rc = msm_vidc_get_inst_capability(inst); return rc; } @@ -43,27 +43,31 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) return -EINVAL; } - if (f->type == INPUT_PLANE) { + if (f->type == INPUT_MPLANE) { if (inst->state == MSM_VIDC_START_INPUT) { d_vpr_e("%s: invalid state %d\n", __func__, inst->state); return -EINVAL; } fmt = &inst->fmts[INPUT_PORT]; - fmt->type = INPUT_PLANE; - fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat; - fmt->fmt.pix.width = VENUS_Y_STRIDE( - v4l2_colorformat_to_media(fmt->fmt.pix.pixelformat), - f->fmt.pix.width); - fmt->fmt.pix.height = VENUS_Y_SCANLINES( - v4l2_colorformat_to_media(fmt->fmt.pix.pixelformat), - f->fmt.pix.height); - fmt->fmt.pix.bytesperline = fmt->fmt.pix.width; - fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_INPUT); - inst->buffers.input.min_count = - call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT); - inst->buffers.input.extra_count = - call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT); + fmt->type = INPUT_MPLANE; + fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; + fmt->fmt.pix_mp.width = VENUS_Y_STRIDE( + v4l2_colorformat_to_media(fmt->fmt.pix_mp.pixelformat, + __func__), + f->fmt.pix_mp.width); + fmt->fmt.pix_mp.height = VENUS_Y_SCANLINES( + v4l2_colorformat_to_media(fmt->fmt.pix_mp.pixelformat, + __func__), + f->fmt.pix_mp.height); + fmt->fmt.pix_mp.num_planes = 1; + fmt->fmt.pix_mp.plane_fmt[0].bytesperline = + fmt->fmt.pix_mp.width; + fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core, + buffer_size, inst, MSM_VIDC_BUF_INPUT); + inst->buffers.input.min_count = call_session_op(core, + min_count, inst, MSM_VIDC_BUF_INPUT); + inst->buffers.input.extra_count = call_session_op(core, + extra_count, inst, MSM_VIDC_BUF_INPUT); if (inst->buffers.input.actual_count < inst->buffers.input.min_count + inst->buffers.input.extra_count) { @@ -71,7 +75,8 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) inst->buffers.input.min_count + inst->buffers.input.extra_count; } - inst->buffers.input.size = fmt->fmt.pix.sizeimage; + inst->buffers.input.size = + fmt->fmt.pix_mp.plane_fmt[0].sizeimage; //rc = msm_vidc_check_session_supported(inst); if (rc) @@ -80,8 +85,9 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) // mplane->pixelformat); s_vpr_h(inst->sid, "%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n", - __func__, f->fmt.pix.pixelformat, f->fmt.pix.width, - f->fmt.pix.height, fmt->fmt.pix.sizeimage, + __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, + f->fmt.pix_mp.height, + fmt->fmt.pix_mp.plane_fmt[0].sizeimage, inst->buffers.input.min_count, inst->buffers.input.extra_count); @@ -110,31 +116,32 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) __func__, fmt->fmt.meta.buffersize, inst->buffers.input_meta.min_count, inst->buffers.input_meta.extra_count); - } else if (f->type == OUTPUT_PLANE) { + } else if (f->type == OUTPUT_MPLANE) { if (inst->state == MSM_VIDC_START_OUTPUT) { d_vpr_e("%s: invalid state %d\n", __func__, inst->state); return -EINVAL; } fmt = &inst->fmts[OUTPUT_PORT]; - if (fmt->fmt.pix.pixelformat != f->fmt.pix.pixelformat) { + if (fmt->fmt.pix_mp.pixelformat != f->fmt.pix_mp.pixelformat) { s_vpr_e(inst->sid, "%s: codec changed from %#x to %#x\n", __func__, - fmt->fmt.pix.pixelformat, f->fmt.pix.pixelformat); - rc = msm_venc_codec_change(inst, f->fmt.pix.pixelformat); + fmt->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat); + rc = msm_venc_codec_change(inst, f->fmt.pix_mp.pixelformat); if (rc) goto err_invalid_fmt; } - fmt->type = OUTPUT_PLANE; - fmt->fmt.pix.width = ALIGN(f->fmt.pix.width, 16); - fmt->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); - fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat; - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_OUTPUT); - inst->buffers.output.min_count = - call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT); - inst->buffers.output.extra_count = - call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT); + fmt->type = OUTPUT_MPLANE; + fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 16); + fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16); + fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; + fmt->fmt.pix_mp.num_planes = 1; + fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; + fmt->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core, + buffer_size, inst, MSM_VIDC_BUF_OUTPUT); + inst->buffers.output.min_count = call_session_op(core, + min_count, inst, MSM_VIDC_BUF_OUTPUT); + inst->buffers.output.extra_count = call_session_op(core, + extra_count, inst, MSM_VIDC_BUF_OUTPUT); if (inst->buffers.output.actual_count < inst->buffers.output.min_count + inst->buffers.output.extra_count) { @@ -142,7 +149,8 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) inst->buffers.output.min_count + inst->buffers.output.extra_count; } - inst->buffers.output.size = fmt->fmt.pix.sizeimage; + inst->buffers.output.size = + fmt->fmt.pix_mp.plane_fmt[0].sizeimage; //rc = msm_vidc_check_session_supported(inst); if (rc) @@ -150,16 +158,17 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) /* update crop dimensions */ inst->crop.x = inst->crop.y = 0; - inst->crop.width = f->fmt.pix.width; - inst->crop.height = f->fmt.pix.height; + inst->crop.width = f->fmt.pix_mp.width; + inst->crop.height = f->fmt.pix_mp.height; //update_log_ctxt(inst->sid, inst->session_type, // mplane->pixelformat); s_vpr_h(inst->sid, "%s: output: format %#x width %d height %d size %d min_count %d extra_count %d\n", - __func__, fmt->fmt.pix.pixelformat, fmt->fmt.pix.width, - fmt->fmt.pix.height, fmt->fmt.pix.sizeimage, + __func__, fmt->fmt.pix_mp.pixelformat, fmt->fmt.pix_mp.width, + fmt->fmt.pix_mp.height, + fmt->fmt.pix_mp.plane_fmt[0].sizeimage, inst->buffers.output.min_count, inst->buffers.output.extra_count); } else if (f->type == OUTPUT_META_PLANE) { @@ -227,7 +236,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) } core = inst->core; - if (f->type == OUTPUT_PLANE) { + if (f->type == OUTPUT_MPLANE) { u32 codecs = core->capabilities[DEC_CODECS].value; while (codecs) { @@ -240,12 +249,13 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) i++; codecs >>= 1; } - f->pixelformat = v4l2_codec_from_driver(array[f->index]); + f->pixelformat = v4l2_codec_from_driver(array[f->index], + __func__); if (!f->pixelformat) return -EINVAL; f->flags = V4L2_FMT_FLAG_COMPRESSED; strlcpy(f->description, "codec", sizeof(f->description)); - } else if (f->type == INPUT_PLANE) { + } else if (f->type == INPUT_MPLANE) { u32 formats = inst->capabilities->cap[PIX_FMTS].step_or_mask; while (formats) { @@ -258,7 +268,8 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) i++; formats >>= 1; } - f->pixelformat = v4l2_colorformat_from_driver(array[f->index]); + f->pixelformat = v4l2_colorformat_from_driver(array[f->index], + __func__); if (!f->pixelformat) return -EINVAL; strlcpy(f->description, "colorformat", sizeof(f->description)); @@ -291,25 +302,26 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) core = inst->core; f = &inst->fmts[OUTPUT_PORT]; - f->type = OUTPUT_PLANE; - f->fmt.pix.width = DEFAULT_WIDTH; - f->fmt.pix.height = DEFAULT_HEIGHT; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_OUTPUT); - inst->buffers.output.min_count = - call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT); - inst->buffers.output.extra_count = - call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT); + f->type = OUTPUT_MPLANE; + f->fmt.pix_mp.width = DEFAULT_WIDTH; + f->fmt.pix_mp.height = DEFAULT_HEIGHT; + f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + f->fmt.pix_mp.num_planes = 1; + f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; + f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core, + buffer_size, inst, MSM_VIDC_BUF_OUTPUT); + inst->buffers.output.min_count = call_session_op(core, + min_count, inst, MSM_VIDC_BUF_OUTPUT); + inst->buffers.output.extra_count = call_session_op(core, + extra_count, inst, MSM_VIDC_BUF_OUTPUT); inst->buffers.output.actual_count = inst->buffers.output.min_count + inst->buffers.output.extra_count; - inst->buffers.output.size = f->fmt.pix.sizeimage; + inst->buffers.output.size = f->fmt.pix_mp.plane_fmt[0].sizeimage; inst->crop.x = inst->crop.y = 0; - inst->crop.width = f->fmt.pix.width; - inst->crop.height = f->fmt.pix.height; + inst->crop.width = f->fmt.pix_mp.width; + inst->crop.height = f->fmt.pix_mp.height; f = &inst->fmts[OUTPUT_META_PORT]; f->type = OUTPUT_META_PLANE; @@ -319,26 +331,29 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) inst->buffers.output_meta.min_count = inst->buffers.output.min_count; inst->buffers.output_meta.extra_count = inst->buffers.output.extra_count; inst->buffers.output_meta.actual_count = inst->buffers.output.actual_count; - inst->buffers.output_meta.size = f->fmt.meta.buffersize; + inst->buffers.output_meta.size = f->fmt.meta.buffersize; f = &inst->fmts[INPUT_PORT]; - f->type = INPUT_PLANE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12_UBWC; - f->fmt.pix.width = VENUS_Y_STRIDE( - v4l2_colorformat_to_media(f->fmt.pix.pixelformat), DEFAULT_WIDTH); - f->fmt.pix.height = VENUS_Y_SCANLINES( - v4l2_colorformat_to_media(f->fmt.pix.pixelformat), DEFAULT_HEIGHT); - f->fmt.pix.bytesperline = f->fmt.pix.width; - f->fmt.pix.sizeimage = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_INPUT); - inst->buffers.input.min_count = - call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT); - inst->buffers.input.extra_count = - call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT); + f->type = INPUT_MPLANE; + f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_UBWC; + f->fmt.pix_mp.width = VENUS_Y_STRIDE( + v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__), + DEFAULT_WIDTH); + f->fmt.pix_mp.height = VENUS_Y_SCANLINES( + v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__), + DEFAULT_HEIGHT); + f->fmt.pix_mp.num_planes = 1; + f->fmt.pix_mp.plane_fmt[0].bytesperline = f->fmt.pix_mp.width; + f->fmt.pix_mp.plane_fmt[0].sizeimage = call_session_op(core, + buffer_size, inst, MSM_VIDC_BUF_INPUT); + inst->buffers.input.min_count = call_session_op(core, + min_count, inst, MSM_VIDC_BUF_INPUT); + inst->buffers.input.extra_count = call_session_op(core, + extra_count, inst, MSM_VIDC_BUF_INPUT); inst->buffers.input.actual_count = inst->buffers.input.min_count + inst->buffers.input.extra_count; - inst->buffers.input.size = f->fmt.pix.sizeimage; + inst->buffers.input.size = f->fmt.pix_mp.plane_fmt[0].sizeimage; f = &inst->fmts[INPUT_META_PORT]; f->type = INPUT_META_PLANE; @@ -352,9 +367,11 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) inst->prop.frame_rate = DEFAULT_FPS << 16; inst->prop.operating_rate = DEFAULT_FPS << 16; + inst->stage = MSM_VIDC_STAGE_2; + inst->pipe = MSM_VIDC_PIPE_4; rc = msm_venc_codec_change(inst, - inst->fmts[OUTPUT_PORT].fmt.pix.pixelformat); + inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat); return rc; } diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 30e48e026e..3e2af014a4 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -98,8 +98,10 @@ int msm_vidc_querycap(void *instance, struct v4l2_capability *cap) strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); cap->bus_info[0] = 0; cap->version = MSM_VIDC_VERSION; - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE | - V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_META_OUTPUT | + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_META_CAPTURE | + V4L2_CAP_META_OUTPUT | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; @@ -213,7 +215,7 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f) return -EINVAL; } - if (f->type == INPUT_PLANE) { + if (f->type == INPUT_MPLANE) { if (inst->state != MSM_VIDC_OPEN && inst->state != MSM_VIDC_START_OUTPUT) { s_vpr_e(inst->sid, @@ -221,7 +223,7 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f) __func__, f->type, inst->state); return -EINVAL; } - } else if (f->type == OUTPUT_PLANE) { + } else if (f->type == OUTPUT_MPLANE) { if (inst->state != MSM_VIDC_OPEN && inst->state != MSM_VIDC_START_INPUT && inst->state != MSM_VIDC_DRAIN_START_INPUT) { @@ -313,7 +315,7 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b) mutex_lock(&inst->lock); - if (b->type == INPUT_PLANE) { + if (b->type == INPUT_MPLANE) { if (inst->state != MSM_VIDC_OPEN && inst->state != MSM_VIDC_START_OUTPUT) { s_vpr_e(inst->sid, @@ -322,7 +324,7 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b) rc = -EINVAL; goto unlock; } - } else if (b->type == OUTPUT_PLANE) { + } else if (b->type == OUTPUT_MPLANE) { if (inst->state != MSM_VIDC_OPEN && inst->state != MSM_VIDC_START_INPUT && inst->state != MSM_VIDC_DRAIN_START_INPUT) { @@ -372,9 +374,9 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, rc = -EINVAL; goto unlock; } - if (b->type == INPUT_PLANE) { + if (b->type == INPUT_MPLANE) { q = &inst->vb2q[INPUT_PORT]; - } else if (b->type == OUTPUT_PLANE) { + } else if (b->type == OUTPUT_MPLANE) { q = &inst->vb2q[OUTPUT_PORT]; } else if (b->type == INPUT_META_PLANE) { q = &inst->vb2q[INPUT_META_PORT]; @@ -409,9 +411,9 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) } mutex_lock(&inst->lock); - if (b->type == INPUT_PLANE) { + if (b->type == INPUT_MPLANE) { q = &inst->vb2q[INPUT_PORT]; - } else if (b->type == OUTPUT_PLANE) { + } else if (b->type == OUTPUT_MPLANE) { q = &inst->vb2q[OUTPUT_PORT]; } else if (b->type == INPUT_META_PLANE) { q = &inst->vb2q[INPUT_META_PORT]; @@ -452,7 +454,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) mutex_lock(&inst->lock); - if (type == INPUT_PLANE) { + if (type == INPUT_MPLANE) { if (inst->state != MSM_VIDC_OPEN && inst->state != MSM_VIDC_START_OUTPUT) { s_vpr_e(inst->sid, @@ -461,7 +463,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) rc = -EINVAL; goto unlock; } - } else if (type == OUTPUT_PLANE) { + } else if (type == OUTPUT_MPLANE) { if (inst->state != MSM_VIDC_OPEN && inst->state != MSM_VIDC_START_INPUT && inst->state != MSM_VIDC_DRAIN_START_INPUT) { @@ -486,7 +488,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) goto unlock; } - if (type == INPUT_PLANE) { + if (type == INPUT_MPLANE) { if (inst->state == MSM_VIDC_OPEN) { new_state = MSM_VIDC_START_INPUT; } else if (inst->state == MSM_VIDC_START_OUTPUT) { @@ -495,7 +497,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) rc = msm_vidc_change_inst_state(inst, new_state, __func__); if (rc) goto unlock; - } else if (type == OUTPUT_PLANE) { + } else if (type == OUTPUT_MPLANE) { if (inst->state == MSM_VIDC_OPEN) { new_state = MSM_VIDC_START_OUTPUT; } else if (inst->state == MSM_VIDC_START_INPUT) { @@ -531,7 +533,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) mutex_lock(&inst->lock); - if (type == INPUT_PLANE) { + if (type == INPUT_MPLANE) { if (inst->state == MSM_VIDC_OPEN || inst->state == MSM_VIDC_START_OUTPUT) { s_vpr_e(inst->sid, @@ -540,7 +542,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) rc = -EINVAL; goto unlock; } - } else if (type == OUTPUT_PLANE) { + } else if (type == OUTPUT_MPLANE) { if (inst->state == MSM_VIDC_OPEN || inst->state == MSM_VIDC_START_INPUT) { s_vpr_e(inst->sid, @@ -564,7 +566,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) goto unlock; } - if (type == INPUT_PLANE) { + if (type == INPUT_MPLANE) { if (inst->state == MSM_VIDC_START_INPUT) { new_state = MSM_VIDC_OPEN; } else if (inst->state == MSM_VIDC_START) { @@ -582,7 +584,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) rc = msm_vidc_change_inst_state(inst, new_state, __func__); if (rc) goto unlock; - } else if (type == OUTPUT_PLANE) { + } else if (type == OUTPUT_MPLANE) { if (inst->state == MSM_VIDC_START_OUTPUT) { new_state = MSM_VIDC_OPEN; } else if (inst->state == MSM_VIDC_START || @@ -832,7 +834,8 @@ int msm_vidc_close(void *instance) return -EINVAL; } s_vpr_h(inst->sid, "%s()\n", __func__); - rc = msm_vidc_session_close(inst); + msm_vidc_session_close(inst); + msm_vidc_remove_session(inst); return rc; } diff --git a/driver/vidc/src/msm_vidc_buffer.c b/driver/vidc/src/msm_vidc_buffer.c index f95850c6a1..5332c7aa06 100644 --- a/driver/vidc/src/msm_vidc_buffer.c +++ b/driver/vidc/src/msm_vidc_buffer.c @@ -151,10 +151,9 @@ u32 msm_vidc_decoder_output_size(struct msm_vidc_inst *inst) struct v4l2_format *f; f = &inst->fmts[OUTPUT_PORT]; - format = v4l2_colorformat_to_media(f->fmt.pix.pixelformat); - size = VENUS_BUFFER_SIZE(format, f->fmt.pix.width, - f->fmt.pix.height); - size = 4; // TODO + format = v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__); + size = VENUS_BUFFER_SIZE(format, f->fmt.pix_mp.width, + f->fmt.pix_mp.height); return size; } @@ -175,10 +174,9 @@ u32 msm_vidc_encoder_input_size(struct msm_vidc_inst *inst) struct v4l2_format *f; f = &inst->fmts[INPUT_PORT]; - format = v4l2_colorformat_to_media(f->fmt.pix.pixelformat); - size = VENUS_BUFFER_SIZE(format, f->fmt.pix.width, - f->fmt.pix.height); - size = 4; // TODO + format = v4l2_colorformat_to_media(f->fmt.pix_mp.pixelformat, __func__); + size = VENUS_BUFFER_SIZE(format, f->fmt.pix_mp.width, + f->fmt.pix_mp.height); return size; } @@ -197,4 +195,4 @@ u32 msm_vidc_encoder_input_meta_size(struct msm_vidc_inst *inst) u32 msm_vidc_encoder_output_meta_size(struct msm_vidc_inst *inst) { return ALIGN(16 * 1024, SZ_4K); -} \ No newline at end of file +} diff --git a/driver/vidc/src/msm_vidc_control.c b/driver/vidc/src/msm_vidc_control.c index df3ccdaf03..89961165e8 100644 --- a/driver/vidc/src/msm_vidc_control.c +++ b/driver/vidc/src/msm_vidc_control.c @@ -642,7 +642,7 @@ int msm_vidc_set_u32(void *instance, if (rc) return -EINVAL; - rc = hfi_packet_session_property(inst, + rc = venus_hfi_session_property(inst, inst->capabilities->cap[cap_id].hfi_id, HFI_HOST_FLAGS_NONE, HFI_PORT_NONE, HFI_PAYLOAD_U32_ENUM, @@ -667,7 +667,7 @@ int msm_vidc_set_s32(void *instance, return -EINVAL; } - rc = hfi_packet_session_property(inst, + rc = venus_hfi_session_property(inst, inst->capabilities->cap[cap_id].hfi_id, HFI_HOST_FLAGS_NONE, HFI_PORT_NONE, HFI_PAYLOAD_S32, diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index d98e4f1dc5..0c87adb603 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -57,21 +57,21 @@ void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst, s_vpr_e(inst->sid, "%s: %s: idx %2d fd %d off %d size %d filled %d\n", - str, vb2->type == INPUT_PLANE ? "INPUT" : "OUTPUT", + str, vb2->type == INPUT_MPLANE ? "INPUT" : "OUTPUT", vb2->index, vb2->planes[0].m.fd, vb2->planes[0].data_offset, vb2->planes[0].length, vb2->planes[0].bytesused); } -enum msm_vidc_buffer_type v4l2_type_to_driver(u32 type) +enum msm_vidc_buffer_type v4l2_type_to_driver(u32 type, const char *func) { enum msm_vidc_buffer_type buffer_type = 0; switch (type) { - case INPUT_PLANE: + case INPUT_MPLANE: buffer_type = MSM_VIDC_BUF_INPUT; break; - case OUTPUT_PLANE: + case OUTPUT_MPLANE: buffer_type = MSM_VIDC_BUF_OUTPUT; break; case INPUT_META_PLANE: @@ -81,23 +81,23 @@ enum msm_vidc_buffer_type v4l2_type_to_driver(u32 type) buffer_type = MSM_VIDC_BUF_OUTPUT_META; break; default: - d_vpr_e("%s: vidc buffer type not found for %#x\n", - __func__, type); + d_vpr_e("%s: invalid v4l2 buffer type %#x\n", func, type); break; } return buffer_type; } -u32 v4l2_type_from_driver(enum msm_vidc_buffer_type buffer_type) +u32 v4l2_type_from_driver(enum msm_vidc_buffer_type buffer_type, + const char *func) { u32 type = 0; switch (buffer_type) { case MSM_VIDC_BUF_INPUT: - type = INPUT_PLANE; + type = INPUT_MPLANE; break; case MSM_VIDC_BUF_OUTPUT: - type = OUTPUT_PLANE; + type = OUTPUT_MPLANE; break; case MSM_VIDC_BUF_INPUT_META: type = INPUT_META_PLANE; @@ -106,14 +106,14 @@ u32 v4l2_type_from_driver(enum msm_vidc_buffer_type buffer_type) type = OUTPUT_META_PLANE; break; default: - d_vpr_e("%s: v4l2 type not found for %#x\n", - __func__, buffer_type); + d_vpr_e("%s: invalid driver buffer type %d\n", + func, buffer_type); break; } - return buffer_type; + return type; } -enum msm_vidc_codec_type v4l2_codec_to_driver(u32 v4l2_codec) +enum msm_vidc_codec_type v4l2_codec_to_driver(u32 v4l2_codec, const char *func) { enum msm_vidc_codec_type codec = 0; @@ -131,13 +131,13 @@ enum msm_vidc_codec_type v4l2_codec_to_driver(u32 v4l2_codec) codec = MSM_VIDC_MPEG2; break; default: - d_vpr_e("%s: vidc codec not found for %#x\n", __func__, v4l2_codec); + d_vpr_e("%s: invalid v4l2 codec %#x\n", func, v4l2_codec); break; } return codec; } -u32 v4l2_codec_from_driver(enum msm_vidc_codec_type codec) +u32 v4l2_codec_from_driver(enum msm_vidc_codec_type codec, const char *func) { u32 v4l2_codec = 0; @@ -155,13 +155,14 @@ u32 v4l2_codec_from_driver(enum msm_vidc_codec_type codec) v4l2_codec = V4L2_PIX_FMT_MPEG2; break; default: - d_vpr_e("%s: v4l2 codec not found for %#x\n", __func__, codec); + d_vpr_e("%s: invalid driver codec %#x\n", func, codec); break; } return v4l2_codec; } -enum msm_vidc_colorformat_type v4l2_colorformat_to_driver(u32 v4l2_colorformat) +enum msm_vidc_colorformat_type v4l2_colorformat_to_driver(u32 v4l2_colorformat, + const char *func) { enum msm_vidc_colorformat_type colorformat = 0; @@ -181,20 +182,19 @@ enum msm_vidc_colorformat_type v4l2_colorformat_to_driver(u32 v4l2_colorformat) case V4L2_PIX_FMT_RGBA8888_UBWC: colorformat = MSM_VIDC_FMT_RGBA8888_UBWC; break; - case V4L2_PIX_FMT_NV12_P010_UBWC: - colorformat = MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS; - break; - case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: - colorformat = MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS; + case V4L2_PIX_FMT_NV12_P010: + colorformat = MSM_VIDC_FMT_NV12_P010; break; default: - d_vpr_e("%s: vidc format not found for %#x\n", __func__, v4l2_colorformat); + d_vpr_e("%s: invalid v4l2 color format %#x\n", + func, v4l2_colorformat); break; } return colorformat; } -u32 v4l2_colorformat_from_driver(enum msm_vidc_colorformat_type colorformat) +u32 v4l2_colorformat_from_driver(enum msm_vidc_colorformat_type colorformat, + const char *func) { u32 v4l2_colorformat = 0; @@ -214,20 +214,18 @@ u32 v4l2_colorformat_from_driver(enum msm_vidc_colorformat_type colorformat) case MSM_VIDC_FMT_RGBA8888_UBWC: v4l2_colorformat = V4L2_PIX_FMT_RGBA8888_UBWC; break; - case MSM_VIDC_FMT_NV12_P010_UBWC: - v4l2_colorformat = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS; - break; - case MSM_VIDC_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: - v4l2_colorformat = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS; + case MSM_VIDC_FMT_NV12_P010: + v4l2_colorformat = V4L2_PIX_FMT_NV12_P010; break; default: - d_vpr_e("%s: v4l2 format not found for %#x\n", __func__, colorformat); + d_vpr_e("%s: invalid driver color format %#x\n", + func, colorformat); break; } return v4l2_colorformat; } -u32 v4l2_colorformat_to_media(u32 v4l2_fmt) +u32 v4l2_colorformat_to_media(u32 v4l2_fmt, const char *func) { switch (v4l2_fmt) { case V4L2_PIX_FMT_NV12: @@ -236,7 +234,7 @@ u32 v4l2_colorformat_to_media(u32 v4l2_fmt) return COLOR_FMT_NV21; case V4L2_PIX_FMT_NV12_512: return COLOR_FMT_NV12_512; - case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: + case V4L2_PIX_FMT_NV12_P010: return COLOR_FMT_P010; case V4L2_PIX_FMT_NV12_UBWC: return COLOR_FMT_NV12_UBWC; @@ -245,9 +243,8 @@ u32 v4l2_colorformat_to_media(u32 v4l2_fmt) case V4L2_PIX_FMT_RGBA8888_UBWC: return COLOR_FMT_RGBA8888_UBWC; default: - d_vpr_e( - "Invalid v4l2 color fmt FMT : %x, Set default(NV12)", - v4l2_fmt); + d_vpr_e("%s: invalid v4l2 color fmt: %#x, set default (NV12)", + func, v4l2_fmt); return COLOR_FMT_NV12; } } @@ -257,16 +254,17 @@ int v4l2_type_to_driver_port(struct msm_vidc_inst *inst, u32 type, { int port; - if (type == INPUT_PLANE) { + if (type == INPUT_MPLANE) { port = INPUT_PORT; } else if (type == INPUT_META_PLANE) { port = INPUT_META_PORT; - } else if (type == OUTPUT_PLANE) { + } else if (type == OUTPUT_MPLANE) { port = OUTPUT_PORT; } else if (type == OUTPUT_META_PLANE) { port = OUTPUT_META_PORT; } else { - s_vpr_e(inst->sid, "%s: invalid type %d\n", func, type); + s_vpr_e(inst->sid, "%s: port not found for v4l2 type %d\n", + func, type); port = -EINVAL; } @@ -317,7 +315,7 @@ u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst, region = MSM_VIDC_SECURE_NONPIXEL; break; default: - s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", + s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n", func, buffer_type); } return region; @@ -347,7 +345,7 @@ struct msm_vidc_buffers *msm_vidc_get_buffers( case MSM_VIDC_BUF_PERSIST_1: return &inst->buffers.persist_1; default: - s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", + s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n", func, buffer_type); return NULL; } @@ -377,7 +375,7 @@ struct msm_vidc_mappings *msm_vidc_get_mappings( case MSM_VIDC_BUF_PERSIST_1: return &inst->mappings.persist_1; default: - s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", + s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n", func, buffer_type); return NULL; } @@ -399,7 +397,7 @@ struct msm_vidc_allocations *msm_vidc_get_allocations( case MSM_VIDC_BUF_PERSIST_1: return &inst->allocations.persist_1; default: - s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", + s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n", func, buffer_type); return NULL; } @@ -457,7 +455,8 @@ int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) return rc; } -static int vb2_buffer_to_driver(struct vb2_buffer *vb2, struct msm_vidc_buffer *buf) +static int vb2_buffer_to_driver(struct vb2_buffer *vb2, + struct msm_vidc_buffer *buf) { int rc = 0; @@ -467,7 +466,7 @@ static int vb2_buffer_to_driver(struct vb2_buffer *vb2, struct msm_vidc_buffer * } buf->valid = true; - buf->type = v4l2_type_to_driver(vb2->type); + buf->type = v4l2_type_to_driver(vb2->type, __func__); if (!buf->type) return -EINVAL; buf->index = vb2->index; @@ -475,7 +474,7 @@ static int vb2_buffer_to_driver(struct vb2_buffer *vb2, struct msm_vidc_buffer * buf->data_offset = vb2->planes[0].data_offset; buf->data_size = vb2->planes[0].bytesused; buf->buffer_size = vb2->planes[0].length; - buf->timestamp = vb2->timestamp; + buf->timestamp = do_div(vb2->timestamp, NSEC_PER_USEC); return rc; } @@ -618,7 +617,7 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, return NULL; } - buf_type = v4l2_type_to_driver(vb2->type); + buf_type = v4l2_type_to_driver(vb2->type, __func__); if (!buf_type) return NULL; @@ -641,8 +640,8 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, } if (found) { /* only YUV buffers are allowed to repeat */ - if ((is_decode_session(inst) && vb2->type != OUTPUT_PLANE) || - (is_encode_session(inst) && vb2->type != INPUT_PLANE)) { + if ((is_decode_session(inst) && vb2->type != OUTPUT_MPLANE) || + (is_encode_session(inst) && vb2->type != INPUT_MPLANE)) { print_vidc_buffer(VIDC_ERR, "existing buffer", inst, buf); goto error; @@ -655,7 +654,7 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, goto error; } /* for encoder, treat the repeated buffer as new buffer */ - if (is_encode_session(inst) && vb2->type == INPUT_PLANE) + if (is_encode_session(inst) && vb2->type == INPUT_MPLANE) found = false; } else { buf = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL); @@ -663,6 +662,7 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, s_vpr_e(inst->sid, "%s: alloc failed\n", __func__); goto error; } + INIT_LIST_HEAD(&buf->list); buf->dmabuf = dmabuf; } rc = vb2_buffer_to_driver(vb2, buf); @@ -688,28 +688,30 @@ struct msm_vidc_buffer *get_meta_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buf) { struct msm_vidc_buffer *mbuf; - struct msm_vidc_buffers *meta; + struct msm_vidc_buffers *buffers; bool found = false; if (!inst || !buf) { d_vpr_e("%s: invalid params\n", __func__); return NULL; } - + /* + * do not call print_vidc_buffer() in this function to avoid recursion, + * this function is called from print_vidc_buffer. + */ if (buf->type == MSM_VIDC_BUF_INPUT) { - meta = &inst->buffers.input_meta; + buffers = &inst->buffers.input_meta; } else if (buf->type == MSM_VIDC_BUF_OUTPUT) { - meta = &inst->buffers.output_meta; + buffers = &inst->buffers.output_meta; } else { s_vpr_e(inst->sid, "%s: invalid buffer type %d\n", __func__, buf->type); return NULL; } - list_for_each_entry(mbuf, &meta->list, list) { + list_for_each_entry(mbuf, &buffers->list, list) { if (!mbuf->valid) continue; - if (mbuf->type == buf->type && - mbuf->index == buf->index) { + if (mbuf->index == buf->index) { found = true; break; } @@ -724,6 +726,7 @@ int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) { int rc = 0; struct msm_vidc_buffer *buf; + struct msm_vidc_buffer *meta; int port; if (!inst || !vb2) { @@ -737,8 +740,12 @@ int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) /* meta buffer will be queued along with actual buffer */ if (buf->type == MSM_VIDC_BUF_INPUT_META || - buf->type == MSM_VIDC_BUF_OUTPUT_META) + buf->type == MSM_VIDC_BUF_OUTPUT_META) { + buf->attr |= MSM_VIDC_ATTR_DEFERRED; + s_vpr_l(inst->sid, "metabuf fd %3d daddr %#x deferred\n", + buf->fd, buf->device_addr); return 0; + } /* skip queuing if streamon not completed */ port = v4l2_type_to_driver_port(inst, vb2->type, __func__); @@ -751,10 +758,18 @@ int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) } print_vidc_buffer(VIDC_HIGH, "qbuf", inst, buf); - rc = venus_hfi_queue_buffer(inst, buf, get_meta_buffer(inst, buf)); + meta = get_meta_buffer(inst, buf); + rc = venus_hfi_queue_buffer(inst, buf, meta); if (rc) return rc; + buf->attr &= ~MSM_VIDC_ATTR_DEFERRED; + buf->attr |= MSM_VIDC_ATTR_QUEUED; + if (meta) { + meta->attr &= ~MSM_VIDC_ATTR_DEFERRED; + meta->attr |= MSM_VIDC_ATTR_QUEUED; + } + return rc; } @@ -839,8 +854,11 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst, return -ENOMEM; list_add_tail(&map->list, &mappings->list); - s_vpr_e(inst->sid, "%s: created buffer_type %#x, size %d\n", - __func__, buffer_type, buffers->size); + buffer->device_addr = map->device_addr; + s_vpr_h(inst->sid, + "%s: created buffer_type %#x, size %d device_addr %#x\n", + __func__, buffer_type, buffers->size, + buffer->device_addr); } return 0; @@ -930,6 +948,55 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst, return 0; } +int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *buf) +{ + int type, port; + struct vb2_queue *q; + struct vb2_buffer *vb2; + struct vb2_v4l2_buffer *vbuf; + bool found; + + if (!inst || !buf) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + type = v4l2_type_from_driver(buf->type, __func__); + if (!type) + return -EINVAL; + port = v4l2_type_to_driver_port(inst, type, __func__); + if (port < 0) + return -EINVAL; + + q = &inst->vb2q[port]; + if (!q->streaming) { + s_vpr_e(inst->sid, "%s: port %d is not streaming\n", + __func__, port); + return -EINVAL; + } + + found = false; + list_for_each_entry(vb2, &q->queued_list, queued_entry) { + if (vb2->state != VB2_BUF_STATE_ACTIVE) + continue; + if (vb2->index == buf->index) { + found = true; + break; + } + } + if (!found) { + print_vidc_buffer(VIDC_ERR, "vb2 not found for", inst, buf); + return -EINVAL; + } + vbuf = to_vb2_v4l2_buffer(vb2); + vbuf->flags = buf->flags; + vb2->timestamp = buf->timestamp * NSEC_PER_USEC; + vb2->planes[0].bytesused = buf->data_size; + vb2_buffer_done(vb2, VB2_BUF_STATE_DONE); + + return 0; +} + int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst) { int rc = 0; @@ -969,7 +1036,7 @@ static int vb2q_init(struct msm_vidc_inst *inst, core = inst->core; q->type = type; - q->io_modes = VB2_MMAP | VB2_USERPTR; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; q->ops = core->vb2_ops; q->mem_ops = core->vb2_mem_ops; @@ -989,11 +1056,11 @@ int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst) return -EINVAL; } - rc = vb2q_init(inst, &inst->vb2q[INPUT_PORT], INPUT_PLANE); + rc = vb2q_init(inst, &inst->vb2q[INPUT_PORT], INPUT_MPLANE); if (rc) return rc; - rc = vb2q_init(inst, &inst->vb2q[OUTPUT_PORT], OUTPUT_PLANE); + rc = vb2q_init(inst, &inst->vb2q[OUTPUT_PORT], OUTPUT_MPLANE); if (rc) return rc; @@ -1041,6 +1108,35 @@ int msm_vidc_add_session(struct msm_vidc_inst *inst) return rc; } +int msm_vidc_remove_session(struct msm_vidc_inst *inst) +{ + struct msm_vidc_inst *i, *temp; + struct msm_vidc_core *core; + u32 count = 0; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + + mutex_lock(&core->lock); + list_for_each_entry_safe(i, temp, &core->instances, list) { + if (i->session_id == inst->session_id) { + list_del_init(&i->list); + d_vpr_h("%s: removed session %d\n", + __func__, i->session_id); + inst->sid = 0; + } + } + list_for_each_entry(i, &core->instances, list) + count++; + d_vpr_h("%s: remaining sessions %d\n", __func__, count); + mutex_unlock(&core->lock); + + return 0; +} + int msm_vidc_session_open(struct msm_vidc_inst *inst) { int rc = 0; @@ -1064,9 +1160,15 @@ int msm_vidc_session_set_codec(struct msm_vidc_inst *inst) return -EINVAL; } - rc = venus_hfi_session_set_codec(inst); + if (inst->codec_set) + return 0; - return rc; + rc = venus_hfi_session_set_codec(inst); + if (rc) + return rc; + + inst->codec_set = true; + return 0; } int msm_vidc_session_close(struct msm_vidc_inst *inst) @@ -1087,7 +1189,7 @@ int msm_vidc_session_close(struct msm_vidc_inst *inst) rc = wait_for_completion_timeout( &inst->completions[SIGNAL_CMD_CLOSE], msecs_to_jiffies( - core->platform->data.core_data[HW_RESPONSE_TIMEOUT].value)); + core->capabilities[HW_RESPONSE_TIMEOUT].value)); if (!rc) { s_vpr_e(inst->sid, "%s: session close timed out\n", __func__); //msm_comm_kill_session(inst); @@ -1350,9 +1452,9 @@ int msm_vidc_core_init(struct msm_vidc_core *core) mutex_unlock(&core->lock); /*TODO: acquire lock or not */ d_vpr_h("%s(): waiting for sys init done, %d ms\n", __func__, - core->platform->data.core_data[HW_RESPONSE_TIMEOUT].value); + core->capabilities[HW_RESPONSE_TIMEOUT].value); rc = wait_for_completion_timeout(&core->init_done, msecs_to_jiffies( - core->platform->data.core_data[HW_RESPONSE_TIMEOUT].value)); + core->capabilities[HW_RESPONSE_TIMEOUT].value)); if (!rc) { d_vpr_e("%s: system init timed out\n", __func__); //msm_comm_kill_session(inst); diff --git a/driver/vidc/src/msm_vidc_dt.c b/driver/vidc/src/msm_vidc_dt.c index 5647fdce0e..82c966618b 100644 --- a/driver/vidc/src/msm_vidc_dt.c +++ b/driver/vidc/src/msm_vidc_dt.c @@ -304,6 +304,7 @@ static int msm_vidc_load_allowed_clocks_table( int rc = 0; struct platform_device *pdev = core->pdev; struct msm_vidc_dt *dt = core->dt; + int i; if (!of_find_property(pdev->dev.of_node, "qcom,allowed-clock-rates", NULL)) { @@ -324,15 +325,20 @@ static int msm_vidc_load_allowed_clocks_table( sort(dt->allowed_clks_tbl, dt->allowed_clks_tbl_size, sizeof(*dt->allowed_clks_tbl), cmp, NULL); + d_vpr_h("Found allowed clock rates\n"); + for (i = 0; i < dt->allowed_clks_tbl_size; i++) + d_vpr_h(" %d\n", dt->allowed_clks_tbl[i]); + return 0; } static int msm_vidc_load_bus_table(struct msm_vidc_core *core) { + int rc = 0; struct platform_device *pdev = core->pdev; struct msm_vidc_dt *dt = core->dt; struct bus_set *buses = &dt->bus_set; - int c = 0, num_buses = 0, rc = 0; + int c = 0, num_buses = 0; u32 *bus_ranges = NULL; num_buses = of_property_count_strings(pdev->dev.of_node, @@ -381,7 +387,8 @@ static int msm_vidc_load_bus_table(struct msm_vidc_core *core) bus->range[0] = bus_ranges[c * 2]; bus->range[1] = bus_ranges[c * 2 + 1]; - d_vpr_h("Found bus %s\n", bus->name); + d_vpr_h("Found bus %s, range [%d %d]\n", bus->name, + bus->range[0], bus->range[1]); } exit: diff --git a/driver/vidc/src/msm_vidc_platform.c b/driver/vidc/src/msm_vidc_platform.c index 9c2955cab4..b992e56644 100644 --- a/driver/vidc/src/msm_vidc_platform.c +++ b/driver/vidc/src/msm_vidc_platform.c @@ -29,10 +29,14 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_enum_framesizes = msm_v4l2_enum_framesizes, .vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt, .vidioc_s_fmt_vid_out = msm_v4l2_s_fmt, + .vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt, + .vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt, .vidioc_s_fmt_meta_out = msm_v4l2_s_fmt, .vidioc_s_fmt_meta_cap = msm_v4l2_s_fmt, .vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt, .vidioc_g_fmt_vid_out = msm_v4l2_g_fmt, + .vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt, + .vidioc_g_fmt_vid_out_mplane = msm_v4l2_g_fmt, .vidioc_g_fmt_meta_out = msm_v4l2_g_fmt, .vidioc_g_fmt_meta_cap = msm_v4l2_g_fmt, .vidioc_reqbufs = msm_v4l2_reqbufs, diff --git a/driver/vidc/src/msm_vidc_probe.c b/driver/vidc/src/msm_vidc_probe.c index dc7eadce1e..31090a1154 100644 --- a/driver/vidc/src/msm_vidc_probe.c +++ b/driver/vidc/src/msm_vidc_probe.c @@ -118,8 +118,10 @@ static int msm_vidc_register_video_device(struct msm_vidc_core *core, core->vdev[index].type = type; core->vdev[index].vdev.v4l2_dev = &core->v4l2_dev; core->vdev[index].vdev.device_caps = - V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE | - V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_META_OUTPUT | + V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_META_CAPTURE | + V4L2_CAP_META_OUTPUT | V4L2_CAP_STREAMING; rc = video_register_device(&core->vdev[index].vdev, VFL_TYPE_GRABBER, nr); diff --git a/driver/vidc/src/msm_vidc_vb2.c b/driver/vidc/src/msm_vidc_vb2.c index 62555f9acd..6e714e052c 100644 --- a/driver/vidc/src/msm_vidc_vb2.c +++ b/driver/vidc/src/msm_vidc_vb2.c @@ -41,6 +41,7 @@ int msm_vidc_queue_setup(struct vb2_queue *q, d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } + if (inst->state == MSM_VIDC_START) { d_vpr_e("%s: invalid state %d\n", __func__, inst->state); return -EINVAL; @@ -50,28 +51,65 @@ int msm_vidc_queue_setup(struct vb2_queue *q, if (port < 0) return -EINVAL; - if (port == INPUT_PORT || port == INPUT_META_PORT) { + if (port == INPUT_PORT) { if (inst->state == MSM_VIDC_START_INPUT) { d_vpr_e("%s: input invalid state %d\n", __func__, inst->state); return -EINVAL; } - } else if (port == OUTPUT_PORT || port == OUTPUT_META_PORT) { + + *num_planes = 1; + if (*num_buffers < inst->buffers.input.min_count + + inst->buffers.input.extra_count) + *num_buffers = inst->buffers.input.min_count + + inst->buffers.input.extra_count; + inst->buffers.input.actual_count = *num_buffers; + + } else if (port == INPUT_META_PORT) { + if (inst->state == MSM_VIDC_START_INPUT) { + d_vpr_e("%s: input_meta invalid state %d\n", + __func__, inst->state); + return -EINVAL; + } + + *num_planes = 1; + if (*num_buffers < inst->buffers.input_meta.min_count + + inst->buffers.input_meta.extra_count) + *num_buffers = inst->buffers.input_meta.min_count + + inst->buffers.input_meta.extra_count; + inst->buffers.input_meta.actual_count = *num_buffers; + + } else if (port == OUTPUT_PORT) { if (inst->state == MSM_VIDC_START_OUTPUT) { d_vpr_e("%s: output invalid state %d\n", __func__, inst->state); return -EINVAL; } + + *num_planes = 1; + if (*num_buffers < inst->buffers.output.min_count + + inst->buffers.output.extra_count) + *num_buffers = inst->buffers.output.min_count + + inst->buffers.output.extra_count; + inst->buffers.output.actual_count = *num_buffers; + + } else if (port == OUTPUT_META_PORT) { + if (inst->state == MSM_VIDC_START_OUTPUT) { + d_vpr_e("%s: output_meta invalid state %d\n", + __func__, inst->state); + return -EINVAL; + } + + *num_planes = 1; + if (*num_buffers < inst->buffers.output_meta.min_count + + inst->buffers.output_meta.extra_count) + *num_buffers = inst->buffers.output_meta.min_count + + inst->buffers.output_meta.extra_count; + inst->buffers.output_meta.actual_count = *num_buffers; } - *num_planes = 1; - if (*num_buffers < inst->buffers.input.min_count + - inst->buffers.input.extra_count) - *num_buffers = inst->buffers.input.min_count + - inst->buffers.input.extra_count; - inst->buffers.input.actual_count = *num_buffers; if (port == INPUT_PORT || port == OUTPUT_PORT) - sizes[0] = inst->fmts[port].fmt.pix.sizeimage; + sizes[0] = inst->fmts[port].fmt.pix_mp.plane_fmt[0].sizeimage; else if (port == INPUT_META_PORT || port == OUTPUT_META_PORT) sizes[0] = inst->fmts[port].fmt.meta.buffersize; @@ -123,19 +161,19 @@ int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) if ((inst->state == MSM_VIDC_START_INPUT) || (inst->state == MSM_VIDC_START && - q->type == INPUT_PLANE)) { + q->type == INPUT_MPLANE)) { rc = msm_vidc_set_fw_list(inst); if (rc) return -EINVAL; } */ - if (q->type == INPUT_PLANE) { + if (q->type == INPUT_MPLANE) { if (is_decode_session(inst)) rc = msm_vdec_start_input(inst); //else if (is_encode_session(inst)) // rc = msm_venc_start_input(inst); - } else if (q->type == OUTPUT_PLANE) { + } else if (q->type == OUTPUT_MPLANE) { if (is_decode_session(inst)) rc = msm_vdec_start_output(inst); //else if (is_encode_session(inst)) diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index 4530986833..5efb7d8031 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -144,7 +144,7 @@ static void __dump_packet(u8 *packet) static void __fatal_error(struct msm_vidc_core *core, bool fatal) { return; - fatal &= core->platform->data.core_data[HW_RESPONSE_TIMEOUT].value; + fatal &= core->capabilities[HW_RESPONSE_TIMEOUT].value; MSM_VIDC_ERROR(fatal); } @@ -273,33 +273,50 @@ int __read_register(struct msm_vidc_core *core, u32 reg) static void __schedule_power_collapse_work(struct msm_vidc_core *core) { - return; - if (!core->platform->data.core_data[SW_PC].value) + if (!core || !core->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); return; + } + if (!core->capabilities[SW_PC].value) { + d_vpr_l("software power collapse not enabled\n"); + return; + } cancel_delayed_work(&core->pm_work); if (!queue_delayed_work(core->pm_workq, &core->pm_work, msecs_to_jiffies( - core->platform->data.core_data[SW_PC_DELAY].value))) { - d_vpr_l("PM work already scheduled\n"); + core->capabilities[SW_PC_DELAY].value))) { + d_vpr_e("power collapse already scheduled\n"); + } else { + d_vpr_l("power collapse scheduled for %d ms\n", + core->capabilities[SW_PC_DELAY].value); } } static void __cancel_power_collapse_work(struct msm_vidc_core *core) { - return; - if (!core->platform->data.core_data[SW_PC].value) + if (!core || !core->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + return; + } + if (!core->capabilities[SW_PC].value) return; cancel_delayed_work(&core->pm_work); } -static int __acquire_regulator(struct regulator_info *rinfo, - struct msm_vidc_core *core) +static int __acquire_regulator(struct msm_vidc_core *core, + struct regulator_info *rinfo) { int rc = 0; if (rinfo->has_hw_power_collapse) { + if (regulator_get_mode(rinfo->regulator) == + REGULATOR_MODE_NORMAL) { + d_vpr_h("Skip acquire regulator %s\n", rinfo->name); + goto exit; + } + rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_NORMAL); if (rc) { @@ -308,27 +325,29 @@ static int __acquire_regulator(struct regulator_info *rinfo, * about it. We can't disable the regulator w/o * getting it back under s/w control */ - d_vpr_e( - "Failed to acquire regulator control: %s\n", + d_vpr_e("Failed to acquire regulator control: %s\n", rinfo->name); + goto exit; } else { - d_vpr_h("Acquire regulator control from HW: %s\n", + d_vpr_h("Acquired regulator control from HW: %s\n", rinfo->name); } + + if (!regulator_is_enabled(rinfo->regulator)) { + d_vpr_e("%s: Regulator is not enabled %s\n", + __func__, rinfo->name); + __fatal_error(core, true); + } } - if (!regulator_is_enabled(rinfo->regulator)) { - d_vpr_e("Regulator is not enabled %s\n", - rinfo->name); - __fatal_error(core, true); - } - +exit: return rc; } -static int __hand_off_regulator(struct regulator_info *rinfo) +static int __hand_off_regulator(struct msm_vidc_core *core, + struct regulator_info *rinfo) { int rc = 0; @@ -336,13 +355,19 @@ static int __hand_off_regulator(struct regulator_info *rinfo) rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_FAST); if (rc) { - d_vpr_e( - "Failed to hand off regulator control: %s\n", + d_vpr_e("Failed to hand off regulator control: %s\n", rinfo->name); + return rc; } else { d_vpr_h("Hand off regulator control to HW: %s\n", rinfo->name); } + + if (!regulator_is_enabled(rinfo->regulator)) { + d_vpr_e("%s: Regulator is not enabled %s\n", + __func__, rinfo->name); + __fatal_error(core, true); + } } return rc; @@ -354,7 +379,7 @@ static int __hand_off_regulators(struct msm_vidc_core *core) int rc = 0, c = 0; venus_hfi_for_each_regulator(core, rinfo) { - rc = __hand_off_regulator(rinfo); + rc = __hand_off_regulator(core, rinfo); /* * If one regulator hand off failed, driver should take * the control for other regulators back. @@ -367,7 +392,7 @@ static int __hand_off_regulators(struct msm_vidc_core *core) return rc; err_reg_handoff_failed: venus_hfi_for_each_regulator_reverse_continue(core, rinfo, c) - __acquire_regulator(rinfo, core); + __acquire_regulator(core, rinfo); return rc; } @@ -490,30 +515,29 @@ static int __set_clk_rate(struct msm_vidc_core *core, int rc = 0; struct clk *clk = cl->clk; + /* bail early if requested clk rate is not changed */ + if (rate == cl->prev) + return 0; + rc = clk_set_rate(clk, rate); if (rc) { - d_vpr_e( - "%s: Failed to set clock rate %llu %s: %d\n", + d_vpr_e("%s: Failed to set clock rate %llu %s: %d\n", __func__, rate, cl->name, rc); return rc; } - - core->power.clk_freq = rate; - + cl->prev = rate; return rc; } static int __set_clocks(struct msm_vidc_core *core, u32 freq) { - struct clock_info *cl; int rc = 0; - - /* bail early if requested clk_freq is not changed */ - if (freq == core->power.clk_freq) - return 0; + struct clock_info *cl; venus_hfi_for_each_clock(core, cl) { if (cl->has_scaling) {/* has_scaling */ + d_vpr_h("Scaling clock %s to %u, prev %llu\n", + cl->name, freq, cl->prev); rc = __set_clk_rate(core, cl, freq); if (rc) return rc; @@ -526,15 +550,19 @@ static int __set_clocks(struct msm_vidc_core *core, u32 freq) static int __scale_clocks(struct msm_vidc_core *core) { int rc = 0; - struct allowed_clock_rates_table *allowed_clks_tbl = NULL; - u32 rate = 0; + struct allowed_clock_rates_table *allowed_clks_tbl; + u32 freq = 0; allowed_clks_tbl = core->dt->allowed_clks_tbl; - rate = core->power.clk_freq ? core->power.clk_freq : + freq = core->power.clk_freq ? core->power.clk_freq : allowed_clks_tbl[0].clock_rate; - rc = __set_clocks(core, rate); - return rc; + rc = __set_clocks(core, freq); + if (rc) + return rc; + + core->power.clk_freq = freq; + return 0; } static int __write_queue(struct msm_vidc_iface_q_info *qinfo, u8 *packet, @@ -806,7 +834,7 @@ err_q_null: return result; } -static int __iface_cmdq_write(struct msm_vidc_core *core, +int __iface_cmdq_write(struct msm_vidc_core *core, void *pkt) { bool needs_interrupt = false; @@ -818,7 +846,7 @@ static int __iface_cmdq_write(struct msm_vidc_core *core, return rc; } -static int __iface_msgq_read(struct msm_vidc_core *core, void *pkt) +int __iface_msgq_read(struct msm_vidc_core *core, void *pkt) { u32 tx_req_is_set = 0; int rc = 0; @@ -856,7 +884,7 @@ read_error_null: return rc; } -static int __iface_dbgq_read(struct msm_vidc_core *core, void *pkt) +int __iface_dbgq_read(struct msm_vidc_core *core, void *pkt) { u32 tx_req_is_set = 0; int rc = 0; @@ -958,7 +986,6 @@ static int __sys_set_debug(struct msm_vidc_core *core, u32 debug) { int rc = 0; - //rc = call_hfi_pkt_op(core, sys_debug_config, pkt, debug); rc = hfi_packet_sys_debug_config(core, core->packet, core->packet_size, debug); if (rc) { @@ -1052,7 +1079,7 @@ static int __power_collapse(struct msm_vidc_core *core, bool force) if (rc) goto skip_power_off; - //__flush_debug_queue(core, core->raw_packet); + __flush_debug_queue(core, core->packet); rc = __suspend(core); if (rc) @@ -1062,6 +1089,7 @@ exit: return rc; skip_power_off: + d_vpr_e("%s: skipped\n", __func__); return -EAGAIN; } @@ -1105,7 +1133,7 @@ static int __protect_cp_mem(struct msm_vidc_core *core) return rc; } - +#if 0 // TODO static int __core_set_resource(struct msm_vidc_core *core, struct vidc_resource_hdr *resource_hdr, void *resource_value) { @@ -1156,7 +1184,7 @@ static int __core_release_resource(struct msm_vidc_core *core, err_create_pkt: return rc; } - +#endif @@ -1281,6 +1309,7 @@ void __disable_unprepare_clks(struct msm_vidc_core *core) __func__, cl->name); clk_disable_unprepare(cl->clk); + cl->prev = 0; if (__clk_is_enabled(cl->clk)) d_vpr_e("%s: clock %s not disabled\n", @@ -1367,6 +1396,7 @@ fail_clk_enable: d_vpr_e("Clock: %s disable and unprepare\n", cl->name); clk_disable_unprepare(cl->clk); + cl->prev = 0; } return rc; @@ -1592,7 +1622,7 @@ static int __disable_regulator(struct regulator_info *rinfo, * is unknown. */ - rc = __acquire_regulator(rinfo, core); + rc = __acquire_regulator(core, rinfo); if (rc) { /* * This is somewhat fatal, but nothing we can do @@ -1632,6 +1662,10 @@ static int __enable_hw_power_collapse(struct msm_vidc_core *core) { int rc = 0; + // TODO: skip if hardwar power control feature is not present + d_vpr_e("%s: skip hand off regulators\n", __func__); + return 0; + rc = __hand_off_regulators(core); if (rc) d_vpr_e("%s: Failed to enable HW power collapse %d\n", @@ -1689,6 +1723,7 @@ int __disable_regulators(struct msm_vidc_core *core) static int __release_subcaches(struct msm_vidc_core *core) { +#if 0 // TODO struct subcache_info *sinfo; int rc = 0; u32 c = 0; @@ -1727,7 +1762,7 @@ static int __release_subcaches(struct msm_vidc_core *core) } core->dt->sys_cache_res_set = false; - +#endif return 0; } @@ -1791,6 +1826,7 @@ err_activate_fail: static int __set_subcaches(struct msm_vidc_core *core) { +#if 0 // TODO int rc = 0; u32 c = 0; struct subcache_info *sinfo; @@ -1845,7 +1881,7 @@ static int __set_subcaches(struct msm_vidc_core *core) err_fail_set_subacaches: __disable_subcaches(core); - +#endif return 0; } /* @@ -2302,6 +2338,7 @@ void venus_hfi_work_handler(struct work_struct *work) call_venus_op(core, clear_interrupt, core); mutex_unlock(&core->lock); + num_responses = __response_handler(core); err_no_work: @@ -2315,12 +2352,11 @@ void venus_hfi_pm_work_handler(struct work_struct *work) int rc = 0; struct msm_vidc_core *core; - core = container_of(work, struct msm_vidc_core, device_work); + core = container_of(work, struct msm_vidc_core, pm_work.work); if (!core) { d_vpr_e("%s: invalid params\n", __func__); return; } - d_vpr_e("%s(): core %pK\n", __func__, core); /* * It is ok to check this variable outside the lock since @@ -2361,6 +2397,36 @@ void venus_hfi_pm_work_handler(struct work_struct *work) mutex_unlock(&core->lock); } +static int __sys_init(struct msm_vidc_core *core) +{ + int rc = 0; + + rc = hfi_packet_sys_init(core, core->packet, core->packet_size); + if (rc) + return rc; + + rc = __iface_cmdq_write(core, core->packet); + if (rc) + return rc; + + return 0; +} + +static int __sys_image_version(struct msm_vidc_core *core) +{ + int rc = 0; + + rc = hfi_packet_image_version(core, core->packet, core->packet_size); + if (rc) + return rc; + + rc = __iface_cmdq_write(core, core->packet); + if (rc) + return rc; + + return 0; +} + int venus_hfi_core_init(struct msm_vidc_core *core) { int rc = 0; @@ -2399,22 +2465,8 @@ int venus_hfi_core_init(struct msm_vidc_core *core) if (rc) goto error; - rc = hfi_packet_sys_init(core, core->packet, core->packet_size); - if (rc) - goto error; - - rc = __iface_cmdq_write(core, core->packet); - if (rc) - goto error; - - rc = hfi_packet_image_version(core, core->packet, core->packet_size); - if (rc) - goto error; - - rc = __iface_cmdq_write(core, core->packet); - if (rc) - goto error; - + __sys_init(core); + __sys_image_version(core); __sys_set_debug(core, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT); __enable_subcaches(core); __set_subcaches(core); @@ -2474,6 +2526,7 @@ int venus_hfi_session_open(struct msm_vidc_inst *inst) d_vpr_e("%s(): inst packet allocation failed\n", __func__); return -ENOMEM; } + rc = hfi_packet_session_command(inst, HFI_CMD_OPEN, (HFI_HOST_FLAGS_RESPONSE_REQUIRED | @@ -2504,7 +2557,7 @@ int venus_hfi_session_set_codec(struct msm_vidc_inst *inst) } codec = get_hfi_codec(inst); - rc = hfi_packet_session_property(inst, + rc = venus_hfi_session_property(inst, HFI_PROP_CODEC, HFI_HOST_FLAGS_NONE, HFI_PORT_NONE, @@ -2514,12 +2567,46 @@ int venus_hfi_session_set_codec(struct msm_vidc_inst *inst) if (rc) goto error; +error: + return rc; +} + +int venus_hfi_session_property(struct msm_vidc_inst *inst, + u32 pkt_type, u32 flags, u32 port, u32 payload_type, + void *payload, u32 payload_size) +{ + int rc = 0; + struct msm_vidc_core *core; + + if (!inst || !inst->core || !inst->packet) { + d_vpr_e("%s: Invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + + rc = hfi_create_header(inst->packet, inst->packet_size, + inst->session_id, core->header_id++); + if (rc) + goto err_prop; + 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_prop; + rc = __iface_cmdq_write(inst->core, inst->packet); if (rc) - goto error; + goto err_prop; - inst->codec_set = true; -error: + return rc; + +err_prop: + d_vpr_e("%s: create packet failed\n", __func__); return rc; } diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index 687c1684da..d4c1473144 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -33,8 +33,8 @@ bool is_valid_hfi_buffer_type(struct msm_vidc_inst *inst, } if (buffer_type != HFI_BUFFER_BITSTREAM && - buffer_type != HFI_BUFFER_RAW && - buffer_type != HFI_BUFFER_METADATA) { + buffer_type != HFI_BUFFER_RAW && + buffer_type != HFI_BUFFER_METADATA) { s_vpr_e(inst->sid, "%s: invalid buffer type %#x\n", func, buffer_type); return false; @@ -210,29 +210,174 @@ static int handle_session_drain(struct msm_vidc_inst *inst, return 0; } -static void handle_input_buffer(struct msm_vidc_inst *inst, +static int handle_input_buffer(struct msm_vidc_inst *inst, struct hfi_buffer *buffer) { + int rc = 0; + struct msm_vidc_buffers *buffers; + struct msm_vidc_buffer *buf; + bool found; + + buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_INPUT, __func__); + if (!buffers) + return -EINVAL; + + found = false; + list_for_each_entry(buf, &buffers->list, list) { + if (buf->device_addr == buffer->base_address) { + found = true; + break; + } + } + if (!found) { + s_vpr_e(inst->sid, "%s: buffer not found for idx %d addr %#x\n", + __func__, buffer->index, buffer->base_address); + return -EINVAL; + } + buf->data_offset = buffer->data_offset; + buf->data_size = buffer->data_size; + buf->attr &= ~MSM_VIDC_ATTR_QUEUED; + buf->flags = 0; + if (buffer->flags & HFI_BUF_FW_FLAG_CORRUPT) { + s_vpr_h(inst->sid, "%s: data corrupted\n", __func__); + buf->flags |= MSM_VIDC_BUF_FLAG_ERROR; + } + if (buffer->flags & HFI_BUF_FW_FLAG_UNSUPPORTED) { + s_vpr_e(inst->sid, "%s: unsupported input\n", __func__); + buf->flags |= MSM_VIDC_BUF_FLAG_ERROR; + // TODO: move inst->state to error state + } + + print_vidc_buffer(VIDC_HIGH, "EBD", inst, buf); + msm_vidc_vb2_buffer_done(inst, buf); + msm_vidc_put_driver_buf(inst, buf); + + return rc; } -static void handle_output_buffer(struct msm_vidc_inst *inst, +static int handle_output_buffer(struct msm_vidc_inst *inst, struct hfi_buffer *buffer) { + int rc = 0; + struct msm_vidc_buffers *buffers; + struct msm_vidc_buffer *buf; + bool found; + + buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_OUTPUT, __func__); + if (!buffers) + return -EINVAL; + + found = false; + list_for_each_entry(buf, &buffers->list, list) { + if (buf->device_addr == buffer->base_address) { + found = true; + break; + } + } + if (!found) { + s_vpr_e(inst->sid, "%s: invalid idx %d daddr %#x\n", + __func__, buffer->index, buffer->base_address); + return -EINVAL; + } + buf->data_offset = buffer->data_offset; + buf->data_size = buffer->data_size; + buf->timestamp = buffer->timestamp; + + buf->attr &= ~MSM_VIDC_ATTR_QUEUED; + if (buffer->flags & HFI_BUF_FW_FLAG_READONLY) + buf->attr |= MSM_VIDC_ATTR_READ_ONLY; + else + buf->attr &= ~MSM_VIDC_ATTR_READ_ONLY; + + buf->flags = 0; + if (buffer->flags & HFI_BUF_FW_FLAG_KEYFRAME) + buf->flags |= MSM_VIDC_BUF_FLAG_KEYFRAME; + if (buffer->flags & HFI_BUF_FW_FLAG_LAST) + buf->flags |= MSM_VIDC_BUF_FLAG_LAST; + if (buffer->flags & HFI_BUF_FW_FLAG_CORRUPT) + buf->flags |= MSM_VIDC_BUF_FLAG_ERROR; + if (buffer->flags & HFI_BUF_FW_FLAG_CODEC_CONFIG) + buf->flags |= MSM_VIDC_BUF_FLAG_CODECCONFIG; + if (buffer->flags & HFI_BUF_FW_FLAG_SUBFRAME) + buf->flags |= MSM_VIDC_BUF_FLAG_SUBFRAME; + + print_vidc_buffer(VIDC_HIGH, "FBD", inst, buf); + msm_vidc_vb2_buffer_done(inst, buf); + msm_vidc_put_driver_buf(inst, buf); + + return rc; } -static void handle_input_metadata_buffer(struct msm_vidc_inst *inst, +static int handle_input_metadata_buffer(struct msm_vidc_inst *inst, struct hfi_buffer *buffer) { + int rc = 0; + struct msm_vidc_buffers *buffers; + struct msm_vidc_buffer *buf; + bool found; + + buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_INPUT_META, __func__); + if (!buffers) + return -EINVAL; + + found = false; + list_for_each_entry(buf, &buffers->list, list) { + if (buf->device_addr == buffer->base_address) { + found = true; + break; + } + } + if (found) { + s_vpr_h(inst->sid, + "input metadata buffer done: idx %d fd %d daddr %#x\n", + buf->index, buf->fd, buf->device_addr); + msm_vidc_vb2_buffer_done(inst, buf); + msm_vidc_put_driver_buf(inst, buf); + } else { + s_vpr_e(inst->sid, "%s: invalid idx %d daddr %#x\n", + __func__, buffer->index, buffer->base_address); + return -EINVAL; + } + return rc; } -static void handle_output_metadata_buffer(struct msm_vidc_inst *inst, +static int handle_output_metadata_buffer(struct msm_vidc_inst *inst, struct hfi_buffer *buffer) { + int rc = 0; + struct msm_vidc_buffers *buffers; + struct msm_vidc_buffer *buf; + bool found; + + buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_OUTPUT_META, __func__); + if (!buffers) + return -EINVAL; + + found = false; + list_for_each_entry(buf, &buffers->list, list) { + if (buf->device_addr == buffer->base_address) { + found = true; + break; + } + } + if (found) { + s_vpr_h(inst->sid, + "output metadata buffer done: idx %d fd %d daddr %#x\n", + buf->index, buf->fd, buf->device_addr); + msm_vidc_vb2_buffer_done(inst, buf); + msm_vidc_put_driver_buf(inst, buf); + } else { + s_vpr_e(inst->sid, "%s: invalid idx %d daddr %#x\n", + __func__, buffer->index, buffer->base_address); + return -EINVAL; + } + return rc; } static int handle_session_buffer(struct msm_vidc_inst *inst, struct hfi_packet *pkt) { + int rc = 0; struct hfi_buffer *buffer; u32 buf_type = 0, port_type = 0; @@ -255,38 +400,37 @@ static int handle_session_buffer(struct msm_vidc_inst *inst, return 0; } - s_vpr_h(inst->sid, "%s: Received buffer of type %#x\n", - __func__, buf_type); - if (is_encode_session(inst)) { if (port_type == HFI_PORT_BITSTREAM) { if (buf_type == HFI_BUFFER_METADATA) - handle_output_metadata_buffer(inst, buffer); + rc = handle_output_metadata_buffer(inst, buffer); else if (buf_type == HFI_BUFFER_BITSTREAM) - handle_output_buffer(inst, buffer); - } else if (port_type == HFI_PORT_RAW) { + rc = handle_output_buffer(inst, buffer); + } else if (port_type == HFI_PORT_RAW) { if (buf_type == HFI_BUFFER_METADATA) - handle_input_metadata_buffer(inst, buffer); + rc = handle_input_metadata_buffer(inst, buffer); else if (buf_type == HFI_BUFFER_RAW) - handle_input_buffer(inst, buffer); + rc = handle_input_buffer(inst, buffer); } } else if (is_decode_session(inst)) { if (port_type == HFI_PORT_BITSTREAM) { if (buf_type == HFI_BUFFER_METADATA) - handle_input_metadata_buffer(inst, buffer); + rc = handle_input_metadata_buffer(inst, buffer); else if (buf_type == HFI_BUFFER_BITSTREAM) - handle_input_buffer(inst, buffer); - } else if (port_type == HFI_PORT_RAW) { + rc = handle_input_buffer(inst, buffer); + } else if (port_type == HFI_PORT_RAW) { if (buf_type == HFI_BUFFER_METADATA) - handle_output_metadata_buffer(inst, buffer); + rc = handle_output_metadata_buffer(inst, buffer); else if (buf_type == HFI_BUFFER_RAW) - handle_output_buffer(inst, buffer); + rc = handle_output_buffer(inst, buffer); } } else { - s_vpr_e(inst->sid, "%s: invalid session\n", __func__); + s_vpr_e(inst->sid, "%s: invalid session %d\n", + __func__, inst->domain); + return -EINVAL; } - return 0; + return rc; } static int handle_port_settings_change(struct msm_vidc_inst *inst, @@ -424,15 +568,18 @@ static int handle_session_response(struct msm_vidc_core *core, inst = get_inst(core, hdr->session_id); if (!inst) { d_vpr_e("%s: invalid params\n", __func__); - goto exit; + return -EINVAL; } + mutex_lock(&inst->lock); pkt = (struct hfi_packet *)((u8 *)hdr + sizeof(struct hfi_header)); for (i = 0; i < hdr->num_packets; i++) { if (validate_packet((u8 *)pkt, core->response_packet, - core->packet_size, __func__)) + core->packet_size, __func__)) { + rc = -EINVAL; goto exit; + } if (pkt->type < HFI_CMD_END && pkt->type > HFI_CMD_BEGIN) { rc = handle_session_command(inst, pkt); } else if (pkt->type > HFI_PROP_BEGIN && @@ -444,11 +591,13 @@ static int handle_session_response(struct msm_vidc_core *core, } else { s_vpr_e(inst->sid, "%s: Unknown packet type: %#x\n", __func__, pkt->type); + rc = -EINVAL; goto exit; } pkt += pkt->size; } exit: + mutex_unlock(&inst->lock); put_inst(inst); return rc; } diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index f5ab05e0ff..9ceef699ef 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -15,12 +15,11 @@ /* NV12_512 8-bit Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV12_512 v4l2_fourcc('Q', '5', '1', '2') /* NV12 10-bit Y/CbCr 4:2:0 */ -#define V4L2_PIX_FMT_NV12_P010_UBWC v4l2_fourcc('Q', '1', '2', 'B') +#define V4L2_PIX_FMT_NV12_P010 v4l2_fourcc('Q', 'P', '1', '0') /* UBWC 10-bit Y/CbCr 4:2:0 */ -#define V4L2_PIX_FMT_NV12_TP10_UBWC v4l2_fourcc('Q', '1', '2', 'A') +#define V4L2_PIX_FMT_NV12_TP10_UBWC v4l2_fourcc('Q', 'T', 'P', '0') #define V4L2_PIX_FMT_RGBA8888_UBWC v4l2_fourcc('Q', 'R', 'G', 'B') /* Y/CbCr 4:2:0 P10 Venus */ -#define V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS v4l2_fourcc('Q', 'P', '1', '0') #define V4L2_PIX_FMT_VIDC_META v4l2_fourcc('Q', 'M', 'E', 'T') /* vendor color format end */