113 lines
2.4 KiB
C
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;
|
|
}
|
|
|