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. *