kernel-brax3-ubuntu-touch/drivers/misc/mediatek/vdec_fmt/vdec_fmt_dmabuf.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

113 lines
2.4 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#include "vdec_fmt_dmabuf.h"
#include "vdec_fmt_utils.h"
int fmt_dmabuf_get_iova(struct dma_buf *dbuf, u64 *iova,
struct device *dev, struct dma_buf_attachment **attach, struct sg_table **sgt,
bool cache_sync)
{
*attach = dma_buf_attach(dbuf, dev);
if (IS_ERR(*attach)) {
fmt_debug(0, "attach fail, return\n");
*attach = NULL;
return -1;
}
if (!cache_sync)
(*attach)->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
*sgt = dma_buf_map_attachment(*attach, DMA_BIDIRECTIONAL);
if (IS_ERR(*sgt)) {
fmt_debug(0, "map failed, detach and return\n");
dma_buf_detach(dbuf, *attach);
*sgt = NULL;
return -1;
}
*iova = sg_dma_address((*sgt)->sgl);
fmt_debug(1, "dbuf %p attach %p sgt %p iova 0x%llx\n", dbuf, *attach, *sgt, *iova);
return 0;
}
void fmt_dmabuf_free_iova(struct dma_buf *dbuf,
struct dma_buf_attachment *attach, struct sg_table *sgt)
{
if (attach == NULL || sgt == NULL) {
fmt_debug(0, "attach or sgt null, not need to free iova");
return;
}
fmt_debug(1, "dbuf %p attach %p sgt %p\n", dbuf, attach, sgt);
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
dma_buf_detach(dbuf, attach);
}
struct dma_buf *fmt_dmabuf_get(int fd)
{
struct dma_buf *dbuf;
dbuf = dma_buf_get(fd);
if (IS_ERR(dbuf)) {
fmt_debug(0, "dma_buf_get fail");
return NULL;
}
fmt_debug(1, "dbuf %p fd %d\n", dbuf, fd);
return dbuf;
}
void fmt_dmabuf_put(struct dma_buf *dbuf)
{
if (!dbuf) {
fmt_debug(0, "dma_buf null, no need to put.");
return;
}
fmt_debug(1, "dbuf %p\n", dbuf);
dma_buf_put(dbuf);
}
u64 fmt_translate_fd(u64 fd, u32 offset, struct dmabufmap map[], struct device *dev,
struct dma_buf **dbuf, struct dma_buf_attachment **attach, struct sg_table **sgt,
bool cache_sync)
{
int i, ret;
u64 iova = 0;
if (fd == 0)
return 0;
for (i = 0; i < FMT_FD_RESERVE; i++) {
if (fd == map[i].fd) {
fmt_debug(3, "quick search iova 0x%llx",
map[i].iova + offset);
return map[i].iova + offset;
}
}
*dbuf = fmt_dmabuf_get(fd);
ret = fmt_dmabuf_get_iova(*dbuf, &iova, dev, attach, sgt, cache_sync);
if (ret != 0) {
fmt_debug(0, "fd: %lu iova get failed", fd);
return 0;
}
for (i = 0; i < FMT_FD_RESERVE; i++) {
if (map[i].fd == -1) {
map[i].fd = fd;
map[i].iova = iova;
break;
}
}
iova += offset;
fmt_debug(1, "iova 0x%llx", iova);
return iova;
}