From 4ce5cb8b0f4a09da49019f70a7bdc241c9c5034e Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Sat, 12 Aug 2023 16:41:02 +0800 Subject: [PATCH] media: rockchip: isp: add lock to save tb info multi sensor share same tb info buf, and this buf will overwrittern when first sensor stream on but second fast_work schedule slowly. So to save tb info for all dev at first read. Change-Id: I335b9e3bd317202a348be17965be112a1259bb3e Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/capture.c | 2 + drivers/media/platform/rockchip/isp/rkisp.c | 95 +++++++++++-------- 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/capture.c b/drivers/media/platform/rockchip/isp/capture.c index fcad97feadb4..60b81ada21be 100644 --- a/drivers/media/platform/rockchip/isp/capture.c +++ b/drivers/media/platform/rockchip/isp/capture.c @@ -1616,7 +1616,9 @@ static void rkisp_stream_fast(struct work_struct *work) if (ispdev->isp_ver != ISP_V32) return; + mutex_lock(&ispdev->hw_dev->dev_lock); rkisp_chk_tb_over(ispdev); + mutex_unlock(&ispdev->hw_dev->dev_lock); if (ispdev->tb_head.complete != RKISP_TB_OK) return; ret = v4l2_pipeline_pm_get(&stream->vnode.vdev.entity); diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index b225e821e87d..e1205baf22aa 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -3817,8 +3817,52 @@ void rkisp_unregister_isp_subdev(struct rkisp_device *isp_dev) }) #ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP +static void rkisp_save_tb_info(struct rkisp_device *isp_dev) +{ + struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev; + void *resmem_va = phys_to_virt(isp_dev->resmem_pa); + struct rkisp_thunderboot_resmem_head *head = resmem_va; + int size = 0, offset = 0; + void *param = NULL; + + switch (isp_dev->isp_ver) { + case ISP_V32: + size = sizeof(struct rkisp32_thunderboot_resmem_head); + offset = size * isp_dev->dev_id; + break; + default: + break; + } + + if (size && size < isp_dev->resmem_size) { + dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset, + size, DMA_FROM_DEVICE); + params_vdev->is_first_cfg = true; + if (isp_dev->isp_ver == ISP_V32) { + struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset; + + param = &tmp->cfg; + head = &tmp->head; + v4l2_info(&isp_dev->v4l2_dev, + "tb param module en:0x%llx upd:0x%llx cfg upd:0x%llx\n", + tmp->cfg.module_en_update, + tmp->cfg.module_ens, + tmp->cfg.module_cfg_update); + } + if (param) + params_vdev->ops->save_first_param(params_vdev, param); + } else if (size > isp_dev->resmem_size) { + v4l2_err(&isp_dev->v4l2_dev, + "resmem size:%zu no enough for head:%d\n", + isp_dev->resmem_size, size); + head->complete = RKISP_TB_NG; + } + memcpy(&isp_dev->tb_head, head, sizeof(*head)); +} + void rkisp_chk_tb_over(struct rkisp_device *isp_dev) { + struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev; struct rkisp_hw_dev *hw = isp_dev->hw_dev; struct rkisp_thunderboot_resmem_head *head; enum rkisp_tb_state tb_state; @@ -3827,6 +3871,9 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) if (!isp_dev->is_thunderboot) return; + if (isp_dev->isp_ver == ISP_V32 && params_vdev->is_first_cfg) + goto end; + resmem_va = phys_to_virt(isp_dev->resmem_pa); head = (struct rkisp_thunderboot_resmem_head *)resmem_va; dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr, @@ -3837,12 +3884,16 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) if (head->complete != RKISP_TB_OK) { v4l2_err(&isp_dev->v4l2_dev, "wait thunderboot over timeout\n"); } else { - struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev; - void *param = NULL; - u32 size = 0, offset = 0, timeout = 50; + int i, timeout = 50; /* wait for all isp dev to register */ if (head->camera_num > 1) { + if (head->camera_num > hw->dev_num) { + v4l2_err(&isp_dev->v4l2_dev, + "thunderboot invalid camera num:%d, dev num:%d\n", + head->camera_num, hw->dev_num); + goto end; + } while (timeout--) { if (hw->dev_num >= head->camera_num && hw->isp[hw->dev_num - 1]->is_probe_end) @@ -3850,41 +3901,11 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) usleep_range(200, 210); } } - - switch (isp_dev->isp_ver) { - case ISP_V32: - size = sizeof(struct rkisp32_thunderboot_resmem_head); - offset = size * isp_dev->dev_id; - break; - default: - break; - } - - if (size && size < isp_dev->resmem_size) { - dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset, - size, DMA_FROM_DEVICE); - params_vdev->is_first_cfg = true; - if (isp_dev->isp_ver == ISP_V32) { - struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset; - - param = &tmp->cfg; - head = &tmp->head; - v4l2_info(&isp_dev->v4l2_dev, - "tb param module en:0x%llx upd:0x%llx cfg upd:0x%llx\n", - tmp->cfg.module_en_update, - tmp->cfg.module_ens, - tmp->cfg.module_cfg_update); - } - if (param) - params_vdev->ops->save_first_param(params_vdev, param); - } else if (size > isp_dev->resmem_size) { - v4l2_err(&isp_dev->v4l2_dev, - "resmem size:%zu no enough for head:%d\n", - isp_dev->resmem_size, size); - head->complete = RKISP_TB_NG; - } + for (i = 0; i < head->camera_num; i++) + rkisp_save_tb_info(hw->isp[i]); } - memcpy(&isp_dev->tb_head, head, sizeof(*head)); +end: + head = &isp_dev->tb_head; v4l2_info(&isp_dev->v4l2_dev, "thunderboot info: %d, %d, %d, %d, %d, %d | %d %d\n", head->enable,