msm: vidc: enhance CVP usage functionality

Amend below CVP functionalities

- enable logic
- start sequence
- frame skip logic
- downscale resolution logic
- debugfs support.

Change-Id: I21ad934526c338916d130aaf3401bd89b574b4c1
Signed-off-by: Maheshwar Ajja <majja@codeaurora.org>
This commit is contained in:
Maheshwar Ajja 2019-05-06 23:26:15 -07:00
commit 35da0d64cf
14 changed files with 331 additions and 212 deletions

View file

@ -299,7 +299,7 @@ static int __dsp_send_hfi_queue(struct venus_hfi_device *device)
{
int rc;
if (!device->res->domain_cvp)
if (!device->res->cvp_internal)
return 0;
if (!device->dsp_iface_q_table.mem_data.dma_handle) {
@ -333,7 +333,7 @@ static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags)
int rc;
struct hal_session *temp;
if (!device->res->domain_cvp)
if (!device->res->cvp_internal)
return 0;
if (!(device->dsp_flags & DSP_INIT))
@ -374,7 +374,7 @@ static int __dsp_resume(struct venus_hfi_device *device, u32 flags)
{
int rc;
if (!device->res->domain_cvp)
if (!device->res->cvp_internal)
return 0;
if (!(device->dsp_flags & DSP_SUSPEND)) {
@ -400,7 +400,7 @@ static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags)
{
int rc;
if (!device->res->domain_cvp)
if (!device->res->cvp_internal)
return 0;
if (!(device->dsp_flags & DSP_INIT)) {
@ -1171,7 +1171,7 @@ static inline int __boot_firmware_common(struct venus_hfi_device *device)
u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000;
ctrl_init_val = BIT(0);
if (device->res->domain_cvp)
if (device->res->cvp_internal)
ctrl_init_val |= BIT(1);
__write_register(device, CTRL_INIT, ctrl_init_val);
@ -1688,7 +1688,7 @@ static void __interface_queues_release(struct venus_hfi_device *device)
device->mem_addr.align_virtual_addr = NULL;
device->mem_addr.align_device_addr = 0;
if (device->res->domain_cvp)
if (device->res->cvp_internal)
__interface_dsp_queues_release(device);
}
@ -1901,7 +1901,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev)
}
if (dev->res->domain_cvp) {
if (dev->res->cvp_internal) {
rc = __interface_dsp_queues_init(dev);
if (rc) {
dprintk(VIDC_ERR, "dsp_queues_init failed\n");

View file

@ -41,7 +41,7 @@ void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device)
__write_register(device, HFI_DSP_UC_REGION_ADDR,
(u32)device->iface_q_table.align_device_addr);
__write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE);
if (device->res->domain_cvp) {
if (device->res->cvp_internal) {
/* initialize DSP QTBL & UCREGION with DSP queues */
__write_register(device, HFI_DSP_QTBL_ADDR,
(u32)device->dsp_iface_q_table.align_device_addr);

View file

@ -383,7 +383,7 @@ int __boot_firmware_iris2(struct venus_hfi_device *device)
u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000;
ctrl_init_val = BIT(0);
if (device->res->domain_cvp)
if (device->res->cvp_internal)
ctrl_init_val |= BIT(1);
__write_register(device, CTRL_INIT_IRIS2, ctrl_init_val);

View file

@ -171,6 +171,66 @@ error:
return rc;
}
static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst)
{
struct msm_cvp_external *cvp;
const u32 width_max = 1920;
u32 width, height, ds_width, ds_height, temp;
if (!inst || !inst->cvp) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
cvp = inst->cvp;
ds_width = cvp->width;
ds_height = cvp->height;
if (!cvp->downscale) {
dprintk(VIDC_DBG, "%s: downscaling not enabled\n", __func__);
goto exit;
}
/* Step 1) make width always the larger number */
if (cvp->height > cvp->width) {
width = cvp->height;
height = cvp->width;
} else {
width = cvp->width;
height = cvp->height;
}
/*
* Step 2) Downscale width by 4 and round
* make sure width stays between 480 and 1920
*/
ds_width = (width + 2) >> 2;
if (ds_width < 480)
ds_width = 480;
if (ds_width > width_max)
ds_width = width_max;
ds_height = (height * ds_width) / width;
if (ds_height < 128)
ds_height = 128;
/* Step 3) do not downscale if width is less than 480 */
if (width <= 480)
ds_width = width;
if (ds_width == width)
ds_height = height;
/* Step 4) switch width and height if already switched */
if (height > width) {
temp = ds_height;
ds_height = ds_width;
ds_width = temp;
}
exit:
cvp->ds_width = ds_width;
cvp->ds_height = ds_height;
return 0;
}
static void msm_cvp_deinit_downscale_buffers(struct msm_vidc_inst *inst)
{
struct msm_cvp_external *cvp;
@ -389,15 +449,12 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst)
struct cvp_kmd_arg *arg;
struct msm_cvp_session_set_persist_buffers_packet persist2_packet;
if (!inst || !inst->cvp) {
if (!inst || !inst->cvp || !inst->cvp->arg) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
if (!arg)
return -ENOMEM;
cvp = inst->cvp;
arg = cvp->arg;
dprintk(VIDC_DBG, "%s:\n", __func__);
cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE;
@ -451,35 +508,36 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst)
print_cvp_buffer(VIDC_DBG, "alloc: output_buffer",
inst, &cvp->output_buffer);
kfree(arg);
return rc;
error:
msm_cvp_deinit_internal_buffers(inst);
kfree(arg);
return rc;
}
static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst,
struct vb2_buffer *vb)
struct msm_vidc_buffer *mbuf)
{
int rc = 0;
struct msm_cvp_external *cvp;
struct dma_buf *dbuf = NULL;
char *kvaddr = NULL;
struct vb2_buffer *vb;
struct dma_buf *dbuf;
char *kvaddr;
struct msm_vidc_extradata_header *e_hdr;
bool input_extradata, found_end;
if (!inst || !inst->cvp || !vb) {
if (!inst || !inst->cvp || !mbuf) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
cvp = inst->cvp;
vb = &mbuf->vvb.vb2_buf;
if (vb->num_planes <= 1) {
dprintk(VIDC_ERR, "%s: extradata plane not enabled\n",
__func__);
return -EINVAL;
}
cvp = inst->cvp;
dbuf = dma_buf_get(vb->planes[1].m.fd);
if (!dbuf) {
@ -539,17 +597,24 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst,
dbuf->size);
goto error;
}
/* copy payload */
e_hdr->version = 0x00000001;
e_hdr->port_index = 1;
e_hdr->type = MSM_VIDC_EXTRADATA_CVP_METADATA;
e_hdr->data_size = sizeof(struct msm_vidc_enc_cvp_metadata_payload);
e_hdr->size = sizeof(struct msm_vidc_extradata_header) +
if (cvp->metadata_available) {
cvp->metadata_available = false;
/* copy payload */
e_hdr->version = 0x00000001;
e_hdr->port_index = 1;
e_hdr->type = MSM_VIDC_EXTRADATA_CVP_METADATA;
e_hdr->data_size =
sizeof(struct msm_vidc_enc_cvp_metadata_payload);
e_hdr->size = sizeof(struct msm_vidc_extradata_header) +
e_hdr->data_size;
dma_buf_begin_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL);
memcpy(e_hdr->data, cvp->output_buffer.kvaddr,
dma_buf_begin_cpu_access(cvp->output_buffer.dbuf,
DMA_BIDIRECTIONAL);
memcpy(e_hdr->data, cvp->output_buffer.kvaddr,
sizeof(struct msm_vidc_enc_cvp_metadata_payload));
dma_buf_end_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL);
dma_buf_end_cpu_access(cvp->output_buffer.dbuf,
DMA_BIDIRECTIONAL);
}
/* fill extradata none */
e_hdr = (struct msm_vidc_extradata_header *)
((char *)e_hdr + e_hdr->size);
@ -607,27 +672,52 @@ static int msm_cvp_reference_management(struct msm_vidc_inst *inst)
}
static int msm_cvp_frame_process(struct msm_vidc_inst *inst,
struct vb2_buffer *vb)
struct msm_vidc_buffer *mbuf)
{
int rc = 0;
struct msm_cvp_external *cvp;
struct vb2_buffer *vb;
struct cvp_kmd_arg *arg;
struct msm_cvp_dme_frame_packet *frame;
const u32 fps_max = 60;
u32 fps, skip_framecount;
bool skipframe = false;
if (!inst || !inst->cvp) {
if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
if (!arg)
return -ENOMEM;
cvp = inst->cvp;
arg = cvp->arg;
vb = &mbuf->vvb.vb2_buf;
cvp->fullres_buffer.index = vb->index;
cvp->fullres_buffer.fd = vb->planes[0].m.fd;
cvp->fullres_buffer.size = vb->planes[0].length;
cvp->fullres_buffer.offset = vb->planes[0].data_offset;
/* frame skip logic */
fps = max(inst->clk_data.operating_rate,
inst->clk_data.frame_rate) >> 16;
if (fps > fps_max) {
/*
* fps <= 120: 0, 2, 4, 6 .. are not skipped
* fps <= 180: 0, 3, 6, 9 .. are not skipped
* fps <= 240: 0, 4, 8, 12 .. are not skipped
* fps <= 960: 0, 16, 32, 48 .. are not skipped
*/
fps = ALIGN(fps, fps_max);
skip_framecount = fps / fps_max;
skipframe = !(cvp->framecount % skip_framecount);
}
if (skipframe) {
print_cvp_buffer(VIDC_DBG, "input frame skipped",
inst, &cvp->fullres_buffer);
cvp->framecount++;
cvp->metadata_available = false;
return 0;
}
arg->type = CVP_KMD_SEND_CMD_PKT;
frame = (struct msm_cvp_dme_frame_packet *)&arg->data.hfi_pkt.pkt_data;
@ -680,18 +770,19 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst,
goto error;
}
cvp->framecount++;
cvp->metadata_available = true;
error:
kfree(arg);
return rc;
}
int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *mbuf)
{
int rc = 0;
struct msm_cvp_external *cvp;
if (!inst || !inst->cvp || !vb) {
if (!inst || !inst->cvp || !mbuf) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
@ -702,13 +793,13 @@ int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
}
cvp = inst->cvp;
rc = msm_cvp_frame_process(inst, vb);
rc = msm_cvp_frame_process(inst, mbuf);
if (rc) {
dprintk(VIDC_ERR, "%s: cvp process failed\n", __func__);
return rc;
}
rc = msm_cvp_prepare_extradata(inst, vb);
rc = msm_cvp_prepare_extradata(inst, mbuf);
if (rc) {
dprintk(VIDC_ERR, "%s: prepare extradata failed\n", __func__);
return rc;
@ -760,6 +851,8 @@ static int msm_vidc_cvp_close(struct msm_vidc_inst *inst)
"%s: cvp close failed with error %d\n", __func__, rc);
cvp->priv = NULL;
kfree(cvp->arg);
cvp->arg = NULL;
kfree(inst->cvp);
inst->cvp = NULL;
@ -792,39 +885,25 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
struct msm_cvp_dme_basic_config_packet *dmecfg;
u32 color_fmt;
if (!inst || !inst->cvp) {
if (!inst || !inst->cvp || !inst->cvp->arg) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
if (!arg)
return -ENOMEM;
f = &inst->fmts[INPUT_PORT].v4l2_fmt;
cvp = inst->cvp;
arg = cvp->arg;
cvp->framecount = 0;
cvp->metadata_available = false;
f = &inst->fmts[INPUT_PORT].v4l2_fmt;
cvp->width = f->fmt.pix_mp.width;
cvp->height = f->fmt.pix_mp.height;
color_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat);
/* enable downscale always */
cvp->downscale = true;
if (cvp->width * cvp->height < 640 * 480) {
cvp->ds_width = cvp->width;
cvp->ds_height = cvp->height;
} else if (cvp->width * cvp->height < 1920 * 1080) {
if (cvp->ds_width >= cvp->ds_height) {
cvp->ds_width = 480;
cvp->ds_height = 270;
} else {
cvp->ds_width = 270;
cvp->ds_height = 480;
}
} else {
cvp->ds_width = cvp->width / 4;
cvp->ds_height = cvp->height / 4;
}
rc = msm_cvp_init_downscale_resolution(inst);
if (rc)
goto error;
dprintk(VIDC_DBG,
"%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d\n",
__func__, f->fmt.pix_mp.pixelformat,
@ -873,12 +952,10 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
if (rc)
goto error;
kfree(arg);
return rc;
error:
msm_vidc_cvp_deinit(inst);
kfree(arg);
return rc;
}
@ -892,18 +969,22 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst)
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
if (!arg)
return -ENOMEM;
inst->cvp = kzalloc(sizeof(struct msm_cvp_external), GFP_KERNEL);
if (!inst->cvp) {
dprintk(VIDC_ERR, "%s: failed to allocate\n", __func__);
rc = -ENOMEM;
goto error;
return -ENOMEM;
}
cvp = inst->cvp;
cvp->arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
if (!cvp->arg) {
kfree(inst->cvp);
inst->cvp = NULL;
return -ENOMEM;
}
arg = cvp->arg;
dprintk(VIDC_DBG, "%s: opening cvp\n", __func__);
cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP);
if (!cvp->priv) {
@ -923,14 +1004,10 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst)
dprintk(VIDC_DBG, "%s: cvp session id %#x\n",
__func__, cvp->session_id);
kfree(arg);
return 0;
error:
msm_vidc_cvp_close(inst);
kfree(inst->cvp);
inst->cvp = NULL;
kfree(arg);
return rc;
}

View file

@ -50,11 +50,6 @@ static inline bool is_vidc_cvp_enabled(struct msm_vidc_inst *inst)
return !!inst->cvp;
}
static inline bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst)
{
return false;
}
struct msm_cvp_buffer_type {
u32 buffer_addr;
u32 size;
@ -143,6 +138,7 @@ struct msm_cvp_buf {
struct msm_cvp_external {
void *priv;
void *arg;
u32 session_id;
u32 width;
u32 height;
@ -151,6 +147,7 @@ struct msm_cvp_external {
bool downscale;
u32 framecount;
u32 buffer_idx;
bool metadata_available;
struct msm_cvp_buf fullres_buffer;
struct msm_cvp_buf src_buffer;
struct msm_cvp_buf ref_buffer;
@ -161,8 +158,7 @@ struct msm_cvp_external {
};
int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst,
struct vb2_buffer *vb);
struct msm_vidc_buffer *mbuf);
int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst);
int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst);
#endif

View file

@ -519,7 +519,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev)
}
/* setup the cvp device */
if (core->resources.domain_cvp) {
if (core->resources.cvp_internal) {
rc = msm_vidc_register_video_device(MSM_VIDC_CVP,
nr + 2, core, dev);
if (rc) {
@ -583,7 +583,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev)
err_fail_sub_device_probe:
vidc_hfi_deinitialize(core->hfi_type, core->device);
err_cores_exceeded:
if (core->resources.domain_cvp) {
if (core->resources.cvp_internal) {
device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev,
&dev_attr_link_name);
video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev);
@ -663,7 +663,7 @@ static int msm_vidc_remove(struct platform_device *pdev)
}
vidc_hfi_deinitialize(core->hfi_type, core->device);
if (core->resources.domain_cvp) {
if (core->resources.cvp_internal) {
device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev,
&dev_attr_link_name);
video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev);

View file

@ -3833,7 +3833,6 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst)
int msm_venc_set_extradata(struct msm_vidc_inst *inst)
{
int rc = 0;
struct v4l2_ctrl *cvp_ctrl;
u32 value = 0x0;
u32 codec;
@ -3872,25 +3871,13 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst)
}
}
cvp_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE);
if (cvp_ctrl->val == V4L2_MPEG_MSM_VIDC_ENABLE) {
if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) {
dprintk(VIDC_ERR,
"%s: invalid params\n", __func__);
return -EINVAL;
}
} else {
/*
* For now, enable CVP metadata only if client provides it.
* Once the kernel-mode CVP metadata implementation
* is completed, this condition should be removed.
*/
if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP)
value = 0x1;
}
if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP)
value = 0x1;
dprintk(VIDC_DBG, "%s: CVP extradata %d\n", __func__, value);
rc = msm_comm_set_extradata(inst,
HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, value);
if (rc)
dprintk(VIDC_ERR, "%s: set CVP extradata failed\n", __func__);
return rc;
}

View file

@ -325,46 +325,6 @@ int msm_vidc_release_buffer(void *instance, int type, unsigned int index)
}
EXPORT_SYMBOL(msm_vidc_release_buffer);
static int msm_vidc_preprocess(struct msm_vidc_inst *inst,
struct vb2_buffer *vb)
{
int rc = 0;
struct buf_queue *q;
if (!inst || !vb) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
if (!is_encode_session(inst) || vb->type !=
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
return 0;
if (!is_vidc_cvp_enabled(inst))
return 0;
q = msm_comm_get_vb2q(inst, vb->type);
if (!q) {
dprintk(VIDC_ERR, "%s: queue not found for type %d\n",
__func__, vb->type);
return -EINVAL;
}
if (!q->vb2_bufq.streaming) {
dprintk(VIDC_ERR,
"%s: enable input port streaming before queuing input buffers\n",
__func__);
return -EINVAL;
}
rc = msm_vidc_cvp_preprocess(inst, vb);
if (rc) {
dprintk(VIDC_ERR, "%s: cvp preprocess failed\n",
__func__);
return rc;
}
return rc;
}
int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
{
struct msm_vidc_inst *inst = instance;
@ -739,6 +699,51 @@ static int msm_vidc_set_properties(struct msm_vidc_inst *inst)
return rc;
}
bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst)
{
bool allowed = false;
struct msm_vidc_core *core;
struct v4l2_ctrl *cvp_disable;
if (!inst || !inst->core) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
goto exit;
}
core = inst->core;
/*
* CVP enable if
* - platform support CVP external
* - client did not disable CVP forcefully
* - client may disable forcefully to save power
* - client did not enable CVP extradata
* - if enabled, client will give CVP extradata
* - rate control is not one of below modes
* - RATE_CONTROL_OFF
* - V4L2_MPEG_VIDEO_BITRATE_MODE_CQ
* - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_PLUS
*/
cvp_disable = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE);
if (core->resources.cvp_external && !cvp_disable->val &&
!(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) &&
inst->rc_type != RATE_CONTROL_OFF &&
inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ &&
!inst->clk_data.is_cbr_plus) {
dprintk(VIDC_DBG, "%s: cvp allowed\n", __func__);
allowed = true;
} else {
dprintk(VIDC_DBG,
"%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d\n",
__func__, core->resources.cvp_external,
cvp_disable->val, inst->prop.extradata_ctrls,
inst->rc_type);
allowed = false;
}
exit:
return allowed;
}
static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst)
{
int rc = 0;
@ -748,6 +753,11 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst)
return -EINVAL;
}
if (!msm_vidc_cvp_usage) {
dprintk(VIDC_DBG, "%s: cvp usage disabled\n", __func__);
return 0;
}
if (!is_vidc_cvp_allowed(inst)) {
dprintk(VIDC_DBG, "%s: cvp not allowed\n", __func__);
return 0;
@ -756,12 +766,21 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst)
rc = msm_vidc_cvp_prepare_preprocess(inst);
if (rc) {
dprintk(VIDC_WARN, "%s: no cvp preprocessing\n", __func__);
msm_vidc_cvp_unprepare_preprocess(inst);
goto exit;
}
dprintk(VIDC_DBG, "%s: cvp enabled\n", __func__);
dprintk(VIDC_DBG, "%s: set CVP extradata\n", __func__);
rc = msm_comm_set_extradata(inst,
HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, 1);
if (rc) {
dprintk(VIDC_WARN, "%s: set CVP extradata failed\n", __func__);
goto exit;
}
exit:
if (rc)
msm_vidc_cvp_unprepare_preprocess(inst);
return rc;
}
@ -783,6 +802,15 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
goto fail_start;
}
if (is_encode_session(inst)) {
rc = msm_vidc_prepare_preprocess(inst);
if (rc) {
dprintk(VIDC_WARN, "%s: no preprocessing\n", __func__);
/* ignore error */
rc = 0;
}
}
b.buffer_type = HFI_BUFFER_OUTPUT;
if (inst->session_type == MSM_VIDC_DECODER &&
is_secondary_output_mode(inst))
@ -968,16 +996,6 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
goto stream_start_failed;
}
if (is_encode_session(inst) && q->type ==
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
rc = msm_vidc_prepare_preprocess(inst);
if (rc) {
dprintk(VIDC_WARN, "%s: no preprocessing\n", __func__);
/* ignore error */
rc = 0;
}
}
rc = msm_comm_qbufs(inst);
if (rc) {
dprintk(VIDC_ERR,
@ -1027,24 +1045,6 @@ stream_start_failed:
return rc;
}
static inline int stop_streaming(struct msm_vidc_inst *inst)
{
int rc = 0;
dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__,
hash32_ptr(inst->session), inst);
rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
if (rc)
dprintk(VIDC_ERR,
"Failed to move inst: %pK to state %d\n",
inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
msm_clock_data_reset(inst);
return rc;
}
static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst)
{
int rc = 0;
@ -1066,6 +1066,32 @@ static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst)
return rc;
}
static inline int stop_streaming(struct msm_vidc_inst *inst)
{
int rc = 0;
dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__,
hash32_ptr(inst->session), inst);
rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
if (rc)
dprintk(VIDC_ERR,
"Failed to move inst: %pK to state %d\n",
inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
if (is_encode_session(inst)) {
rc = msm_vidc_unprepare_preprocess(inst);
if (rc)
dprintk(VIDC_ERR,
"%s: failed to unprepare preprocess\n",
__func__);
}
msm_clock_data_reset(inst);
return rc;
}
static void msm_vidc_stop_streaming(struct vb2_queue *q)
{
struct msm_vidc_inst *inst;
@ -1078,16 +1104,6 @@ static void msm_vidc_stop_streaming(struct vb2_queue *q)
inst = q->drv_priv;
dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
if (is_encode_session(inst) && q->type ==
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
rc = msm_vidc_unprepare_preprocess(inst);
if (rc)
dprintk(VIDC_ERR,
"%s: failed to unprepare preprocess\n",
__func__);
}
switch (q->type) {
case INPUT_MPLANE:
if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
@ -1209,20 +1225,11 @@ static void msm_vidc_buf_queue(struct vb2_buffer *vb2)
return;
}
/* do preprocessing if any */
rc = msm_vidc_preprocess(inst, vb2);
if (rc) {
dprintk(VIDC_ERR, "%s: preprocess failed %x\n",
__func__, hash32_ptr(inst->session));
goto exit;
}
if (inst->batch.enable)
rc = msm_vidc_queue_buf_batch(inst, vb2);
else
rc = msm_vidc_queue_buf(inst, vb2);
exit:
if (rc) {
print_vb2_buffer(VIDC_ERR, "failed vb2-qbuf", inst, vb2);
msm_comm_generate_session_error(inst);

View file

@ -15,6 +15,7 @@
#include "vidc_hfi.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_clocks.h"
#include "msm_cvp_external.h"
#include "msm_cvp_internal.h"
#include "msm_vidc_buffer_calculations.h"
@ -4058,6 +4059,34 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
return rc;
}
static int msm_comm_preprocess(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *mbuf)
{
int rc = 0;
if (!inst || !mbuf) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
/* preprocessing is allowed for encoder input buffer only */
if (!is_encode_session(inst) || mbuf->vvb.vb2_buf.type != INPUT_MPLANE)
return 0;
/* preprocessing is done using CVP module only */
if (!is_vidc_cvp_enabled(inst))
return 0;
rc = msm_vidc_cvp_preprocess(inst, mbuf);
if (rc) {
dprintk(VIDC_ERR, "%s: cvp preprocess failed\n",
__func__);
return rc;
}
return rc;
}
static void populate_frame_data(struct vidc_frame_data *data,
struct msm_vidc_buffer *mbuf, struct msm_vidc_inst *inst)
{
@ -4264,6 +4293,10 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
return 0;
}
rc = msm_comm_preprocess(inst, mbuf);
if (rc)
return rc;
rc = msm_comm_scale_clocks_and_bus(inst);
if (rc)
dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);
@ -4280,6 +4313,7 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst)
{
int rc = 0;
struct msm_vidc_buffer *mbuf;
bool found;
if (!inst) {
dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
@ -4292,24 +4326,36 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst)
return 0;
}
rc = msm_comm_scale_clocks_and_bus(inst);
if (rc)
dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);
mutex_lock(&inst->registeredbufs.lock);
list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
/* Queue only deferred buffers */
if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED))
continue;
print_vidc_buffer(VIDC_DBG, "qbufs", inst, mbuf);
rc = msm_comm_qbuf_to_hfi(inst, mbuf);
if (rc) {
dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n",
__func__, rc);
do {
mutex_lock(&inst->registeredbufs.lock);
found = false;
list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
/* Queue only deferred buffers */
if (mbuf->flags & MSM_VIDC_FLAG_DEFERRED) {
found = true;
break;
}
}
mutex_unlock(&inst->registeredbufs.lock);
if (!found) {
dprintk(VIDC_DBG,
"%s: no more deferred qbufs\n", __func__);
break;
}
}
mutex_unlock(&inst->registeredbufs.lock);
/* do not call msm_comm_qbuf() under registerbufs lock */
if (!kref_get_mbuf(inst, mbuf)) {
dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__);
rc = -EINVAL;
break;
}
rc = msm_comm_qbuf(inst, mbuf);
kref_put_mbuf(mbuf);
if (rc) {
dprintk(VIDC_ERR, "%s: failed qbuf\n", __func__);
break;
}
} while (found);
return rc;
}

View file

@ -25,6 +25,7 @@ bool msm_vidc_fw_coverage = !true;
bool msm_vidc_thermal_mitigation_disabled = !true;
int msm_vidc_clock_voting = !1;
bool msm_vidc_syscache_disable = !true;
bool msm_vidc_cvp_usage = !true;
#define MAX_DBG_BUF_SIZE 4096
@ -188,6 +189,7 @@ struct dentry *msm_vidc_debugfs_init_drv(void)
&msm_vidc_clock_voting) &&
__debugfs_create(bool, "disable_video_syscache",
&msm_vidc_syscache_disable) &&
__debugfs_create(bool, "cvp_usage", &msm_vidc_cvp_usage) &&
__debugfs_create(bool, "lossless_encoding",
&msm_vidc_lossless_encode);

View file

@ -61,6 +61,7 @@ extern bool msm_vidc_thermal_mitigation_disabled;
extern int msm_vidc_clock_voting;
extern bool msm_vidc_syscache_disable;
extern bool msm_vidc_lossless_encode;
extern bool msm_vidc_cvp_usage;
#define dprintk(__level, __fmt, ...) \
do { \

View file

@ -299,7 +299,7 @@ static struct msm_vidc_common_data lito_common_data_v0[] = {
.value = 0,
},
{
.key = "qcom,domain-cvp",
.key = "qcom,cvp-internal",
.value = 1,
},
{
@ -370,7 +370,7 @@ static struct msm_vidc_common_data lito_common_data_v1[] = {
.value = 0,
},
{
.key = "qcom,domain-cvp",
.key = "qcom,cvp-internal",
.value = 1,
},
{
@ -445,8 +445,8 @@ static struct msm_vidc_common_data kona_common_data[] = {
.value = 0,
},
{
.key = "qcom,domain-cvp",
.value = 0,
.key = "qcom,cvp-external",
.value = 1,
},
{
.key = "qcom,decode-batching",
@ -587,7 +587,7 @@ static struct msm_vidc_common_data sm8150_common_data[] = {
.value = 0,
},
{
.key = "qcom,domain-cvp",
.key = "qcom,cvp-internal",
.value = 1,
},
{

View file

@ -806,8 +806,10 @@ int read_platform_resources_from_drv_data(
"qcom,fw-unload-delay");
res->msm_vidc_hw_rsp_timeout = find_key_value(platform_data,
"qcom,hw-resp-timeout");
res->domain_cvp = find_key_value(platform_data,
"qcom,domain-cvp");
res->cvp_internal = find_key_value(platform_data,
"qcom,cvp-internal");
res->cvp_external = find_key_value(platform_data,
"qcom,cvp-external");
res->non_fatal_pagefaults = find_key_value(platform_data,
"qcom,domain-attr-non-fatal-faults");
res->cache_pagetables = find_key_value(platform_data,

View file

@ -188,7 +188,8 @@ struct msm_vidc_platform_resources {
int msm_vidc_hw_rsp_timeout;
int msm_vidc_firmware_unload_delay;
uint32_t msm_vidc_pwr_collapse_delay;
bool domain_cvp;
bool cvp_internal;
bool cvp_external;
bool non_fatal_pagefaults;
bool cache_pagetables;
bool decode_batching;