Loading drivers/media/platform/msm/vpu/vpu_channel.c +35 −23 Original line number Diff line number Diff line Loading @@ -983,7 +983,7 @@ void vpu_hw_session_close(u32 sid) * sid must be valid */ static int ipc_cmd_set_session_prop(u32 sid, u32 prop_id, void *extra, u32 extra_size) u32 port_id, void *extra, u32 extra_size) { struct vpu_ipc_cmd_session_set_property_packet packet; int cid = SID2CID(sid); Loading @@ -995,6 +995,7 @@ static int ipc_cmd_set_session_prop(u32 sid, u32 prop_id, packet.hdr.flags = 0; /* no ack */ packet.hdr.trans_id = 0; /* no sync */ packet.hdr.sid = sid; packet.hdr.port_id = port_id; packet.prop_id = prop_id; packet.data_offset = sizeof(packet); Loading @@ -1021,7 +1022,7 @@ static int ipc_cmd_set_session_prop(u32 sid, u32 prop_id, * Return: 0 on success, -ve on failure */ static int ipc_cmd_sync_get_session_prop(u32 sid, u32 prop_id, u8 *rxd, u32 rxd_size) u32 port_id, u8 *rxd, u32 rxd_size) { struct vpu_ipc_cmd_session_get_property_packet packet; struct vpu_sync_transact *ptrans; Loading @@ -1032,6 +1033,7 @@ static int ipc_cmd_sync_get_session_prop(u32 sid, u32 prop_id, packet.hdr.size = sizeof(packet); packet.hdr.cmd_id = VPU_IPC_CMD_SESSION_GET_PROPERTY; packet.hdr.sid = sid; packet.hdr.port_id = port_id; packet.prop_id = prop_id; packet.data_offset = 0; Loading Loading @@ -1195,7 +1197,7 @@ int vpu_hw_session_resume(u32 sid) return rc; } int vpu_hw_session_flush(u32 sid, enum flush_buf_type type) int vpu_hw_session_flush(u32 sid, u32 port_id, enum flush_buf_type type) { int rc; struct vpu_ipc_cmd_session_flush_packet packet; Loading @@ -1210,6 +1212,7 @@ int vpu_hw_session_flush(u32 sid, enum flush_buf_type type) packet.hdr.size = sizeof(packet); packet.hdr.cmd_id = VPU_IPC_CMD_SESSION_FLUSH; packet.hdr.sid = sid; packet.hdr.port_id = port_id; packet.flush_type = type; Loading @@ -1219,7 +1222,8 @@ int vpu_hw_session_flush(u32 sid, enum flush_buf_type type) return rc; } int vpu_hw_session_release_buffers(u32 sid, enum release_buf_type release_type) int vpu_hw_session_release_buffers(u32 sid, u32 port_id, enum release_buf_type release_type) { int rc; struct vpu_ipc_cmd_session_release_buffers_packet packet; Loading @@ -1235,6 +1239,7 @@ int vpu_hw_session_release_buffers(u32 sid, enum release_buf_type release_type) packet.hdr.size = sizeof(packet); packet.hdr.cmd_id = VPU_IPC_CMD_SESSION_RELEASE_BUFFERS; packet.hdr.sid = sid; packet.hdr.port_id = port_id; switch (release_type) { case CH_RELEASE_IN_BUF: Loading Loading @@ -1370,7 +1375,7 @@ static void vpu_buf_to_ipc_buf_info(struct vpu_buffer *vb, bool input, *pktflag = flag; } int vpu_hw_session_register_buffers(u32 sid, bool input, int vpu_hw_session_register_buffers(u32 sid, u32 port_id, struct vpu_buffer *vb, u32 num) { int rc; Loading @@ -1380,6 +1385,7 @@ int vpu_hw_session_register_buffers(u32 sid, bool input, u8 extra_info[MAX_BUFFER_NUM * sizeof(struct _ipc_buffer_info_ext)]; struct _ipc_buffer_info_ext *pbuf_info_ext; int cid = SID2CID(sid); bool input = (port_id == VPU_IPC_PORT_INPUT) ? true : false; if (unlikely(!vb)) { pr_err("Null pointer vb\n"); Loading Loading @@ -1413,6 +1419,7 @@ int vpu_hw_session_register_buffers(u32 sid, bool input, buffer_packet.hdr.flags = 0; /* no ack */ buffer_packet.hdr.trans_id = 0; /* no sync */ buffer_packet.hdr.sid = sid; buffer_packet.hdr.port_id = port_id; if (input) { buffer_packet.num_in_buf = num; Loading Loading @@ -1456,7 +1463,7 @@ int vpu_hw_session_register_buffers(u32 sid, bool input, * vpu_hw_session_fill_buffer * to queue an empty output buffer */ int vpu_hw_session_fill_buffer(u32 sid, struct vpu_buffer *vb) int vpu_hw_session_fill_buffer(u32 sid, u32 port_id, struct vpu_buffer *vb) { int rc; struct vpu_ipc_cmd_session_buffers_packet buffer_packet; Loading Loading @@ -1486,6 +1493,7 @@ int vpu_hw_session_fill_buffer(u32 sid, struct vpu_buffer *vb) buffer_packet.hdr.flags = 0; /* no ack */ buffer_packet.hdr.trans_id = 0; /* no sync */ buffer_packet.hdr.sid = sid; buffer_packet.hdr.port_id = port_id; buffer_packet.num_out_buf = 1; buffer_packet.num_in_buf = 0; Loading @@ -1509,7 +1517,7 @@ int vpu_hw_session_fill_buffer(u32 sid, struct vpu_buffer *vb) return rc; } int vpu_hw_session_empty_buffer(u32 sid, struct vpu_buffer *vb) int vpu_hw_session_empty_buffer(u32 sid, u32 port_id, struct vpu_buffer *vb) { int rc; struct vpu_ipc_cmd_session_buffers_packet buffer_packet; Loading Loading @@ -1539,6 +1547,7 @@ int vpu_hw_session_empty_buffer(u32 sid, struct vpu_buffer *vb) buffer_packet.hdr.flags = 0; /* no ack */ buffer_packet.hdr.trans_id = 0; /* no sync */ buffer_packet.hdr.sid = sid; buffer_packet.hdr.port_id = port_id; buffer_packet.num_out_buf = 0; buffer_packet.num_in_buf = 1; Loading Loading @@ -1600,7 +1609,7 @@ int vpu_hw_session_commit(u32 sid, enum commit_type ct, return rc; } int vpu_hw_session_s_input_params(u32 sid, int vpu_hw_session_s_input_params(u32 sid, u32 port_id, const struct vpu_prop_session_input *inparam) { int cid = SID2CID(sid); Loading @@ -1610,11 +1619,11 @@ int vpu_hw_session_s_input_params(u32 sid, return -EINVAL; } return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_INPUT, return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_INPUT, port_id, (void *)inparam, sizeof(*inparam)); } int vpu_hw_session_s_output_params(u32 sid, int vpu_hw_session_s_output_params(u32 sid, u32 port_id, const struct vpu_prop_session_output *outparam) { int cid = SID2CID(sid); Loading @@ -1624,11 +1633,12 @@ int vpu_hw_session_s_output_params(u32 sid, return -EINVAL; } return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_OUTPUT, return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_OUTPUT, port_id, (void *)outparam, sizeof(*outparam)); } int vpu_hw_session_g_input_params(u32 sid, struct vpu_prop_session_input *inp) int vpu_hw_session_g_input_params(u32 sid, u32 port_id, struct vpu_prop_session_input *inp) { int rc; int cid = SID2CID(sid); Loading @@ -1640,7 +1650,7 @@ int vpu_hw_session_g_input_params(u32 sid, struct vpu_prop_session_input *inp) /* send the synchronous command (blocking call) */ rc = ipc_cmd_sync_get_session_prop(sid, VPU_PROP_SESSION_INPUT, (u8 *)inp, sizeof(*inp)); port_id, (u8 *)inp, sizeof(*inp)); if (unlikely(rc)) pr_err("Error while getting input param property\n"); Loading @@ -1648,7 +1658,7 @@ int vpu_hw_session_g_input_params(u32 sid, struct vpu_prop_session_input *inp) return rc; } int vpu_hw_session_g_output_params(u32 sid, int vpu_hw_session_g_output_params(u32 sid, u32 port_id, struct vpu_prop_session_output *outp) { int rc; Loading @@ -1661,7 +1671,7 @@ int vpu_hw_session_g_output_params(u32 sid, /* send the synchronous command (blocking call) */ rc = ipc_cmd_sync_get_session_prop(sid, VPU_PROP_SESSION_OUTPUT, (u8 *)outp, sizeof(*outp)); port_id, (u8 *)outp, sizeof(*outp)); if (unlikely(rc)) pr_err("Error while getting output param property\n"); Loading @@ -1685,7 +1695,7 @@ int vpu_hw_session_nr_buffer_config(u32 sid, u32 in_addr, u32 out_addr) nr_conf_pkt.release_flag = false; return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_NOISE_REDUCTION_CONFIG, VPU_PROP_SESSION_NOISE_REDUCTION_CONFIG, VPU_IPC_PORT_UNUSED, (void *)&nr_conf_pkt, sizeof(nr_conf_pkt)); } Loading @@ -1705,7 +1715,7 @@ int vpu_hw_session_nr_buffer_release(u32 sid) nr_conf_pkt.release_flag = true; return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_NOISE_REDUCTION_CONFIG, VPU_PROP_SESSION_NOISE_REDUCTION_CONFIG, VPU_IPC_PORT_UNUSED, (void *)&nr_conf_pkt, sizeof(nr_conf_pkt)); } Loading @@ -1720,7 +1730,8 @@ int vpu_hw_session_s_property(u32 sid, u32 prop_id, void *data, u32 data_size) } /* Send the command for the current property, asynchronously */ return ipc_cmd_set_session_prop(sid, prop_id, data, data_size); return ipc_cmd_set_session_prop(sid, prop_id, VPU_IPC_PORT_UNUSED, data, data_size); } int vpu_hw_session_g_property(u32 sid, u32 prop_id, void *data, u32 data_size) Loading @@ -1733,7 +1744,8 @@ int vpu_hw_session_g_property(u32 sid, u32 prop_id, void *data, u32 data_size) return -EINVAL; } return ipc_cmd_sync_get_session_prop(sid, prop_id, data, data_size); return ipc_cmd_sync_get_session_prop(sid, prop_id, VPU_IPC_PORT_UNUSED, data, data_size); } int vpu_hw_session_s_property_ext(u32 sid, Loading drivers/media/platform/msm/vpu/vpu_channel.h +10 −10 Original line number Diff line number Diff line Loading @@ -205,9 +205,9 @@ int vpu_hw_session_resume(u32 sid); * Set input/output port configuration. Channel *does not* commit new settings. * return 0 on success, -ve value on failure */ int vpu_hw_session_s_input_params(u32 sid, int vpu_hw_session_s_input_params(u32 sid, u32 port_id, const struct vpu_prop_session_input *inp); int vpu_hw_session_s_output_params(u32 sid, int vpu_hw_session_s_output_params(u32 sid, u32 port_id, const struct vpu_prop_session_output *outp); /* Loading @@ -215,9 +215,9 @@ int vpu_hw_session_s_output_params(u32 sid, * Channel copies current hardware configuration into *param. * return 0 on success, -ve value on failure */ int vpu_hw_session_g_input_params(u32 sid, int vpu_hw_session_g_input_params(u32 sid, u32 port_id, struct vpu_prop_session_input *inp); int vpu_hw_session_g_output_params(u32 sid, int vpu_hw_session_g_output_params(u32 sid, u32 port_id, struct vpu_prop_session_output *outp); /** Loading Loading @@ -291,7 +291,7 @@ int vpu_hw_session_commit(u32 sid, enum commit_type type, u32 load, /* register session buffers * pass a list of buffers to session for use in tunnel case */ int vpu_hw_session_register_buffers(u32 sid, bool input, int vpu_hw_session_register_buffers(u32 sid, u32 port_id, struct vpu_buffer *vb, u32 num); /* Loading @@ -305,19 +305,19 @@ enum release_buf_type { CH_RELEASE_OUT_BUF, CH_RELEASE_NR_BUF }; int vpu_hw_session_release_buffers(u32 sid, enum release_buf_type); int vpu_hw_session_release_buffers(u32 sid, u32 port_id, enum release_buf_type); /* * fill an output buffer * pass an empty output buffer to the session */ int vpu_hw_session_fill_buffer(u32 sid, struct vpu_buffer*); int vpu_hw_session_fill_buffer(u32 sid, u32 port_id, struct vpu_buffer*); /* * empty an input buffer * pass a filled input buffer to the session to process */ int vpu_hw_session_empty_buffer(u32 sid, struct vpu_buffer*); int vpu_hw_session_empty_buffer(u32 sid, u32 port_id, struct vpu_buffer*); /* * session flush Loading @@ -330,7 +330,7 @@ enum flush_buf_type { CH_FLUSH_OUT_BUF, CH_FLUSH_ALL_BUF }; int vpu_hw_session_flush(u32 sid, enum flush_buf_type); int vpu_hw_session_flush(u32 sid, u32 port_id, enum flush_buf_type); #ifdef CONFIG_DEBUG_FS Loading drivers/media/platform/msm/vpu/vpu_configuration.c +19 −11 Original line number Diff line number Diff line Loading @@ -1277,7 +1277,8 @@ static int __configure_input_port(struct vpu_dev_session *session) translate_input_format_to_hfi(&session->port_info[INPUT_PORT], &in_param); ret = vpu_hw_session_s_input_params(session->id, &in_param); ret = vpu_hw_session_s_input_params(session->id, translate_port_id(INPUT_PORT), &in_param); if (ret) { pr_err("Failed to set input port config\n"); return ret; Loading @@ -1301,31 +1302,32 @@ static int __configure_input_port(struct vpu_dev_session *session) return 0; } static int __configure_output_port(struct vpu_dev_session *session) static int __configure_output_port(struct vpu_dev_session *session, int port) { struct vpu_prop_session_output out_param; int ret = 0; translate_output_format_to_hfi(&session->port_info[OUTPUT_PORT], translate_output_format_to_hfi(&session->port_info[port], &out_param); ret = vpu_hw_session_s_output_params(session->id, &out_param); ret = vpu_hw_session_s_output_params(session->id, translate_port_id(port), &out_param); if (ret) { pr_err("Failed to set output port config\n"); pr_err("Failed to set output port %d config\n", port); return ret; } if (session->port_info[OUTPUT_PORT].destination if (session->port_info[port].destination != VPU_OUTPUT_TYPE_HOST) { struct vpu_data_pkt out_dest_ch; memset(&out_dest_ch, 0, sizeof(out_dest_ch)); out_dest_ch.payload[0] = translate_output_destination_ch( session->port_info[OUTPUT_PORT].destination); session->port_info[port].destination); out_dest_ch.size = sizeof(out_dest_ch); ret = vpu_hw_session_s_property(session->id, VPU_PROP_SESSION_SINK_CONFIG, &out_dest_ch, sizeof(out_dest_ch)); if (ret) { pr_err("Failed to set port 1 dest ch\n"); pr_err("Failed to set port %d dest ch\n", port); return ret; } } Loading Loading @@ -1362,10 +1364,16 @@ int commit_initial_config(struct vpu_dev_session *session) if (ret) return ret; ret = __configure_output_port(session); ret = __configure_output_port(session, OUTPUT_PORT); if (ret) return ret; if (session->dual_output) { ret = __configure_output_port(session, OUTPUT_PORT2); if (ret) return ret; } ret = __do_commit(session, CH_COMMIT_AT_ONCE, 1); if (ret) return ret; Loading @@ -1389,8 +1397,8 @@ int commit_port_config(struct vpu_dev_session *session, int port, int new_load) if (ret) return ret; } else if (port == OUTPUT_PORT) { ret = __configure_output_port(session); } else if (port == OUTPUT_PORT || port == OUTPUT_PORT2) { ret = __configure_output_port(session, port); if (ret) return ret; } else { Loading drivers/media/platform/msm/vpu/vpu_in_vcap.c +6 −3 Original line number Diff line number Diff line Loading @@ -373,7 +373,8 @@ static int vcap2vpu_set_src_buffer(void *sink_ctx, } else if (i_port_hnd->start_req) { pr_debug("Last buffer received, streamon requested, start\n"); ret = vpu_hw_session_register_buffers(session->id, true, ret = vpu_hw_session_register_buffers(session->id, translate_port_id(INPUT_PORT), i_port_hnd->buf_array, i_port_hnd->buf_num); if (ret) { pr_err("Register buffer failed (error %d)\n", ret); Loading Loading @@ -421,7 +422,8 @@ static void vpu_in_vcap_streamoff(struct vpu_dev_session *session, BUG_ON(session != i_port_hnd->session); BUG_ON(session->streaming_state == ALL_STREAMING); if (vpu_hw_session_release_buffers(session->id, CH_RELEASE_IN_BUF)) if (vpu_hw_session_release_buffers(session->id, translate_port_id(INPUT_PORT), CH_RELEASE_IN_BUF)) pr_err("Release buffer failed\n"); /* notify VCAP*/ Loading Loading @@ -488,7 +490,8 @@ static int vpu_in_vcap_streamon(struct vpu_dev_session *session, } pr_debug("Set tunnel buffers to VPU on port %d\n", port); ret = vpu_hw_session_register_buffers(session->id, true, ret = vpu_hw_session_register_buffers(session->id, translate_port_id(INPUT_PORT), i_port_hnd->buf_array, i_port_hnd->buf_num); if (unlikely(ret)) pr_err("Register buffer failed (error %d)\n", ret); Loading drivers/media/platform/msm/vpu/vpu_ioctl.c +109 −53 Original line number Diff line number Diff line Loading @@ -147,7 +147,7 @@ static void __sys_buffer_callback_handler(u32 sid, struct vpu_buffer *pbuf, return; } port = get_port_number(pbuf->vb.vb2_queue->type); port = get_queue_port_number(pbuf->vb.vb2_queue); session = vb2_get_drv_priv(pbuf->vb.vb2_queue); if (data) { Loading Loading @@ -206,7 +206,7 @@ static int __vpu_hw_switch(struct vpu_dev_core *core, int on) return ret; } static void __vpu_streamoff_port(struct vpu_dev_session *session, int port) static void __vpu_streamoff_port(struct vpu_dev_session *session, int port_type) { /* Stop end-to-end session streaming on first streamoff */ if (session->streaming_state == ALL_STREAMING) { Loading @@ -215,7 +215,7 @@ static void __vpu_streamoff_port(struct vpu_dev_session *session, int port) pr_debug("Session streaming stopped\n"); session->commit_state = 0; } session->streaming_state &= ~(0x1 << port); session->streaming_state &= ~(0x1 << port_type); } static struct vpu_client *__create_client(struct vpu_dev_core *core, Loading Loading @@ -404,21 +404,22 @@ void vpu_detach_client(struct vpu_client *client) /* close hw session on last detach */ vpu_hw_session_close(session->id); /* ports cleanup */ for (port = 0; port < NUM_VPU_PORTS; ++port) { /* detach tunneling ports */ for (port = 0; port < NUM_VPU_PORTS; ++port) call_port_op(session, port, detach); memset(&session->port_info[port], 0, sizeof(session->port_info[port])); } /* reset session state and configuration data */ deinit_vpu_controller(session->controller); session->controller = NULL; memset(&session->port_info[INPUT_PORT], 0, sizeof(session->port_info[INPUT_PORT])); memset(&session->port_info[OUTPUT_PORT], 0, sizeof(session->port_info[OUTPUT_PORT])); session->streaming_state = 0; session->commit_state = 0; session->dual_output = false; } list_del_init(&client->clients_entry); /* remove from attached list */ Loading @@ -435,8 +436,8 @@ void vpu_detach_client(struct vpu_client *client) int vpu_enum_fmt(struct v4l2_fmtdesc *f) { const struct vpu_format_desc *fmt; int port = get_port_number(f->type); if (port < 0) int port_type = get_port_type(f->type); if (port_type < 0) return -EINVAL; fmt = query_supported_formats(f->index); Loading @@ -460,21 +461,23 @@ int vpu_get_fmt(struct vpu_client *client, struct v4l2_format *f) if (!session) return -EPERM; port = get_port_number(f->type); port = get_port_number(client, f->type); if (port < 0) return -EINVAL; if (port == INPUT_PORT) { ret = vpu_hw_session_g_input_params(session->id, &in_param); ret = vpu_hw_session_g_input_params(session->id, translate_port_id(port), &in_param); translate_input_format_to_api(&in_param, f); f->fmt.pix_mp.colorspace = session->port_info[INPUT_PORT].format.colorspace; session->port_info[port].format.colorspace; } else { ret = vpu_hw_session_g_output_params(session->id, &out_param); ret = vpu_hw_session_g_output_params(session->id, translate_port_id(port), &out_param); translate_output_format_to_api(&out_param, f); f->fmt.pix_mp.colorspace = session->port_info[OUTPUT_PORT].format.colorspace; session->port_info[port].format.colorspace; } return ret; Loading Loading @@ -530,9 +533,9 @@ int vpu_set_fmt(struct vpu_client *client, struct v4l2_format *f) pr_err("invalid session\n"); return -EPERM; } port = get_port_number(f->type); port = get_port_number(client, f->type); if (port < 0) { pr_err("invalid port (%d)\n", port); pr_err("invalid buffer type (%d)\n", f->type); return -EINVAL; } Loading Loading @@ -575,10 +578,12 @@ static int __vpu_get_framerate(struct vpu_client *client, u32 *framerate, int ret = 0; if (port == INPUT_PORT) { ret = vpu_hw_session_g_input_params(session->id, &in_param); ret = vpu_hw_session_g_input_params(session->id, translate_port_id(port), &in_param); *framerate = in_param.frame_rate; } else { ret = vpu_hw_session_g_output_params(session->id, &out_param); ret = vpu_hw_session_g_output_params(session->id, translate_port_id(port), &out_param); *framerate = out_param.frame_rate; } Loading Loading @@ -610,16 +615,18 @@ int vpu_get_region_of_intereset(struct vpu_client *client, if (!session) return -EPERM; port = get_port_number(crop->type); port = get_port_number(client, crop->type); if (port < 0) return -EINVAL; if (port == INPUT_PORT) { ret = vpu_hw_session_g_input_params(session->id, &in_param); ret = vpu_hw_session_g_input_params(session->id, translate_port_id(port), &in_param); translate_roi_rect_to_api(&in_param.region_interest, &crop->c); } else { ret = vpu_hw_session_g_output_params(session->id, &out_param); ret = vpu_hw_session_g_output_params(session->id, translate_port_id(port), &out_param); translate_roi_rect_to_api(&out_param.dest_rect, &crop->c); } Loading @@ -631,7 +638,9 @@ int vpu_set_region_of_intereset(struct vpu_client *client, const struct v4l2_crop *crop) { struct vpu_dev_session *session = client ? client->session : 0; int ret = 0, port = get_port_number(crop->type); int ret = 0, port; port = get_port_number(client, crop->type); if (!session) return -EPERM; Loading Loading @@ -665,7 +674,7 @@ int vpu_set_input(struct vpu_client *client, unsigned int i) /* Changing input/output only allowed if port is not streaming */ mutex_lock(&session->lock); if (session->streaming_state & (0x1 << INPUT_PORT)) { if (session->streaming_state & (0x1 << PORT_TYPE_INPUT)) { ret = -EBUSY; goto exit_s_input; } Loading Loading @@ -697,44 +706,50 @@ exit_s_input: int vpu_get_output(struct vpu_client *client, unsigned int *i) { int port; if (!client || !client->session) return -EPERM; *i = client->session->port_info[OUTPUT_PORT].destination; port = client->uses_output2 ? OUTPUT_PORT2 : OUTPUT_PORT; *i = client->session->port_info[port].destination; return 0; } int vpu_set_output(struct vpu_client *client, unsigned int i) { int ret = 0; int ret = 0, port; struct vpu_dev_session *session = client ? client->session : 0; if (!session) return -EPERM; port = client->uses_output2 ? OUTPUT_PORT2 : OUTPUT_PORT; mutex_lock(&session->lock); if (session->streaming_state & (0x1 << OUTPUT_PORT)) { if (session->streaming_state & (0x1 << PORT_TYPE_OUTPUT)) { ret = -EBUSY; goto exit_s_output; } session->port_info[OUTPUT_PORT].destination = i; session->port_info[port].destination = i; /* detach previous output tunnel port, if existing */ call_port_op(session, OUTPUT_PORT, detach); call_port_op(session, port, detach); /* initiate and attach input tunnel port, if needed */ if (i != VPU_OUTPUT_TYPE_HOST) { ret = vpu_init_port_mdss(session, &session->port_info[OUTPUT_PORT]); &session->port_info[port]); if (ret) goto exit_s_output; ret = call_port_op(session, OUTPUT_PORT, attach); ret = call_port_op(session, port, attach); if (ret) goto exit_s_output; } ret = commit_port_config(session, OUTPUT_PORT, 1); ret = commit_port_config(session, port, 1); exit_s_output: mutex_unlock(&session->lock); Loading Loading @@ -781,9 +796,12 @@ int vpu_get_control_port(struct vpu_client *client, if (!session) return -EPERM; if (port < 0 || port > NUM_VPU_PORTS) if (port < 0 || port >= NUM_VPU_PORT_TYPES) return -EINVAL; if (port == PORT_TYPE_OUTPUT && client->uses_output2) port = OUTPUT_PORT2; if (control->control_id == VPU_CTRL_FPS) return __vpu_get_framerate(client, &control->data.framerate, port); Loading @@ -799,9 +817,12 @@ int vpu_set_control_port(struct vpu_client *client, if (!session) return -EPERM; if (port < 0 || port > NUM_VPU_PORTS) if (port < 0 || port >= NUM_VPU_PORT_TYPES) return -EINVAL; if (port == PORT_TYPE_OUTPUT && client->uses_output2) port = OUTPUT_PORT2; if (control->control_id == VPU_CTRL_FPS) return __vpu_set_framerate(client, control->data.framerate, port); Loading @@ -823,6 +844,26 @@ int vpu_commit_configuration(struct vpu_client *client) return ret; } int vpu_dual_output(struct vpu_client *client) { int ret = 0; struct vpu_dev_session *session = client ? client->session : 0; if (!session) return -EPERM; mutex_lock(&session->lock); if (session->io_client[OUTPUT_PORT] == client) { pr_err("Client using output port 1\n"); ret = -EINVAL; } else { session->dual_output = true; client->uses_output2 = true; } mutex_unlock(&session->lock); return ret; } /* * Streaming I/O operations */ Loading @@ -840,13 +881,13 @@ int vpu_reqbufs(struct vpu_client *client, struct v4l2_requestbuffers *req) if (!session) return -EPERM; port = get_port_number(req->type); port = get_port_number(client, req->type); if (port < 0) { pr_err("Invalid buffer type %d\n", req->type); return -EINVAL; } pr_debug("count = %d\n", req->count); pr_debug("port %d count = %d\n", port, req->count); mutex_lock(&session->que_lock[port]); if (session->io_client[port] != client && session->io_client[port]) { Loading Loading @@ -921,7 +962,7 @@ int vpu_qbuf(struct vpu_client *client, struct v4l2_buffer *b) if (!session) return -EPERM; port = get_port_number(b->type); port = get_port_number(client, b->type); if (port < 0) { pr_err("Invalid type %d\n", b->type); return -EINVAL; Loading Loading @@ -956,7 +997,7 @@ int vpu_dqbuf(struct vpu_client *client, struct v4l2_buffer *b, if (!session) return -EPERM; port = get_port_number(b->type); port = get_port_number(client, b->type); if (port < 0) { pr_err("Invalid type %d\n", b->type); return -EINVAL; Loading Loading @@ -1001,10 +1042,10 @@ static int __queue_pending_buffers(struct vpu_dev_session *session) { if (port == INPUT_PORT) ret = vpu_hw_session_empty_buffer(session->id, buff); translate_port_id(port), buff); else ret = vpu_hw_session_fill_buffer(session->id, buff); translate_port_id(port), buff); if (ret) { pr_err("returning buffer\n"); Loading @@ -1021,11 +1062,13 @@ static int __queue_pending_buffers(struct vpu_dev_session *session) int vpu_flush_bufs(struct vpu_client *client, enum v4l2_buf_type type) { struct vpu_dev_session *session = client ? client->session : 0; int ret = 0, port; int ret = 0, port, port_type; if (!session) return -EPERM; port = get_port_number(type); port_type = get_port_type(type); port = get_port_number(client, type); if (port < 0) { pr_err("Invalid type %d\n", type); return -EINVAL; Loading @@ -1038,7 +1081,7 @@ int vpu_flush_bufs(struct vpu_client *client, enum v4l2_buf_type type) ret = -EINVAL; goto exit_flush; } else { if (!(session->streaming_state & (0x1 << port))) { if (!(session->streaming_state & (0x1 << port_type))) { /* Can't flush if port is not streaming */ ret = -EINVAL; goto exit_flush; Loading Loading @@ -1072,6 +1115,15 @@ int vpu_trigger_stream(struct vpu_dev_session *session) return ret; } if (session->dual_output) { ret = vb2_streamon(&session->vbqueue[OUTPUT_PORT2], session->vbqueue[OUTPUT_PORT2].type); if (ret) { pr_err("Failed to vb2_streamon output port 2\n"); return ret; } } session->streaming_state = ALL_STREAMING; __queue_pending_buffers(session); Loading @@ -1081,16 +1133,19 @@ int vpu_trigger_stream(struct vpu_dev_session *session) int vpu_streamon(struct vpu_client *client, enum v4l2_buf_type type) { struct vpu_dev_session *session = client ? client->session : 0; int ret = 0, port; int ret = 0, port, port_type; u32 temp_streaming = 0; if (!session) return -EPERM; port = get_port_number(type); port_type = get_port_type(type); port = get_port_number(client, type); if (port < 0) { pr_err("Invalid type %d\n", type); return -EINVAL; } if (port == OUTPUT_PORT2) return 0; /* do nothing for second output port */ mutex_lock(&session->lock); /* needed to sync streamon from two ports */ Loading @@ -1107,10 +1162,10 @@ int vpu_streamon(struct vpu_client *client, enum v4l2_buf_type type) if (ret) goto early_exit_streamon; if (temp_streaming & (0x1 << port)) { if (temp_streaming & (0x1 << port_type)) { goto early_exit_streamon; /* This port already streaming */ } else { temp_streaming |= (0x1 << port); temp_streaming |= (0x1 << port_type); /* lock port if tunneling */ if (__is_tunneling(session, port)) session->io_client[port] = client; Loading Loading @@ -1144,12 +1199,11 @@ int vpu_streamon(struct vpu_client *client, enum v4l2_buf_type type) /* Start end-to-end session streaming */ ret = vpu_trigger_stream(session); if (!ret) pr_debug("Session streaming started successfully\n"); late_exit_streamon: if (ret) { /* TODO: How do we notify the streamed on sessions? */ if (__is_tunneling(session, port)) session->io_client[port] = NULL; } Loading @@ -1173,11 +1227,13 @@ int vpu_streamoff(struct vpu_client *client, enum v4l2_buf_type type) if (!session) return -EPERM; port = get_port_number(type); port = get_port_number(client, type); if (port < 0) { pr_err("Invalid type %d\n", type); return -EINVAL; } if (port == OUTPUT_PORT2) return 0; /* do nothing for second output port */ /* session lock needed to protect actions inside vb2_stream_off */ mutex_lock(&session->lock); Loading Loading
drivers/media/platform/msm/vpu/vpu_channel.c +35 −23 Original line number Diff line number Diff line Loading @@ -983,7 +983,7 @@ void vpu_hw_session_close(u32 sid) * sid must be valid */ static int ipc_cmd_set_session_prop(u32 sid, u32 prop_id, void *extra, u32 extra_size) u32 port_id, void *extra, u32 extra_size) { struct vpu_ipc_cmd_session_set_property_packet packet; int cid = SID2CID(sid); Loading @@ -995,6 +995,7 @@ static int ipc_cmd_set_session_prop(u32 sid, u32 prop_id, packet.hdr.flags = 0; /* no ack */ packet.hdr.trans_id = 0; /* no sync */ packet.hdr.sid = sid; packet.hdr.port_id = port_id; packet.prop_id = prop_id; packet.data_offset = sizeof(packet); Loading @@ -1021,7 +1022,7 @@ static int ipc_cmd_set_session_prop(u32 sid, u32 prop_id, * Return: 0 on success, -ve on failure */ static int ipc_cmd_sync_get_session_prop(u32 sid, u32 prop_id, u8 *rxd, u32 rxd_size) u32 port_id, u8 *rxd, u32 rxd_size) { struct vpu_ipc_cmd_session_get_property_packet packet; struct vpu_sync_transact *ptrans; Loading @@ -1032,6 +1033,7 @@ static int ipc_cmd_sync_get_session_prop(u32 sid, u32 prop_id, packet.hdr.size = sizeof(packet); packet.hdr.cmd_id = VPU_IPC_CMD_SESSION_GET_PROPERTY; packet.hdr.sid = sid; packet.hdr.port_id = port_id; packet.prop_id = prop_id; packet.data_offset = 0; Loading Loading @@ -1195,7 +1197,7 @@ int vpu_hw_session_resume(u32 sid) return rc; } int vpu_hw_session_flush(u32 sid, enum flush_buf_type type) int vpu_hw_session_flush(u32 sid, u32 port_id, enum flush_buf_type type) { int rc; struct vpu_ipc_cmd_session_flush_packet packet; Loading @@ -1210,6 +1212,7 @@ int vpu_hw_session_flush(u32 sid, enum flush_buf_type type) packet.hdr.size = sizeof(packet); packet.hdr.cmd_id = VPU_IPC_CMD_SESSION_FLUSH; packet.hdr.sid = sid; packet.hdr.port_id = port_id; packet.flush_type = type; Loading @@ -1219,7 +1222,8 @@ int vpu_hw_session_flush(u32 sid, enum flush_buf_type type) return rc; } int vpu_hw_session_release_buffers(u32 sid, enum release_buf_type release_type) int vpu_hw_session_release_buffers(u32 sid, u32 port_id, enum release_buf_type release_type) { int rc; struct vpu_ipc_cmd_session_release_buffers_packet packet; Loading @@ -1235,6 +1239,7 @@ int vpu_hw_session_release_buffers(u32 sid, enum release_buf_type release_type) packet.hdr.size = sizeof(packet); packet.hdr.cmd_id = VPU_IPC_CMD_SESSION_RELEASE_BUFFERS; packet.hdr.sid = sid; packet.hdr.port_id = port_id; switch (release_type) { case CH_RELEASE_IN_BUF: Loading Loading @@ -1370,7 +1375,7 @@ static void vpu_buf_to_ipc_buf_info(struct vpu_buffer *vb, bool input, *pktflag = flag; } int vpu_hw_session_register_buffers(u32 sid, bool input, int vpu_hw_session_register_buffers(u32 sid, u32 port_id, struct vpu_buffer *vb, u32 num) { int rc; Loading @@ -1380,6 +1385,7 @@ int vpu_hw_session_register_buffers(u32 sid, bool input, u8 extra_info[MAX_BUFFER_NUM * sizeof(struct _ipc_buffer_info_ext)]; struct _ipc_buffer_info_ext *pbuf_info_ext; int cid = SID2CID(sid); bool input = (port_id == VPU_IPC_PORT_INPUT) ? true : false; if (unlikely(!vb)) { pr_err("Null pointer vb\n"); Loading Loading @@ -1413,6 +1419,7 @@ int vpu_hw_session_register_buffers(u32 sid, bool input, buffer_packet.hdr.flags = 0; /* no ack */ buffer_packet.hdr.trans_id = 0; /* no sync */ buffer_packet.hdr.sid = sid; buffer_packet.hdr.port_id = port_id; if (input) { buffer_packet.num_in_buf = num; Loading Loading @@ -1456,7 +1463,7 @@ int vpu_hw_session_register_buffers(u32 sid, bool input, * vpu_hw_session_fill_buffer * to queue an empty output buffer */ int vpu_hw_session_fill_buffer(u32 sid, struct vpu_buffer *vb) int vpu_hw_session_fill_buffer(u32 sid, u32 port_id, struct vpu_buffer *vb) { int rc; struct vpu_ipc_cmd_session_buffers_packet buffer_packet; Loading Loading @@ -1486,6 +1493,7 @@ int vpu_hw_session_fill_buffer(u32 sid, struct vpu_buffer *vb) buffer_packet.hdr.flags = 0; /* no ack */ buffer_packet.hdr.trans_id = 0; /* no sync */ buffer_packet.hdr.sid = sid; buffer_packet.hdr.port_id = port_id; buffer_packet.num_out_buf = 1; buffer_packet.num_in_buf = 0; Loading @@ -1509,7 +1517,7 @@ int vpu_hw_session_fill_buffer(u32 sid, struct vpu_buffer *vb) return rc; } int vpu_hw_session_empty_buffer(u32 sid, struct vpu_buffer *vb) int vpu_hw_session_empty_buffer(u32 sid, u32 port_id, struct vpu_buffer *vb) { int rc; struct vpu_ipc_cmd_session_buffers_packet buffer_packet; Loading Loading @@ -1539,6 +1547,7 @@ int vpu_hw_session_empty_buffer(u32 sid, struct vpu_buffer *vb) buffer_packet.hdr.flags = 0; /* no ack */ buffer_packet.hdr.trans_id = 0; /* no sync */ buffer_packet.hdr.sid = sid; buffer_packet.hdr.port_id = port_id; buffer_packet.num_out_buf = 0; buffer_packet.num_in_buf = 1; Loading Loading @@ -1600,7 +1609,7 @@ int vpu_hw_session_commit(u32 sid, enum commit_type ct, return rc; } int vpu_hw_session_s_input_params(u32 sid, int vpu_hw_session_s_input_params(u32 sid, u32 port_id, const struct vpu_prop_session_input *inparam) { int cid = SID2CID(sid); Loading @@ -1610,11 +1619,11 @@ int vpu_hw_session_s_input_params(u32 sid, return -EINVAL; } return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_INPUT, return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_INPUT, port_id, (void *)inparam, sizeof(*inparam)); } int vpu_hw_session_s_output_params(u32 sid, int vpu_hw_session_s_output_params(u32 sid, u32 port_id, const struct vpu_prop_session_output *outparam) { int cid = SID2CID(sid); Loading @@ -1624,11 +1633,12 @@ int vpu_hw_session_s_output_params(u32 sid, return -EINVAL; } return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_OUTPUT, return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_OUTPUT, port_id, (void *)outparam, sizeof(*outparam)); } int vpu_hw_session_g_input_params(u32 sid, struct vpu_prop_session_input *inp) int vpu_hw_session_g_input_params(u32 sid, u32 port_id, struct vpu_prop_session_input *inp) { int rc; int cid = SID2CID(sid); Loading @@ -1640,7 +1650,7 @@ int vpu_hw_session_g_input_params(u32 sid, struct vpu_prop_session_input *inp) /* send the synchronous command (blocking call) */ rc = ipc_cmd_sync_get_session_prop(sid, VPU_PROP_SESSION_INPUT, (u8 *)inp, sizeof(*inp)); port_id, (u8 *)inp, sizeof(*inp)); if (unlikely(rc)) pr_err("Error while getting input param property\n"); Loading @@ -1648,7 +1658,7 @@ int vpu_hw_session_g_input_params(u32 sid, struct vpu_prop_session_input *inp) return rc; } int vpu_hw_session_g_output_params(u32 sid, int vpu_hw_session_g_output_params(u32 sid, u32 port_id, struct vpu_prop_session_output *outp) { int rc; Loading @@ -1661,7 +1671,7 @@ int vpu_hw_session_g_output_params(u32 sid, /* send the synchronous command (blocking call) */ rc = ipc_cmd_sync_get_session_prop(sid, VPU_PROP_SESSION_OUTPUT, (u8 *)outp, sizeof(*outp)); port_id, (u8 *)outp, sizeof(*outp)); if (unlikely(rc)) pr_err("Error while getting output param property\n"); Loading @@ -1685,7 +1695,7 @@ int vpu_hw_session_nr_buffer_config(u32 sid, u32 in_addr, u32 out_addr) nr_conf_pkt.release_flag = false; return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_NOISE_REDUCTION_CONFIG, VPU_PROP_SESSION_NOISE_REDUCTION_CONFIG, VPU_IPC_PORT_UNUSED, (void *)&nr_conf_pkt, sizeof(nr_conf_pkt)); } Loading @@ -1705,7 +1715,7 @@ int vpu_hw_session_nr_buffer_release(u32 sid) nr_conf_pkt.release_flag = true; return ipc_cmd_set_session_prop(sid, VPU_PROP_SESSION_NOISE_REDUCTION_CONFIG, VPU_PROP_SESSION_NOISE_REDUCTION_CONFIG, VPU_IPC_PORT_UNUSED, (void *)&nr_conf_pkt, sizeof(nr_conf_pkt)); } Loading @@ -1720,7 +1730,8 @@ int vpu_hw_session_s_property(u32 sid, u32 prop_id, void *data, u32 data_size) } /* Send the command for the current property, asynchronously */ return ipc_cmd_set_session_prop(sid, prop_id, data, data_size); return ipc_cmd_set_session_prop(sid, prop_id, VPU_IPC_PORT_UNUSED, data, data_size); } int vpu_hw_session_g_property(u32 sid, u32 prop_id, void *data, u32 data_size) Loading @@ -1733,7 +1744,8 @@ int vpu_hw_session_g_property(u32 sid, u32 prop_id, void *data, u32 data_size) return -EINVAL; } return ipc_cmd_sync_get_session_prop(sid, prop_id, data, data_size); return ipc_cmd_sync_get_session_prop(sid, prop_id, VPU_IPC_PORT_UNUSED, data, data_size); } int vpu_hw_session_s_property_ext(u32 sid, Loading
drivers/media/platform/msm/vpu/vpu_channel.h +10 −10 Original line number Diff line number Diff line Loading @@ -205,9 +205,9 @@ int vpu_hw_session_resume(u32 sid); * Set input/output port configuration. Channel *does not* commit new settings. * return 0 on success, -ve value on failure */ int vpu_hw_session_s_input_params(u32 sid, int vpu_hw_session_s_input_params(u32 sid, u32 port_id, const struct vpu_prop_session_input *inp); int vpu_hw_session_s_output_params(u32 sid, int vpu_hw_session_s_output_params(u32 sid, u32 port_id, const struct vpu_prop_session_output *outp); /* Loading @@ -215,9 +215,9 @@ int vpu_hw_session_s_output_params(u32 sid, * Channel copies current hardware configuration into *param. * return 0 on success, -ve value on failure */ int vpu_hw_session_g_input_params(u32 sid, int vpu_hw_session_g_input_params(u32 sid, u32 port_id, struct vpu_prop_session_input *inp); int vpu_hw_session_g_output_params(u32 sid, int vpu_hw_session_g_output_params(u32 sid, u32 port_id, struct vpu_prop_session_output *outp); /** Loading Loading @@ -291,7 +291,7 @@ int vpu_hw_session_commit(u32 sid, enum commit_type type, u32 load, /* register session buffers * pass a list of buffers to session for use in tunnel case */ int vpu_hw_session_register_buffers(u32 sid, bool input, int vpu_hw_session_register_buffers(u32 sid, u32 port_id, struct vpu_buffer *vb, u32 num); /* Loading @@ -305,19 +305,19 @@ enum release_buf_type { CH_RELEASE_OUT_BUF, CH_RELEASE_NR_BUF }; int vpu_hw_session_release_buffers(u32 sid, enum release_buf_type); int vpu_hw_session_release_buffers(u32 sid, u32 port_id, enum release_buf_type); /* * fill an output buffer * pass an empty output buffer to the session */ int vpu_hw_session_fill_buffer(u32 sid, struct vpu_buffer*); int vpu_hw_session_fill_buffer(u32 sid, u32 port_id, struct vpu_buffer*); /* * empty an input buffer * pass a filled input buffer to the session to process */ int vpu_hw_session_empty_buffer(u32 sid, struct vpu_buffer*); int vpu_hw_session_empty_buffer(u32 sid, u32 port_id, struct vpu_buffer*); /* * session flush Loading @@ -330,7 +330,7 @@ enum flush_buf_type { CH_FLUSH_OUT_BUF, CH_FLUSH_ALL_BUF }; int vpu_hw_session_flush(u32 sid, enum flush_buf_type); int vpu_hw_session_flush(u32 sid, u32 port_id, enum flush_buf_type); #ifdef CONFIG_DEBUG_FS Loading
drivers/media/platform/msm/vpu/vpu_configuration.c +19 −11 Original line number Diff line number Diff line Loading @@ -1277,7 +1277,8 @@ static int __configure_input_port(struct vpu_dev_session *session) translate_input_format_to_hfi(&session->port_info[INPUT_PORT], &in_param); ret = vpu_hw_session_s_input_params(session->id, &in_param); ret = vpu_hw_session_s_input_params(session->id, translate_port_id(INPUT_PORT), &in_param); if (ret) { pr_err("Failed to set input port config\n"); return ret; Loading @@ -1301,31 +1302,32 @@ static int __configure_input_port(struct vpu_dev_session *session) return 0; } static int __configure_output_port(struct vpu_dev_session *session) static int __configure_output_port(struct vpu_dev_session *session, int port) { struct vpu_prop_session_output out_param; int ret = 0; translate_output_format_to_hfi(&session->port_info[OUTPUT_PORT], translate_output_format_to_hfi(&session->port_info[port], &out_param); ret = vpu_hw_session_s_output_params(session->id, &out_param); ret = vpu_hw_session_s_output_params(session->id, translate_port_id(port), &out_param); if (ret) { pr_err("Failed to set output port config\n"); pr_err("Failed to set output port %d config\n", port); return ret; } if (session->port_info[OUTPUT_PORT].destination if (session->port_info[port].destination != VPU_OUTPUT_TYPE_HOST) { struct vpu_data_pkt out_dest_ch; memset(&out_dest_ch, 0, sizeof(out_dest_ch)); out_dest_ch.payload[0] = translate_output_destination_ch( session->port_info[OUTPUT_PORT].destination); session->port_info[port].destination); out_dest_ch.size = sizeof(out_dest_ch); ret = vpu_hw_session_s_property(session->id, VPU_PROP_SESSION_SINK_CONFIG, &out_dest_ch, sizeof(out_dest_ch)); if (ret) { pr_err("Failed to set port 1 dest ch\n"); pr_err("Failed to set port %d dest ch\n", port); return ret; } } Loading Loading @@ -1362,10 +1364,16 @@ int commit_initial_config(struct vpu_dev_session *session) if (ret) return ret; ret = __configure_output_port(session); ret = __configure_output_port(session, OUTPUT_PORT); if (ret) return ret; if (session->dual_output) { ret = __configure_output_port(session, OUTPUT_PORT2); if (ret) return ret; } ret = __do_commit(session, CH_COMMIT_AT_ONCE, 1); if (ret) return ret; Loading @@ -1389,8 +1397,8 @@ int commit_port_config(struct vpu_dev_session *session, int port, int new_load) if (ret) return ret; } else if (port == OUTPUT_PORT) { ret = __configure_output_port(session); } else if (port == OUTPUT_PORT || port == OUTPUT_PORT2) { ret = __configure_output_port(session, port); if (ret) return ret; } else { Loading
drivers/media/platform/msm/vpu/vpu_in_vcap.c +6 −3 Original line number Diff line number Diff line Loading @@ -373,7 +373,8 @@ static int vcap2vpu_set_src_buffer(void *sink_ctx, } else if (i_port_hnd->start_req) { pr_debug("Last buffer received, streamon requested, start\n"); ret = vpu_hw_session_register_buffers(session->id, true, ret = vpu_hw_session_register_buffers(session->id, translate_port_id(INPUT_PORT), i_port_hnd->buf_array, i_port_hnd->buf_num); if (ret) { pr_err("Register buffer failed (error %d)\n", ret); Loading Loading @@ -421,7 +422,8 @@ static void vpu_in_vcap_streamoff(struct vpu_dev_session *session, BUG_ON(session != i_port_hnd->session); BUG_ON(session->streaming_state == ALL_STREAMING); if (vpu_hw_session_release_buffers(session->id, CH_RELEASE_IN_BUF)) if (vpu_hw_session_release_buffers(session->id, translate_port_id(INPUT_PORT), CH_RELEASE_IN_BUF)) pr_err("Release buffer failed\n"); /* notify VCAP*/ Loading Loading @@ -488,7 +490,8 @@ static int vpu_in_vcap_streamon(struct vpu_dev_session *session, } pr_debug("Set tunnel buffers to VPU on port %d\n", port); ret = vpu_hw_session_register_buffers(session->id, true, ret = vpu_hw_session_register_buffers(session->id, translate_port_id(INPUT_PORT), i_port_hnd->buf_array, i_port_hnd->buf_num); if (unlikely(ret)) pr_err("Register buffer failed (error %d)\n", ret); Loading
drivers/media/platform/msm/vpu/vpu_ioctl.c +109 −53 Original line number Diff line number Diff line Loading @@ -147,7 +147,7 @@ static void __sys_buffer_callback_handler(u32 sid, struct vpu_buffer *pbuf, return; } port = get_port_number(pbuf->vb.vb2_queue->type); port = get_queue_port_number(pbuf->vb.vb2_queue); session = vb2_get_drv_priv(pbuf->vb.vb2_queue); if (data) { Loading Loading @@ -206,7 +206,7 @@ static int __vpu_hw_switch(struct vpu_dev_core *core, int on) return ret; } static void __vpu_streamoff_port(struct vpu_dev_session *session, int port) static void __vpu_streamoff_port(struct vpu_dev_session *session, int port_type) { /* Stop end-to-end session streaming on first streamoff */ if (session->streaming_state == ALL_STREAMING) { Loading @@ -215,7 +215,7 @@ static void __vpu_streamoff_port(struct vpu_dev_session *session, int port) pr_debug("Session streaming stopped\n"); session->commit_state = 0; } session->streaming_state &= ~(0x1 << port); session->streaming_state &= ~(0x1 << port_type); } static struct vpu_client *__create_client(struct vpu_dev_core *core, Loading Loading @@ -404,21 +404,22 @@ void vpu_detach_client(struct vpu_client *client) /* close hw session on last detach */ vpu_hw_session_close(session->id); /* ports cleanup */ for (port = 0; port < NUM_VPU_PORTS; ++port) { /* detach tunneling ports */ for (port = 0; port < NUM_VPU_PORTS; ++port) call_port_op(session, port, detach); memset(&session->port_info[port], 0, sizeof(session->port_info[port])); } /* reset session state and configuration data */ deinit_vpu_controller(session->controller); session->controller = NULL; memset(&session->port_info[INPUT_PORT], 0, sizeof(session->port_info[INPUT_PORT])); memset(&session->port_info[OUTPUT_PORT], 0, sizeof(session->port_info[OUTPUT_PORT])); session->streaming_state = 0; session->commit_state = 0; session->dual_output = false; } list_del_init(&client->clients_entry); /* remove from attached list */ Loading @@ -435,8 +436,8 @@ void vpu_detach_client(struct vpu_client *client) int vpu_enum_fmt(struct v4l2_fmtdesc *f) { const struct vpu_format_desc *fmt; int port = get_port_number(f->type); if (port < 0) int port_type = get_port_type(f->type); if (port_type < 0) return -EINVAL; fmt = query_supported_formats(f->index); Loading @@ -460,21 +461,23 @@ int vpu_get_fmt(struct vpu_client *client, struct v4l2_format *f) if (!session) return -EPERM; port = get_port_number(f->type); port = get_port_number(client, f->type); if (port < 0) return -EINVAL; if (port == INPUT_PORT) { ret = vpu_hw_session_g_input_params(session->id, &in_param); ret = vpu_hw_session_g_input_params(session->id, translate_port_id(port), &in_param); translate_input_format_to_api(&in_param, f); f->fmt.pix_mp.colorspace = session->port_info[INPUT_PORT].format.colorspace; session->port_info[port].format.colorspace; } else { ret = vpu_hw_session_g_output_params(session->id, &out_param); ret = vpu_hw_session_g_output_params(session->id, translate_port_id(port), &out_param); translate_output_format_to_api(&out_param, f); f->fmt.pix_mp.colorspace = session->port_info[OUTPUT_PORT].format.colorspace; session->port_info[port].format.colorspace; } return ret; Loading Loading @@ -530,9 +533,9 @@ int vpu_set_fmt(struct vpu_client *client, struct v4l2_format *f) pr_err("invalid session\n"); return -EPERM; } port = get_port_number(f->type); port = get_port_number(client, f->type); if (port < 0) { pr_err("invalid port (%d)\n", port); pr_err("invalid buffer type (%d)\n", f->type); return -EINVAL; } Loading Loading @@ -575,10 +578,12 @@ static int __vpu_get_framerate(struct vpu_client *client, u32 *framerate, int ret = 0; if (port == INPUT_PORT) { ret = vpu_hw_session_g_input_params(session->id, &in_param); ret = vpu_hw_session_g_input_params(session->id, translate_port_id(port), &in_param); *framerate = in_param.frame_rate; } else { ret = vpu_hw_session_g_output_params(session->id, &out_param); ret = vpu_hw_session_g_output_params(session->id, translate_port_id(port), &out_param); *framerate = out_param.frame_rate; } Loading Loading @@ -610,16 +615,18 @@ int vpu_get_region_of_intereset(struct vpu_client *client, if (!session) return -EPERM; port = get_port_number(crop->type); port = get_port_number(client, crop->type); if (port < 0) return -EINVAL; if (port == INPUT_PORT) { ret = vpu_hw_session_g_input_params(session->id, &in_param); ret = vpu_hw_session_g_input_params(session->id, translate_port_id(port), &in_param); translate_roi_rect_to_api(&in_param.region_interest, &crop->c); } else { ret = vpu_hw_session_g_output_params(session->id, &out_param); ret = vpu_hw_session_g_output_params(session->id, translate_port_id(port), &out_param); translate_roi_rect_to_api(&out_param.dest_rect, &crop->c); } Loading @@ -631,7 +638,9 @@ int vpu_set_region_of_intereset(struct vpu_client *client, const struct v4l2_crop *crop) { struct vpu_dev_session *session = client ? client->session : 0; int ret = 0, port = get_port_number(crop->type); int ret = 0, port; port = get_port_number(client, crop->type); if (!session) return -EPERM; Loading Loading @@ -665,7 +674,7 @@ int vpu_set_input(struct vpu_client *client, unsigned int i) /* Changing input/output only allowed if port is not streaming */ mutex_lock(&session->lock); if (session->streaming_state & (0x1 << INPUT_PORT)) { if (session->streaming_state & (0x1 << PORT_TYPE_INPUT)) { ret = -EBUSY; goto exit_s_input; } Loading Loading @@ -697,44 +706,50 @@ exit_s_input: int vpu_get_output(struct vpu_client *client, unsigned int *i) { int port; if (!client || !client->session) return -EPERM; *i = client->session->port_info[OUTPUT_PORT].destination; port = client->uses_output2 ? OUTPUT_PORT2 : OUTPUT_PORT; *i = client->session->port_info[port].destination; return 0; } int vpu_set_output(struct vpu_client *client, unsigned int i) { int ret = 0; int ret = 0, port; struct vpu_dev_session *session = client ? client->session : 0; if (!session) return -EPERM; port = client->uses_output2 ? OUTPUT_PORT2 : OUTPUT_PORT; mutex_lock(&session->lock); if (session->streaming_state & (0x1 << OUTPUT_PORT)) { if (session->streaming_state & (0x1 << PORT_TYPE_OUTPUT)) { ret = -EBUSY; goto exit_s_output; } session->port_info[OUTPUT_PORT].destination = i; session->port_info[port].destination = i; /* detach previous output tunnel port, if existing */ call_port_op(session, OUTPUT_PORT, detach); call_port_op(session, port, detach); /* initiate and attach input tunnel port, if needed */ if (i != VPU_OUTPUT_TYPE_HOST) { ret = vpu_init_port_mdss(session, &session->port_info[OUTPUT_PORT]); &session->port_info[port]); if (ret) goto exit_s_output; ret = call_port_op(session, OUTPUT_PORT, attach); ret = call_port_op(session, port, attach); if (ret) goto exit_s_output; } ret = commit_port_config(session, OUTPUT_PORT, 1); ret = commit_port_config(session, port, 1); exit_s_output: mutex_unlock(&session->lock); Loading Loading @@ -781,9 +796,12 @@ int vpu_get_control_port(struct vpu_client *client, if (!session) return -EPERM; if (port < 0 || port > NUM_VPU_PORTS) if (port < 0 || port >= NUM_VPU_PORT_TYPES) return -EINVAL; if (port == PORT_TYPE_OUTPUT && client->uses_output2) port = OUTPUT_PORT2; if (control->control_id == VPU_CTRL_FPS) return __vpu_get_framerate(client, &control->data.framerate, port); Loading @@ -799,9 +817,12 @@ int vpu_set_control_port(struct vpu_client *client, if (!session) return -EPERM; if (port < 0 || port > NUM_VPU_PORTS) if (port < 0 || port >= NUM_VPU_PORT_TYPES) return -EINVAL; if (port == PORT_TYPE_OUTPUT && client->uses_output2) port = OUTPUT_PORT2; if (control->control_id == VPU_CTRL_FPS) return __vpu_set_framerate(client, control->data.framerate, port); Loading @@ -823,6 +844,26 @@ int vpu_commit_configuration(struct vpu_client *client) return ret; } int vpu_dual_output(struct vpu_client *client) { int ret = 0; struct vpu_dev_session *session = client ? client->session : 0; if (!session) return -EPERM; mutex_lock(&session->lock); if (session->io_client[OUTPUT_PORT] == client) { pr_err("Client using output port 1\n"); ret = -EINVAL; } else { session->dual_output = true; client->uses_output2 = true; } mutex_unlock(&session->lock); return ret; } /* * Streaming I/O operations */ Loading @@ -840,13 +881,13 @@ int vpu_reqbufs(struct vpu_client *client, struct v4l2_requestbuffers *req) if (!session) return -EPERM; port = get_port_number(req->type); port = get_port_number(client, req->type); if (port < 0) { pr_err("Invalid buffer type %d\n", req->type); return -EINVAL; } pr_debug("count = %d\n", req->count); pr_debug("port %d count = %d\n", port, req->count); mutex_lock(&session->que_lock[port]); if (session->io_client[port] != client && session->io_client[port]) { Loading Loading @@ -921,7 +962,7 @@ int vpu_qbuf(struct vpu_client *client, struct v4l2_buffer *b) if (!session) return -EPERM; port = get_port_number(b->type); port = get_port_number(client, b->type); if (port < 0) { pr_err("Invalid type %d\n", b->type); return -EINVAL; Loading Loading @@ -956,7 +997,7 @@ int vpu_dqbuf(struct vpu_client *client, struct v4l2_buffer *b, if (!session) return -EPERM; port = get_port_number(b->type); port = get_port_number(client, b->type); if (port < 0) { pr_err("Invalid type %d\n", b->type); return -EINVAL; Loading Loading @@ -1001,10 +1042,10 @@ static int __queue_pending_buffers(struct vpu_dev_session *session) { if (port == INPUT_PORT) ret = vpu_hw_session_empty_buffer(session->id, buff); translate_port_id(port), buff); else ret = vpu_hw_session_fill_buffer(session->id, buff); translate_port_id(port), buff); if (ret) { pr_err("returning buffer\n"); Loading @@ -1021,11 +1062,13 @@ static int __queue_pending_buffers(struct vpu_dev_session *session) int vpu_flush_bufs(struct vpu_client *client, enum v4l2_buf_type type) { struct vpu_dev_session *session = client ? client->session : 0; int ret = 0, port; int ret = 0, port, port_type; if (!session) return -EPERM; port = get_port_number(type); port_type = get_port_type(type); port = get_port_number(client, type); if (port < 0) { pr_err("Invalid type %d\n", type); return -EINVAL; Loading @@ -1038,7 +1081,7 @@ int vpu_flush_bufs(struct vpu_client *client, enum v4l2_buf_type type) ret = -EINVAL; goto exit_flush; } else { if (!(session->streaming_state & (0x1 << port))) { if (!(session->streaming_state & (0x1 << port_type))) { /* Can't flush if port is not streaming */ ret = -EINVAL; goto exit_flush; Loading Loading @@ -1072,6 +1115,15 @@ int vpu_trigger_stream(struct vpu_dev_session *session) return ret; } if (session->dual_output) { ret = vb2_streamon(&session->vbqueue[OUTPUT_PORT2], session->vbqueue[OUTPUT_PORT2].type); if (ret) { pr_err("Failed to vb2_streamon output port 2\n"); return ret; } } session->streaming_state = ALL_STREAMING; __queue_pending_buffers(session); Loading @@ -1081,16 +1133,19 @@ int vpu_trigger_stream(struct vpu_dev_session *session) int vpu_streamon(struct vpu_client *client, enum v4l2_buf_type type) { struct vpu_dev_session *session = client ? client->session : 0; int ret = 0, port; int ret = 0, port, port_type; u32 temp_streaming = 0; if (!session) return -EPERM; port = get_port_number(type); port_type = get_port_type(type); port = get_port_number(client, type); if (port < 0) { pr_err("Invalid type %d\n", type); return -EINVAL; } if (port == OUTPUT_PORT2) return 0; /* do nothing for second output port */ mutex_lock(&session->lock); /* needed to sync streamon from two ports */ Loading @@ -1107,10 +1162,10 @@ int vpu_streamon(struct vpu_client *client, enum v4l2_buf_type type) if (ret) goto early_exit_streamon; if (temp_streaming & (0x1 << port)) { if (temp_streaming & (0x1 << port_type)) { goto early_exit_streamon; /* This port already streaming */ } else { temp_streaming |= (0x1 << port); temp_streaming |= (0x1 << port_type); /* lock port if tunneling */ if (__is_tunneling(session, port)) session->io_client[port] = client; Loading Loading @@ -1144,12 +1199,11 @@ int vpu_streamon(struct vpu_client *client, enum v4l2_buf_type type) /* Start end-to-end session streaming */ ret = vpu_trigger_stream(session); if (!ret) pr_debug("Session streaming started successfully\n"); late_exit_streamon: if (ret) { /* TODO: How do we notify the streamed on sessions? */ if (__is_tunneling(session, port)) session->io_client[port] = NULL; } Loading @@ -1173,11 +1227,13 @@ int vpu_streamoff(struct vpu_client *client, enum v4l2_buf_type type) if (!session) return -EPERM; port = get_port_number(type); port = get_port_number(client, type); if (port < 0) { pr_err("Invalid type %d\n", type); return -EINVAL; } if (port == OUTPUT_PORT2) return 0; /* do nothing for second output port */ /* session lock needed to protect actions inside vb2_stream_off */ mutex_lock(&session->lock); Loading