/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2022 NVIDIA Corporation. All rights reserved. */ /** * @file include/media/fusa-capture/capture-vi.h * * @brief VI channel operations header for the T186/T194 Camera RTCPU platform. */ #ifndef __FUSA_CAPTURE_VI_H__ #define __FUSA_CAPTURE_VI_H__ #if defined(__KERNEL__) #include #include #else #include #endif #include #include #include "soc/tegra/camrtc-capture.h" #include "soc/tegra/camrtc-capture-messages.h" #define __VI_CAPTURE_ALIGN __aligned(8) struct tegra_vi_channel; struct capture_buffer_table; /** * @brief VI channel capture context. */ struct vi_capture { uint16_t channel_id; /**< RCE-assigned VI FW channel id */ struct device *rtcpu_dev; /**< rtcpu device */ struct tegra_vi_channel *vi_channel; /**< VI channel context */ struct capture_buffer_table *buf_ctx; /**< Surface buffer management table */ struct capture_common_buf requests; /**< Capture descriptors queue */ struct capture_descriptor_memoryinfo *requests_memoryinfo; /**< memory info ringbuffer handle*/ uint64_t requests_memoryinfo_iova; /**< memory info ringbuffer rtcpu iova */ size_t request_buf_size; /**< Size of capture descriptor queue [byte] */ uint32_t queue_depth; /**< No. of capture descriptors in queue */ uint32_t request_size; /**< Size of single capture descriptor [byte] */ bool is_mem_pinned; /**< Whether capture request memory is pinned */ struct capture_common_status_notifier progress_status_notifier; /**< Capture progress status notifier context */ uint32_t progress_status_buffer_depth; /**< No. of capture descriptors */ bool is_progress_status_notifier_set; /**< Whether progress_status_notifer has been initialized */ uint32_t stream_id; /**< NVCSI PixelParser index [0-5] */ uint32_t csi_port; /**< NVCSI ports A-H [0-7] */ uint32_t virtual_channel_id; /**< CSI virtual channel id [0-15] */ uint32_t num_gos_tables; /**< No. of cv devices in gos_tables */ const dma_addr_t *gos_tables; /**< IOVA addresses of all GoS devices */ struct syncpoint_info progress_sp; /**< Syncpoint for frame progress */ struct syncpoint_info embdata_sp; /**< Syncpoint for embedded metadata */ struct syncpoint_info linetimer_sp; /**< Syncpoint for frame line timer */ struct completion control_resp; /**< Completion for capture-control IVC response */ struct completion capture_resp; /**< * Completion for capture requests (frame), if progress status * notifier is not in use */ struct mutex control_msg_lock; /**< Lock for capture-control IVC control_resp_msg */ struct CAPTURE_CONTROL_MSG control_resp_msg; /**< capture-control IVC resp msg written to by callback */ struct mutex reset_lock; /**< Channel lock for reset/abort support (via RCE) */ struct mutex unpins_list_lock; /**< Lock for unpins_list */ struct capture_common_unpins *unpins_list; /**< List of capture request buffer unpins */ uint64_t vi_channel_mask; /**< Bitmask of RCE-assigned VI FW channel(s). */ uint64_t vi2_channel_mask; /**< Bitmask of RCE-assigned VI FW channel(s) for 2nd VI. */ }; /** * @brief VI channel setup config (IOCTL payload). * * These fields are used to set up the VI channel and capture contexts, and will * be copied verbatim in the IVC capture_channel_config struct to allocate VI * resources in the RCE subsystem. */ struct vi_capture_setup { uint32_t channel_flags; /**< * Bitmask for channel flags, see @ref CAPTURE_CHANNEL_FLAGS */ uint32_t error_mask_correctable; /**< * Bitmask for correctable channel errors. See * @ref CAPTURE_CHANNEL_ERRORS */ uint64_t vi_channel_mask; /**< Bitmask of VI channels to consider for allocation by RCE */ uint64_t vi2_channel_mask; /**< Bitmask of 2nd VI channels */ uint32_t queue_depth; /**< No. of capture descriptors in queue. */ uint32_t request_size; /**< Size of a single capture descriptor [byte] */ union { uint32_t mem; /**< Capture descriptors queue NvRm handle */ uint64_t iova; /**< * Capture descriptors queue base address (written back * after pinning by KMD) */ }; uint8_t slvsec_stream_main; /**< SLVS-EC main stream (hardcode to 0x00) */ uint8_t slvsec_stream_sub; /**< SLVS-EC sub stream (hardcode to 0xFF - disabled) */ uint16_t __pad_slvsec1; uint32_t csi_stream_id; /**< NVCSI PixelParser index [0-5] */ uint32_t virtual_channel_id; /**< Virtual Channel index [0-15] */ uint32_t csi_port; /**< NVCSI Port [0-7], not valid for TPG */ uint32_t __pad_csi; /**< Reserved */ uint32_t error_mask_uncorrectable; /**< * Bitmask for correctable channel errors. See * @ref CAPTURE_CHANNEL_ERRORS */ uint64_t stop_on_error_notify_bits; /**< * Bitmask for NOTIFY errors that force channel stop upon * receipt */ uint64_t reserved[2]; } __VI_CAPTURE_ALIGN; /** * @brief VI capture info (resp. to query). */ struct vi_capture_info { struct vi_capture_syncpts { uint32_t progress_syncpt; /**< Progress syncpoint id */ uint32_t progress_syncpt_val; /**< Progress syncpoint value. */ uint32_t emb_data_syncpt; /**< Embedded metadata syncpoint id */ uint32_t emb_data_syncpt_val; /**< Embedded metadata syncpt value. */ uint32_t line_timer_syncpt; /**< Line timer syncpoint id */ uint32_t line_timer_syncpt_val; /**< Line timer syncpoint value */ } syncpts; uint32_t hw_channel_id; /**< RCE-assigned VI FW channel id */ uint32_t __pad; uint64_t vi_channel_mask; /**< Bitmask of RCE-assigned VI FW channel(s) */ uint64_t vi2_channel_mask; /**< Bitmask of RCE-assigned VI FW channel(s) for 2nd VI */ } __VI_CAPTURE_ALIGN; /** * @brief Container for CAPTURE_CONTROL_MSG req./resp. from FuSa UMD (IOCTL * payload). * * The response and request pointers may be to the same memory allocation; in * which case the request message will be overwritten by the response. */ struct vi_capture_control_msg { uint64_t ptr; /**< Pointer to capture-control message req. */ uint32_t size; /**< Size of req./resp. msg [byte] */ uint32_t __pad; uint64_t response; /**< Pointer to capture-control message resp. */ } __VI_CAPTURE_ALIGN; /** * @brief VI capture request (IOCTL payload). */ struct vi_capture_req { uint32_t buffer_index; /**< Capture descriptor index. */ uint32_t num_relocs; /**< No. of surface buffers to pin/reloc. */ uint64_t reloc_relatives; /**< * Offsets to surface buffer addresses to patch in capture * descriptor [byte]. */ } __VI_CAPTURE_ALIGN; /** * @brief VI capture progress status setup config (IOCTL payload) */ struct vi_capture_progress_status_req { uint32_t mem; /**< NvRm handle to buffer region start. */ uint32_t mem_offset; /**< Status notifier offset [byte]. */ uint32_t buffer_depth; /**< Capture descriptor queue size [num]. */ uint32_t __pad[3]; } __VI_CAPTURE_ALIGN; /** * @brief Add VI capture surface buffer to management table (IOCTL payload) */ struct vi_buffer_req { uint32_t mem; /**< NvRm handle to buffer. */ uint32_t flag; /**< Buffer @ref CAPTURE_BUFFER_OPS bitmask. */ } __VI_CAPTURE_ALIGN; /** * @brief The compand configuration describes a piece-wise linear tranformation * function used by the VI companding module. */ #define VI_CAPTURE_NUM_COMPAND_KNEEPTS 10 /** * @brief VI compand setup config (IOCTL payload). */ struct vi_capture_compand { uint32_t base[VI_CAPTURE_NUM_COMPAND_KNEEPTS]; /**< kneept base param. */ uint32_t scale[VI_CAPTURE_NUM_COMPAND_KNEEPTS]; /**< kneept scale param. */ uint32_t offset[VI_CAPTURE_NUM_COMPAND_KNEEPTS]; /**< kneept offset param. */ } __VI_CAPTURE_ALIGN; /** * @brief Initialize a VI channel capture context (at channel open). * * The VI channel context is already partially-initialized by the calling * function, the channel capture context is allocated and linked here. * * @param[in,out] chan Allocated VI channel context, * partially-initialized * @param[in] is_mem_pinned Whether capture request memory is pinned * * @returns 0 (success), neg. errno (failure) */ int vi_capture_init( struct tegra_vi_channel *chan, bool is_mem_pinned); /** * @brief De-initialize a VI capture channel, closing open VI/NVCSI streams, and * freeing the buffer management table and channel capture context. * * The VI channel context is not freed in this function, only the capture * context is. * * @param[in,out] chan VI channel context */ void vi_capture_shutdown( struct tegra_vi_channel *chan); /** * @brief Select the NvHost VI client instance platform driver to be * associated with the channel. * Only used in the case where VI standalone driver is used * to enumerate the VI channel character drivers * * @param[in/out] chan VI channel context * @param[in] setup VI channel setup config * */ void vi_get_nvhost_device( struct tegra_vi_channel *chan, struct vi_capture_setup *setup); /** * @brief The function returns the corresponding NvHost VI client device * pointer associated with the NVCSI stream Id. A NULL value is returned * if invalid input parameters are passed. * * @param[in] pdev VI capture platform device pointer * @param[in] csi_stream_id NVCSI stream Id * * @returns reference to VI device (success), null (failure) */ struct device *vi_csi_stream_to_nvhost_device( struct platform_device *pdev, uint32_t csi_stream_id); /** * @brief Open a VI channel in RCE, sending channel configuration to request a * HW channel allocation. Syncpoints are allocated by the KMD in this * subroutine. * * @param[in,out] chan VI channel context * @param[in] setup VI channel setup config * * @returns 0 (success), neg. errno (failure) */ int vi_capture_setup( struct tegra_vi_channel *chan, struct vi_capture_setup *setup); /** * @brief Get the pointer to tegra_vi_channel struct associated with the * stream id and virtual id passed as function input params. * * If no valid tegra_vi_channel pointer is found associated with the given * stream id/ VC id combo then NULL is returned. * * @param[in] stream_id CSI stream ID * @param[in] virtual_channel_id CSI virtual channel ID * * @returns pointer to tegra_vi_channel(success), NULL(failure) */ struct tegra_vi_channel *get_tegra_vi_channel( unsigned int stream_id, unsigned int virtual_channel_id); /** * @brief Reset an opened VI channel, all pending capture requests to RCE are * discarded. * * The channel's progress syncpoint is advanced to the threshold of the latest * capture request to unblock any waiting observers. * * A reset barrier may be enqueued in the capture IVC channel to flush stale * capture descriptors, in case of abnormal channel termination. * * @param[in] chan VI channel context * @param[in] reset_flags Bitmask for VI channel reset options * (CAPTURE_CHANNEL_RESET_FLAG_*) * * @returns 0 (success), neg. errno (failure) */ int vi_capture_reset( struct tegra_vi_channel *chan, uint32_t reset_flags); /** * @brief Release an opened VI channel; the RCE channel allocation, syncpts and * IVC channel callbacks are released. * * @param[in] chan VI channel context * @param[in] reset_flags Bitmask for VI channel reset options * (CAPTURE_CHANNEL_RESET_FLAG_*) * * @returns 0 (success), neg. errno (failure) */ int vi_capture_release( struct tegra_vi_channel *chan, uint32_t reset_flags); /** * @brief Release the TPG and/or NVCSI stream on a VI channel, if they are * active. * * This function normally does not execute except in the event of abnormal UMD * termination, as it is the client's responsibility to open and close NVCSI and * TPG sources. * * @param[in] chan VI channel context * * @returns 0 (success), neg. errno (failure) */ int csi_stream_release( struct tegra_vi_channel *chan); /** * @brief Send a capture-control IVC message to RCE and wait for a response. * * This is a blocking call, with the possibility of timeout. * * @param[in] chan VI channel context * @param[in,out] msg capture-control IVC container w/ req./resp. pair * * @returns 0 (success), neg. errno (failure) */ int vi_capture_control_message( struct tegra_vi_channel *chan, struct vi_capture_control_msg *msg); /** * @brief Send a capture-control IVC message which is received from * userspace to RCE and wait for a response. * * This is a blocking call, with the possibility of timeout. * * @param[in] chan VI channel context * @param[in,out] msg capture-control IVC container w/ req./resp. pair * * @returns 0 (success), neg. errno (failure) */ int vi_capture_control_message_from_user( struct tegra_vi_channel *chan, struct vi_capture_control_msg *msg); /** * @brief Query a VI channel's syncpt ids and values, and retrieve the * RCE-assigned VI FW channel id and mask. * * @param[in] chan VI channel context * @param[out] info VI channel info response * @returns 0 (success), neg. errno (failure) */ int vi_capture_get_info( struct tegra_vi_channel *chan, struct vi_capture_info *info); /** * @brief Send a capture request for a frame via the capture IVC channel to RCE. * * This is a non-blocking call. * * @param[in] chan VI channel context * @param[in] req VI capture request * * @returns 0 (success), neg. errno (failure) */ int vi_capture_request( struct tegra_vi_channel *chan, struct vi_capture_req *req); /** * @brief Wait on receipt of the capture status of the head of the capture * request FIFO queue to RCE. The RCE VI driver sends a * CAPTURE_STATUS_IND notification at frame completion. * * This is a blocking call, with the possibility of timeout. * * @param[in] chan VI channel context * @param[in] timeout_ms Time to wait for status completion [ms], set to * 0 for indefinite * * @returns 0 (success), neg. errno (failure) */ int vi_capture_status( struct tegra_vi_channel *chan, int32_t timeout_ms); /** * @brief Setup VI channel capture status progress notifier. * * @param[in] chan VI channel context * @param[in] req VI capture progress status setup config * * @returns 0 (success), neg. errno (failure) */ int vi_capture_set_progress_status_notifier( struct tegra_vi_channel *chan, struct vi_capture_progress_status_req *req); #endif /* __FUSA_CAPTURE_VI_H__ */