Re: [RFC, v3 9/9] media: platform: Add Mediatek ISP P1 shared memory device

Jungo Lin
2019-07-26T11:59:46Z

Hi Robin:

On Fri, 2019-07-26 at 12:04 +0100, Robin Murphy wrote:
> On 26/07/2019 08:42, Tomasz Figa wrote:
> > On Fri, Jul 26, 2019 at 4:41 PM Christoph Hellwig <hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org> wrote:
> >>
> >> On Fri, Jul 26, 2019 at 02:15:14PM +0900, Tomasz Figa wrote:
> >>> Could you try dma_get_sgtable() with the SCP struct device and then
> >>> dma_map_sg() with the P1 struct device?
> >>
> >> Please don't do that. dma_get_sgtable is a pretty broken API (see
> >> the common near the arm implementation) and we should not add more
> >> users of it. If you want a piece of memory that can be mapped to
> >> multiple devices allocate it using alloc_pages and then just map
> >> it to each device.
> >
> > Thanks for taking a look at this thread.
> >
> > Unfortunately that wouldn't work. We have a specific reserved memory
> > pool that is the only memory area accessible to one of the devices.
> > Any idea how to handle this?
>
> If it's reserved in the sense of being outside struct-page-backed
> "kernel memory", then provided you have a consistent CPU physical
> address it might be reasonable for other devices to access it via
> dma_map_resource().
>
> Robin.

Thank you for your suggestion.

After revising to use dma_map_resource(), it is worked. Below is the
current implementation. Pleas kindly help us to check if there is any
misunderstanding.

#define MTK_ISP_COMPOSER_MEM_SIZE 0x200000

/*
* Allocate coherent reserved memory for SCP firmware usage.
* The size of SCP composer's memory is fixed to 0x200000
* for the requirement of firmware.
*/
ptr = dma_alloc_coherent(p1_dev->cam_dev.smem_dev,
MTK_ISP_COMPOSER_MEM_SIZE, &addr, GFP_KERNEL);
if (!ptr) {
dev_err(dev, "failed to allocate compose memory\n");
return -ENOMEM;
}
p1_dev->composer_scp_addr = addr;
p1_dev->composer_virt_addr = ptr;
dev_dbg(dev, "scp addr:%pad va:%pK\n", &addr, ptr);

/*
* This reserved memory is also be used by ISP P1 HW.
* Need to get iova address for ISP P1 DMA.
*/
addr = dma_map_resource(dev, addr, MTK_ISP_COMPOSER_MEM_SIZE,
DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC);
if (dma_mapping_error(dev, addr)) {
dev_err(dev, "Failed to map scp iova\n");
ret = -ENOMEM;
goto fail_free_mem;
}
p1_dev->composer_iova = addr;
dev_info(dev, "scp iova addr:%pad\n", &addr);

Moreover, appropriate Tomasz & Christoph's help on this issue.

Best regards,

Jungo