diff --git a/drivers/media/platform/msm/cvp/cvp_hfi.c b/drivers/media/platform/msm/cvp/cvp_hfi.c index a2625c694f17..92ceaf65d2f3 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi.c +++ b/drivers/media/platform/msm/cvp/cvp_hfi.c @@ -77,7 +77,14 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { .type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS, .buf_offset = HFI_PERSIST_BUFFERS_OFFSET, .buf_num = HFI_PERSIST_BUF_NUM, - .resp = HAL_SESSION_PERSIST_CMD_DONE, + .resp = HAL_SESSION_PERSIST_SET_DONE, + }, + { + .size = 0xffffffff, + .type = HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_PERSIST_REL_DONE, }, { .size = HFI_DS_CMD_SIZE, @@ -2847,7 +2854,8 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_DME_FRAME_CMD_DONE: case HAL_SESSION_ICA_FRAME_CMD_DONE: case HAL_SESSION_FD_FRAME_CMD_DONE: - case HAL_SESSION_PERSIST_CMD_DONE: + case HAL_SESSION_PERSIST_SET_DONE: + case HAL_SESSION_PERSIST_REL_DONE: case HAL_SESSION_FD_CONFIG_CMD_DONE: case HAL_SESSION_MODEL_BUF_CMD_DONE: case HAL_SESSION_PROPERTY_INFO: diff --git a/drivers/media/platform/msm/cvp/cvp_hfi.h b/drivers/media/platform/msm/cvp/cvp_hfi.h index b8c56040e9b0..b52b47769d7c 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi.h +++ b/drivers/media/platform/msm/cvp/cvp_hfi.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef __H_CVP_HFI_H__ @@ -96,6 +96,8 @@ (HFI_CMD_SESSION_CVP_START + 0x053) #define HFI_CMD_SESSION_CVP_FD_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x054) +#define HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x055) #define HFI_CMD_SESSION_CVP_ICA_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x100) #define HFI_CMD_SESSION_CVP_ICA_CONFIG\ @@ -140,6 +142,8 @@ (HFI_MSG_SESSION_CVP_START + 0x036) #define HFI_MSG_SESSION_CVP_FD\ (HFI_MSG_SESSION_CVP_START + 0x037) +#define HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS\ + (HFI_MSG_SESSION_CVP_START + 0x038) #define CVP_IFACEQ_MAX_PKT_SIZE 1024 #define CVP_IFACEQ_MED_PKT_SIZE 768 diff --git a/drivers/media/platform/msm/cvp/cvp_hfi_api.h b/drivers/media/platform/msm/cvp/cvp_hfi_api.h index 85186eca80d5..166fb082933b 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi_api.h +++ b/drivers/media/platform/msm/cvp/cvp_hfi_api.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef __CVP_HFI_API_H__ @@ -248,7 +248,8 @@ enum hal_command_response { HAL_SESSION_DCM_CONFIG_CMD_DONE, HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE, HAL_SESSION_FD_CONFIG_CMD_DONE, - HAL_SESSION_PERSIST_CMD_DONE, + HAL_SESSION_PERSIST_SET_DONE, + HAL_SESSION_PERSIST_REL_DONE, HAL_SESSION_MODEL_BUF_CMD_DONE, HAL_SESSION_ICA_FRAME_CMD_DONE, HAL_SESSION_FD_FRAME_CMD_DONE, diff --git a/drivers/media/platform/msm/cvp/hfi_response_handler.c b/drivers/media/platform/msm/cvp/hfi_response_handler.c index ce302cb2adc2..cd6480711436 100644 --- a/drivers/media/platform/msm/cvp/hfi_response_handler.c +++ b/drivers/media/platform/msm/cvp/hfi_response_handler.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -385,6 +385,10 @@ static int hfi_process_session_cvp_operation_config(u32 device_id, if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS) signal = get_signal_from_pkt_type( HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS); + else if (pkt->packet_type == + HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + signal = get_signal_from_pkt_type( + HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS); else if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS) signal = get_signal_from_pkt_type( HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS); @@ -608,6 +612,7 @@ int cvp_hfi_process_msg_packet(u32 device_id, break; case HFI_MSG_SESSION_CVP_OPERATION_CONFIG: case HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS: + case HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS: case HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS: pkt_func = (pkt_func_def)hfi_process_session_cvp_operation_config; diff --git a/drivers/media/platform/msm/cvp/msm_cvp.c b/drivers/media/platform/msm/cvp/msm_cvp.c index e19ab1b30c77..0e6ab73baff3 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp.c +++ b/drivers/media/platform/msm/cvp/msm_cvp.c @@ -595,6 +595,104 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, return rc; } +static int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num) +{ + struct cvp_buf_type *buf; + struct cvp_hfi_cmd_session_hdr *cmd_hdr; + struct cvp_internal_buf *cbuf, *dummy; + u64 ktid; + int i, rc = 0; + + if (!offset || !buf_num) + return 0; + + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + ktid = cmd_hdr->client_data.kdata; + + for (i = 0; i < buf_num; i++) { + buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; + offset += sizeof(*buf) >> 2; + mutex_lock(&inst->persistbufs.lock); + list_for_each_entry_safe(cbuf, dummy, &inst->persistbufs.list, + list) { + if (cbuf->ktid == ktid) { + list_del(&cbuf->list); + dprintk(CVP_DBG, + "unmap persist: %x %d %d %#x", + hash32_ptr(inst->session), + cbuf->smem.fd, + cbuf->smem.size, + cbuf->smem.device_addr); + msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); + kfree(cbuf); + rc = 1; + break; + } + } + mutex_unlock(&inst->persistbufs.lock); + if (!rc) { + dprintk(CVP_ERR, "%s, failed unmapi %llx\n", + __func__, ktid); + rc = -EFAULT; + break; + } + rc = 0; + } + return rc; +} + +static int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num) +{ + struct cvp_hfi_cmd_session_hdr *cmd_hdr; + struct cvp_internal_buf *cbuf, *dummy; + u64 ktid; + struct cvp_buf_type *buf; + int i, rc = 0; + + if (!offset || !buf_num) + return 0; + + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + ktid = atomic64_inc_return(&inst->core->kernel_trans_id); + ktid &= (FENCE_BIT - 1); + cmd_hdr->client_data.kdata = ktid; + + for (i = 0; i < buf_num; i++) { + buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; + offset += sizeof(*buf) >> 2; + + /* Validate buffer descriptor */ + if (buf->fd <= 0 || !buf->size) + continue; + + mutex_lock(&inst->persistbufs.lock); + list_for_each_entry_safe(cbuf, dummy, &inst->persistbufs.list, + list) { + if (cbuf->smem.fd == buf->fd && + cbuf->smem.size == buf->size && + cbuf->buffer_ownership == CLIENT) { + rc = 1; + break; + } + } + mutex_unlock(&inst->persistbufs.lock); + if (!rc) { + dprintk(CVP_ERR, "%s No persist buf %d found\n", + __func__, buf->fd); + rc = -EFAULT; + break; + } + buf->fd = cbuf->smem.device_addr; + cbuf->ktid = ktid; + rc = 0; + } + return rc; +} + static int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, struct cvp_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num) @@ -728,7 +826,7 @@ static int msm_cvp_session_process_hfi( unsigned int in_offset, unsigned int in_buf_num) { - int pkt_idx, rc = 0; + int pkt_idx, pkt_type, rc = 0; struct cvp_hfi_device *hdev; unsigned int offset, buf_num, signal; struct cvp_session_queue *sq; @@ -777,8 +875,11 @@ static int msm_cvp_session_process_hfi( buf_num = in_buf_num; } - if (in_pkt->pkt_data[1] == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS) + pkt_type = in_pkt->pkt_data[1]; + if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS) rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num); + else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num); else rc = msm_cvp_map_buf(inst, in_pkt, offset, buf_num); @@ -796,13 +897,18 @@ static int msm_cvp_session_process_hfi( if (signal != HAL_NO_RESP) { rc = wait_for_sess_signal_receipt(inst, signal); - if (rc) + if (rc) { dprintk(CVP_ERR, "%s: wait for signal failed, rc %d %d, %x %d\n", __func__, rc, in_pkt->pkt_data[0], in_pkt->pkt_data[1], signal); + goto exit; + } + if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + rc = msm_cvp_unmap_user_persist(inst, in_pkt, + offset, buf_num); } exit: diff --git a/drivers/media/platform/msm/cvp/msm_cvp_common.c b/drivers/media/platform/msm/cvp/msm_cvp_common.c index 71ea4d785e31..12201bccbac1 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_common.c +++ b/drivers/media/platform/msm/cvp/msm_cvp_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -232,6 +232,10 @@ static void cvp_handle_session_cmd_done(enum hal_command_response cmd, return; } + if (response->status) + dprintk(CVP_ERR, "HFI MSG error %d cmd response %d\n", + response->status, cmd); + dprintk(CVP_DBG, "%s: inst=%pK\n", __func__, inst); if (IS_HAL_SESSION_CMD(cmd)) { @@ -770,7 +774,8 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data) case HAL_SESSION_DME_CONFIG_CMD_DONE: case HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE: case HAL_SESSION_DME_FRAME_CMD_DONE: - case HAL_SESSION_PERSIST_CMD_DONE: + case HAL_SESSION_PERSIST_SET_DONE: + case HAL_SESSION_PERSIST_REL_DONE: case HAL_SESSION_TME_CONFIG_CMD_DONE: case HAL_SESSION_ODT_CONFIG_CMD_DONE: case HAL_SESSION_OD_CONFIG_CMD_DONE: @@ -1770,7 +1775,7 @@ int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst) buf->smem.dma_buf->name, buf->smem.size); msm_cvp_smem_free(handle); } else if (buf->buffer_ownership == CLIENT) { - dprintk(CVP_DBG, + dprintk(CVP_ERR, "%s: %x : fd %d %s size %d", "unmap persist", hash32_ptr(inst->session), buf->smem.fd, buf->smem.dma_buf->name, buf->smem.size); diff --git a/drivers/media/platform/msm/cvp/msm_cvp_internal.h b/drivers/media/platform/msm/cvp/msm_cvp_internal.h index bb8370e01aa7..8c9ae465ce8f 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_internal.h +++ b/drivers/media/platform/msm/cvp/msm_cvp_internal.h @@ -115,7 +115,7 @@ struct cvp_internal_buf { u32 buffer_type; struct msm_cvp_smem smem; enum buffer_owner buffer_ownership; - bool mark_remove; + u64 ktid; }; struct msm_cvp_common_data {