// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2013--2024 Intel Corporation
 */

#include <linux/cacheflush.h>
#include <linux/dma-mapping.h>
#include <linux/iova.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/types.h>

#include "ipu6.h"
#include "ipu6-bus.h"
#include "ipu6-dma.h"
#include "ipu6-mmu.h"

struct vm_info {
	struct list_head list;
	struct page **pages;
	dma_addr_t ipu6_iova;
	void *vaddr;
	unsigned long size;
};

static struct vm_info *get_vm_info(struct ipu6_mmu *mmu, dma_addr_t iova)
{
	struct vm_info *info, *save;

	list_for_each_entry_safe(info, save, &mmu->vma_list, list) {
		if (iova >= info->ipu6_iova &&
		    iova < (info->ipu6_iova + info->size))
			return info;
	}

	return NULL;
}

static void __dma_clear_buffer(struct page *page, size_t size,
			       unsigned long attrs)
{
	void *ptr;

	if (!page)
		return;
	/*
	 * Ensure that the allocated pages are zeroed, and that any data
	 * lurking in the kernel direct-mapped region is invalidated.
	 */
	ptr = page_address(page);
	memset(ptr, 0, size);
	if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
		clflush_cache_range(ptr, size);
}

static struct page **__dma_alloc_buffer(struct device *dev, size_t size,
					gfp_t gfp, unsigned long attrs)
{
	int count = PHYS_PFN(size);
	int array_size = count * sizeof(struct page *);
	struct page **pages;
	int i = 0;

	pages = kvzalloc(array_size, GFP_KERNEL);
	if (!pages)
		return NULL;

	gfp |= __GFP_NOWARN;

	while (count) {
		int j, order = __fls(count);

		pages[i] = alloc_pages(gfp, order);
		while (!pages[i] && order)
			pages[i] = alloc_pages(gfp, --order);
		if (!pages[i])
			goto error;

		if (order) {
			split_page(pages[i], order);
			j = 1 << order;
			while (j--)
				pages[i + j] = pages[i] + j;
		}

		__dma_clear_buffer(pages[i], PAGE_SIZE << order, attrs);
		i += 1 << order;
		count -= 1 << order;
	}

	return pages;
error:
	while (i--)
		if (pages[i])
			__free_pages(pages[i], 0);
	kvfree(pages);
	return NULL;
}

static void __dma_free_buffer(struct device *dev, struct page **pages,
			      size_t size, unsigned long attrs)
{
	int count = PHYS_PFN(size);
	unsigned int i;

	for (i = 0; i < count && pages[i]; i++) {
		__dma_clear_buffer(pages[i], PAGE_SIZE, attrs);
		__free_pages(pages[i], 0);
	}

	kvfree(pages);
}

static void ipu6_dma_sync_single_for_cpu(struct device *dev,
					 dma_addr_t dma_handle,
					 size_t size,
					 enum dma_data_direction dir)
{
	void *vaddr;
	u32 offset;
	struct vm_info *info;
	struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;

	info = get_vm_info(mmu, dma_handle);
	if (WARN_ON(!info))
		return;

	offset = dma_handle - info->ipu6_iova;
	if (WARN_ON(size > (info->size - offset)))
		return;

	vaddr = info->vaddr + offset;
	clflush_cache_range(vaddr, size);
}

static void ipu6_dma_sync_sg_for_cpu(struct device *dev,
				     struct scatterlist *sglist,
				     int nents, enum dma_data_direction dir)
{
	struct scatterlist *sg;
	int i;

	for_each_sg(sglist, sg, nents, i)
		clflush_cache_range(page_to_virt(sg_page(sg)), sg->length);
}

static void *ipu6_dma_alloc(struct device *dev, size_t size,
			    dma_addr_t *dma_handle, gfp_t gfp,
			    unsigned long attrs)
{
	struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
	struct pci_dev *pdev = to_ipu6_bus_device(dev)->isp->pdev;
	dma_addr_t pci_dma_addr, ipu6_iova;
	struct vm_info *info;
	unsigned long count;
	struct page **pages;
	struct iova *iova;
	unsigned int i;
	int ret;

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return NULL;

	size = PAGE_ALIGN(size);
	count = PHYS_PFN(size);

	iova = alloc_iova(&mmu->dmap->iovad, count,
			  PHYS_PFN(dma_get_mask(dev)), 0);
	if (!iova)
		goto out_kfree;

	pages = __dma_alloc_buffer(dev, size, gfp, attrs);
	if (!pages)
		goto out_free_iova;

	dev_dbg(dev, "dma_alloc: size %zu iova low pfn %lu, high pfn %lu\n",
		size, iova->pfn_lo, iova->pfn_hi);
	for (i = 0; iova->pfn_lo + i <= iova->pfn_hi; i++) {
		pci_dma_addr = dma_map_page_attrs(&pdev->dev, pages[i], 0,
						  PAGE_SIZE, DMA_BIDIRECTIONAL,
						  attrs);
		dev_dbg(dev, "dma_alloc: mapped pci_dma_addr %pad\n",
			&pci_dma_addr);
		if (dma_mapping_error(&pdev->dev, pci_dma_addr)) {
			dev_err(dev, "pci_dma_mapping for page[%d] failed", i);
			goto out_unmap;
		}

		ret = ipu6_mmu_map(mmu->dmap->mmu_info,
				   PFN_PHYS(iova->pfn_lo + i), pci_dma_addr,
				   PAGE_SIZE);
		if (ret) {
			dev_err(dev, "ipu6_mmu_map for pci_dma[%d] %pad failed",
				i, &pci_dma_addr);
			dma_unmap_page_attrs(&pdev->dev, pci_dma_addr,
					     PAGE_SIZE, DMA_BIDIRECTIONAL,
					     attrs);
			goto out_unmap;
		}
	}

	info->vaddr = vmap(pages, count, VM_USERMAP, PAGE_KERNEL);
	if (!info->vaddr)
		goto out_unmap;

	*dma_handle = PFN_PHYS(iova->pfn_lo);

	info->pages = pages;
	info->ipu6_iova = *dma_handle;
	info->size = size;
	list_add(&info->list, &mmu->vma_list);

	return info->vaddr;

out_unmap:
	while (i--) {
		ipu6_iova = PFN_PHYS(iova->pfn_lo + i);
		pci_dma_addr = ipu6_mmu_iova_to_phys(mmu->dmap->mmu_info,
						     ipu6_iova);
		dma_unmap_page_attrs(&pdev->dev, pci_dma_addr, PAGE_SIZE,
				     DMA_BIDIRECTIONAL, attrs);

		ipu6_mmu_unmap(mmu->dmap->mmu_info, ipu6_iova, PAGE_SIZE);
	}

	__dma_free_buffer(dev, pages, size, attrs);

out_free_iova:
	__free_iova(&mmu->dmap->iovad, iova);
out_kfree:
	kfree(info);

	return NULL;
}

static void ipu6_dma_free(struct device *dev, size_t size, void *vaddr,
			  dma_addr_t dma_handle,
			  unsigned long attrs)
{
	struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
	struct pci_dev *pdev = to_ipu6_bus_device(dev)->isp->pdev;
	struct iova *iova = find_iova(&mmu->dmap->iovad, PHYS_PFN(dma_handle));
	dma_addr_t pci_dma_addr, ipu6_iova;
	struct vm_info *info;
	struct page **pages;
	unsigned int i;

	if (WARN_ON(!iova))
		return;

	info = get_vm_info(mmu, dma_handle);
	if (WARN_ON(!info))
		return;

	if (WARN_ON(!info->vaddr))
		return;

	if (WARN_ON(!info->pages))
		return;

	list_del(&info->list);

	size = PAGE_ALIGN(size);

	pages = info->pages;

	vunmap(vaddr);

	for (i = 0; i < PHYS_PFN(size); i++) {
		ipu6_iova = PFN_PHYS(iova->pfn_lo + i);
		pci_dma_addr = ipu6_mmu_iova_to_phys(mmu->dmap->mmu_info,
						     ipu6_iova);
		dma_unmap_page_attrs(&pdev->dev, pci_dma_addr, PAGE_SIZE,
				     DMA_BIDIRECTIONAL, attrs);
	}

	ipu6_mmu_unmap(mmu->dmap->mmu_info, PFN_PHYS(iova->pfn_lo),
		       PFN_PHYS(iova_size(iova)));

	__dma_free_buffer(dev, pages, size, attrs);

	mmu->tlb_invalidate(mmu);

	__free_iova(&mmu->dmap->iovad, iova);

	kfree(info);
}

static int ipu6_dma_mmap(struct device *dev, struct vm_area_struct *vma,
			 void *addr, dma_addr_t iova, size_t size,
			 unsigned long attrs)
{
	struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
	size_t count = PHYS_PFN(PAGE_ALIGN(size));
	struct vm_info *info;
	size_t i;
	int ret;

	info = get_vm_info(mmu, iova);
	if (!info)
		return -EFAULT;

	if (!info->vaddr)
		return -EFAULT;

	if (vma->vm_start & ~PAGE_MASK)
		return -EINVAL;

	if (size > info->size)
		return -EFAULT;

	for (i = 0; i < count; i++) {
		ret = vm_insert_page(vma, vma->vm_start + PFN_PHYS(i),
				     info->pages[i]);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static void ipu6_dma_unmap_sg(struct device *dev,
			      struct scatterlist *sglist,
			      int nents, enum dma_data_direction dir,
			      unsigned long attrs)
{
	struct pci_dev *pdev = to_ipu6_bus_device(dev)->isp->pdev;
	struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
	struct iova *iova = find_iova(&mmu->dmap->iovad,
				      PHYS_PFN(sg_dma_address(sglist)));
	int i, npages, count;
	struct scatterlist *sg;
	dma_addr_t pci_dma_addr;

	if (!nents)
		return;

	if (WARN_ON(!iova))
		return;

	if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
		ipu6_dma_sync_sg_for_cpu(dev, sglist, nents, DMA_BIDIRECTIONAL);

	/* get the nents as orig_nents given by caller */
	count = 0;
	npages = iova_size(iova);
	for_each_sg(sglist, sg, nents, i) {
		if (sg_dma_len(sg) == 0 ||
		    sg_dma_address(sg) == DMA_MAPPING_ERROR)
			break;

		npages -= PHYS_PFN(PAGE_ALIGN(sg_dma_len(sg)));
		count++;
		if (npages <= 0)
			break;
	}

	/*
	 * Before IPU6 mmu unmap, return the pci dma address back to sg
	 * assume the nents is less than orig_nents as the least granule
	 * is 1 SZ_4K page
	 */
	dev_dbg(dev, "trying to unmap concatenated %u ents\n", count);
	for_each_sg(sglist, sg, count, i) {
		dev_dbg(dev, "ipu unmap sg[%d] %pad\n", i, &sg_dma_address(sg));
		pci_dma_addr = ipu6_mmu_iova_to_phys(mmu->dmap->mmu_info,
						     sg_dma_address(sg));
		dev_dbg(dev, "return pci_dma_addr %pad back to sg[%d]\n",
			&pci_dma_addr, i);
		sg_dma_address(sg) = pci_dma_addr;
	}

	dev_dbg(dev, "ipu6_mmu_unmap low pfn %lu high pfn %lu\n",
		iova->pfn_lo, iova->pfn_hi);
	ipu6_mmu_unmap(mmu->dmap->mmu_info, PFN_PHYS(iova->pfn_lo),
		       PFN_PHYS(iova_size(iova)));

	mmu->tlb_invalidate(mmu);

	dma_unmap_sg_attrs(&pdev->dev, sglist, nents, dir, attrs);

	__free_iova(&mmu->dmap->iovad, iova);
}

static int ipu6_dma_map_sg(struct device *dev, struct scatterlist *sglist,
			   int nents, enum dma_data_direction dir,
			   unsigned long attrs)
{
	struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
	struct pci_dev *pdev = to_ipu6_bus_device(dev)->isp->pdev;
	struct scatterlist *sg;
	struct iova *iova;
	size_t npages = 0;
	unsigned long iova_addr;
	int i, count;

	for_each_sg(sglist, sg, nents, i) {
		if (sg->offset) {
			dev_err(dev, "Unsupported non-zero sg[%d].offset %x\n",
				i, sg->offset);
			return -EFAULT;
		}
	}

	dev_dbg(dev, "pci_dma_map_sg trying to map %d ents\n", nents);
	count  = dma_map_sg_attrs(&pdev->dev, sglist, nents, dir, attrs);
	if (count <= 0) {
		dev_err(dev, "pci_dma_map_sg %d ents failed\n", nents);
		return 0;
	}

	dev_dbg(dev, "pci_dma_map_sg %d ents mapped\n", count);

	for_each_sg(sglist, sg, count, i)
		npages += PHYS_PFN(PAGE_ALIGN(sg_dma_len(sg)));

	iova = alloc_iova(&mmu->dmap->iovad, npages,
			  PHYS_PFN(dma_get_mask(dev)), 0);
	if (!iova)
		return 0;

	dev_dbg(dev, "dmamap: iova low pfn %lu, high pfn %lu\n", iova->pfn_lo,
		iova->pfn_hi);

	iova_addr = iova->pfn_lo;
	for_each_sg(sglist, sg, count, i) {
		int ret;

		dev_dbg(dev, "mapping entry %d: iova 0x%llx phy %pad size %d\n",
			i, PFN_PHYS(iova_addr), &sg_dma_address(sg),
			sg_dma_len(sg));

		ret = ipu6_mmu_map(mmu->dmap->mmu_info, PFN_PHYS(iova_addr),
				   sg_dma_address(sg),
				   PAGE_ALIGN(sg_dma_len(sg)));
		if (ret)
			goto out_fail;

		sg_dma_address(sg) = PFN_PHYS(iova_addr);

		iova_addr += PHYS_PFN(PAGE_ALIGN(sg_dma_len(sg)));
	}

	if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
		ipu6_dma_sync_sg_for_cpu(dev, sglist, nents, DMA_BIDIRECTIONAL);

	return count;

out_fail:
	ipu6_dma_unmap_sg(dev, sglist, i, dir, attrs);

	return 0;
}

/*
 * Create scatter-list for the already allocated DMA buffer
 */
static int ipu6_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
				void *cpu_addr, dma_addr_t handle, size_t size,
				unsigned long attrs)
{
	struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
	struct vm_info *info;
	int n_pages;
	int ret = 0;

	info = get_vm_info(mmu, handle);
	if (!info)
		return -EFAULT;

	if (!info->vaddr)
		return -EFAULT;

	if (WARN_ON(!info->pages))
		return -ENOMEM;

	n_pages = PHYS_PFN(PAGE_ALIGN(size));

	ret = sg_alloc_table_from_pages(sgt, info->pages, n_pages, 0, size,
					GFP_KERNEL);
	if (ret)
		dev_warn(dev, "IPU6 get sgt table failed\n");

	return ret;
}

const struct dma_map_ops ipu6_dma_ops = {
	.alloc = ipu6_dma_alloc,
	.free = ipu6_dma_free,
	.mmap = ipu6_dma_mmap,
	.map_sg = ipu6_dma_map_sg,
	.unmap_sg = ipu6_dma_unmap_sg,
	.sync_single_for_cpu = ipu6_dma_sync_single_for_cpu,
	.sync_single_for_device = ipu6_dma_sync_single_for_cpu,
	.sync_sg_for_cpu = ipu6_dma_sync_sg_for_cpu,
	.sync_sg_for_device = ipu6_dma_sync_sg_for_cpu,
	.get_sgtable = ipu6_dma_get_sgtable,
};
