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:
committed by
Noah Wager
parent
72ac5288b5
commit
b4275efbf8
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user