Hi, I encountered some issues. My requirement is to write a custom UI image into the memory of NVBUF_MEM_SURFACE_ARRAY
and then pass this address to the FPGA for DMA transfer. However, I am unable to obtain the physical address of the NVBUF_MEM_SURFACE_ARRAY
memory. I used to do this on the IMX8 development board, but now I need to switch platforms. How should I proceed? Thank you very much.
Error log:
[ 224.877369] Failed to attachement -12
[ 224.882494] 12
[ 224.882504] got dmabuf 00000000e815829f nvmap_dmabuf
[ 224.882575] Failed to attachement -12
[ 224.887076] 14
[ 224.887085] got dmabuf 000000004402ac59 nvmap_dmabuf
[ 224.887156] Failed to attachement -12
[ 224.891731] 16
[ 224.891740] got dmabuf 00000000e9ed1f60 nvmap_dmabuf
[ 224.891819] Failed to attachement -12
[ 224.896304] 18
[ 224.896313] got dmabuf 00000000cf2f2a57 nvmap_dmabuf
[ 224.896378] Failed to attachement -12
C++:
void NVBuffAllocTest::TestAlloc(int iWidth, int iHeight)
{
int testfd = open(“/dev/test”, O_RDWR);
if (testfd < 0)
{
std::cout<<“open /dev/test fail:”<<strerror(errno)<<std::endl;
return;
}
static int alloccnt = 0;
while (alloccnt < 10)
{
alloccnt++;
NvBufSurf::NvCommonAllocateParams allocParams;
allocParams.width = iWidth;
allocParams.height = iHeight;
// allocParams.layout = NVBUF_LAYOUT_BLOCK_LINEAR;
allocParams.layout = NVBUF_LAYOUT_PITCH;
allocParams.memType = NVBUF_MEM_SURFACE_ARRAY;
allocParams.colorFormat = NVBUF_COLOR_FORMAT_ARGB;
allocParams.memtag = NvBufSurfaceTag_VIDEO_ENC;
// allocParams.memtag = NvBufSurfaceTag_JPEG;
int iDmaBufFd = -1;
int iRet = NvBufSurf::NvAllocate(&allocParams, 1, &iDmaBufFd);
if(iRet)
{
std::cout<<"Error in creating the input buffer."<<std::endl;
if (testfd > 0)
{
close(testfd);
testfd = -1;
}
return;
}
else
{
std::cout<<"the fd of the input buffer is:"<<iDmaBufFd<<std::endl;
}
NvBufSurface nvbuf_surf1;
nvbuf_surf1.isContiguous = true;
NvBufSurface *nvbuf_surf = &nvbuf_surf1;
NvBufSurfaceAllocateParams input_params = {{0}};
input_params.params.width = iWidth;
input_params.params.height = iHeight;
input_params.params.isContiguous = true;
input_params.params.memType = NVBUF_MEM_SURFACE_ARRAY;
input_params.params.layout = NVBUF_LAYOUT_PITCH;
input_params.params.colorFormat = NVBUF_COLOR_FORMAT_ARGB;
input_params.memtag = NvBufSurfaceTag_VIDEO_CONVERT;
iRet = NvBufSurfaceAllocate(&nvbuf_surf, 1, &input_params);
//iRet = NvBufSurfaceFromFd(iDmaBufFd, (void**)(&nvbuf_surf));
std::cout<<"the buff batchsize:"<<nvbuf_surf->batchSize<<",isContiguous:"<<nvbuf_surf->isContiguous<<std::endl;
NvBufSurfaceParams surfacePara = nvbuf_surf->surfaceList[0];
std::cout<<"dataSize:"<<surfacePara.dataSize<<" "<<surfacePara.paramex<<std::endl;
NvBufSurfaceParamsEx exSurfacePara = surfacePara.paramex[0];
std::cout<<"phy addr:"<<exSurfacePara.planeParamsex.physicaladdress[0]<<std::endl;
int buf = iDmaBufFd;
write(testfd, &buf, sizeof(int));
}
if (testfd > 0)
{
close(testfd);
testfd = -1;
}
}
driver:
static ssize_t demo_write(struct file *fp, const char __user *buf, size_t size, loff_t *pos)
{
int rc;
int iTestFd = -1;
rc = copy_from_user(&iTestFd, buf, sizeof(int));
if(rc < 0) {
return -EFAULT;
pr_err("copy_from_user failed!");
}
printk(KERN_DEBUG"%d\n", iTestFd);
importer_read(iTestFd);
return size;
}
static int importer_read(int dmabuf_fd)
{
struct dma_buf_attachment *attachment;
struct sg_table *sgt;
struct scatterlist *sg;
unsigned int si;
struct device *dev;
struct dma_buf *dmabuf;
int err;
dmabuf = dma_buf_get(dmabuf_fd); //share bug between sub devices
if (IS_ERR(dmabuf)) {
err = PTR_ERR(dmabuf);
printk(KERN_DEBUG"got dmabuf fail %d\n", err);
goto err_buf_get;
}
printk(KERN_DEBUG"got dmabuf %p %s\n", dmabuf, dmabuf->exp_name);
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
dev_set_name(dev, "try_get_sg");
attachment = dma_buf_attach(dmabuf, dev);
if (IS_ERR(attachment)) {
err = PTR_ERR(attachment);
printk(KERN_DEBUG"Failed to attach %d\n", err);
goto err_buf_attach;
}
sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
if (IS_ERR(sgt)) {
err = PTR_ERR(sgt);
printk(KERN_DEBUG"Failed to attachement %d\n", err);
goto err_buf_attachment;
}
printk(KERN_DEBUG"got sg->nents %d\n", sgt->nents);
printk(KERN_DEBUG"got sg->orig_nents %d dma_buf->size=%ld/%lx\n",
sgt->orig_nents, dmabuf->size, dmabuf->size);
for_each_sg(sgt->sgl, sg, sgt->orig_nents, si) {
dma_addr_t sg_addr = sg_dma_address(sg);
u32 sg_len = sg_dma_len(sg);
printk(KERN_DEBUG"sgt[%d] sg_addr = 0x%lx, sg_len = %d/%#x sg_phys= %#llx\n",
si,
(unsigned long)sg_addr, sg_len, sg_len,
(unsigned long long)sg_phys(sg));
}
dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
err_buf_attachment:
dma_buf_detach(dmabuf, attachment);
err_buf_attach:
dma_buf_put(dmabuf);
err_buf_get:
kfree(dev);
return err;
}