NVIDIA: SAUCE: firmware: ivc: merge ivc_ext.c with upstream ivc.c

merging ivc_ext.c driver with upstream ivc.c driver
and stop building ivc_ext.ko driver in nvidia-oot driver.

http://nvbugs/4551265

Signed-off-by: Manish Bhardwaj <mbhardwaj@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Sumit Gupta <sumitg@nvidia.com>
Signed-off-by: Vishwaroop A <va@nvidia.com>
Acked-by: Noah Wager <noah.wager@canonical.com>
Acked-by: Jacob Martin <jacob.martin@canonical.com>
Signed-off-by: Noah Wager <noah.wager@canonical.com>
This commit is contained in:
Manish Bhardwaj
2024-08-21 06:52:00 +00:00
committed by Noah Wager
parent 72ac5288b5
commit b4275efbf8
2 changed files with 215 additions and 7 deletions
+125 -4
View File
@@ -1,7 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
*/
// SPDX-FileCopyrightText: Copyright (c) 2014-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <soc/tegra/ivc.h>
@@ -92,7 +90,7 @@ static inline void tegra_ivc_flush(struct tegra_ivc *ivc, dma_addr_t phys)
DMA_TO_DEVICE);
}
static inline bool tegra_ivc_empty(struct tegra_ivc *ivc, struct iosys_map *map)
bool tegra_ivc_empty(struct tegra_ivc *ivc, struct iosys_map *map)
{
/*
* This function performs multiple checks on the same values with
@@ -117,6 +115,7 @@ static inline bool tegra_ivc_empty(struct tegra_ivc *ivc, struct iosys_map *map)
return tx == rx;
}
EXPORT_SYMBOL(tegra_ivc_empty);
static inline bool tegra_ivc_full(struct tegra_ivc *ivc, struct iosys_map *map)
{
@@ -622,6 +621,128 @@ static int tegra_ivc_check_params(unsigned long rx, unsigned long tx,
return 0;
}
int tegra_ivc_can_read(struct tegra_ivc *ivc)
{
return tegra_ivc_check_read(ivc) == 0;
}
EXPORT_SYMBOL(tegra_ivc_can_read);
int tegra_ivc_can_write(struct tegra_ivc *ivc)
{
return tegra_ivc_check_write(ivc) == 0;
}
EXPORT_SYMBOL(tegra_ivc_can_write);
int tegra_ivc_read(struct tegra_ivc *ivc, void __user *usr_buf, void *buf, size_t max_read)
{
struct iosys_map map;
int err;
BUG_ON(buf && usr_buf);
/* get next frame to be read from IVC channel */
err = tegra_ivc_read_get_next_frame(ivc, &map);
if (err)
return err;
/* update the buffer with read data*/
if (buf) {
iosys_map_memcpy_from(buf, &map, 0, max_read);
} else if (usr_buf) {
// FIXME handle io address space
if (WARN_ON(map.is_iomem) || copy_to_user(usr_buf, map.vaddr, max_read))
return -EFAULT;
} else
BUG();
/* Advance to next read frame*/
if (tegra_ivc_read_advance(ivc) == 0)
return max_read;
else
return 0;
}
EXPORT_SYMBOL(tegra_ivc_read);
int tegra_ivc_read_peek(struct tegra_ivc *ivc, void __user *usr_buf,
void *buf, size_t offset, size_t size)
{
struct iosys_map map;
int err;
BUG_ON(buf && usr_buf);
/* get next frame to be read from IVC channel */
err = tegra_ivc_read_get_next_frame(ivc, &map);
if (err)
return err;
/* update the buffer with read data*/
if (buf) {
iosys_map_memcpy_from(buf, &map, offset, size);
} else if (usr_buf) {
// FIXME handle io address space
if (WARN_ON(map.is_iomem) || copy_to_user(usr_buf, map.vaddr + offset, size))
return -EFAULT;
} else
BUG();
return size;
}
EXPORT_SYMBOL(tegra_ivc_read_peek);
int tegra_ivc_write(struct tegra_ivc *ivc, const void __user *usr_buf, const void *buf, size_t size)
{
struct iosys_map map;
int err;
BUG_ON(buf && usr_buf);
/* get next frame to be written from IVC channel */
err = tegra_ivc_write_get_next_frame(ivc, &map);
if (err)
return err;
/* update the write frame with data buffer*/
if (buf) {
iosys_map_memcpy_to(&map, 0, buf, size);
} else if (usr_buf) {
// FIXME handle io address space
if (WARN_ON(map.is_iomem) || copy_from_user(map.vaddr, usr_buf, size))
return -EFAULT;
} else
BUG();
/* Advance to next write frame*/
if (tegra_ivc_write_advance(ivc) == 0)
return size;
else
return 0;
}
EXPORT_SYMBOL(tegra_ivc_write);
int tegra_ivc_channel_sync(struct tegra_ivc *ivc)
{
if ((ivc == NULL) || (ivc->num_frames == 0)) {
return -EINVAL;
} else {
u32 count;
count = tegra_ivc_header_read_field(&ivc->tx.map, tx.count);
ivc->tx.position = count % ivc->num_frames;
count = tegra_ivc_header_read_field(&ivc->rx.map, rx.count);
ivc->rx.position = count % ivc->num_frames;
}
return 0;
}
EXPORT_SYMBOL(tegra_ivc_channel_sync);
uint32_t tegra_ivc_frames_available(struct tegra_ivc *ivc, struct iosys_map *map)
{
return (ivc->num_frames - tegra_ivc_available(ivc, map));
}
EXPORT_SYMBOL(tegra_ivc_frames_available);
static inline void iosys_map_copy(struct iosys_map *dst, const struct iosys_map *src)
{
*dst = *src;
+90 -3
View File
@@ -1,7 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*/
/* SPDX-FileCopyrightText: Copyright (c) 2016-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#ifndef __TEGRA_IVC_H
#define __TEGRA_IVC_H
@@ -29,6 +27,95 @@ struct tegra_ivc {
size_t frame_size;
};
/**
* tegra_ivc_empty - Checks whether channel is empty or not
* @map pointer to iosys-map buffer for the IVC channel
*
* Checks whether channel is empty or not to read or write
*
* Returns true if channel is empty to read or write.
*/
bool tegra_ivc_empty(struct tegra_ivc *ivc, struct iosys_map *map);
/**
* tegra_ivc_channel_sync - Syncs the IVC channel across reboots.
* @ivc pointer of the IVC channel
*
* Syncs the IVC channel across reboots.
*
* Returns 0 on success.
*/
int tegra_ivc_channel_sync(struct tegra_ivc *ivc);
/**
* tegra_ivc_frames_available - Checks number of available frames.
* @map pointer to iosys-map buffer for the IVC channel
*
* Checks number of available frames.
*
* Returns integer value indicating number of available frames..
*/
uint32_t tegra_ivc_frames_available(struct tegra_ivc *ivc, struct iosys_map *map);
/**
* tegra_ivc_can_read - Checks whether we can read from ivc channel
* @ivc pointer of the IVC channel
*
* Checks whether we can read from ivc channel or not
*
* Returns 1 for success and 0 for failure.
*/
int tegra_ivc_can_read(struct tegra_ivc *ivc);
/**
* tegra_ivc_can_write - Checks whether we can write to ivc channel
* @ivc pointer of the IVC channel
*
* Checks whether we can write to ivc channel or not
*
* Returns 1 for success and 0 for failure.
*/
int tegra_ivc_can_write(struct tegra_ivc *ivc);
/**
* tegra_ivc_read - Reads frame form ivc channel
* @ivc pointer of the IVC channel
* @usr_buf user buffer to be updated with data
* @buf kernel buffer to be updated with data
* @max_read max data ro be read form ivc channel
*
* Reads frame form ivc channel
*
* Returns no. of bytes read from ivc channel else return error.
*/
int tegra_ivc_read(struct tegra_ivc *ivc, void __user *usr_buf, void *buf, size_t max_read);
/**
* tegra_ivc_read_peek - Reads frame form ivc channel
* @ivc pointer of the IVC channel
* @usr_buf user buffer to be updated with data
* @buf kernel buffer to be updated with data
* @offset kernel buffer to be updated with data from some offset
* @size max data ro be read form ivc channel
*
* Reads frame form ivc channel from some offset
*
* Returns no. of bytes read from ivc channel else return error.
*/
int tegra_ivc_read_peek(struct tegra_ivc *ivc, void __user *usr_buf, void *buf, size_t offset, size_t size);
/**
* tegra_ivc_write - Writes frame to ivc channel
* @ivc pointer of the IVC channel
* @usr_buf user buffer to e written to ivc channel
* @buf kernel buffer to be written to ivc channel
* @size Data size to be written to ivc channel
*
* Writes frame to ivc channel
*
* Returns no. of bytes written to ivc channel else return error.
*/
int tegra_ivc_write(struct tegra_ivc *ivc, const void __user *usr_buf, const void *buf, size_t size);
/**
* tegra_ivc_read_get_next_frame - Peek at the next frame to receive
* @ivc pointer of the IVC channel