Hi, Shu-hsiang: On Wed, 2024-10-09 at 19:15 +0800, Shu-hsiang Yang wrote: > Introduces the top media device driver for the MediaTek ISP7X CAMSYS. > The driver maintains the camera system, including sub-device management, > DMA operations, and integration with the V4L2 framework. It handles > request stream data, buffer management, and MediaTek-specific features, > and pipeline management, streaming control, error handling mechanism. > Additionally, it aggregates sub-drivers for the camera interface, raw > and yuv pipelines. > > Signed-off-by: Shu-hsiang Yang <Shu-hsiang.Yang@xxxxxxxxxxxx> > --- [snip] > +void mtk_cam_buf_try_queue(struct mtk_cam_ctx *ctx) > +{ > + struct mtk_cam_device *cam; > + struct mtk_cam_buffer *buf, *buf_prev; > + struct mtkcam_ipi_event event; > + struct mtkcam_ipi_session_cookie *session = &event.cookie; > + struct mtkcam_ipi_frame_info *frame_info = &event.frame_data; > + struct mtkcam_ipi_frame_param *frame_param; > + struct mtkcam_ipi_frame_param *frame_data; > + struct mtk_cam_working_buf_entry *buf_entry; > + struct list_head equeue_list; > + unsigned int processing_cnt, enque_cnt; > + > + cam = ctx->cam; > + if (!cam->streaming_ctx) { > + dev_info(cam->dev, "streams are off\n"); > + return; > + } > + > + INIT_LIST_HEAD(&equeue_list); > + > + spin_lock(&cam->dma_processing_lock); > + processing_cnt = cam->dma_processing_count; > + spin_unlock(&cam->dma_processing_lock); > + > + enque_cnt = 0; > + spin_lock(&cam->dma_pending_lock); > + list_for_each_entry_safe(buf, buf_prev, &cam->dma_pending, list) { > + if (processing_cnt + enque_cnt >= MTK_CAM_MAX_PROCESSING_BUFS) { > + dev_dbg(cam->dev, > + "processing bufs are full, buf cnt(%d)\n", > + processing_cnt); > + break; > + } > + dev_dbg(cam->dev, "%s buf cnt(%d)\n", > + __func__, processing_cnt + enque_cnt); > + > + enque_cnt++; > + list_del(&buf->list); > + list_add_tail(&buf->list, &equeue_list); > + } > + spin_unlock(&cam->dma_pending_lock); > + > + if (!enque_cnt) > + return; > + > + frame_param = kzalloc(sizeof(*frame_param), GFP_KERNEL); > + if (!frame_param) > + return; > + > + list_for_each_entry_safe(buf, buf_prev, &equeue_list, list) { > + if (buf->state.estate == E_BUF_STATE_COMPOSED) This would never happened. buf in equeue_list is moved from cam->dma_pending and buf's state is E_BUF_STATE_QUEUED. So drop this checking. Regards, CK > + continue; > + > + memset(&event, 0, sizeof(event)); > + event.cmd_id = CAM_CMD_FRAME; > + session->session_id = ctx->stream_id; > + /* prepare working buffer */ > + buf_entry = mtk_cam_working_buf_get(ctx); > + if (!buf_entry) { > + dev_info(cam->dev, > + "%s: No CQ buf availablle: enqueued_frame_seq_no:%d\n", > + __func__, atomic_read(&ctx->enqueued_frame_seq_no)); > + WARN_ON(1); > + goto EXIT; > + } > + > + spin_lock(&ctx->using_buffer_list.lock); > + list_add_tail(&buf_entry->list_entry, &ctx->using_buffer_list.list); > + ctx->using_buffer_list.cnt++; > + spin_unlock(&ctx->using_buffer_list.lock); > + > + spin_lock(&cam->dma_processing_lock); > + list_del(&buf->list); > + list_add_tail(&buf->list, &cam->dma_processing); > + cam->dma_processing_count++; > + spin_unlock(&cam->dma_processing_lock); > + > + /* Prepare rp message */ > + frame_info->cur_msgbuf_offset = > + buf_entry->msg_buffer.va - > + cam->ctxs[session->session_id].buf_pool.msg_buf_va; > + frame_info->cur_msgbuf_size = buf_entry->msg_buffer.size; > + frame_data = (struct mtkcam_ipi_frame_param *)buf_entry->msg_buffer.va; > + session->frame_no = atomic_inc_return(&ctx->enqueued_frame_seq_no); > + > + if (mtk_cam_buf_config(cam, frame_param, buf)) { > + dev_err(cam->dev, "%s: Buffer config failed\n", __func__); > + continue; > + } > + memcpy(frame_data, frame_param, sizeof(*frame_param)); > + frame_data->cur_workbuf_offset = > + buf_entry->buffer.iova - > + cam->ctxs[session->session_id].buf_pool.working_buf_iova; > + frame_data->cur_workbuf_size = buf_entry->buffer.size; > + > + if (ctx->pipe->res_config.bin_limit == BIN_AUTO) > + frame_data->raw_param.bin_flag = ctx->pipe->res_config.bin_enable; > + else > + frame_data->raw_param.bin_flag = ctx->pipe->res_config.bin_limit; > + > + scp_ipi_send(cam->scp, SCP_IPI_ISP_FRAME, &event, > + sizeof(event), MTK_CAM_IPI_SEND_TIMEOUT); > + buf->state.estate = E_BUF_STATE_COMPOSED; > + } > +EXIT: > + kfree(frame_param); > +} > +