video: driver: add decoder input streamon support

Add decoder input streamon functionality which
include internal buffers support as well.

Change-Id: Ifb5afa51a29270705863c273d1ae08310666895d
Signed-off-by: Maheshwar Ajja <majja@codeaurora.org>
This commit is contained in:
Maheshwar Ajja
2020-08-14 00:25:14 -07:00
parent 4b08bf5e4d
commit 6f3faa8d04
21 changed files with 2993 additions and 232 deletions

View File

@@ -21,6 +21,7 @@ msm-vidc-objs := driver/vidc/src/msm_vidc_v4l2.o \
driver/vidc/src/msm_vdec.o \ driver/vidc/src/msm_vdec.o \
driver/vidc/src/msm_venc.o \ driver/vidc/src/msm_venc.o \
driver/vidc/src/msm_vidc_driver.o \ driver/vidc/src/msm_vidc_driver.o \
driver/vidc/src/msm_vidc_buffer.o \
driver/vidc/src/msm_vidc_probe.o \ driver/vidc/src/msm_vidc_probe.o \
driver/vidc/src/msm_vidc_dt.o \ driver/vidc/src/msm_vidc_dt.o \
driver/vidc/src/msm_vidc_platform.o \ driver/vidc/src/msm_vidc_platform.o \
@@ -36,7 +37,8 @@ include $(srctree)/techpack/video/config/waipio_video.conf
LINUXINCLUDE += -include $(srctree)/techpack/video/config/waipio_video.h LINUXINCLUDE += -include $(srctree)/techpack/video/config/waipio_video.h
msm-vidc-objs += driver/platform/waipio/src/msm_vidc_waipio.o \ msm-vidc-objs += driver/platform/waipio/src/msm_vidc_waipio.o \
driver/variant/iris2/src/msm_vidc_iris2.o driver/variant/iris2/src/msm_vidc_iris2.o \
driver/variant/iris2/src/msm_vidc_buffer_iris2.o
endif endif
endif endif

View File

@@ -1 +1 @@
export CONFIG_MSM_VIDC_V4L2=m export CONFIG_MSM_VIDC_V4L2=y

View File

@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#ifndef __H_MSM_VIDC_BUFFER_IRIS2_H__
#define __H_MSM_VIDC_BUFFER_IRIS2_H__
#include "msm_vidc_inst.h"
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);
u32 msm_vidc_decoder_persist_1_size_iris2(struct msm_vidc_inst *inst);
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);
u32 msm_vidc_encoder_scratch_2_size_iris2(struct msm_vidc_inst *inst);
u32 msm_vidc_encoder_persist_size_iris2(struct msm_vidc_inst *inst);
#endif // __H_MSM_VIDC_BUFFER_IRIS2_H__

File diff suppressed because it is too large Load Diff

View File

@@ -6,10 +6,14 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include "msm_vidc_iris2.h" #include "msm_vidc_iris2.h"
#include "msm_vidc_buffer_iris2.h"
#include "venus_hfi.h" #include "venus_hfi.h"
#include "msm_vidc_inst.h"
#include "msm_vidc_core.h" #include "msm_vidc_core.h"
#include "msm_vidc_driver.h"
#include "msm_vidc_dt.h" #include "msm_vidc_dt.h"
#include "msm_vidc_internal.h" #include "msm_vidc_internal.h"
#include "msm_vidc_buffer.h"
#include "msm_vidc_debug.h" #include "msm_vidc_debug.h"
@@ -490,52 +494,161 @@ static struct msm_vidc_venus_ops iris2_ops = {
.noc_error_info = __noc_error_info_iris2, .noc_error_info = __noc_error_info_iris2,
}; };
static int msm_vidc_buffer_size(struct msm_vidc_inst *inst, static int msm_vidc_buffer_size_iris2(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type type) enum msm_vidc_buffer_type buffer_type)
{ {
int rc = 0; int size = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
d_vpr_h("%s()\n", __func__); d_vpr_h("%s()\n", __func__);
return rc; if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return size;
}
if (is_decode_session(inst)) {
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
size = msm_vidc_decoder_input_size(inst);
break;
case MSM_VIDC_BUF_OUTPUT:
size = msm_vidc_decoder_output_size(inst);
break;
case MSM_VIDC_BUF_INPUT_META:
size = msm_vidc_decoder_input_meta_size(inst);
break;
case MSM_VIDC_BUF_OUTPUT_META:
size = msm_vidc_decoder_output_meta_size(inst);
break;
case MSM_VIDC_BUF_SCRATCH:
size = msm_vidc_decoder_scratch_size_iris2(inst);
break;
case MSM_VIDC_BUF_SCRATCH_1:
size = msm_vidc_decoder_scratch_1_size_iris2(inst);
break;
case MSM_VIDC_BUF_PERSIST_1:
size = msm_vidc_decoder_persist_1_size_iris2(inst);
break;
default:
break;
}
} else if (is_encode_session(inst)) {
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
size = msm_vidc_encoder_input_size(inst);
break;
case MSM_VIDC_BUF_OUTPUT:
size = msm_vidc_encoder_output_size(inst);
break;
case MSM_VIDC_BUF_INPUT_META:
size = msm_vidc_encoder_input_meta_size(inst);
break;
case MSM_VIDC_BUF_OUTPUT_META:
size = msm_vidc_encoder_output_meta_size(inst);
break;
case MSM_VIDC_BUF_SCRATCH:
size = msm_vidc_encoder_scratch_size_iris2(inst);
break;
case MSM_VIDC_BUF_SCRATCH_1:
size = msm_vidc_encoder_scratch_1_size_iris2(inst);
break;
case MSM_VIDC_BUF_SCRATCH_2:
size = msm_vidc_encoder_scratch_2_size_iris2(inst);
break;
case MSM_VIDC_BUF_PERSIST:
size = msm_vidc_encoder_persist_size_iris2(inst);
break;
default:
break;
}
}
return size;
} }
static int msm_vidc_buffer_min_count(struct msm_vidc_inst *inst, static int msm_vidc_min_count_iris2(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type type) enum msm_vidc_buffer_type buffer_type)
{ {
int rc = 0; int count = 0;
if (!inst) { if (!inst) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
d_vpr_h("%s()\n", __func__); d_vpr_h("%s()\n", __func__);
return rc;
if (is_decode_session(inst)) {
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
case MSM_VIDC_BUF_INPUT_META:
count = msm_vidc_input_min_count(inst);
break;
case MSM_VIDC_BUF_OUTPUT:
case MSM_VIDC_BUF_OUTPUT_META:
count = msm_vidc_output_min_count(inst);
break;
case MSM_VIDC_BUF_SCRATCH:
case MSM_VIDC_BUF_SCRATCH_1:
case MSM_VIDC_BUF_PERSIST_1:
count = 1;
break;
default:
break;
}
} else if (is_encode_session(inst)) {
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
case MSM_VIDC_BUF_INPUT_META:
count = msm_vidc_input_min_count(inst);
break;
case MSM_VIDC_BUF_OUTPUT:
case MSM_VIDC_BUF_OUTPUT_META:
count = msm_vidc_output_min_count(inst);
break;
case MSM_VIDC_BUF_SCRATCH:
case MSM_VIDC_BUF_SCRATCH_1:
case MSM_VIDC_BUF_SCRATCH_2:
case MSM_VIDC_BUF_PERSIST:
count = 1;
break;
default:
break;
}
}
return count;
} }
static int msm_vidc_buffer_extra_count(struct msm_vidc_inst *inst, static int msm_vidc_extra_count_iris2(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type type) enum msm_vidc_buffer_type buffer_type)
{ {
int rc = 0; int count = 0;
if (!inst) { if (!inst) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
d_vpr_h("%s()\n", __func__); d_vpr_h("%s()\n", __func__);
return rc;
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
case MSM_VIDC_BUF_INPUT_META:
count = msm_vidc_input_extra_count(inst);
break;
case MSM_VIDC_BUF_OUTPUT:
case MSM_VIDC_BUF_OUTPUT_META:
count = msm_vidc_output_extra_count(inst);
break;
default:
break;
}
return count;
} }
static struct msm_vidc_session_ops msm_session_ops = { static struct msm_vidc_session_ops msm_session_ops = {
.buffer_size = msm_vidc_buffer_size, .buffer_size = msm_vidc_buffer_size_iris2,
.min_count = msm_vidc_buffer_min_count, .min_count = msm_vidc_min_count_iris2,
.extra_count = msm_vidc_buffer_extra_count, .extra_count = msm_vidc_extra_count_iris2,
.calc_freq = NULL, .calc_freq = NULL,
.calc_bw = NULL, .calc_bw = NULL,
.decide_work_route = NULL, .decide_work_route = NULL,

View File

@@ -81,12 +81,11 @@ enum hfi_buffer_type {
HFI_BUFFER_BITSTREAM = 0x00000001, HFI_BUFFER_BITSTREAM = 0x00000001,
HFI_BUFFER_RAW = 0x00000002, HFI_BUFFER_RAW = 0x00000002,
HFI_BUFFER_METADATA = 0x00000003, HFI_BUFFER_METADATA = 0x00000003,
HFI_BUFFER_DPB = 0x00000010, HFI_BUFFER_SCRATCH = 0x00000010,
HFI_BUFFER_BIN = 0x00000011, HFI_BUFFER_SCRATCH_1 = 0x00000011,
HFI_BUFFER_LINE = 0x00000012, HFI_BUFFER_SCRATCH_2 = 0x00000012,
HFI_BUFFER_ARP = 0x00000013, HFI_BUFFER_PERSIST = 0x00000013,
HFI_BUFFER_COMV = 0x00000014, HFI_BUFFER_PERSIST_1 = 0x00000014,
HFI_BUFFER_NON_COMV = 0x00000015,
HFI_BUFFER_SUBCACHE = 0x00000020, HFI_BUFFER_SUBCACHE = 0x00000020,
HFI_BUFFER_SFR = 0x00000021, HFI_BUFFER_SFR = 0x00000021,
}; };

View File

@@ -13,6 +13,13 @@
#include "hfi_property.h" #include "hfi_property.h"
#include "hfi_definition.h" #include "hfi_definition.h"
u32 get_hfi_port(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type);
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);
int get_hfi_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buffer, struct hfi_buffer *buf);
int hfi_create_header(u8 *pkt, u32 session_id, int hfi_create_header(u8 *pkt, u32 session_id,
u32 header_id, u32 num_packets, u32 total_size); u32 header_id, u32 num_packets, u32 total_size);
int hfi_create_packet(u8 *packet, u32 packet_size, u32 *offset, int hfi_create_packet(u8 *packet, u32 packet_size, u32 *offset,
@@ -32,8 +39,8 @@ int hfi_packet_sys_debug_config(struct msm_vidc_core *core,
int hfi_packet_session_command(struct msm_vidc_inst *inst, int hfi_packet_session_command(struct msm_vidc_inst *inst,
u32 pkt_type, u32 flags, u32 port, u32 session_id, u32 pkt_type, u32 flags, u32 port, u32 session_id,
u32 payload_type, void *payload, u32 payload_size); u32 payload_type, void *payload, u32 payload_size);
int hfi_packet_create_property(struct msm_vidc_inst *inst, int hfi_packet_session_property(struct msm_vidc_inst *inst,
void *pkt, u32 pkt_size, u32 pkt_type, u32 flags, u32 pkt_type, u32 flags, u32 port,
u32 port, u32 payload, u32 payload_type, u32 payload_size); u32 payload_type, void *payload, u32 payload_size);
#endif // _HFI_PACKET_H_ #endif // _HFI_PACKET_H_

View File

@@ -9,6 +9,10 @@
#include "msm_vidc_core.h" #include "msm_vidc_core.h"
#include "msm_vidc_inst.h" #include "msm_vidc_inst.h"
int msm_vdec_stop_input(struct msm_vidc_inst *inst);
int msm_vdec_start_input(struct msm_vidc_inst *inst);
int msm_vdec_stop_output(struct msm_vidc_inst *inst);
int msm_vdec_start_output(struct msm_vidc_inst *inst);
int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_vdec_inst_init(struct msm_vidc_inst *inst); int msm_vdec_inst_init(struct msm_vidc_inst *inst);

View File

@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#ifndef __H_MSM_VIDC_BUFFER_H__
#define __H_MSM_VIDC_BUFFER_H__
#include "msm_vidc_inst.h"
u32 msm_vidc_input_min_count(struct msm_vidc_inst *inst);
u32 msm_vidc_output_min_count(struct msm_vidc_inst *inst);
u32 msm_vidc_input_extra_count(struct msm_vidc_inst *inst);
u32 msm_vidc_output_extra_count(struct msm_vidc_inst *inst);
u32 msm_vidc_decoder_input_size(struct msm_vidc_inst *inst);
u32 msm_vidc_decoder_output_size(struct msm_vidc_inst *inst);
u32 msm_vidc_decoder_input_meta_size(struct msm_vidc_inst *inst);
u32 msm_vidc_decoder_output_meta_size(struct msm_vidc_inst *inst);
u32 msm_vidc_encoder_input_size(struct msm_vidc_inst *inst);
u32 msm_vidc_encoder_output_size(struct msm_vidc_inst *inst);
u32 msm_vidc_encoder_input_meta_size(struct msm_vidc_inst *inst);
u32 msm_vidc_encoder_output_meta_size(struct msm_vidc_inst *inst);
#endif // __H_MSM_VIDC_BUFFER_H__

View File

@@ -8,7 +8,6 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/iommu.h> #include <linux/iommu.h>
#include "msm_vidc_internal.h" #include "msm_vidc_internal.h"
#include "msm_vidc_core.h" #include "msm_vidc_core.h"
#include "msm_vidc_inst.h" #include "msm_vidc_inst.h"
@@ -23,7 +22,60 @@ static inline is_encode_session(struct msm_vidc_inst *inst)
return inst->domain == MSM_VIDC_ENCODER; return inst->domain == MSM_VIDC_ENCODER;
} }
static inline is_secure_session(struct msm_vidc_inst *inst)
{
return false;
}
static inline is_input_buffer(enum msm_vidc_buffer_type buffer_type)
{
return buffer_type == MSM_VIDC_BUF_INPUT;
}
static inline is_output_buffer(enum msm_vidc_buffer_type buffer_type)
{
return buffer_type == MSM_VIDC_BUF_OUTPUT;
}
static inline is_input_meta_buffer(enum msm_vidc_buffer_type buffer_type)
{
return buffer_type == MSM_VIDC_BUF_INPUT_META;
}
static inline is_output_meta_buffer(enum msm_vidc_buffer_type buffer_type)
{
return buffer_type == MSM_VIDC_BUF_OUTPUT_META;
}
static inline is_internal_buffer(enum msm_vidc_buffer_type buffer_type)
{
return buffer_type == MSM_VIDC_BUF_SCRATCH ||
buffer_type == MSM_VIDC_BUF_SCRATCH_1 ||
buffer_type == MSM_VIDC_BUF_SCRATCH_2 ||
buffer_type == MSM_VIDC_BUF_PERSIST ||
buffer_type == MSM_VIDC_BUF_PERSIST_1;
}
static inline bool is_secondary_output_mode(struct msm_vidc_inst *inst)
{
return false; // TODO: inst->stream_output_mode == HAL_VIDEO_DECODER_SECONDARY;
}
static inline bool is_thumbnail_session(struct msm_vidc_inst *inst)
{
return false; // TODO: fix it
}
int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
enum msm_vidc_inst_state state);
int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type);
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_add_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_core_init(struct msm_vidc_core *core); int msm_vidc_core_init(struct msm_vidc_core *core);
int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
struct device *dev, unsigned long iova, int flags, void *data); struct device *dev, unsigned long iova, int flags, void *data);
@@ -34,14 +86,17 @@ void msm_vidc_pm_work_handler(struct work_struct *work);
void msm_vidc_fw_unload_handler(struct work_struct *work); void msm_vidc_fw_unload_handler(struct work_struct *work);
void msm_vidc_batch_handler(struct work_struct *work); void msm_vidc_batch_handler(struct work_struct *work);
int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst); int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst);
int msm_vidc_queue_init(struct msm_vidc_inst *inst); int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst);
u32 msm_vidc_convert_color_fmt(u32 v4l2_fmt); u32 msm_vidc_convert_color_fmt(u32 v4l2_fmt);
int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl); int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl);
int msm_vidc_get_port_from_type(u32 type); int msm_vidc_get_port_from_v4l2_type(u32 type);
int msm_vidc_start_input(struct msm_vidc_inst *inst); u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst,
int msm_vidc_start_output(struct msm_vidc_inst *inst); enum msm_vidc_buffer_type buffer_type);
int msm_vidc_stop_input(struct msm_vidc_inst *inst); struct msm_vidc_buffer_info *msm_vidc_get_buffer_info(struct msm_vidc_inst *inst,
int msm_vidc_stop_output(struct msm_vidc_inst *inst); enum msm_vidc_buffer_type buffer_type);
struct msm_vidc_map_info *msm_vidc_get_map_info(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type);
struct msm_vidc_alloc_info *msm_vidc_get_alloc_info(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type);
#endif // _MSM_VIDC_DRIVER_H_ #endif // _MSM_VIDC_DRIVER_H_

View File

@@ -90,6 +90,7 @@ struct msm_vidc_inst {
struct v4l2_ctrl **ctrls; struct v4l2_ctrl **ctrls;
u32 num_ctrls; u32 num_ctrls;
struct vb2_queue vb2q[MAX_PORT]; struct vb2_queue vb2q[MAX_PORT];
struct msm_vidc_crop crop;
struct msm_vidc_properties prop; struct msm_vidc_properties prop;
struct msm_vidc_power power; struct msm_vidc_power power;
struct msm_vidc_buffers buffers; struct msm_vidc_buffers buffers;
@@ -102,6 +103,7 @@ struct msm_vidc_inst {
struct list_head input_ts; struct list_head input_ts;
struct list_head enc_input_crs; struct list_head enc_input_crs;
struct list_head decode_bitrate_data; struct list_head decode_bitrate_data;
bool session_created;
struct dentry *debugfs_root; struct dentry *debugfs_root;
struct msm_vidc_debug debug; struct msm_vidc_debug debug;
}; };

View File

@@ -96,21 +96,23 @@ enum msm_vidc_colorformat_type {
}; };
enum msm_vidc_buffer_type { enum msm_vidc_buffer_type {
MSM_VIDC_QUEUE = BIT(0), MSM_VIDC_BUF_QUEUE = BIT(0),
MSM_VIDC_INPUT = BIT(1), MSM_VIDC_BUF_INPUT = BIT(1),
MSM_VIDC_OUTPUT = BIT(2), MSM_VIDC_BUF_OUTPUT = BIT(2),
MSM_VIDC_INPUT_META = BIT(3), MSM_VIDC_BUF_INPUT_META = BIT(3),
MSM_VIDC_OUTPUT_META = BIT(4), MSM_VIDC_BUF_OUTPUT_META = BIT(4),
MSM_VIDC_DPB = BIT(5), MSM_VIDC_BUF_SCRATCH = BIT(5),
MSM_VIDC_ARP = BIT(6), MSM_VIDC_BUF_SCRATCH_1 = BIT(6),
MSM_VIDC_LINE = BIT(7), MSM_VIDC_BUF_SCRATCH_2 = BIT(7),
MSM_VIDC_BIN = BIT(8), MSM_VIDC_BUF_PERSIST = BIT(8),
MSM_VIDC_BUF_PERSIST_1 = BIT(9),
}; };
enum msm_vidc_buffer_attributes { enum msm_vidc_buffer_attributes {
MSM_VIDC_DEFERRED_SUBMISSION = BIT(0), MSM_VIDC_ATTR_DEFERRED_SUBMISSION = BIT(0),
MSM_VIDC_READ_ONLY = BIT(1), MSM_VIDC_ATTR_READ_ONLY = BIT(1),
MSM_VIDC_PENDING_RELEASE = BIT(2), MSM_VIDC_ATTR_PENDING_RELEASE = BIT(2),
MSM_VIDC_ATTR_QUEUED = BIT(3),
}; };
enum msm_vidc_buffer_region { enum msm_vidc_buffer_region {
@@ -385,6 +387,7 @@ struct msm_vidc_power {
}; };
struct msm_vidc_alloc { struct msm_vidc_alloc {
struct list_head list;
enum msm_vidc_buffer_type buffer_type; enum msm_vidc_buffer_type buffer_type;
enum msm_vidc_buffer_region region; enum msm_vidc_buffer_region region;
u32 size; u32 size;
@@ -400,6 +403,7 @@ struct msm_vidc_alloc_info {
}; };
struct msm_vidc_map { struct msm_vidc_map {
struct list_head list;
bool valid; bool valid;
enum msm_vidc_buffer_type buffer_type; enum msm_vidc_buffer_type buffer_type;
enum msm_vidc_buffer_region region; enum msm_vidc_buffer_region region;
@@ -415,6 +419,7 @@ struct msm_vidc_map_info {
}; };
struct msm_vidc_buffer { struct msm_vidc_buffer {
struct list_head list;
bool valid; bool valid;
enum msm_vidc_buffer_type type; enum msm_vidc_buffer_type type;
u32 index; u32 index;
@@ -437,6 +442,13 @@ struct msm_vidc_buffer_info {
u32 size; u32 size;
}; };
struct msm_vidc_crop {
u32 x;
u32 y;
u32 width;
u32 height;
};
struct msm_vidc_properties { struct msm_vidc_properties {
u32 frame_rate; u32 frame_rate;
u32 operating_rate; u32 operating_rate;

View File

@@ -46,10 +46,19 @@ struct hfi_resource_syscache_info_type {
struct hfi_resource_subcache_type rg_subcache_entries[1]; struct hfi_resource_subcache_type rg_subcache_entries[1];
}; };
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,
struct msm_vidc_buffer *buffer);
int venus_hfi_start_input(struct msm_vidc_inst *inst);
int venus_hfi_stop_input(struct msm_vidc_inst *inst);
int venus_hfi_start_output(struct msm_vidc_inst *inst);
int venus_hfi_stop_output(struct msm_vidc_inst *inst);
int venus_hfi_session_close(struct msm_vidc_inst *inst);
int venus_hfi_session_open(struct msm_vidc_inst *inst);
int venus_hfi_core_init(struct msm_vidc_core *core); int venus_hfi_core_init(struct msm_vidc_core *core);
int venus_hfi_core_release(struct msm_vidc_core *core); int venus_hfi_core_release(struct msm_vidc_core *core);
int venus_hfi_suspend(struct msm_vidc_core *core); int venus_hfi_suspend(struct msm_vidc_core *core);
int venus_hfi_session_open(struct msm_vidc_core *core, struct msm_vidc_inst *inst);
void venus_hfi_work_handler(struct work_struct *work); void venus_hfi_work_handler(struct work_struct *work);
void venus_hfi_pm_work_handler(struct work_struct *work); void venus_hfi_pm_work_handler(struct work_struct *work);

View File

@@ -6,59 +6,136 @@
#include "hfi_packet.h" #include "hfi_packet.h"
#include "msm_vidc_core.h" #include "msm_vidc_core.h"
#include "msm_vidc_inst.h" #include "msm_vidc_inst.h"
#include "msm_vidc_driver.h"
#include "msm_vidc_debug.h" #include "msm_vidc_debug.h"
#include "msm_vidc_platform.h" #include "msm_vidc_platform.h"
static u32 get_hfi_buffer_type(enum msm_vidc_domain_type domain, u32 get_hfi_port(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buf_type) enum msm_vidc_buffer_type buffer_type)
{ {
switch (buf_type) { u32 hfi_port = HFI_PORT_NONE;
case MSM_VIDC_QUEUE:
return 0; /* TODO */ if (is_decode_session(inst)) {
case MSM_VIDC_INPUT: switch(buffer_type) {
case MSM_VIDC_BUF_INPUT:
case MSM_VIDC_BUF_INPUT_META:
hfi_port = HFI_PORT_BITSTREAM;
break;
case MSM_VIDC_BUF_OUTPUT:
case MSM_VIDC_BUF_OUTPUT_META:
hfi_port = HFI_PORT_RAW;
break;
default:
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, buffer_type);
break;
}
} else if (is_encode_session(inst)) {
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
case MSM_VIDC_BUF_INPUT_META:
hfi_port = HFI_PORT_RAW;
break;
case MSM_VIDC_BUF_OUTPUT:
case MSM_VIDC_BUF_OUTPUT_META:
hfi_port = HFI_PORT_BITSTREAM;
break;
default:
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, buffer_type);
break;
}
} else {
s_vpr_e(inst->sid, "%s: invalid domain %#x\n",
__func__, inst->domain);
}
return hfi_port;
}
u32 get_hfi_buffer_type(enum msm_vidc_domain_type domain,
enum msm_vidc_buffer_type buffer_type)
{
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
if (domain == MSM_VIDC_DECODER) if (domain == MSM_VIDC_DECODER)
return HFI_PORT_BITSTREAM; return HFI_BUFFER_BITSTREAM;
else else
return HFI_PORT_RAW; return HFI_BUFFER_RAW;
case MSM_VIDC_OUTPUT: case MSM_VIDC_BUF_OUTPUT:
if (domain == MSM_VIDC_DECODER) if (domain == MSM_VIDC_DECODER)
return HFI_PORT_RAW; return HFI_BUFFER_RAW;
else else
return HFI_PORT_BITSTREAM; return HFI_BUFFER_BITSTREAM;
case MSM_VIDC_INPUT_META: case MSM_VIDC_BUF_INPUT_META:
case MSM_VIDC_OUTPUT_META: case MSM_VIDC_BUF_OUTPUT_META:
return HFI_BUFFER_METADATA; return HFI_BUFFER_METADATA;
case MSM_VIDC_DPB: case MSM_VIDC_BUF_SCRATCH:
return HFI_BUFFER_DPB; return HFI_BUFFER_SCRATCH;
case MSM_VIDC_ARP: case MSM_VIDC_BUF_SCRATCH_1:
return HFI_BUFFER_ARP; return HFI_BUFFER_SCRATCH_1;
case MSM_VIDC_LINE: case MSM_VIDC_BUF_SCRATCH_2:
return HFI_BUFFER_LINE; return HFI_BUFFER_SCRATCH_2;
case MSM_VIDC_BIN: case MSM_VIDC_BUF_PERSIST:
return HFI_BUFFER_BIN; return HFI_BUFFER_PERSIST;
case MSM_VIDC_BUF_PERSIST_1:
return HFI_BUFFER_PERSIST_1;
default: default:
d_vpr_e("%s: Invalid buffer type %d\n", d_vpr_e("invalid buffer type %d\n",
__func__, buf_type); buffer_type);
return 0; return 0;
} }
} }
static u32 get_hfi_buffer_flags(enum msm_vidc_buffer_attributes attr) u32 get_hfi_codec(struct msm_vidc_inst *inst)
{ {
switch (attr) { switch (inst->codec) {
case MSM_VIDC_DEFERRED_SUBMISSION: case MSM_VIDC_H264:
return 0; /*not sure what it should be mapped to??*/ if (inst->domain == MSM_VIDC_ENCODER)
case MSM_VIDC_READ_ONLY: return HFI_CODEC_ENCODE_AVC;
return HFI_BUF_HOST_FLAG_READONLY; else
case MSM_VIDC_PENDING_RELEASE: return HFI_CODEC_DECODE_AVC;
return HFI_BUF_HOST_FLAG_RELEASE; case MSM_VIDC_HEVC:
if (inst->domain == MSM_VIDC_ENCODER)
return HFI_CODEC_ENCODE_HEVC;
else
return HFI_CODEC_DECODE_HEVC;
case MSM_VIDC_VP9:
return HFI_CODEC_DECODE_VP9;
case MSM_VIDC_MPEG2:
return HFI_CODEC_DECODE_MPEG2;
default: default:
d_vpr_e("%s: Invalid buffer attribute %d\n", d_vpr_e("invalid codec %d, domain %d\n",
__func__, attr); inst->codec, inst->domain);
return 0; return 0;
} }
} }
int get_hfi_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buffer, struct hfi_buffer *buf)
{
if (!inst || !buffer || !buf) {
d_vpr_e("%: invalid params\n", __func__);
return -EINVAL;
}
memset(buf, 0, sizeof(struct hfi_buffer));
buf->type = get_hfi_buffer_type(inst->domain, buffer->type);
buf->index = buffer->index;
buf->base_address = buffer->device_addr;
buf->addr_offset = 0;
buf->buffer_size = buffer->buffer_size;
buf->data_offset = buffer->data_offset;
buf->data_size = buffer->data_size;
if (buffer->attr & MSM_VIDC_ATTR_READ_ONLY)
buf->flags |= HFI_BUF_HOST_FLAG_READONLY;
if (buffer->attr & MSM_VIDC_ATTR_PENDING_RELEASE)
buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
buf->timestamp = buffer->timestamp;
return 0;
}
int hfi_create_header(u8 *pkt, u32 session_id, int hfi_create_header(u8 *pkt, u32 session_id,
u32 header_id, u32 num_packets, u32 total_size) u32 header_id, u32 num_packets, u32 total_size)
{ {
@@ -102,34 +179,6 @@ int hfi_create_packet(u8 *packet, u32 packet_size, u32 *offset,
return 0; return 0;
} }
int hfi_create_buffer(u8 *packet, u32 packet_size, u32 *offset,
enum msm_vidc_domain_type domain, struct msm_vidc_buffer *data)
{
u32 available_size = packet_size - *offset;
u32 buf_size = sizeof(struct hfi_buffer);
struct hfi_buffer *buf = (struct hfi_buffer *)packet;
if (available_size < sizeof(struct hfi_buffer)) {
d_vpr_e("%s: Bad buffer Size for buffer type %d\n",
__func__, data->type);
return -EINVAL;
}
memset(buf, 0, buf_size);
buf->type = get_hfi_buffer_type(domain, data->type);
buf->index = data->index;
buf->base_address = data->device_addr;
buf->addr_offset = 0;
buf->buffer_size = data->buffer_size;
buf->data_offset = data->data_offset;
buf->data_size = data->data_size;
buf->flags = get_hfi_buffer_flags(data->attr);
buf->timestamp = data->timestamp;
*offset = *offset + buf_size;
return 0;
}
int hfi_packet_sys_init(struct msm_vidc_core *core, int hfi_packet_sys_init(struct msm_vidc_core *core,
u8 *pkt, u32 pkt_size) u8 *pkt, u32 pkt_size)
{ {
@@ -474,34 +523,35 @@ err_cmd:
return rc; return rc;
} }
int hfi_packet_create_property(struct msm_vidc_inst *inst, int hfi_packet_session_property(struct msm_vidc_inst *inst,
void *pkt, u32 pkt_size, u32 pkt_type, u32 flags, u32 pkt_type, u32 flags, u32 port, u32 payload_type,
u32 port, u32 payload, u32 payload_type, u32 payload_size) void *payload, u32 payload_size)
{ {
int rc = 0; int rc = 0;
u32 num_packets = 0, offset = 0; u32 num_packets = 0, offset = 0;
struct msm_vidc_core *core; struct msm_vidc_core *core;
if (!inst || !inst->core || !pkt) { if (!inst || !inst->core || !inst->packet) {
d_vpr_e("%s: Invalid params\n", __func__); d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
core = inst->core; core = inst->core;
offset = sizeof(struct hfi_header); offset = sizeof(struct hfi_header);
rc = hfi_create_packet(pkt, pkt_size, &offset, rc = hfi_create_packet(inst->packet, inst->packet_size,
&offset,
pkt_type, pkt_type,
flags, flags,
payload_type, payload_type,
port, port,
core->packet_id++, core->packet_id++,
&payload, payload,
payload_size); payload_size);
if (rc) if (rc)
goto err_prop; goto err_prop;
num_packets++; num_packets++;
rc = hfi_create_header(pkt, inst->session_id, rc = hfi_create_header(inst->packet, inst->session_id,
core->header_id++, core->header_id++,
num_packets, num_packets,
offset); offset);
@@ -515,4 +565,4 @@ int hfi_packet_create_property(struct msm_vidc_inst *inst,
err_prop: err_prop:
d_vpr_e("%s: create packet failed\n", __func__); d_vpr_e("%s: create packet failed\n", __func__);
return rc; return rc;
} }

View File

@@ -13,6 +13,7 @@
#include "msm_vidc_internal.h" #include "msm_vidc_internal.h"
#include "msm_vidc_platform.h" #include "msm_vidc_platform.h"
#include "msm_vidc_debug.h" #include "msm_vidc_debug.h"
#include "venus_hfi.h"
static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec) static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec)
{ {
@@ -29,6 +30,222 @@ static int msm_vdec_codec_change(struct msm_vidc_inst *inst, u32 codec)
return rc; return rc;
} }
static int msm_vdec_set_input_properties(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
return rc;
}
static int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
struct msm_vidc_core *core;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
inst->buffers.scratch.size = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_SCRATCH);
inst->buffers.scratch_1.size = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_SCRATCH_1);
inst->buffers.persist_1.size = call_session_op(core, buffer_size,
inst, MSM_VIDC_BUF_PERSIST_1);
inst->buffers.scratch.min_count = call_session_op(core, min_count,
inst, MSM_VIDC_BUF_SCRATCH);
inst->buffers.scratch_1.min_count = call_session_op(core, min_count,
inst, MSM_VIDC_BUF_SCRATCH_1);
inst->buffers.persist_1.min_count = call_session_op(core, min_count,
inst, MSM_VIDC_BUF_PERSIST_1);
return rc;
}
static int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH);
if (rc)
return rc;
rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH_1);
if (rc)
return rc;
rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_PERSIST_1);
if (rc)
return rc;
return 0;
}
static int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH);
if (rc)
return rc;
rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH_1);
if (rc)
return rc;
rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_PERSIST_1);
if (rc)
return rc;
return 0;
}
/*
static int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = msm_vidc_release_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH);
if (rc)
return rc;
rc = msm_vidc_release_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH_1);
if (rc)
return rc;
rc = msm_vidc_release_internal_buffers(inst, MSM_VIDC_BUF_PERSIST_1);
if (rc)
return rc;
return 0;
}
*/
int msm_vdec_stop_input(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
return rc;
}
int msm_vdec_start_input(struct msm_vidc_inst *inst)
{
int rc = 0;
struct msm_vidc_core *core;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
//rc = msm_vidc_check_session_supported(inst);
if (rc)
goto error;
//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);
if (rc)
goto error;
/* Decide bse vpp delay after work mode */
//msm_vidc_set_bse_vpp_delay(inst);
rc = msm_vdec_get_input_internal_buffers(inst);
if (rc)
goto error;
/* check for memory after all buffers calculation */
//rc = msm_vidc_check_memory_supported(inst);
if (rc)
goto error;
//msm_vidc_update_dcvs(inst);
//msm_vidc_update_batching(inst);
//msm_vidc_scale_power(inst);
rc = msm_vdec_set_input_properties(inst);
if (rc)
goto error;
rc = msm_vdec_create_input_internal_buffers(inst);
if (rc)
goto error;
rc = msm_vdec_queue_input_internal_buffers(inst);
if (rc)
goto error;
rc = venus_hfi_start_input(inst);
if (rc)
goto error;
rc = msm_vidc_change_inst_state(inst, MSM_VIDC_START_INPUT);
if (rc)
goto error;
d_vpr_h("%s: done\n", __func__);
return 0;
error:
msm_vdec_stop_input(inst);
return rc;
}
int msm_vdec_stop_output(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
return rc;
}
int msm_vdec_start_output(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
return rc;
}
int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
{ {
int rc = 0; int rc = 0;
@@ -64,16 +281,16 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
} }
fmt = &inst->fmts[INPUT_PORT]; fmt = &inst->fmts[INPUT_PORT];
fmt->type = INPUT_PLANE; fmt->type = INPUT_PLANE;
fmt->fmt.pix.width = f->fmt.pix.width; fmt->fmt.pix.width = ALIGN(f->fmt.pix.width, 16);
fmt->fmt.pix.height = f->fmt.pix.height; fmt->fmt.pix.height = ALIGN(f->fmt.pix.height, 16);
fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat; fmt->fmt.pix.pixelformat = f->fmt.pix.pixelformat;
fmt->fmt.pix.bytesperline = 0; fmt->fmt.pix.bytesperline = 0;
fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size, fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_INPUT); inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.min_count = inst->buffers.input.min_count =
call_session_op(core, min_count, inst, MSM_VIDC_INPUT); call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.extra_count = inst->buffers.input.extra_count =
call_session_op(core, extra_count, inst, MSM_VIDC_INPUT); call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT);
if (inst->buffers.input.actual_count < if (inst->buffers.input.actual_count <
inst->buffers.input.min_count + inst->buffers.input.min_count +
inst->buffers.input.extra_count) { inst->buffers.input.extra_count) {
@@ -83,6 +300,11 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
} }
inst->buffers.input.size = fmt->fmt.pix.sizeimage; inst->buffers.input.size = fmt->fmt.pix.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;
//rc = msm_vidc_check_session_supported(inst); //rc = msm_vidc_check_session_supported(inst);
if (rc) if (rc)
goto err_invalid_fmt; goto err_invalid_fmt;
@@ -90,10 +312,14 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
// mplane->pixelformat); // mplane->pixelformat);
s_vpr_h(inst->sid, s_vpr_h(inst->sid,
"%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n", "%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n",
__func__, fmt->fmt.pix.pixelformat, fmt->fmt.pix.width, __func__, f->fmt.pix.pixelformat, f->fmt.pix.width,
fmt->fmt.pix.height, fmt->fmt.pix.sizeimage, f->fmt.pix.height, fmt->fmt.pix.sizeimage,
inst->buffers.input.min_count, inst->buffers.input.min_count,
inst->buffers.input.extra_count); inst->buffers.input.extra_count);
//msm_vidc_update_dcvs(inst);
//msm_vidc_update_batching(inst);
} else if (f->type == INPUT_META_PLANE) { } else if (f->type == INPUT_META_PLANE) {
if (inst->state == MSM_VIDC_START_INPUT) { if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state); d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
@@ -103,7 +329,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
fmt->type = INPUT_META_PLANE; fmt->type = INPUT_META_PLANE;
fmt->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META; fmt->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
fmt->fmt.meta.buffersize = call_session_op(core, buffer_size, fmt->fmt.meta.buffersize = call_session_op(core, buffer_size,
inst, MSM_VIDC_INPUT_META); inst, MSM_VIDC_BUF_INPUT_META);
inst->buffers.input_meta.min_count = inst->buffers.input_meta.min_count =
inst->buffers.input.min_count; inst->buffers.input.min_count;
inst->buffers.input_meta.extra_count = inst->buffers.input_meta.extra_count =
@@ -132,11 +358,11 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
f->fmt.pix.height); f->fmt.pix.height);
fmt->fmt.pix.bytesperline = fmt->fmt.pix.width; fmt->fmt.pix.bytesperline = fmt->fmt.pix.width;
fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size, fmt->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_OUTPUT); inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.min_count = inst->buffers.output.min_count =
call_session_op(core, min_count, inst, MSM_VIDC_OUTPUT); call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.extra_count = inst->buffers.output.extra_count =
call_session_op(core, extra_count, inst, MSM_VIDC_OUTPUT); call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT);
if (inst->buffers.output.actual_count < if (inst->buffers.output.actual_count <
inst->buffers.output.min_count + inst->buffers.output.min_count +
inst->buffers.output.extra_count) { inst->buffers.output.extra_count) {
@@ -164,7 +390,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
fmt->type = OUTPUT_META_PLANE; fmt->type = OUTPUT_META_PLANE;
fmt->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META; fmt->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
fmt->fmt.meta.buffersize = call_session_op(core, buffer_size, fmt->fmt.meta.buffersize = call_session_op(core, buffer_size,
inst, MSM_VIDC_OUTPUT_META); inst, MSM_VIDC_BUF_OUTPUT_META);
inst->buffers.output_meta.min_count = inst->buffers.output_meta.min_count =
inst->buffers.output.min_count; inst->buffers.output.min_count;
inst->buffers.output_meta.extra_count = inst->buffers.output_meta.extra_count =
@@ -177,7 +403,11 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
__func__, fmt->fmt.meta.buffersize, __func__, fmt->fmt.meta.buffersize,
inst->buffers.output_meta.min_count, inst->buffers.output_meta.min_count,
inst->buffers.output_meta.extra_count); inst->buffers.output_meta.extra_count);
} else {
s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, f->type);
goto err_invalid_fmt;
} }
memcpy(f, fmt, sizeof(struct v4l2_format));
err_invalid_fmt: err_invalid_fmt:
return rc; return rc;
@@ -233,11 +463,11 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264; f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
f->fmt.pix.bytesperline = 0; f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = call_session_op(core, buffer_size, f->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_INPUT); inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.min_count = inst->buffers.input.min_count =
call_session_op(core, min_count, inst, MSM_VIDC_INPUT); call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.extra_count = inst->buffers.input.extra_count =
call_session_op(core, extra_count, inst, MSM_VIDC_INPUT); call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.actual_count = inst->buffers.input.actual_count =
inst->buffers.input.min_count + inst->buffers.input.min_count +
inst->buffers.input.extra_count; inst->buffers.input.extra_count;
@@ -247,7 +477,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
f->type = INPUT_META_PLANE; f->type = INPUT_META_PLANE;
f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META; f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
f->fmt.meta.buffersize = call_session_op(core, buffer_size, f->fmt.meta.buffersize = call_session_op(core, buffer_size,
inst, MSM_VIDC_INPUT_META); inst, MSM_VIDC_BUF_INPUT_META);
inst->buffers.input_meta.min_count = inst->buffers.input.min_count; inst->buffers.input_meta.min_count = inst->buffers.input.min_count;
inst->buffers.input_meta.extra_count = inst->buffers.input.extra_count; inst->buffers.input_meta.extra_count = inst->buffers.input.extra_count;
inst->buffers.input_meta.actual_count = inst->buffers.input.actual_count; inst->buffers.input_meta.actual_count = inst->buffers.input.actual_count;
@@ -262,11 +492,11 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_HEIGHT); msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_HEIGHT);
f->fmt.pix.bytesperline = f->fmt.pix.width; f->fmt.pix.bytesperline = f->fmt.pix.width;
f->fmt.pix.sizeimage = call_session_op(core, buffer_size, f->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_OUTPUT); inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.min_count = inst->buffers.output.min_count =
call_session_op(core, min_count, inst, MSM_VIDC_OUTPUT); call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.extra_count = inst->buffers.output.extra_count =
call_session_op(core, extra_count, inst, MSM_VIDC_OUTPUT); call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.actual_count = inst->buffers.output.actual_count =
inst->buffers.output.min_count + inst->buffers.output.min_count +
inst->buffers.output.extra_count; inst->buffers.output.extra_count;
@@ -276,7 +506,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
f->type = OUTPUT_META_PLANE; f->type = OUTPUT_META_PLANE;
f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META; f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
f->fmt.meta.buffersize = call_session_op(core, buffer_size, f->fmt.meta.buffersize = call_session_op(core, buffer_size,
inst, MSM_VIDC_OUTPUT_META); inst, MSM_VIDC_BUF_OUTPUT_META);
inst->buffers.output_meta.min_count = inst->buffers.output.min_count; 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.extra_count = inst->buffers.output.extra_count;
inst->buffers.output_meta.actual_count = inst->buffers.output.actual_count; inst->buffers.output_meta.actual_count = inst->buffers.output.actual_count;

View File

@@ -35,11 +35,11 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264; f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
f->fmt.pix.bytesperline = 0; f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = call_session_op(core, buffer_size, f->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_OUTPUT); inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.min_count = inst->buffers.output.min_count =
call_session_op(core, min_count, inst, MSM_VIDC_OUTPUT); call_session_op(core, min_count, inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.extra_count = inst->buffers.output.extra_count =
call_session_op(core, extra_count, inst, MSM_VIDC_OUTPUT); call_session_op(core, extra_count, inst, MSM_VIDC_BUF_OUTPUT);
inst->buffers.output.actual_count = inst->buffers.output.actual_count =
inst->buffers.output.min_count + inst->buffers.output.min_count +
inst->buffers.output.extra_count; inst->buffers.output.extra_count;
@@ -49,7 +49,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
f->type = OUTPUT_META_PLANE; f->type = OUTPUT_META_PLANE;
f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META; f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
f->fmt.meta.buffersize = call_session_op(core, buffer_size, f->fmt.meta.buffersize = call_session_op(core, buffer_size,
inst, MSM_VIDC_OUTPUT_META); inst, MSM_VIDC_BUF_OUTPUT_META);
inst->buffers.output_meta.min_count = inst->buffers.output.min_count; 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.extra_count = inst->buffers.output.extra_count;
inst->buffers.output_meta.actual_count = inst->buffers.output.actual_count; inst->buffers.output_meta.actual_count = inst->buffers.output.actual_count;
@@ -64,11 +64,11 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_HEIGHT); msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat), DEFAULT_HEIGHT);
f->fmt.pix.bytesperline = f->fmt.pix.width; f->fmt.pix.bytesperline = f->fmt.pix.width;
f->fmt.pix.sizeimage = call_session_op(core, buffer_size, f->fmt.pix.sizeimage = call_session_op(core, buffer_size,
inst, MSM_VIDC_INPUT); inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.min_count = inst->buffers.input.min_count =
call_session_op(core, min_count, inst, MSM_VIDC_INPUT); call_session_op(core, min_count, inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.extra_count = inst->buffers.input.extra_count =
call_session_op(core, extra_count, inst, MSM_VIDC_INPUT); call_session_op(core, extra_count, inst, MSM_VIDC_BUF_INPUT);
inst->buffers.input.actual_count = inst->buffers.input.actual_count =
inst->buffers.input.min_count + inst->buffers.input.min_count +
inst->buffers.input.extra_count; inst->buffers.input.extra_count;
@@ -78,7 +78,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
f->type = INPUT_META_PLANE; f->type = INPUT_META_PLANE;
f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META; f->fmt.meta.dataformat = V4L2_PIX_FMT_VIDC_META;
f->fmt.meta.buffersize = call_session_op(core, buffer_size, f->fmt.meta.buffersize = call_session_op(core, buffer_size,
inst, MSM_VIDC_INPUT_META); inst, MSM_VIDC_BUF_INPUT_META);
inst->buffers.input_meta.min_count = inst->buffers.input.min_count; inst->buffers.input_meta.min_count = inst->buffers.input.min_count;
inst->buffers.input_meta.extra_count = inst->buffers.input.extra_count; inst->buffers.input_meta.extra_count = inst->buffers.input.extra_count;
inst->buffers.input_meta.actual_count = inst->buffers.input.actual_count; inst->buffers.input_meta.actual_count = inst->buffers.input.actual_count;

View File

@@ -119,9 +119,9 @@ int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
return -EINVAL; return -EINVAL;
if (inst->domain == MSM_VIDC_DECODER) if (inst->domain == MSM_VIDC_DECODER)
return 0;//msm_vdec_enum_fmt(instance, f); return -EINVAL;//msm_vdec_enum_fmt(instance, f);
else if (inst->domain == MSM_VIDC_ENCODER) else if (inst->domain == MSM_VIDC_ENCODER)
return 0;//msm_venc_enum_fmt(instance, f); return -EINVAL;//msm_venc_enum_fmt(instance, f);
return -EINVAL; return -EINVAL;
} }
EXPORT_SYMBOL(msm_vidc_enum_fmt); EXPORT_SYMBOL(msm_vidc_enum_fmt);
@@ -203,6 +203,25 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
if (!inst || !f) if (!inst || !f)
return -EINVAL; return -EINVAL;
if (f->type == INPUT_PLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_OUTPUT) {
s_vpr_e(inst->sid,
"%s: s_fmt(%d) not allowed in %d state\n",
__func__, f->type, inst->state);
return -EINVAL;
}
} else if (f->type == OUTPUT_PLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_INPUT &&
inst->state != MSM_VIDC_DRAIN_START_INPUT) {
s_vpr_e(inst->sid,
"%s: s_fmt(%d) not allowed in %d state\n",
__func__, f->type, inst->state);
return -EINVAL;
}
}
if (inst->domain == MSM_VIDC_DECODER) if (inst->domain == MSM_VIDC_DECODER)
rc = msm_vdec_s_fmt(inst, f); rc = msm_vdec_s_fmt(inst, f);
if (inst->domain == MSM_VIDC_ENCODER) if (inst->domain == MSM_VIDC_ENCODER)
@@ -269,17 +288,41 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
if (!inst || !b) if (!inst || !b)
return -EINVAL; return -EINVAL;
port = msm_vidc_get_port_from_type(b->type); mutex_lock(&inst->lock);
if (b->type == INPUT_PLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_OUTPUT) {
s_vpr_e(inst->sid,
"%s: reqbufs(%d) not allowed in %d state\n",
__func__, b->type, inst->state);
return -EINVAL;
}
} else if (b->type == OUTPUT_PLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_INPUT &&
inst->state != MSM_VIDC_DRAIN_START_INPUT) {
s_vpr_e(inst->sid,
"%s: reqbufs(%d) not allowed in %d state\n",
__func__, b->type, inst->state);
return -EINVAL;
}
}
port = msm_vidc_get_port_from_v4l2_type(b->type);
if (port < 0) { if (port < 0) {
d_vpr_e("%s: invalid queue type %d\n", __func__, b->type); d_vpr_e("%s: invalid queue type %d\n", __func__, b->type);
return -EINVAL; return -EINVAL;
} }
mutex_lock(&inst->lock);
rc = vb2_reqbufs(&inst->vb2q[port], b); rc = vb2_reqbufs(&inst->vb2q[port], b);
mutex_unlock(&inst->lock); if (rc) {
if (rc) s_vpr_e(inst->sid, "%s: vb2_reqbufs(%d) failed, %d\n",
s_vpr_e(inst->sid, "%s: vb2_reqbufs failed, %d\n", rc); __func__, b->type, rc);
goto unlock;
}
unlock:
mutex_unlock(&inst->lock);
return rc; return rc;
} }
EXPORT_SYMBOL(msm_vidc_reqbufs); EXPORT_SYMBOL(msm_vidc_reqbufs);
@@ -297,50 +340,168 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
} }
EXPORT_SYMBOL(msm_vidc_dqbuf); EXPORT_SYMBOL(msm_vidc_dqbuf);
int msm_vidc_streamon(void *instance, enum v4l2_buf_type i) int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
{ {
int rc = 0; int rc = 0;
struct msm_vidc_inst *inst = instance; struct msm_vidc_inst *inst = instance;
enum msm_vidc_inst_state new_state = 0;
int port; int port;
if (!inst) if (!inst)
return -EINVAL; return -EINVAL;
port = msm_vidc_get_port_from_type(i);
if (port < 0) {
d_vpr_e("%s: invalid buf type %d\n", __func__, i);
return -EINVAL;
}
mutex_lock(&inst->lock); mutex_lock(&inst->lock);
rc = vb2_streamon(&inst->vb2q[port], i);
mutex_unlock(&inst->lock);
if (rc)
s_vpr_e(inst->sid, "%s: vb2_streamon failed, %d\n", rc);
if (type == INPUT_PLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_OUTPUT) {
s_vpr_e(inst->sid,
"%s: streamon(%d) not allowed in %d state\n",
__func__, type, inst->state);
rc = -EINVAL;
goto unlock;
}
} else if (type == OUTPUT_PLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_INPUT &&
inst->state != MSM_VIDC_DRAIN_START_INPUT) {
s_vpr_e(inst->sid,
"%s: streamon(%d) not allowed in %d state\n",
__func__, type, inst->state);
rc = -EINVAL;
goto unlock;
}
}
port = msm_vidc_get_port_from_v4l2_type(type);
if (port < 0) {
d_vpr_e("%s: invalid buf type %d\n", __func__, type);
rc = -EINVAL;
goto unlock;
}
rc = vb2_streamon(&inst->vb2q[port], type);
if (rc) {
s_vpr_e(inst->sid, "%s: vb2_streamon(%d) failed, %d\n",
__func__, type, rc);
goto unlock;
}
if (type == INPUT_PLANE) {
if (inst->state == MSM_VIDC_OPEN) {
new_state = MSM_VIDC_START_INPUT;
} else if (inst->state == MSM_VIDC_START_OUTPUT) {
new_state = MSM_VIDC_START;
}
rc = msm_vidc_change_inst_state(inst, new_state);
if (rc)
goto unlock;
} else if (type == OUTPUT_PLANE) {
if (inst->state == MSM_VIDC_OPEN) {
new_state = MSM_VIDC_START_OUTPUT;
} else if (inst->state == MSM_VIDC_START_INPUT) {
new_state = MSM_VIDC_START;
} else if (inst->state == MSM_VIDC_DRAIN_START_INPUT) {
if (0 /* check if input port settings change pending */)
new_state = MSM_VIDC_DRC_DRAIN;
else
new_state = MSM_VIDC_DRAIN;
}
rc = msm_vidc_change_inst_state(inst, new_state);
if (rc)
goto unlock;
}
unlock:
mutex_unlock(&inst->lock);
return rc; return rc;
} }
EXPORT_SYMBOL(msm_vidc_streamon); EXPORT_SYMBOL(msm_vidc_streamon);
int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i) int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
{ {
int rc = 0; int rc = 0;
struct msm_vidc_inst *inst = instance; struct msm_vidc_inst *inst = instance;
enum msm_vidc_inst_state new_state = 0;
int port; int port;
if (!inst) if (!inst)
return -EINVAL; return -EINVAL;
port = msm_vidc_get_port_from_type(i);
if (port < 0) {
d_vpr_e("%s: invalid buf type %d\n", __func__, i);
return -EINVAL;
}
mutex_lock(&inst->lock); mutex_lock(&inst->lock);
rc = vb2_streamoff(&inst->vb2q[port], i);
mutex_unlock(&inst->lock);
if (rc)
s_vpr_e(inst->sid, "%s: vb2_streamoff failed, %d\n", rc);
if (type == INPUT_PLANE) {
if (inst->state == MSM_VIDC_OPEN ||
inst->state == MSM_VIDC_START_OUTPUT) {
s_vpr_e(inst->sid,
"%s: streamoff(%d) not allowed in %d state\n",
__func__, type, inst->state);
rc = -EINVAL;
goto unlock;
}
} else if (type == OUTPUT_PLANE) {
if (inst->state == MSM_VIDC_OPEN ||
inst->state == MSM_VIDC_START_INPUT) {
s_vpr_e(inst->sid,
"%s: streamoff(%d) not allowed in %d state\n",
__func__, type, inst->state);
rc = -EINVAL;
goto unlock;
}
}
port = msm_vidc_get_port_from_v4l2_type(type);
if (port < 0) {
d_vpr_e("%s: invalid buf type %d\n", __func__, type);
rc = -EINVAL;
goto unlock;
}
rc = vb2_streamoff(&inst->vb2q[port], type);
if (rc) {
s_vpr_e(inst->sid, "%s: vb2_streamoff(%d) failed, %d\n",
__func__, type, rc);
goto unlock;
}
if (type == INPUT_PLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
new_state = MSM_VIDC_OPEN;
} else if (inst->state == MSM_VIDC_START) {
new_state = MSM_VIDC_START_OUTPUT;
} else if (inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRAIN ||
inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN ||
inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRAIN_START_INPUT) {
new_state = MSM_VIDC_START_OUTPUT;
/* discard pending port settings change if any */
}
rc = msm_vidc_change_inst_state(inst, new_state);
if (rc)
goto unlock;
} else if (type == OUTPUT_PLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
new_state = MSM_VIDC_OPEN;
} else if (inst->state == MSM_VIDC_START ||
inst->state == MSM_VIDC_DRAIN ||
inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN) {
new_state = MSM_VIDC_START_INPUT;
} else if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG) {
new_state = MSM_VIDC_DRAIN_START_INPUT;
}
rc = msm_vidc_change_inst_state(inst, new_state);
if (rc)
goto unlock;
}
unlock:
mutex_unlock(&inst->lock);
return rc; return rc;
} }
EXPORT_SYMBOL(msm_vidc_streamoff); EXPORT_SYMBOL(msm_vidc_streamoff);
@@ -357,44 +518,46 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize)
} }
EXPORT_SYMBOL(msm_vidc_enum_framesizes); EXPORT_SYMBOL(msm_vidc_enum_framesizes);
int msm_vidc_subscribe_event(void *inst, int msm_vidc_subscribe_event(void *instance,
const struct v4l2_event_subscription *sub) const struct v4l2_event_subscription *sub)
{ {
int rc = 0; int rc = 0;
struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
if (!inst || !sub) if (!inst || !sub)
return -EINVAL; return -EINVAL;
rc = v4l2_event_subscribe(&vidc_inst->event_handler, s_vpr_e(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
rc = v4l2_event_subscribe(&inst->event_handler,
sub, MAX_EVENTS, NULL); sub, MAX_EVENTS, NULL);
return rc; return rc;
} }
EXPORT_SYMBOL(msm_vidc_subscribe_event); EXPORT_SYMBOL(msm_vidc_subscribe_event);
int msm_vidc_unsubscribe_event(void *inst, int msm_vidc_unsubscribe_event(void *instance,
const struct v4l2_event_subscription *sub) const struct v4l2_event_subscription *sub)
{ {
int rc = 0; int rc = 0;
struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
if (!inst || !sub) if (!inst || !sub)
return -EINVAL; return -EINVAL;
rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub); s_vpr_e(inst->sid, "%s: type %d id %d\n", __func__, sub->type, sub->id);
rc = v4l2_event_unsubscribe(&inst->event_handler, sub);
return rc; return rc;
} }
EXPORT_SYMBOL(msm_vidc_unsubscribe_event); EXPORT_SYMBOL(msm_vidc_unsubscribe_event);
int msm_vidc_dqevent(void *inst, struct v4l2_event *event) int msm_vidc_dqevent(void *instance, struct v4l2_event *event)
{ {
int rc = 0; int rc = 0;
struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
if (!inst || !event) if (!inst || !event)
return -EINVAL; return -EINVAL;
rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false); rc = v4l2_event_dequeue(&inst->event_handler, event, false);
return rc; return rc;
} }
EXPORT_SYMBOL(msm_vidc_dqevent); EXPORT_SYMBOL(msm_vidc_dqevent);
@@ -455,6 +618,20 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
INIT_LIST_HEAD(&inst->buffers.scratch_2.list); INIT_LIST_HEAD(&inst->buffers.scratch_2.list);
INIT_LIST_HEAD(&inst->buffers.persist.list); INIT_LIST_HEAD(&inst->buffers.persist.list);
INIT_LIST_HEAD(&inst->buffers.persist_1.list); INIT_LIST_HEAD(&inst->buffers.persist_1.list);
INIT_LIST_HEAD(&inst->allocations.scratch.list);
INIT_LIST_HEAD(&inst->allocations.scratch_1.list);
INIT_LIST_HEAD(&inst->allocations.scratch_2.list);
INIT_LIST_HEAD(&inst->allocations.persist.list);
INIT_LIST_HEAD(&inst->allocations.persist_1.list);
INIT_LIST_HEAD(&inst->maps.input.list);
INIT_LIST_HEAD(&inst->maps.input_meta.list);
INIT_LIST_HEAD(&inst->maps.output.list);
INIT_LIST_HEAD(&inst->maps.output_meta.list);
INIT_LIST_HEAD(&inst->maps.scratch.list);
INIT_LIST_HEAD(&inst->maps.scratch_1.list);
INIT_LIST_HEAD(&inst->maps.scratch_2.list);
INIT_LIST_HEAD(&inst->maps.persist.list);
INIT_LIST_HEAD(&inst->maps.persist_1.list);
inst->domain = session_type; inst->domain = session_type;
inst->state = MSM_VIDC_OPEN; inst->state = MSM_VIDC_OPEN;
//inst->debugfs_root = //inst->debugfs_root =
@@ -476,7 +653,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
goto error; goto error;
} }
rc = msm_vidc_queue_init(inst); rc = msm_vidc_vb2_queue_init(inst);
if (rc) if (rc)
goto error; goto error;

View File

@@ -0,0 +1,190 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#include <media/msm_media_info.h>
#include "msm_vidc_buffer.h"
#include "msm_vidc_inst.h"
#include "msm_vidc_core.h"
#include "msm_vidc_driver.h"
#include "msm_vidc_debug.h"
#define MIN_INPUT_BUFFERS 4
#define MIN_ENC_OUTPUT_BUFFERS 4
u32 msm_vidc_input_min_count(struct msm_vidc_inst *inst)
{
u32 input_min_count = 0;
//struct v4l2_ctrl *max_layer = NULL;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return 0;
}
if (!is_decode_session(inst) && !is_encode_session(inst))
return 0;
input_min_count = MIN_INPUT_BUFFERS;
if (is_thumbnail_session(inst))
input_min_count = 1;
//if (is_grid_session(inst))
// input_min_count = 2;
//if (is_hier_b_session(inst)) {
//max_layer = get_ctrl(inst,
// V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER);
//input_min_count = (1 << (max_layer->val - 1)) + 2;
//}
return input_min_count;
}
u32 msm_vidc_output_min_count(struct msm_vidc_inst *inst)
{
u32 output_min_count;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return 0;
}
if (!is_decode_session(inst) && !is_encode_session(inst))
return 0;
if (is_thumbnail_session(inst))
return inst->codec == MSM_VIDC_VP9 ? 8 : 1;
if (is_decode_session(inst)) {
switch (inst->codec) {
case MSM_VIDC_H264:
case MSM_VIDC_HEVC:
output_min_count = 4;
break;
case MSM_VIDC_VP9:
output_min_count = 9;
break;
case MSM_VIDC_MPEG2:
output_min_count = 6;
break;
default:
output_min_count = 4;
}
} else {
output_min_count = MIN_ENC_OUTPUT_BUFFERS;
}
//if (is_vpp_delay_allowed(inst)) {
// output_min_count =
// max(output_min_count, (u32)MAX_BSE_VPP_DELAY);
// output_min_count =
// max(output_min_count, (u32)(msm_vidc_vpp_delay & 0x1F));
//}
return output_min_count;
}
u32 msm_vidc_input_extra_count(struct msm_vidc_inst *inst)
{
u32 extra_input_count = 0;
struct msm_vidc_core *core;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params %pK\n", __func__, inst);
return 0;
}
core = inst->core;
if (is_thumbnail_session(inst))
return extra_input_count;
if (is_decode_session(inst)) {
/* add dcvs buffers */
/* add batching buffers */
extra_input_count = 6;
} else if (is_encode_session(inst)) {
/* add dcvs buffers */
extra_input_count = 4;
}
return extra_input_count;
}
u32 msm_vidc_output_extra_count(struct msm_vidc_inst *inst)
{
u32 extra_output_count = 0;
struct msm_vidc_core *core;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params %pK\n", __func__, inst);
return 0;
}
core = inst->core;
if (is_thumbnail_session(inst))
return 0;
if (is_decode_session(inst)) {
/* add dcvs buffers */
/* add batching buffers */
extra_output_count = 6;
} else if (is_encode_session(inst)) {
/* add heif buffers */
//extra_output_count = 8
}
return extra_output_count;
}
u32 msm_vidc_decoder_input_size(struct msm_vidc_inst *inst)
{
return ALIGN(15 * 1024 * 1024, SZ_4K);
}
u32 msm_vidc_decoder_output_size(struct msm_vidc_inst *inst)
{
u32 format;
struct v4l2_format *f;
f = &inst->fmts[OUTPUT_PORT];
format = msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat);
return VENUS_BUFFER_SIZE(format, f->fmt.pix.width,
f->fmt.pix.height);
}
u32 msm_vidc_decoder_input_meta_size(struct msm_vidc_inst *inst)
{
return ALIGN(16 * 1024, SZ_4K);
}
u32 msm_vidc_decoder_output_meta_size(struct msm_vidc_inst *inst)
{
return ALIGN(16 * 1024, SZ_4K);
}
u32 msm_vidc_encoder_input_size(struct msm_vidc_inst *inst)
{
u32 format;
struct v4l2_format *f;
f = &inst->fmts[INPUT_PORT];
format = msm_vidc_convert_color_fmt(f->fmt.pix.pixelformat);
return VENUS_BUFFER_SIZE(format, f->fmt.pix.width,
f->fmt.pix.height);
}
u32 msm_vidc_encoder_output_size(struct msm_vidc_inst *inst)
{
return ALIGN(15 * 1024 * 1024, SZ_4K);
}
u32 msm_vidc_encoder_input_meta_size(struct msm_vidc_inst *inst)
{
return ALIGN(1 * 1024 * 1024, SZ_4K);
}
u32 msm_vidc_encoder_output_meta_size(struct msm_vidc_inst *inst)
{
return ALIGN(16 * 1024, SZ_4K);
}

View File

@@ -10,10 +10,15 @@
#include "msm_vidc_driver.h" #include "msm_vidc_driver.h"
#include "msm_vidc_internal.h" #include "msm_vidc_internal.h"
#include "msm_vidc_memory.h"
#include "msm_vidc_debug.h" #include "msm_vidc_debug.h"
#include "venus_hfi.h" #include "venus_hfi.h"
int msm_vidc_get_port_from_type(u32 type) void print_vidc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *b)
{
}
int msm_vidc_get_port_from_v4l2_type(u32 type)
{ {
int port; int port;
@@ -26,12 +31,167 @@ int msm_vidc_get_port_from_type(u32 type)
} else if (type == OUTPUT_META_PLANE) { } else if (type == OUTPUT_META_PLANE) {
port = OUTPUT_META_PORT; port = OUTPUT_META_PORT;
} else { } else {
d_vpr_e("invalid type %d\n", type); d_vpr_e("%s: invalid type %d\n", __func__, type);
port = -EINVAL; port = -EINVAL;
} }
return port; return port;
} }
u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{
u32 region = MSM_VIDC_NON_SECURE;
if (!is_secure_session(inst))
return region;
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
if (is_encode_session(inst))
region = MSM_VIDC_SECURE_PIXEL;
else
region = MSM_VIDC_SECURE_BITSTREAM;
break;
case MSM_VIDC_BUF_OUTPUT:
if (is_encode_session(inst))
region = MSM_VIDC_SECURE_BITSTREAM;
else
region = MSM_VIDC_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_INPUT_META:
case MSM_VIDC_BUF_OUTPUT_META:
region = MSM_VIDC_NON_SECURE;
break;
case MSM_VIDC_BUF_SCRATCH:
region = MSM_VIDC_SECURE_BITSTREAM;
break;
case MSM_VIDC_BUF_SCRATCH_1:
region = MSM_VIDC_SECURE_NONPIXEL;
break;
case MSM_VIDC_BUF_SCRATCH_2:
region = MSM_VIDC_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_PERSIST:
if (is_encode_session(inst))
region = MSM_VIDC_SECURE_NONPIXEL;
else
region = MSM_VIDC_SECURE_BITSTREAM;
break;
case MSM_VIDC_BUF_PERSIST_1:
region = MSM_VIDC_SECURE_NONPIXEL;
break;
default:
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, buffer_type);
}
return region;
}
struct msm_vidc_buffer_info *msm_vidc_get_buffer_info(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
return &inst->buffers.input;
case MSM_VIDC_BUF_INPUT_META:
return &inst->buffers.input_meta;
case MSM_VIDC_BUF_OUTPUT:
return &inst->buffers.output;
case MSM_VIDC_BUF_OUTPUT_META:
return &inst->buffers.output_meta;
case MSM_VIDC_BUF_SCRATCH:
return &inst->buffers.scratch;
case MSM_VIDC_BUF_SCRATCH_1:
return &inst->buffers.scratch_1;
case MSM_VIDC_BUF_SCRATCH_2:
return &inst->buffers.scratch_2;
case MSM_VIDC_BUF_PERSIST:
return &inst->buffers.persist;
case MSM_VIDC_BUF_PERSIST_1:
return &inst->buffers.persist_1;
default:
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, buffer_type);
return NULL;
}
}
struct msm_vidc_map_info *msm_vidc_get_map_info(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
return &inst->maps.input;
case MSM_VIDC_BUF_INPUT_META:
return &inst->maps.input_meta;
case MSM_VIDC_BUF_OUTPUT:
return &inst->maps.output;
case MSM_VIDC_BUF_OUTPUT_META:
return &inst->maps.output_meta;
case MSM_VIDC_BUF_SCRATCH:
return &inst->maps.scratch;
case MSM_VIDC_BUF_SCRATCH_1:
return &inst->maps.scratch_1;
case MSM_VIDC_BUF_SCRATCH_2:
return &inst->maps.scratch_2;
case MSM_VIDC_BUF_PERSIST:
return &inst->maps.persist;
case MSM_VIDC_BUF_PERSIST_1:
return &inst->maps.persist_1;
default:
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, buffer_type);
return NULL;
}
}
struct msm_vidc_alloc_info *msm_vidc_get_alloc_info(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{
switch (buffer_type) {
case MSM_VIDC_BUF_SCRATCH:
return &inst->allocations.scratch;
case MSM_VIDC_BUF_SCRATCH_1:
return &inst->allocations.scratch_1;
case MSM_VIDC_BUF_SCRATCH_2:
return &inst->allocations.scratch_2;
case MSM_VIDC_BUF_PERSIST:
return &inst->allocations.persist;
case MSM_VIDC_BUF_PERSIST_1:
return &inst->allocations.persist_1;
default:
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, buffer_type);
return NULL;
}
}
int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
enum msm_vidc_inst_state request_state)
{
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (!request_state) {
d_vpr_e("%s: invalid request state\n", __func__);
return -EINVAL;
}
if (inst->state == MSM_VIDC_ERROR) {
s_vpr_h(inst->sid,
"inst is in bad state, can not change state to %d\n",
request_state);
return 0;
}
s_vpr_h(inst->sid, "state changed from %d to %d\n",
inst->state, request_state);
inst->state = request_state;
return 0;
}
int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
{ {
int rc = 0; int rc = 0;
@@ -84,72 +244,226 @@ u32 msm_vidc_convert_color_fmt(u32 v4l2_fmt)
} }
} }
int msm_vidc_stop_input(struct msm_vidc_inst *inst) int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{ {
int rc = 0; int rc = 0;
struct msm_vidc_buffer_info *buffer_info;
struct msm_vidc_alloc_info *alloc_info;
struct msm_vidc_map_info *map_info;
int i;
d_vpr_h("%s()\n", __func__); d_vpr_h("%s()\n", __func__);
if (!inst) { if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
if (!is_internal_buffer(buffer_type)) {
s_vpr_e(inst->sid, "%s: buffer type %#d is not internal\n",
__func__, buffer_type);
return 0;
}
return rc; buffer_info = msm_vidc_get_buffer_info(inst, buffer_type);
if (!buffer_info)
return -EINVAL;
alloc_info = msm_vidc_get_alloc_info(inst, buffer_type);
if (!alloc_info)
return -EINVAL;
map_info = msm_vidc_get_map_info(inst, buffer_type);
if (!alloc_info)
return -EINVAL;
for (i = 0; i < buffer_info->min_count; i++) {
struct msm_vidc_buffer *buffer;
struct msm_vidc_alloc *alloc;
struct msm_vidc_map *map;
if (!buffer_info->size) {
d_vpr_e("%s: invalid buffer %#x\n", __func__, buffer_type);
return -EINVAL;
}
buffer = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL);
if (!buffer) {
s_vpr_e(inst->sid, "%s: msm_vidc_buffer alloc failed\n", __func__);
return -ENOMEM;
}
INIT_LIST_HEAD(&buffer->list);
buffer->valid = true;
buffer->type = buffer_type;
buffer->index = i;
buffer->buffer_size = buffer_info->size;
list_add_tail(&buffer->list, &buffer_info->list);
alloc = kzalloc(sizeof(struct msm_vidc_alloc), GFP_KERNEL);
if (!alloc) {
s_vpr_e(inst->sid, "%s: msm_vidc_alloc alloc failed\n", __func__);
return -ENOMEM;
}
INIT_LIST_HEAD(&alloc->list);
alloc->buffer_type = buffer_type;
alloc->region = msm_vidc_get_buffer_region(inst, buffer_type);
alloc->size = buffer->buffer_size;
rc = msm_vidc_memory_alloc(inst->core, alloc);
if (rc)
return -ENOMEM;
list_add_tail(&alloc->list, &alloc_info->list);
map = kzalloc(sizeof(struct msm_vidc_map), GFP_KERNEL);
if (!map) {
s_vpr_e(inst->sid, "%s: msm_vidc_map alloc failed\n", __func__);
return -ENOMEM;
}
INIT_LIST_HEAD(&map->list);
map->buffer_type = alloc->buffer_type;
map->region = alloc->region;
map->dmabuf = alloc->dmabuf;
rc = msm_vidc_memory_map(inst->core, map);
if (rc)
return -ENOMEM;
list_add_tail(&map->list, &map_info->list);
s_vpr_e(inst->sid, "%s: created buffer_type %d, size %d\n",
__func__, buffer_type, buffer_info->size);
}
return 0;
} }
int msm_vidc_stop_output(struct msm_vidc_inst *inst) int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{ {
int rc = 0; int rc = 0;
struct msm_vidc_buffer_info *buffer_info;
struct msm_vidc_buffer *buffer, *dummy;
d_vpr_h("%s()\n", __func__); d_vpr_h("%s()\n", __func__);
if (!inst) { if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
if (!is_internal_buffer(buffer_type)) {
s_vpr_e(inst->sid, "%s: buffer type %#d is not internal\n",
__func__, buffer_type);
return 0;
}
return rc; buffer_info = msm_vidc_get_buffer_info(inst, buffer_type);
if (!buffer_info)
return -EINVAL;
list_for_each_entry_safe(buffer, dummy, &buffer_info->list, list) {
/* do not queue pending release buffers */
if (buffer->flags & MSM_VIDC_ATTR_PENDING_RELEASE)
continue;
/* do not queue already queued buffers */
if (buffer->attr & MSM_VIDC_ATTR_QUEUED)
continue;
rc = venus_hfi_queue_buffer(inst, buffer, NULL);
if (rc)
return rc;
/* mark queued */
buffer->attr |= MSM_VIDC_ATTR_QUEUED;
s_vpr_e(inst->sid, "%s: queued buffer_type %d, size %d\n",
__func__, buffer_type, buffer_info->size);
}
return 0;
} }
int msm_vidc_start_input(struct msm_vidc_inst *inst) int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{ {
int rc = 0; int rc = 0;
struct msm_vidc_buffer_info *buffer_info;
struct msm_vidc_buffer *buffer, *dummy;
d_vpr_h("%s()\n", __func__); d_vpr_h("%s()\n", __func__);
if (!inst) { if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
if (!is_internal_buffer(buffer_type)) {
return rc; s_vpr_e(inst->sid, "%s: buffer type %#d is not internal\n",
} __func__, buffer_type);
return 0;
int msm_vidc_start_output(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
} }
return rc; buffer_info = msm_vidc_get_buffer_info(inst, buffer_type);
if (!buffer_info)
return -EINVAL;
list_for_each_entry_safe(buffer, dummy, &buffer_info->list, list) {
/* do not release already pending release buffers */
if (buffer->attr & MSM_VIDC_ATTR_PENDING_RELEASE)
continue;
/* release only queued buffers */
if (!(buffer->attr & MSM_VIDC_ATTR_QUEUED))
continue;
rc = venus_hfi_release_buffer(inst, buffer);
if (rc)
return rc;
/* mark pending release */
buffer->attr |= MSM_VIDC_ATTR_PENDING_RELEASE;
s_vpr_e(inst->sid, "%s: released buffer_type %d, size %d\n",
__func__, buffer_type, buffer_info->size);
}
return 0;
} }
int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst) int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst)
{ {
int rc = 0; int rc = 0;
int index;
struct msm_vidc_core *core;
d_vpr_h("%s()\n", __func__); d_vpr_h("%s()\n", __func__);
if (!inst) { if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
core = inst->core;
// TODO: check decode is index = 0 and encode is index 1
if (is_decode_session(inst))
index = 0;
else if (is_encode_session(inst))
index = 1;
else
return -EINVAL;
v4l2_fh_init(&inst->event_handler, &core->vdev[index].vdev);
v4l2_fh_add(&inst->event_handler);
return rc; return rc;
} }
int msm_vidc_queue_init(struct msm_vidc_inst *inst) static int vb2q_init(struct msm_vidc_inst *inst,
struct vb2_queue *q, enum v4l2_buf_type type)
{
struct msm_vidc_core *core;
if (!inst || !q || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
q->type = type;
q->io_modes = VB2_MMAP | VB2_USERPTR;
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
q->ops = core->vb2_ops;
q->mem_ops = core->vb2_mem_ops;
q->drv_priv = inst;
q->allow_zero_bytesused = 1;
q->copy_timestamp = 1;
return vb2_queue_init(q);
}
int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst)
{ {
int rc = 0; int rc = 0;
@@ -159,6 +473,22 @@ int msm_vidc_queue_init(struct msm_vidc_inst *inst)
return -EINVAL; return -EINVAL;
} }
rc = vb2q_init(inst, &inst->vb2q[INPUT_PORT], INPUT_PLANE);
if (rc)
return rc;
rc = vb2q_init(inst, &inst->vb2q[OUTPUT_PORT], OUTPUT_PLANE);
if (rc)
return rc;
rc = vb2q_init(inst, &inst->vb2q[INPUT_META_PORT], INPUT_META_PLANE);
if (rc)
return rc;
rc = vb2q_init(inst, &inst->vb2q[OUTPUT_META_PORT], OUTPUT_META_PLANE);
if (rc)
return rc;
return rc; return rc;
} }
@@ -195,6 +525,23 @@ int msm_vidc_add_session(struct msm_vidc_inst *inst)
return rc; return rc;
} }
int msm_vidc_session_open(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = venus_hfi_session_open(inst);
if (rc)
return rc;
inst->session_created = true;
return 0;
}
int msm_vidc_core_init(struct msm_vidc_core *core) int msm_vidc_core_init(struct msm_vidc_core *core)
{ {
int rc; int rc;

View File

@@ -8,6 +8,8 @@
#include "msm_vidc_inst.h" #include "msm_vidc_inst.h"
#include "msm_vidc_internal.h" #include "msm_vidc_internal.h"
#include "msm_vidc_driver.h" #include "msm_vidc_driver.h"
#include "msm_vdec.h"
#include "msm_venc.h"
#include "msm_vidc_debug.h" #include "msm_vidc_debug.h"
void *msm_vb2_get_userptr(struct device *dev, unsigned long vaddr, void *msm_vb2_get_userptr(struct device *dev, unsigned long vaddr,
@@ -44,7 +46,7 @@ int msm_vidc_queue_setup(struct vb2_queue *q,
return -EINVAL; return -EINVAL;
} }
port = msm_vidc_get_port_from_type(q->type); port = msm_vidc_get_port_from_v4l2_type(q->type);
if (port < 0) { if (port < 0) {
d_vpr_e("%s: invalid queue type %d\n", __func__, q->type); d_vpr_e("%s: invalid queue type %d\n", __func__, q->type);
return -EINVAL; return -EINVAL;
@@ -96,12 +98,29 @@ int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
__func__, q->type); __func__, q->type);
return 0; return 0;
} }
if (!is_decode_session(inst) && !is_encode_session(inst)) {
s_vpr_e(inst->sid, "%s: invalid session %d\n",
__func__, inst->domain);
return -EINVAL;
}
s_vpr_h(inst->sid, "Streamon: %d\n", q->type); s_vpr_h(inst->sid, "Streamon: %d\n", q->type);
if (!inst->session_created) {
rc = msm_vidc_session_open(inst);
if (rc)
return -EINVAL;
}
if (q->type == INPUT_PLANE) { if (q->type == INPUT_PLANE) {
rc = msm_vidc_start_input(inst); if (is_decode_session(inst))
} else if (q->type == INPUT_PLANE) { rc = msm_vdec_start_input(inst);
rc = msm_vidc_start_output(inst); //else if (is_encode_session(inst))
// rc = msm_venc_start_input(inst);
} else if (q->type == OUTPUT_PLANE) {
if (is_decode_session(inst))
rc = msm_vdec_start_output(inst);
//else if (is_encode_session(inst))
// rc = msm_venc_start_output(inst);
} else { } else {
s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, q->type); s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, q->type);
rc = -EINVAL; rc = -EINVAL;

View File

@@ -20,6 +20,7 @@
#include "msm_vidc_dt.h" #include "msm_vidc_dt.h"
#include "msm_vidc_platform.h" #include "msm_vidc_platform.h"
#include "msm_vidc_memory.h" #include "msm_vidc_memory.h"
#include "msm_vidc_driver.h"
#include "msm_vidc_debug.h" #include "msm_vidc_debug.h"
#include "hfi_packet.h" #include "hfi_packet.h"
@@ -561,6 +562,10 @@ static int __write_queue(struct msm_vidc_iface_q_info *qinfo, u8 *packet,
__dump_packet(packet); __dump_packet(packet);
} }
// TODO: handle writing packet
d_vpr_e("skip writing packet\n");
return 0;
packet_size_in_words = (*(u32 *)packet) >> 2; packet_size_in_words = (*(u32 *)packet) >> 2;
if (!packet_size_in_words || packet_size_in_words > if (!packet_size_in_words || packet_size_in_words >
qinfo->q_array.mem_size>>2) { qinfo->q_array.mem_size>>2) {
@@ -2005,7 +2010,7 @@ static int __interface_queues_init(struct msm_vidc_core *core)
q_size = SHARED_QSIZE - ALIGNED_SFR_SIZE - ALIGNED_QDSS_SIZE; q_size = SHARED_QSIZE - ALIGNED_SFR_SIZE - ALIGNED_QDSS_SIZE;
memset(&alloc, 0, sizeof(alloc)); memset(&alloc, 0, sizeof(alloc));
alloc.buffer_type = MSM_VIDC_QUEUE; alloc.buffer_type = MSM_VIDC_BUF_QUEUE;
alloc.region = MSM_VIDC_NON_SECURE; alloc.region = MSM_VIDC_NON_SECURE;
alloc.size = q_size; alloc.size = q_size;
alloc.cached = false; alloc.cached = false;
@@ -2078,7 +2083,7 @@ static int __interface_queues_init(struct msm_vidc_core *core)
/* sfr buffer */ /* sfr buffer */
memset(&alloc, 0, sizeof(alloc)); memset(&alloc, 0, sizeof(alloc));
alloc.buffer_type = MSM_VIDC_QUEUE; alloc.buffer_type = MSM_VIDC_BUF_QUEUE;
alloc.region = MSM_VIDC_NON_SECURE; alloc.region = MSM_VIDC_NON_SECURE;
alloc.size = ALIGNED_SFR_SIZE; alloc.size = ALIGNED_SFR_SIZE;
alloc.cached = false; alloc.cached = false;
@@ -2339,15 +2344,14 @@ int venus_hfi_suspend(struct msm_vidc_core *core)
return rc; return rc;
} }
int venus_hfi_session_open(struct msm_vidc_core *core, int venus_hfi_session_open(struct msm_vidc_inst *inst)
struct msm_vidc_inst *inst)
{ {
int rc = 0; int rc = 0;
u32 codec;
d_vpr_h("%s(): inst %p, core %p\n", d_vpr_h("%s(): inst %p %p\n", __func__, inst);
__func__, inst, core);
if (!core || !inst) { if (!inst) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
@@ -2359,14 +2363,319 @@ int venus_hfi_session_open(struct msm_vidc_core *core,
return -ENOMEM; return -ENOMEM;
} }
rc = hfi_packet_session_command(inst, rc = hfi_packet_session_command(inst,
HFI_CMD_OPEN, HFI_CMD_OPEN,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED | (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED), HFI_HOST_FLAGS_INTR_REQUIRED),
HFI_PORT_NONE, HFI_PORT_NONE,
0 /* session_id */, 0, /* session_id */
HFI_PAYLOAD_U32, HFI_PAYLOAD_U32,
&inst->session_id /*payload*/, &inst->session_id, /* payload */
sizeof(u32)); sizeof(u32));
if (rc)
goto error;
rc = __iface_cmdq_write(inst->core, inst->packet);
if (rc)
goto error;
codec = get_hfi_codec(inst);
rc = hfi_packet_session_property(inst,
HFI_PROP_CODEC,
HFI_HOST_FLAGS_NONE,
HFI_PORT_NONE,
HFI_PAYLOAD_U32,
&codec,
sizeof(u32));
if (rc)
goto error;
rc = __iface_cmdq_write(inst->core, inst->packet);
if (rc)
goto error;
inst->session_created = true;
error:
return rc;
}
int venus_hfi_session_close(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst || !inst->packet) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = hfi_packet_session_command(inst,
HFI_CMD_CLOSE,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED |
HFI_HOST_FLAGS_NON_DISCARDABLE),
HFI_PORT_NONE,
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
0);
if (!rc)
__iface_cmdq_write(inst->core, inst->packet);
kfree(inst->packet);
return rc;
}
int venus_hfi_start_input(struct msm_vidc_inst *inst)
{
int rc = 0;
u32 port;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
port = is_decode_session(inst) ? HFI_PORT_BITSTREAM : HFI_PORT_RAW;
rc = hfi_packet_session_command(inst,
HFI_CMD_START,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
port,
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
0);
if (rc)
return rc;
rc = __iface_cmdq_write(inst->core, inst->packet);
if (rc)
return rc;
return rc;
}
int venus_hfi_stop_input(struct msm_vidc_inst *inst)
{
int rc = 0;
u32 port;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
port = is_decode_session(inst) ? HFI_PORT_BITSTREAM : HFI_PORT_RAW;
rc = hfi_packet_session_command(inst,
HFI_CMD_STOP,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED |
HFI_HOST_FLAGS_NON_DISCARDABLE),
port,
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
0);
if (rc)
return rc;
rc = __iface_cmdq_write(inst->core, inst->packet);
if (rc)
return rc;
return rc;
}
int venus_hfi_start_output(struct msm_vidc_inst *inst)
{
int rc = 0;
u32 port;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
port = is_decode_session(inst) ? HFI_PORT_RAW : HFI_PORT_BITSTREAM;
rc = hfi_packet_session_command(inst,
HFI_CMD_START,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
port,
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
0);
if (rc)
return rc;
rc = __iface_cmdq_write(inst->core, inst->packet);
if (rc)
return rc;
return rc;
}
int venus_hfi_stop_output(struct msm_vidc_inst *inst)
{
int rc = 0;
u32 port;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
port = is_decode_session(inst) ? HFI_PORT_RAW : HFI_PORT_BITSTREAM;
rc = hfi_packet_session_command(inst,
HFI_CMD_STOP,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED |
HFI_HOST_FLAGS_NON_DISCARDABLE),
port,
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
0);
if (rc)
return rc;
rc = __iface_cmdq_write(inst->core, inst->packet);
if (rc)
return rc;
return rc;
}
int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buffer, struct msm_vidc_buffer *metabuf)
{
int rc = 0;
struct msm_vidc_core *core;
struct hfi_buffer hfi_buffer;
u32 num_packets = 0, offset = 0;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst || !inst->core || !inst->packet) {
d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
rc = get_hfi_buffer(inst, buffer, &hfi_buffer);
if (rc)
return rc;
offset = sizeof(struct hfi_header);
rc = hfi_create_packet(inst->packet,
inst->packet_size,
&offset,
HFI_CMD_BUFFER,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
HFI_PAYLOAD_STRUCTURE,
get_hfi_port(inst, buffer->type),
core->packet_id++,
&hfi_buffer,
sizeof(hfi_buffer));
if (rc)
return rc;
num_packets++;
if (metabuf) {
rc = get_hfi_buffer(inst, metabuf, &hfi_buffer);
if (rc)
return rc;
rc = hfi_create_packet(inst->packet,
inst->packet_size,
&offset,
HFI_CMD_BUFFER,
HFI_HOST_FLAGS_NONE,
HFI_PAYLOAD_STRUCTURE,
get_hfi_port(inst, metabuf->type),
core->packet_id++,
&hfi_buffer,
sizeof(hfi_buffer));
if (rc)
return rc;
num_packets++;
}
rc = hfi_create_header(inst->packet, inst->session_id,
core->header_id++,
num_packets,
offset);
if (rc)
return rc;
rc = __iface_cmdq_write(inst->core, inst->packet);
if (rc)
return rc;
return rc;
}
int venus_hfi_release_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buffer)
{
int rc = 0;
struct msm_vidc_core *core;
struct hfi_buffer hfi_buffer;
u32 num_packets = 0, offset = 0;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst || !buffer) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (!is_internal_buffer(buffer->type)) {
s_vpr_e(inst->sid, "release not allowed for buffer type %d\n",
buffer->type);
return 0;
}
core = inst->core;
rc = get_hfi_buffer(inst, buffer, &hfi_buffer);
if (rc)
return rc;
/* add pending release flag */
hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
offset = sizeof(struct hfi_header);
rc = hfi_create_packet(inst->packet,
inst->packet_size,
&offset,
HFI_CMD_BUFFER,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
HFI_PAYLOAD_STRUCTURE,
get_hfi_port(inst, buffer->type),
core->packet_id++,
&hfi_buffer,
sizeof(hfi_buffer));
if (rc)
return rc;
num_packets++;
rc = hfi_create_header(inst->packet, inst->session_id,
core->header_id++,
num_packets,
offset);
if (rc)
return rc;
rc = __iface_cmdq_write(inst->core, inst->packet);
if (rc) if (rc)
return rc; return rc;