From 6086680640979a260a2b0c8ce08224b7cd4175a5 Mon Sep 17 00:00:00 2001 From: Haseeb Khan Date: Wed, 24 Jun 2020 16:35:06 +0530 Subject: [PATCH] msm: cvp: Re-initialize the HFI queue headers after CDSP-SSR The change is to fix hang issue after CDSP-SSR. Change-Id: I7608b32b5c308c08902b19b1b2343a0fae6888ab Signed-off-by: Haseeb Khan --- drivers/media/platform/msm/cvp/cvp_hfi.c | 36 +---------- drivers/media/platform/msm/cvp/msm_cvp_dsp.c | 68 ++++++++++++++++++++ drivers/media/platform/msm/cvp/msm_cvp_dsp.h | 1 + 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/drivers/media/platform/msm/cvp/cvp_hfi.c b/drivers/media/platform/msm/cvp/cvp_hfi.c index ada9ce10e71c..2d436f67a51e 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi.c +++ b/drivers/media/platform/msm/cvp/cvp_hfi.c @@ -1492,8 +1492,6 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) { int rc = 0; u32 i; - struct cvp_hfi_queue_table_header *q_tbl_hdr; - struct cvp_hfi_queue_header *q_hdr; struct cvp_iface_q_info *iface_q; int offset = 0; phys_addr_t fw_bias = 0; @@ -1552,43 +1550,11 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) iface_q->q_array.align_virtual_addr = kvaddr + offset; iface_q->q_array.mem_size = CVP_IFACEQ_QUEUE_SIZE; offset += iface_q->q_array.mem_size; - iface_q->q_hdr = CVP_IFACEQ_GET_QHDR_START_ADDR( - dev->dsp_iface_q_table.align_virtual_addr, i); - __set_queue_hdr_defaults(iface_q->q_hdr); spin_lock_init(&iface_q->hfi_lock); } - q_tbl_hdr = (struct cvp_hfi_queue_table_header *) - dev->dsp_iface_q_table.align_virtual_addr; - q_tbl_hdr->qtbl_version = 0; - q_tbl_hdr->device_addr = (void *)dev; - strlcpy(q_tbl_hdr->name, "msm_cvp", sizeof(q_tbl_hdr->name)); - q_tbl_hdr->qtbl_size = CVP_IFACEQ_TABLE_SIZE; - q_tbl_hdr->qtbl_qhdr0_offset = - sizeof(struct cvp_hfi_queue_table_header); - q_tbl_hdr->qtbl_qhdr_size = sizeof(struct cvp_hfi_queue_header); - q_tbl_hdr->qtbl_num_q = CVP_IFACEQ_NUMQ; - q_tbl_hdr->qtbl_num_active_q = CVP_IFACEQ_NUMQ; + cvp_dsp_init_hfi_queue_hdr(dev); - iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; - - iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; - - iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_DBGQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; - /* - * Set receive request to zero on debug queue as there is no - * need of interrupt from cvp hardware for debug messages - */ - q_hdr->qhdr_rx_req = 0; return rc; fail_dma_map: diff --git a/drivers/media/platform/msm/cvp/msm_cvp_dsp.c b/drivers/media/platform/msm/cvp/msm_cvp_dsp.c index ae3977034466..f0493d98e97e 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_dsp.c +++ b/drivers/media/platform/msm/cvp/msm_cvp_dsp.c @@ -393,6 +393,68 @@ static struct rpmsg_driver cvp_dsp_rpmsg_client = { }, }; +static void cvp_dsp_set_queue_hdr_defaults(struct cvp_hfi_queue_header *q_hdr) +{ + q_hdr->qhdr_status = 0x1; + q_hdr->qhdr_type = CVP_IFACEQ_DFLT_QHDR; + q_hdr->qhdr_q_size = CVP_IFACEQ_QUEUE_SIZE / 4; + q_hdr->qhdr_pkt_size = 0; + q_hdr->qhdr_rx_wm = 0x1; + q_hdr->qhdr_tx_wm = 0x1; + q_hdr->qhdr_rx_req = 0x1; + q_hdr->qhdr_tx_req = 0x0; + q_hdr->qhdr_rx_irq_status = 0x0; + q_hdr->qhdr_tx_irq_status = 0x0; + q_hdr->qhdr_read_idx = 0x0; + q_hdr->qhdr_write_idx = 0x0; +} + +void cvp_dsp_init_hfi_queue_hdr(struct iris_hfi_device *device) +{ + u32 i; + struct cvp_hfi_queue_table_header *q_tbl_hdr; + struct cvp_hfi_queue_header *q_hdr; + struct cvp_iface_q_info *iface_q; + + for (i = 0; i < CVP_IFACEQ_NUMQ; i++) { + iface_q = &device->dsp_iface_queues[i]; + iface_q->q_hdr = CVP_IFACEQ_GET_QHDR_START_ADDR( + device->dsp_iface_q_table.align_virtual_addr, i); + cvp_dsp_set_queue_hdr_defaults(iface_q->q_hdr); + } + q_tbl_hdr = (struct cvp_hfi_queue_table_header *) + device->dsp_iface_q_table.align_virtual_addr; + q_tbl_hdr->qtbl_version = 0; + q_tbl_hdr->device_addr = (void *)device; + strlcpy(q_tbl_hdr->name, "msm_cvp", sizeof(q_tbl_hdr->name)); + q_tbl_hdr->qtbl_size = CVP_IFACEQ_TABLE_SIZE; + q_tbl_hdr->qtbl_qhdr0_offset = + sizeof(struct cvp_hfi_queue_table_header); + q_tbl_hdr->qtbl_qhdr_size = sizeof(struct cvp_hfi_queue_header); + q_tbl_hdr->qtbl_num_q = CVP_IFACEQ_NUMQ; + q_tbl_hdr->qtbl_num_active_q = CVP_IFACEQ_NUMQ; + + iface_q = &device->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; + + iface_q = &device->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; + + iface_q = &device->dsp_iface_queues[CVP_IFACEQ_DBGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; + /* + * Set receive request to zero on debug queue as there is no + * need of interrupt from cvp hardware for debug messages + */ + q_hdr->qhdr_rx_req = 0; +} + void cvp_dsp_send_hfi_queue(void) { struct msm_cvp_core *core; @@ -436,6 +498,12 @@ void cvp_dsp_send_hfi_queue(void) goto exit; } + if (me->state == DSP_PROBED) { + cvp_dsp_init_hfi_queue_hdr(device); + dprintk(CVP_WARN, + "%s: Done init of HFI queue headers\n", __func__); + } + rc = cvp_dsp_send_cmd_hfi_queue((phys_addr_t *)addr, size); if (rc) { dprintk(CVP_WARN, "%s: Send HFI Queue failed rc = %d\n", diff --git a/drivers/media/platform/msm/cvp/msm_cvp_dsp.h b/drivers/media/platform/msm/cvp/msm_cvp_dsp.h index 0ea8b690f512..c2eb5a3b0501 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_dsp.h +++ b/drivers/media/platform/msm/cvp/msm_cvp_dsp.h @@ -24,6 +24,7 @@ int cvp_dsp_device_init(void); void cvp_dsp_device_exit(void); void cvp_dsp_send_hfi_queue(void); +void cvp_dsp_init_hfi_queue_hdr(struct iris_hfi_device *device); enum CVP_DSP_COMMAND { CPU2DSP_SEND_HFI_QUEUE = 0,