Files
Aniket Bahadarpurkar 3b116f7c1a tegra: rtcpu: use separate thread for reading ivc
Using global work queue and its associated worker
pool to read IVC messages from RTCPU may lead to
capture timeouts if the worker thread is not able
to get cpu due to other higher priority threads in
the system. Hence use a separate RT thread to read
IVC.

Notes for nvidia-oot: 

Use low fifo priority for worker threads to avoid
pre-empting the interrupt thread serving the HSP
driver.

Bug 200643334
Bug 3293029
Bug 3291799
Bug 4084364

Old-Change-Id: I5a3e749ec46fac1c7a2de74968169443f5cab939
Signed-off-by: Aniket Bahadarpurkar <aniketb@nvidia.com>
Signed-off-by: Pekka Pessi <ppessi@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2689827
(cherry picked from commit 18d670accc7960b0afbc7b58b339a323e424e010)
Change-Id: I48e22606e53d934d3788d524fd1f496d0f92a04a
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2939796
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Viktor Horsmanheimo <viktorh@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Kalle Jokiniemi <kjokiniemi@nvidia.com>
Reviewed-by: Sudhir Vyas <svyas@nvidia.com>
Tested-by: Viktor Horsmanheimo <viktorh@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
2023-07-25 15:26:25 -07:00

137 lines
3.8 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#ifndef __CAPTURE_IVC_PRIV_H__
#define __CAPTURE_IVC_PRIV_H__
/** Total number of capture channels (2 * VI + ISP). T234 has two VI units */
#define NUM_CAPTURE_CHANNELS 88
/** Temporary ids for the clients whose channel-id is not yet allocated */
#define NUM_CAPTURE_TRANSACTION_IDS NUM_CAPTURE_CHANNELS
/** Total number of channels including Temporary IDs */
#define TOTAL_CHANNELS (NUM_CAPTURE_CHANNELS + NUM_CAPTURE_TRANSACTION_IDS)
#define TRANS_ID_START_IDX NUM_CAPTURE_CHANNELS
/**
* @brief Callback context of an IVC channel.
*/
struct tegra_capture_ivc_cb_ctx {
/** Linked list of callback contexts */
struct list_head node;
/** Callback function registered by client */
tegra_capture_ivc_cb_func cb_func;
/** Private context of a VI/ISP capture context */
const void *priv_context;
};
/**
* @brief IVC channel context.
*/
struct tegra_capture_ivc {
/** Pointer to IVC channel */
struct tegra_ivc_channel *chan;
/** Callback context lock */
struct mutex cb_ctx_lock;
/** Channel write lock */
struct mutex ivc_wr_lock;
/** Deferred work */
struct kthread_work work;
/** ivc worker thread **/
struct kthread_worker ivc_worker;
/** task struct **/
struct task_struct *ivc_kthread;
/** Channel work queue head */
wait_queue_head_t write_q;
/** Array holding callbacks registered by each channel */
struct tegra_capture_ivc_cb_ctx cb_ctx[TOTAL_CHANNELS];
/** spinlock protecting access to linked list */
spinlock_t avl_ctx_list_lock;
/** Linked list holding callback contexts */
struct list_head avl_ctx_list;
};
/**
* @brief Standard message header for all capture IVC messages.
*/
struct tegra_capture_ivc_msg_header {
/** Message identifier. */
uint32_t msg_id;
union {
/** Channel identifier. */
uint32_t channel_id;
/** Transaction id */
uint32_t transaction;
};
} __aligned(8);
/**
* @brief Response of IVC msg
*/
struct tegra_capture_ivc_resp {
/** IVC msg header. See @ref tegra_capture_ivc_msg_header */
struct tegra_capture_ivc_msg_header header;
};
/** Pointer holding the Control IVC channel context, created during probe call*/
static struct tegra_capture_ivc *__scivc_control;
/** Pointer holding the Capture IVC channel context, created during probe call*/
static struct tegra_capture_ivc *__scivc_capture;
/**
* @brief Worker thread to handle the asynchronous msgs on the IVC channel.
This will further calls callbacks registered by Channel drivers.
*
* @param[in] work kthread_work pointer
*/
static void tegra_capture_ivc_worker(
struct kthread_work *work);
/**
* @brief Implementation of IVC notify operation which gets called when we any
* new message on the bus for the channel. This signals the worker thread.
*
* @param[in] chan tegra_ivc_channel channel pointer
*/
static void tegra_capture_ivc_notify(
struct tegra_ivc_channel *chan);
/**
* @brief Implementation of probe operation which gets called during boot
*
* @param[in,out] chan tegra_ivc_channel channel pointer
*
* @returns 0 (success), neg. errno (failure)
*/
static int tegra_capture_ivc_probe(
struct tegra_ivc_channel *chan);
/**
* @brief Implementation of remove operation
*
* @param[in] chan tegra_ivc_channel channel pointer
*/
static void tegra_capture_ivc_remove(
struct tegra_ivc_channel *chan);
/**
* @brief Function to transmit the IVC msg after checking if it can write,
* using Tegra IVC core library APIs.
*
* @param[in] civc IVC channel on which the msg needs to be transmitted.
* @param[in] req IVC msg blob.
* @param[in] len IVC msg length.
*
* @returns 0 (success), neg. errno (failure)
*/
static int tegra_capture_ivc_tx(
struct tegra_capture_ivc *civc,
const void *req,
size_t len);
#endif /* __CAPTURE_IVC_PRIV_H__ */