<html><body><p>
<pre>
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@mediatek.com>
> ---
[snip]
> +struct mtk_cam_ctx *mtk_cam_start_ctx(struct mtk_cam_device *cam,
> + struct mtk_cam_video_device *node)
> +{
> +struct mtk_cam_ctx *ctx = node->ctx;
> +struct device *dev;
> +struct v4l2_subdev **target_sd;
> +int ret, i, is_first_ctx;
> +struct media_entity *entity = &node->vdev.entity;
> +struct media_graph graph;
> +
> +dev_info(cam->dev, "%s:ctx(%d): triggered by %s\n",
> + __func__, ctx->stream_id, entity->name);
> +
> +atomic_set(&ctx->enqueued_frame_seq_no, 0);
> +ctx->composed_frame_seq_no = 0;
> +ctx->dequeued_frame_seq_no = 0;
> +atomic_set(&ctx->running_s_data_cnt, 0);
> +init_completion(&ctx->session_complete);
> +init_completion(&ctx->m2m_complete);
> +
> +is_first_ctx = !cam->composer_cnt;
> +if (is_first_ctx) {
> +spin_lock(&cam->dma_processing_lock);
> +cam->dma_processing_count = 0;
> +spin_unlock(&cam->dma_processing_lock);
> +
> +spin_lock(&cam->running_job_lock);
> +cam->running_job_count = 0;
> +spin_unlock(&cam->running_job_lock);
> +
> +dev_info(cam->dev, "%s: power on camsys\n", __func__);
> +ret = pm_runtime_resume_and_get(cam->dev);
> +if (ret < 0) {
> +dev_info(cam->dev, "%s: power on camsys failed\n",
> + __func__);
> +return NULL;
> +}
> +
> +ret = isp_composer_init(cam);
> +if (ret)
> +goto fail_shutdown;
> +
> +/* To catch camsys exception and trigger dump */
> +if (cam->debug_fs)
> +cam->debug_fs->ops->exp_reinit(cam->debug_fs);
> +}
> +cam->composer_cnt++;
> +if (is_yuv_node(node->desc.id))
> +dev = cam->raw.yuvs[0];
> +else
> +dev = cam->raw.devs[0];
> +
> +ret = mtk_cam_working_buf_pool_init(ctx, dev);
> +if (ret) {
> +dev_info(cam->dev, "failed to reserve DMA memory:%d\n", ret);
> +goto fail_uninit_composer;
> +}
> +
> +kthread_init_worker(&ctx->sensor_worker);
> +ctx->sensor_worker_task = kthread_run(kthread_worker_fn,
> + &ctx->sensor_worker,
> + "sensor_worker-%d",
> + ctx->stream_id);
> +if (IS_ERR(ctx->sensor_worker_task)) {
> +dev_info(cam->dev,
> + "%s:ctx(%d): could not create sensor_worker_task\n",
> + __func__, ctx->stream_id);
> +goto fail_release_buffer_pool;
> +}
> +
> +sched_set_fifo(ctx->sensor_worker_task);
> +
> +ctx->composer_wq = alloc_ordered_workqueue(dev_name(cam->dev),
> + WQ_HIGHPRI | WQ_FREEZABLE);
> +if (!ctx->composer_wq) {
> +dev_info(cam->dev, "failed to alloc composer workqueue\n");
> +goto fail_uninit_sensor_worker_task;
> +}
> +
> +ctx->frame_done_wq = alloc_ordered_workqueue(dev_name(cam->dev),
> + WQ_HIGHPRI | WQ_FREEZABLE);
> +if (!ctx->frame_done_wq) {
> +dev_info(cam->dev, "failed to alloc frame_done workqueue\n");
> +goto fail_uninit_composer_wq;
> +}
> +
> +ret = media_pipeline_start(&entity->pads[0], &ctx->pipeline);
> +if (ret) {
> +dev_warn(cam->dev,
> + "%s:pipe(%d):failed in media_pipeline_start:%d\n",
> + __func__, node->uid.pipe_id, ret);
> +goto fail_uninit_frame_done_wq;
> +}
> +
> +/* traverse to update used subdevs & number of nodes */
> +i = 0;
> +ret = media_graph_walk_init(&graph, entity->graph_obj.mdev);
> +if (ret)
> +goto fail_stop_pipeline;
> +
> +media_graph_walk_start(&graph, entity);
> +while ((entity = media_graph_walk_next(&graph))) {
> +dev_dbg(cam->dev, "linked entity %s\n", entity->name);
> +
> +target_sd = NULL;
> +
> +switch (entity->function) {
> +case MEDIA_ENT_F_IO_V4L:
> +ctx->enabled_node_cnt++;
> +break;
> +case MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER: /* pipeline */
> +if (i >= MAX_PIPES_PER_STREAM)
> +goto fail_stop_pipeline;
> +target_sd = ctx->pipe_subdevs + i;
> +i++;
> +break;
> +case MEDIA_ENT_F_VID_IF_BRIDGE: /* seninf */
> +target_sd = &ctx->seninf;
> +break;
> +case MEDIA_ENT_F_CAM_SENSOR:
This does not exist, so drop ctx->sensor.
Regards,
CK
> +target_sd = &ctx->sensor;
> +break;
> +default:
> +break;
> +}
> +
> +if (!target_sd)
> +continue;
> +
> +if (*target_sd) {
> +dev_info(cam->dev, "duplicated subdevs!!!\n");
> +goto fail_traverse_subdev;
> +}
> +
> +if (is_media_entity_v4l2_subdev(entity))
> +*target_sd = media_entity_to_v4l2_subdev(entity);
> +}
> +media_graph_walk_cleanup(&graph);
> +
> +return ctx;
> +
> +fail_traverse_subdev:
> +media_graph_walk_cleanup(&graph);
> +fail_stop_pipeline:
> +media_pipeline_stop(&entity->pads[0]);
> +fail_uninit_frame_done_wq:
> +destroy_workqueue(ctx->frame_done_wq);
> +fail_uninit_composer_wq:
> +destroy_workqueue(ctx->composer_wq);
> +fail_uninit_sensor_worker_task:
> +kthread_stop(ctx->sensor_worker_task);
> +ctx->sensor_worker_task = NULL;
> +fail_release_buffer_pool:
> +mtk_cam_working_buf_pool_release(ctx, dev);
> +fail_uninit_composer:
> +isp_composer_uninit(cam);
> +cam->composer_cnt--;
> +fail_shutdown:
> +if (is_first_ctx)
> +rproc_shutdown(cam->rproc_handle);
> +
> +return NULL;
> +}
> +
</pre>
</p></body></html><!--type:text--><!--{--><pre>************* MEDIATEK Confidentiality Notice
********************
The information contained in this e-mail message (including any
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be
conveyed only to the designated recipient(s). Any use, dissemination,
distribution, printing, retaining or copying of this e-mail (including its
attachments) by unintended recipient(s) is strictly prohibited and may
be unlawful. If you are not an intended recipient of this e-mail, or believe
that you have received this e-mail in error, please notify the sender
immediately (by replying to this e-mail), delete any and all copies of
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!
</pre><!--}-->