Loading drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +61 −13 Original line number Diff line number Diff line Loading @@ -105,6 +105,8 @@ static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev, qcmd; \ }) #define MSM_CPP_MAX_TIMEOUT_TRIAL 3 struct msm_cpp_timer_data_t { struct cpp_device *cpp_dev; struct msm_cpp_frame_info_t *processed_frame; Loading Loading @@ -175,6 +177,14 @@ static void msm_cpp_write(u32 data, void __iomem *cpp_base) writel_relaxed((data), cpp_base + MSM_CPP_MICRO_FIFO_RX_DATA); } static void msm_cpp_clear_timer(struct cpp_device *cpp_dev) { atomic_set(&cpp_timer.used, 0); del_timer(&cpp_timer.cpp_timer); cpp_timer.data.processed_frame = NULL; cpp_dev->timeout_trial_cnt = 0; } static uint32_t msm_cpp_read(void __iomem *cpp_base) { uint32_t tmp, retry = 0; Loading Loading @@ -598,7 +608,6 @@ void msm_cpp_do_tasklet(unsigned long data) uint32_t tx_fifo[MSM_CPP_TX_FIFO_LEVEL]; struct cpp_device *cpp_dev = (struct cpp_device *) data; struct msm_cpp_tasklet_queue_cmd *queue_cmd; struct msm_cpp_timer_t *timer = NULL; while (atomic_read(&cpp_dev->irq_cnt)) { spin_lock_irqsave(&cpp_dev->tasklet_lock, flags); Loading Loading @@ -627,19 +636,13 @@ void msm_cpp_do_tasklet(unsigned long data) CPP_DBG("Frame done!!\n"); /* delete CPP timer */ CPP_DBG("delete timer.\n"); timer = &cpp_timer; atomic_set(&timer->used, 0); del_timer(&timer->cpp_timer); timer->data.processed_frame = NULL; msm_cpp_clear_timer(cpp_dev); msm_cpp_notify_frame_done(cpp_dev); } else if (msg_id == MSM_CPP_MSG_ID_FRAME_NACK) { pr_err("NACK error from hw!!\n"); CPP_DBG("delete timer.\n"); timer = &cpp_timer; atomic_set(&timer->used, 0); del_timer(&timer->cpp_timer); timer->data.processed_frame = NULL; msm_cpp_clear_timer(cpp_dev); msm_cpp_notify_frame_done(cpp_dev); } i += cmd_len + 2; Loading Loading @@ -1043,6 +1046,7 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) pr_debug("DEBUG_R1: 0x%x\n", msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C)); msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL); msm_cpp_clear_timer(cpp_dev); cpp_deinit_mem(cpp_dev); iommu_detach_device(cpp_dev->domain, cpp_dev->iommu_ctx); cpp_release_hardware(cpp_dev); Loading Loading @@ -1176,8 +1180,9 @@ static void msm_cpp_do_timeout_work(struct work_struct *work) pr_err("cpp_timer_callback called. (jiffies=%lu)\n", jiffies); if (!work) { pr_err("Invalid work:%p\n", work); if (!work || cpp_timer.data.cpp_dev->state != CPP_STATE_ACTIVE) { pr_err("Invalid work:%p or state:%d\n", work, cpp_timer.data.cpp_dev->state); return; } if (!atomic_read(&cpp_timer.used)) { Loading @@ -1201,6 +1206,14 @@ static void msm_cpp_do_timeout_work(struct work_struct *work) return; } if (cpp_timer.data.cpp_dev->timeout_trial_cnt >= MSM_CPP_MAX_TIMEOUT_TRIAL) { pr_info("Max trial reached\n"); msm_cpp_notify_frame_done(cpp_timer.data.cpp_dev); cpp_timer.data.cpp_dev->timeout_trial_cnt = 0; return; } this_frame = cpp_timer.data.processed_frame; pr_err("Starting timer to fire in %d ms. (jiffies=%lu)\n", CPP_CMD_TIMEOUT_MS, jiffies); Loading @@ -1216,6 +1229,7 @@ static void msm_cpp_do_timeout_work(struct work_struct *work) for (i = 0; i < this_frame->msg_len; i++) msm_cpp_write(this_frame->cpp_cmd_msg[i], cpp_timer.data.cpp_dev->base); cpp_timer.data.cpp_dev->timeout_trial_cnt++; return; } Loading Loading @@ -1483,6 +1497,26 @@ ERROR1: return rc; } void msm_cpp_clean_queue(struct cpp_device *cpp_dev) { struct msm_queue_cmd *frame_qcmd = NULL; struct msm_cpp_frame_info_t *processed_frame = NULL; struct msm_device_queue *queue = NULL; while (cpp_dev->processing_q.len) { pr_info("queue len:%d\n", cpp_dev->processing_q.len); queue = &cpp_dev->processing_q; frame_qcmd = msm_dequeue(queue, list_frame); if (frame_qcmd) { processed_frame = frame_qcmd->command; kfree(frame_qcmd); if (processed_frame) kfree(processed_frame->cpp_cmd_msg); kfree(processed_frame); } } } long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { Loading Loading @@ -1643,6 +1677,11 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, kfree(k_stream_buff_info.buffer_info); kfree(u_stream_buff_info); if (cpp_dev->stream_cnt == 0) { cpp_dev->state = CPP_STATE_ACTIVE; msm_cpp_clear_timer(cpp_dev); msm_cpp_clean_queue(cpp_dev); } if (cmd != VIDIOC_MSM_CPP_APPEND_STREAM_BUFF_INFO) { cpp_dev->stream_cnt++; Loading Loading @@ -1683,11 +1722,14 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, buff_queue_info->stream_id); if (cpp_dev->stream_cnt > 0) { cpp_dev->stream_cnt--; pr_err("stream_cnt:%d\n", cpp_dev->stream_cnt); pr_info("stream_cnt:%d\n", cpp_dev->stream_cnt); if (cpp_dev->stream_cnt == 0) { rc = msm_isp_update_bandwidth(ISP_CPP, 0, 0); if (rc < 0) pr_err("Bandwidth Reset Failed!\n"); cpp_dev->state = CPP_STATE_IDLE; msm_cpp_clear_timer(cpp_dev); msm_cpp_clean_queue(cpp_dev); } } else { pr_err("error: stream count underflow %d\n", Loading Loading @@ -1769,6 +1811,12 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, case MSM_SD_SHUTDOWN: CPP_DBG("MSM_SD_SHUTDOWN\n"); mutex_unlock(&cpp_dev->mutex); pr_info("shutdown cpp node. open cnt:%d\n", cpp_dev->cpp_open_cnt); if (atomic_read(&cpp_timer.used)) pr_info("Timer state not cleared\n"); while (cpp_dev->cpp_open_cnt != 0) cpp_close_node(sd, NULL); mutex_lock(&cpp_dev->mutex); Loading drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h +1 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ struct cpp_device { struct msm_cpp_work_t *work; uint32_t fw_version; uint8_t stream_cnt; uint8_t timeout_trial_cnt; int domain_num; struct iommu_domain *domain; Loading Loading
drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +61 −13 Original line number Diff line number Diff line Loading @@ -105,6 +105,8 @@ static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev, qcmd; \ }) #define MSM_CPP_MAX_TIMEOUT_TRIAL 3 struct msm_cpp_timer_data_t { struct cpp_device *cpp_dev; struct msm_cpp_frame_info_t *processed_frame; Loading Loading @@ -175,6 +177,14 @@ static void msm_cpp_write(u32 data, void __iomem *cpp_base) writel_relaxed((data), cpp_base + MSM_CPP_MICRO_FIFO_RX_DATA); } static void msm_cpp_clear_timer(struct cpp_device *cpp_dev) { atomic_set(&cpp_timer.used, 0); del_timer(&cpp_timer.cpp_timer); cpp_timer.data.processed_frame = NULL; cpp_dev->timeout_trial_cnt = 0; } static uint32_t msm_cpp_read(void __iomem *cpp_base) { uint32_t tmp, retry = 0; Loading Loading @@ -598,7 +608,6 @@ void msm_cpp_do_tasklet(unsigned long data) uint32_t tx_fifo[MSM_CPP_TX_FIFO_LEVEL]; struct cpp_device *cpp_dev = (struct cpp_device *) data; struct msm_cpp_tasklet_queue_cmd *queue_cmd; struct msm_cpp_timer_t *timer = NULL; while (atomic_read(&cpp_dev->irq_cnt)) { spin_lock_irqsave(&cpp_dev->tasklet_lock, flags); Loading Loading @@ -627,19 +636,13 @@ void msm_cpp_do_tasklet(unsigned long data) CPP_DBG("Frame done!!\n"); /* delete CPP timer */ CPP_DBG("delete timer.\n"); timer = &cpp_timer; atomic_set(&timer->used, 0); del_timer(&timer->cpp_timer); timer->data.processed_frame = NULL; msm_cpp_clear_timer(cpp_dev); msm_cpp_notify_frame_done(cpp_dev); } else if (msg_id == MSM_CPP_MSG_ID_FRAME_NACK) { pr_err("NACK error from hw!!\n"); CPP_DBG("delete timer.\n"); timer = &cpp_timer; atomic_set(&timer->used, 0); del_timer(&timer->cpp_timer); timer->data.processed_frame = NULL; msm_cpp_clear_timer(cpp_dev); msm_cpp_notify_frame_done(cpp_dev); } i += cmd_len + 2; Loading Loading @@ -1043,6 +1046,7 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) pr_debug("DEBUG_R1: 0x%x\n", msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C)); msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL); msm_cpp_clear_timer(cpp_dev); cpp_deinit_mem(cpp_dev); iommu_detach_device(cpp_dev->domain, cpp_dev->iommu_ctx); cpp_release_hardware(cpp_dev); Loading Loading @@ -1176,8 +1180,9 @@ static void msm_cpp_do_timeout_work(struct work_struct *work) pr_err("cpp_timer_callback called. (jiffies=%lu)\n", jiffies); if (!work) { pr_err("Invalid work:%p\n", work); if (!work || cpp_timer.data.cpp_dev->state != CPP_STATE_ACTIVE) { pr_err("Invalid work:%p or state:%d\n", work, cpp_timer.data.cpp_dev->state); return; } if (!atomic_read(&cpp_timer.used)) { Loading @@ -1201,6 +1206,14 @@ static void msm_cpp_do_timeout_work(struct work_struct *work) return; } if (cpp_timer.data.cpp_dev->timeout_trial_cnt >= MSM_CPP_MAX_TIMEOUT_TRIAL) { pr_info("Max trial reached\n"); msm_cpp_notify_frame_done(cpp_timer.data.cpp_dev); cpp_timer.data.cpp_dev->timeout_trial_cnt = 0; return; } this_frame = cpp_timer.data.processed_frame; pr_err("Starting timer to fire in %d ms. (jiffies=%lu)\n", CPP_CMD_TIMEOUT_MS, jiffies); Loading @@ -1216,6 +1229,7 @@ static void msm_cpp_do_timeout_work(struct work_struct *work) for (i = 0; i < this_frame->msg_len; i++) msm_cpp_write(this_frame->cpp_cmd_msg[i], cpp_timer.data.cpp_dev->base); cpp_timer.data.cpp_dev->timeout_trial_cnt++; return; } Loading Loading @@ -1483,6 +1497,26 @@ ERROR1: return rc; } void msm_cpp_clean_queue(struct cpp_device *cpp_dev) { struct msm_queue_cmd *frame_qcmd = NULL; struct msm_cpp_frame_info_t *processed_frame = NULL; struct msm_device_queue *queue = NULL; while (cpp_dev->processing_q.len) { pr_info("queue len:%d\n", cpp_dev->processing_q.len); queue = &cpp_dev->processing_q; frame_qcmd = msm_dequeue(queue, list_frame); if (frame_qcmd) { processed_frame = frame_qcmd->command; kfree(frame_qcmd); if (processed_frame) kfree(processed_frame->cpp_cmd_msg); kfree(processed_frame); } } } long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { Loading Loading @@ -1643,6 +1677,11 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, kfree(k_stream_buff_info.buffer_info); kfree(u_stream_buff_info); if (cpp_dev->stream_cnt == 0) { cpp_dev->state = CPP_STATE_ACTIVE; msm_cpp_clear_timer(cpp_dev); msm_cpp_clean_queue(cpp_dev); } if (cmd != VIDIOC_MSM_CPP_APPEND_STREAM_BUFF_INFO) { cpp_dev->stream_cnt++; Loading Loading @@ -1683,11 +1722,14 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, buff_queue_info->stream_id); if (cpp_dev->stream_cnt > 0) { cpp_dev->stream_cnt--; pr_err("stream_cnt:%d\n", cpp_dev->stream_cnt); pr_info("stream_cnt:%d\n", cpp_dev->stream_cnt); if (cpp_dev->stream_cnt == 0) { rc = msm_isp_update_bandwidth(ISP_CPP, 0, 0); if (rc < 0) pr_err("Bandwidth Reset Failed!\n"); cpp_dev->state = CPP_STATE_IDLE; msm_cpp_clear_timer(cpp_dev); msm_cpp_clean_queue(cpp_dev); } } else { pr_err("error: stream count underflow %d\n", Loading Loading @@ -1769,6 +1811,12 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, case MSM_SD_SHUTDOWN: CPP_DBG("MSM_SD_SHUTDOWN\n"); mutex_unlock(&cpp_dev->mutex); pr_info("shutdown cpp node. open cnt:%d\n", cpp_dev->cpp_open_cnt); if (atomic_read(&cpp_timer.used)) pr_info("Timer state not cleared\n"); while (cpp_dev->cpp_open_cnt != 0) cpp_close_node(sd, NULL); mutex_lock(&cpp_dev->mutex); Loading
drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h +1 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ struct cpp_device { struct msm_cpp_work_t *work; uint32_t fw_version; uint8_t stream_cnt; uint8_t timeout_trial_cnt; int domain_num; struct iommu_domain *domain; Loading