From d0edc7b3e70a4e1a2e76734bb79dbbf4fc204e0a Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Mon, 6 Mar 2023 15:45:37 +0800 Subject: [PATCH] media: rockchip: isp: thunder boot with multi sensor Change-Id: I20efdaf70a24e9b892b40bed6420b2988b8125b4 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/dev.c | 8 +- drivers/media/platform/rockchip/isp/dmarx.c | 3 + .../media/platform/rockchip/isp/isp_stats.c | 3 + drivers/media/platform/rockchip/isp/rkisp.c | 149 +++++++++--------- include/uapi/linux/rkisp2-config.h | 3 +- include/uapi/linux/rkisp32-config.h | 2 +- 6 files changed, 83 insertions(+), 85 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index a6abe6fc722e..9aecc186faaa 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -861,11 +861,9 @@ static int rkisp_plat_probe(struct platform_device *pdev) strscpy(isp_dev->media_dev.driver_name, isp_dev->name, sizeof(isp_dev->media_dev.driver_name)); - if (isp_dev->hw_dev->is_thunderboot) { - ret = rkisp_get_reserved_mem(isp_dev); - if (ret) - return ret; - } + ret = rkisp_get_reserved_mem(isp_dev); + if (ret) + return ret; mutex_init(&isp_dev->apilock); mutex_init(&isp_dev->iqlock); diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index e190fef6386a..b7af0af8dc3f 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -471,6 +471,9 @@ static int dmarx_frame_end(struct rkisp_stream *stream) true, dev->hw_dev->is_unite); rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, CIF_ISP_FRAME_IN, true, dev->hw_dev->is_unite); + dev_info(dev->dev, + "switch online seq:%d mode:0x%x\n", + rx_buf->sequence, dev->rd_mode); } rx_buf->runtime_us = dev->isp_sdev.dbg.interval / 1000; v4l2_subdev_call(sd, video, s_rx_buffer, rx_buf, NULL); diff --git a/drivers/media/platform/rockchip/isp/isp_stats.c b/drivers/media/platform/rockchip/isp/isp_stats.c index 025ff95843d5..7d21e2cb4c01 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.c +++ b/drivers/media/platform/rockchip/isp/isp_stats.c @@ -158,6 +158,9 @@ static void rkisp_stats_vb2_buf_queue(struct vb2_buffer *vb) struct rkisp32_isp_stat_buffer *buf = stats_dev->stats_buf[0].vaddr; if (buf && !buf->frame_id && buf->meas_type && stats_buf->vaddr[0]) { + dev_info(stats_dev->dev->dev, + "tb stat seq:%d meas_type:0x%x\n", + buf->frame_id, buf->meas_type); memcpy(stats_buf->vaddr[0], buf, sizeof(struct rkisp32_isp_stat_buffer)); buf->meas_type = 0; vb2_set_plane_payload(vb, 0, sizeof(struct rkisp32_isp_stat_buffer)); diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 0039b204070c..44173416fa60 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -722,7 +722,7 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo params_vdev->rdbk_times = dma2frm + 1; run_next: - if (hw->is_multi_overflow) { + if (hw->is_multi_overflow && !dev->is_first_double) { stats_vdev->rdbk_drop = false; if (dev->sw_rd_cnt) { rkisp_multi_overflow_hdl(dev, false); @@ -908,6 +908,7 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) if (isp->is_pre_on && t.frame_id == 0) { isp->is_first_double = true; isp->skip_frame = 1; + isp->sw_rd_cnt = 0; rkisp_fast_switch_rx_buf(isp, false); } } @@ -969,7 +970,8 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq) if (dev->hw_dev->is_multi_overflow && dev->sw_rd_cnt && - irq & ISP_FRAME_END) + irq & ISP_FRAME_END && + !dev->is_first_double) goto end; dev->irq_ends |= (irq & dev->irq_ends_mask); @@ -2961,10 +2963,9 @@ static int rkisp_rx_qbuf(struct rkisp_device *dev, } v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, - "%s rd_mode:%d dma:0x%x vaddr:%p", - __func__, dev->rd_mode, - pool->buf.buff_addr[RKISP_PLANE_Y], - pool->buf.vaddr[RKISP_PLANE_Y]); + "%s rd_mode:%d seq:%d dma:0x%x\n", + __func__, dev->rd_mode, dbufs->sequence, + pool->buf.buff_addr[RKISP_PLANE_Y]); if (!IS_HDR_RDBK(dev->rd_mode)) { rkisp_rx_qbuf_online(stream, pool); @@ -3768,94 +3769,86 @@ void rkisp_unregister_isp_subdev(struct rkisp_device *isp_dev) #ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP void rkisp_chk_tb_over(struct rkisp_device *isp_dev) { + struct rkisp_hw_dev *hw = isp_dev->hw_dev; struct rkisp_thunderboot_resmem_head *head; enum rkisp_tb_state tb_state; void *resmem_va; - if (!isp_dev->hw_dev->is_thunderboot) + if (!isp_dev->is_thunderboot) return; - if (!isp_dev->is_thunderboot) { - v4l2_info(&isp_dev->v4l2_dev, - "no reserved memory for thunderboot\n"); - if (isp_dev->hw_dev->is_thunderboot) { - rkisp_tb_set_state(RKISP_TB_NG); - rkisp_tb_unprotect_clk(); - rkisp_register_irq(isp_dev->hw_dev); - isp_dev->hw_dev->is_thunderboot = false; - } - return; - } - resmem_va = phys_to_virt(isp_dev->resmem_pa); head = (struct rkisp_thunderboot_resmem_head *)resmem_va; - if (isp_dev->is_thunderboot) { - dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr, - sizeof(struct rkisp_thunderboot_resmem_head), - DMA_FROM_DEVICE); - if (head->enable && !head->complete) { - /* notify rtt to stop */ - head->enable = 0; - dma_sync_single_for_device(isp_dev->dev, isp_dev->resmem_addr, - sizeof(struct rkisp_thunderboot_resmem_head), - DMA_TO_DEVICE); - } - shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 400 * USEC_PER_MSEC); - 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; + dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr, + sizeof(struct rkisp_thunderboot_resmem_head), + DMA_FROM_DEVICE); - switch (isp_dev->hw_dev->isp_ver) { - case ISP_V32: - size = sizeof(struct rkisp32_thunderboot_resmem_head); - break; - default: - break; - } - if (size && size < isp_dev->resmem_size) { - dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr, - size, DMA_FROM_DEVICE); - params_vdev->is_first_cfg = true; - if (isp_dev->hw_dev->isp_ver == ISP_V32) { - struct rkisp32_thunderboot_resmem_head *tmp = resmem_va; - - param = &tmp->cfg; - } - 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; + shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 200 * USEC_PER_MSEC); + 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; + + 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)); - v4l2_info(&isp_dev->v4l2_dev, - "thunderboot info: %d, %d, %d, %d, %d, %d %d\n", - head->enable, - head->complete, - head->frm_total, - head->hdr_mode, - head->width, - head->height, - head->bus_fmt); + } + memcpy(&isp_dev->tb_head, head, sizeof(*head)); + v4l2_info(&isp_dev->v4l2_dev, + "thunderboot info: %d, %d, %d, %d, %d, %d | %d %d\n", + head->enable, + head->complete, + head->frm_total, + head->hdr_mode, + head->width, + head->height, + head->camera_num, + head->camera_index); - tb_state = RKISP_TB_OK; - if (head->complete != RKISP_TB_OK) { - head->frm_total = 0; - tb_state = RKISP_TB_NG; - } + tb_state = RKISP_TB_OK; + if (head->complete != RKISP_TB_OK) { + head->frm_total = 0; + tb_state = RKISP_TB_NG; + } + if (hw->is_thunderboot) { + rkisp_register_irq(hw); rkisp_tb_set_state(tb_state); rkisp_tb_unprotect_clk(); - rkisp_register_irq(isp_dev->hw_dev); - isp_dev->hw_dev->is_thunderboot = false; - isp_dev->is_thunderboot = false; + hw->is_thunderboot = false; } + isp_dev->is_thunderboot = false; } #endif diff --git a/include/uapi/linux/rkisp2-config.h b/include/uapi/linux/rkisp2-config.h index cb0078ccccf1..efdcd2f4c326 100644 --- a/include/uapi/linux/rkisp2-config.h +++ b/include/uapi/linux/rkisp2-config.h @@ -1977,7 +1977,8 @@ struct rkisp_thunderboot_resmem_head { u16 hdr_mode; u16 width; u16 height; - u32 bus_fmt; + u16 camera_num; + u16 camera_index; u32 exp_time[3]; u32 exp_gain[3]; diff --git a/include/uapi/linux/rkisp32-config.h b/include/uapi/linux/rkisp32-config.h index a49f481579a0..b8d1cd6c73c9 100644 --- a/include/uapi/linux/rkisp32-config.h +++ b/include/uapi/linux/rkisp32-config.h @@ -1467,7 +1467,7 @@ struct rkisp32_isp_stat_buffer { struct rkisp32_thunderboot_resmem_head { struct rkisp_thunderboot_resmem_head head; struct isp32_isp_params_cfg cfg; -}; +} __attribute__ ((packed)); /****************isp32 lite********************/