From d4f85d7379e00377462acb6b6fa8f31ecd672f35 Mon Sep 17 00:00:00 2001 From: Rakibul Hassan Date: Wed, 30 Oct 2024 21:12:51 +0000 Subject: [PATCH] nvidia-oot: camera: vi: track syncpt threshold This change does the following: - Keep the capture progress syncpt threshold up to date by incrementing it when a capture request is made - Fast forward the syncpoints via host1x api on reset Bug 4882047 Change-Id: Ic2a677575d9ade45ae6b69de5fd49d40029f7053 Signed-off-by: Rakibul Hassan Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3248336 (cherry picked from commit 6343864b8b7f70f1bc87f8503f28b07a3bb024bc) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3240448 Reviewed-by: Justin Kim (SW-TEGRA) GVS: buildbot_gerritrpt Tested-by: mobile promotions Reviewed-by: Shiva Dubey Tested-by: Justin Kim (SW-TEGRA) Reviewed-by: mobile promotions --- .../tegra/camera/fusa-capture/capture-vi.c | 65 +++++++++++++++++++ drivers/video/tegra/host/vi/vi5.c | 7 ++ .../media/fusa-capture/capture-vi-channel.h | 12 ++++ 3 files changed, 84 insertions(+) diff --git a/drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c b/drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c index 9e2d48e1..59846b5b 100644 --- a/drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c +++ b/drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c @@ -169,6 +169,22 @@ cleanup: return err; } +/** + * @brief Fast forward a VI syncpoint to its threshold value. + * + * @param[in] chan VI channel context + */ +static void vi_capture_fastforward_syncpt( + struct tegra_vi_channel *chan) +{ + struct vi_capture *capture = chan->capture_data; + + if (capture->progress_sp.id) + chan->ops->fast_forward_syncpt(chan->ndev, + capture->progress_sp.id, + capture->progress_sp.threshold); +} + /** * @brief Release a VI syncpoint and clear its handle. * @@ -918,6 +934,8 @@ int vi_capture_reset( err = -EINVAL; } + vi_capture_fastforward_syncpt(chan); + submit_fail: mutex_unlock(&capture->reset_lock); return err; @@ -1380,6 +1398,50 @@ int vi_capture_get_info( } EXPORT_SYMBOL_GPL(vi_capture_get_info); +static uint32_t vi_capture_get_num_progress( + struct tegra_vi_channel *chan, + struct vi_capture_req *req) +{ + struct vi_capture *capture = chan->capture_data; + struct capture_descriptor* desc = (struct capture_descriptor*) + (capture->requests.va + + req->buffer_index * capture->request_size); + struct vi_channel_config* config = &desc->ch_cfg; + + const uint16_t minProgress = 2U; + uint16_t numProgress = minProgress; + + /* Minimum of two progress fences for PXL_SOF and PXL_EOF */ + if (config->flush_enable == 0x1UL) + { + if (config->flush_periodic == 0x1UL) + { + if (config->flush_first != 0U) + { + numProgress++; + } + numProgress += (config->frame.frame_y - config->flush_first) / + config->flush; + } + else + { + numProgress++; + } + /** + * if (HEIGHT % TRIPLINE == 0) then TRIPLINE is reached at the same + * time as PXL_EOF. EOF occurs on the cropped last line, hence EOF and + * EOL are simultaneous. In this case, final PXL_EOF tag have NLINES bit + * set in its payload, while there is no NLINE_DONE tag. Therefore, + * number of progress fences should be decreased by one. + */ + if (((config->frame.frame_y - config->flush_first) % config->flush) == 0U) + { + numProgress--; + } + } + return (uint32_t)numProgress; +} + int vi_capture_request( struct tegra_vi_channel *chan, struct vi_capture_req *req) @@ -1435,6 +1497,9 @@ int vi_capture_request( return err; } + // Progress syncpoints + 1 for status syncpoint + capture->progress_sp.threshold += vi_capture_get_num_progress(chan, req) + 1; + mutex_unlock(&capture->reset_lock); return 0; diff --git a/drivers/video/tegra/host/vi/vi5.c b/drivers/video/tegra/host/vi/vi5.c index e0975ae1..635acbf4 100644 --- a/drivers/video/tegra/host/vi/vi5.c +++ b/drivers/video/tegra/host/vi/vi5.c @@ -117,6 +117,12 @@ static void vi5_release_syncpt(struct platform_device *pdev, uint32_t id) nvhost_syncpt_put_ref_ext(pdev, id); } +static void vi5_fast_forward_syncpt(struct platform_device *pdev, uint32_t id, uint32_t threshold) +{ + dev_dbg(&pdev->dev, "%s: id=%u -> thresh=%u\n", __func__, id, threshold); + nvhost_syncpt_set_min_update(pdev, id, threshold); +} + static void vi5_get_gos_table(struct platform_device *pdev, int *count, const dma_addr_t **table) { @@ -160,6 +166,7 @@ static int vi5_get_syncpt_gos_backing(struct platform_device *pdev, static struct vi_channel_drv_ops vi5_channel_drv_ops = { .alloc_syncpt = vi5_alloc_syncpt, .release_syncpt = vi5_release_syncpt, + .fast_forward_syncpt = vi5_fast_forward_syncpt, .get_gos_table = vi5_get_gos_table, .get_syncpt_gos_backing = vi5_get_syncpt_gos_backing, }; diff --git a/include/media/fusa-capture/capture-vi-channel.h b/include/media/fusa-capture/capture-vi-channel.h index 719dc72d..faa83344 100644 --- a/include/media/fusa-capture/capture-vi-channel.h +++ b/include/media/fusa-capture/capture-vi-channel.h @@ -45,6 +45,18 @@ struct vi_channel_drv_ops { struct platform_device *pdev, uint32_t id); + /** + * Fast forward a progres syncpt to Host1x. + * + * @param[in] pdev VI platform_device + * @param[in] id syncpt id to fast forward + * @param[in] threshold value to fast forward to + */ + void (*fast_forward_syncpt)( + struct platform_device *pdev, + uint32_t id, + uint32_t threshold); + /** * Retrieve the GoS table allocated in the VI-THI carveout. *