// SPDX-License-Identifier: GPL-2.0-only
/*
 *
 * Copyright (C) 2013 Freescale Semiconductor, Inc.
 * Author: Varun Sethi <varun.sethi@freescale.com>
 */

#define pr_fmt(fmt)    "fsl-pamu-domain: %s: " fmt, __func__

#include "fsl_pamu_domain.h"

#include <linux/platform_device.h>
#include <sysdev/fsl_pci.h>

/*
 * Global spinlock that needs to be held while
 * configuring PAMU.
 */
static DEFINE_SPINLOCK(iommu_lock);

static struct kmem_cache *fsl_pamu_domain_cache;
static struct kmem_cache *iommu_devinfo_cache;
static DEFINE_SPINLOCK(device_domain_lock);

struct iommu_device pamu_iommu;	/* IOMMU core code handle */

static struct fsl_dma_domain *to_fsl_dma_domain(struct iommu_domain *dom)
{
	return container_of(dom, struct fsl_dma_domain, iommu_domain);
}

static int __init iommu_init_mempool(void)
{
	fsl_pamu_domain_cache = kmem_cache_create("fsl_pamu_domain",
						  sizeof(struct fsl_dma_domain),
						  0,
						  SLAB_HWCACHE_ALIGN,
						  NULL);
	if (!fsl_pamu_domain_cache) {
		pr_debug("Couldn't create fsl iommu_domain cache\n");
		return -ENOMEM;
	}

	iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
						sizeof(struct device_domain_info),
						0,
						SLAB_HWCACHE_ALIGN,
						NULL);
	if (!iommu_devinfo_cache) {
		pr_debug("Couldn't create devinfo cache\n");
		kmem_cache_destroy(fsl_pamu_domain_cache);
		return -ENOMEM;
	}

	return 0;
}

static int update_liodn_stash(int liodn, struct fsl_dma_domain *dma_domain,
			      u32 val)
{
	int ret = 0;
	unsigned long flags;

	spin_lock_irqsave(&iommu_lock, flags);
	ret = pamu_update_paace_stash(liodn, val);
	if (ret) {
		pr_debug("Failed to update SPAACE for liodn %d\n ", liodn);
		spin_unlock_irqrestore(&iommu_lock, flags);
		return ret;
	}

	spin_unlock_irqrestore(&iommu_lock, flags);

	return ret;
}

/* Set the geometry parameters for a LIODN */
static int pamu_set_liodn(struct fsl_dma_domain *dma_domain, struct device *dev,
			  int liodn)
{
	u32 omi_index = ~(u32)0;
	unsigned long flags;
	int ret;

	/*
	 * Configure the omi_index at the geometry setup time.
	 * This is a static value which depends on the type of
	 * device and would not change thereafter.
	 */
	get_ome_index(&omi_index, dev);

	spin_lock_irqsave(&iommu_lock, flags);
	ret = pamu_disable_liodn(liodn);
	if (ret)
		goto out_unlock;
	ret = pamu_config_ppaace(liodn, omi_index, dma_domain->stash_id, 0);
	if (ret)
		goto out_unlock;
	ret = pamu_config_ppaace(liodn, ~(u32)0, dma_domain->stash_id,
				 PAACE_AP_PERMS_QUERY | PAACE_AP_PERMS_UPDATE);
out_unlock:
	spin_unlock_irqrestore(&iommu_lock, flags);
	if (ret) {
		pr_debug("PAACE configuration failed for liodn %d\n",
			 liodn);
	}
	return ret;
}

static void remove_device_ref(struct device_domain_info *info)
{
	unsigned long flags;

	list_del(&info->link);
	spin_lock_irqsave(&iommu_lock, flags);
	pamu_disable_liodn(info->liodn);
	spin_unlock_irqrestore(&iommu_lock, flags);
	spin_lock_irqsave(&device_domain_lock, flags);
	dev_iommu_priv_set(info->dev, NULL);
	kmem_cache_free(iommu_devinfo_cache, info);
	spin_unlock_irqrestore(&device_domain_lock, flags);
}

static void detach_device(struct device *dev, struct fsl_dma_domain *dma_domain)
{
	struct device_domain_info *info, *tmp;
	unsigned long flags;

	spin_lock_irqsave(&dma_domain->domain_lock, flags);
	/* Remove the device from the domain device list */
	list_for_each_entry_safe(info, tmp, &dma_domain->devices, link) {
		if (!dev || (info->dev == dev))
			remove_device_ref(info);
	}
	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
}

static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct device *dev)
{
	struct device_domain_info *info, *old_domain_info;
	unsigned long flags;

	spin_lock_irqsave(&device_domain_lock, flags);
	/*
	 * Check here if the device is already attached to domain or not.
	 * If the device is already attached to a domain detach it.
	 */
	old_domain_info = dev_iommu_priv_get(dev);
	if (old_domain_info && old_domain_info->domain != dma_domain) {
		spin_unlock_irqrestore(&device_domain_lock, flags);
		detach_device(dev, old_domain_info->domain);
		spin_lock_irqsave(&device_domain_lock, flags);
	}

	info = kmem_cache_zalloc(iommu_devinfo_cache, GFP_ATOMIC);

	info->dev = dev;
	info->liodn = liodn;
	info->domain = dma_domain;

	list_add(&info->link, &dma_domain->devices);
	/*
	 * In case of devices with multiple LIODNs just store
	 * the info for the first LIODN as all
	 * LIODNs share the same domain
	 */
	if (!dev_iommu_priv_get(dev))
		dev_iommu_priv_set(dev, info);
	spin_unlock_irqrestore(&device_domain_lock, flags);
}

static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain,
					 dma_addr_t iova)
{
	if (iova < domain->geometry.aperture_start ||
	    iova > domain->geometry.aperture_end)
		return 0;
	return iova;
}

static bool fsl_pamu_capable(struct device *dev, enum iommu_cap cap)
{
	return cap == IOMMU_CAP_CACHE_COHERENCY;
}

static void fsl_pamu_domain_free(struct iommu_domain *domain)
{
	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);

	/* remove all the devices from the device list */
	detach_device(NULL, dma_domain);
	kmem_cache_free(fsl_pamu_domain_cache, dma_domain);
}

static struct iommu_domain *fsl_pamu_domain_alloc(unsigned type)
{
	struct fsl_dma_domain *dma_domain;

	/*
	 * FIXME: This isn't creating an unmanaged domain since the
	 * default_domain_ops do not have any map/unmap function it doesn't meet
	 * the requirements for __IOMMU_DOMAIN_PAGING. The only purpose seems to
	 * allow drivers/soc/fsl/qbman/qman_portal.c to do
	 * fsl_pamu_configure_l1_stash()
	 */
	if (type != IOMMU_DOMAIN_UNMANAGED)
		return NULL;

	dma_domain = kmem_cache_zalloc(fsl_pamu_domain_cache, GFP_KERNEL);
	if (!dma_domain)
		return NULL;

	dma_domain->stash_id = ~(u32)0;
	INIT_LIST_HEAD(&dma_domain->devices);
	spin_lock_init(&dma_domain->domain_lock);

	/* default geometry 64 GB i.e. maximum system address */
	dma_domain->iommu_domain. geometry.aperture_start = 0;
	dma_domain->iommu_domain.geometry.aperture_end = (1ULL << 36) - 1;
	dma_domain->iommu_domain.geometry.force_aperture = true;

	return &dma_domain->iommu_domain;
}

/* Update stash destination for all LIODNs associated with the domain */
static int update_domain_stash(struct fsl_dma_domain *dma_domain, u32 val)
{
	struct device_domain_info *info;
	int ret = 0;

	list_for_each_entry(info, &dma_domain->devices, link) {
		ret = update_liodn_stash(info->liodn, dma_domain, val);
		if (ret)
			break;
	}

	return ret;
}

static int fsl_pamu_attach_device(struct iommu_domain *domain,
				  struct device *dev)
{
	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
	unsigned long flags;
	int len, ret = 0, i;
	const u32 *liodn;
	struct pci_dev *pdev = NULL;
	struct pci_controller *pci_ctl;

	/*
	 * Use LIODN of the PCI controller while attaching a
	 * PCI device.
	 */
	if (dev_is_pci(dev)) {
		pdev = to_pci_dev(dev);
		pci_ctl = pci_bus_to_host(pdev->bus);
		/*
		 * make dev point to pci controller device
		 * so we can get the LIODN programmed by
		 * u-boot.
		 */
		dev = pci_ctl->parent;
	}

	liodn = of_get_property(dev->of_node, "fsl,liodn", &len);
	if (!liodn) {
		pr_debug("missing fsl,liodn property at %pOF\n", dev->of_node);
		return -ENODEV;
	}

	spin_lock_irqsave(&dma_domain->domain_lock, flags);
	for (i = 0; i < len / sizeof(u32); i++) {
		/* Ensure that LIODN value is valid */
		if (liodn[i] >= PAACE_NUMBER_ENTRIES) {
			pr_debug("Invalid liodn %d, attach device failed for %pOF\n",
				 liodn[i], dev->of_node);
			ret = -ENODEV;
			break;
		}

		attach_device(dma_domain, liodn[i], dev);
		ret = pamu_set_liodn(dma_domain, dev, liodn[i]);
		if (ret)
			break;
		ret = pamu_enable_liodn(liodn[i]);
		if (ret)
			break;
	}
	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
	return ret;
}

/*
 * FIXME: fsl/pamu is completely broken in terms of how it works with the iommu
 * API. Immediately after probe the HW is left in an IDENTITY translation and
 * the driver provides a non-working UNMANAGED domain that it can switch over
 * to. However it cannot switch back to an IDENTITY translation, instead it
 * switches to what looks like BLOCKING.
 */
static int fsl_pamu_platform_attach(struct iommu_domain *platform_domain,
				    struct device *dev)
{
	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
	struct fsl_dma_domain *dma_domain;
	const u32 *prop;
	int len;
	struct pci_dev *pdev = NULL;
	struct pci_controller *pci_ctl;

	/*
	 * Hack to keep things working as they always have, only leaving an
	 * UNMANAGED domain makes it BLOCKING.
	 */
	if (domain == platform_domain || !domain ||
	    domain->type != IOMMU_DOMAIN_UNMANAGED)
		return 0;

	dma_domain = to_fsl_dma_domain(domain);

	/*
	 * Use LIODN of the PCI controller while detaching a
	 * PCI device.
	 */
	if (dev_is_pci(dev)) {
		pdev = to_pci_dev(dev);
		pci_ctl = pci_bus_to_host(pdev->bus);
		/*
		 * make dev point to pci controller device
		 * so we can get the LIODN programmed by
		 * u-boot.
		 */
		dev = pci_ctl->parent;
	}

	prop = of_get_property(dev->of_node, "fsl,liodn", &len);
	if (prop)
		detach_device(dev, dma_domain);
	else
		pr_debug("missing fsl,liodn property at %pOF\n", dev->of_node);
	return 0;
}

static struct iommu_domain_ops fsl_pamu_platform_ops = {
	.attach_dev = fsl_pamu_platform_attach,
};

static struct iommu_domain fsl_pamu_platform_domain = {
	.type = IOMMU_DOMAIN_PLATFORM,
	.ops = &fsl_pamu_platform_ops,
};

/* Set the domain stash attribute */
int fsl_pamu_configure_l1_stash(struct iommu_domain *domain, u32 cpu)
{
	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&dma_domain->domain_lock, flags);
	dma_domain->stash_id = get_stash_id(PAMU_ATTR_CACHE_L1, cpu);
	if (dma_domain->stash_id == ~(u32)0) {
		pr_debug("Invalid stash attributes\n");
		spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
		return -EINVAL;
	}
	ret = update_domain_stash(dma_domain, dma_domain->stash_id);
	spin_unlock_irqrestore(&dma_domain->domain_lock, flags);

	return ret;
}

static  bool check_pci_ctl_endpt_part(struct pci_controller *pci_ctl)
{
	u32 version;

	/* Check the PCI controller version number by readding BRR1 register */
	version = in_be32(pci_ctl->cfg_addr + (PCI_FSL_BRR1 >> 2));
	version &= PCI_FSL_BRR1_VER;
	/* If PCI controller version is >= 0x204 we can partition endpoints */
	return version >= 0x204;
}

static struct iommu_group *fsl_pamu_device_group(struct device *dev)
{
	struct iommu_group *group;
	struct pci_dev *pdev;

	/*
	 * For platform devices we allocate a separate group for each of the
	 * devices.
	 */
	if (!dev_is_pci(dev))
		return generic_device_group(dev);

	/*
	 * We can partition PCIe devices so assign device group to the device
	 */
	pdev = to_pci_dev(dev);
	if (check_pci_ctl_endpt_part(pci_bus_to_host(pdev->bus)))
		return pci_device_group(&pdev->dev);

	/*
	 * All devices connected to the controller will share the same device
	 * group.
	 *
	 * Due to ordering between fsl_pamu_init() and fsl_pci_init() it is
	 * guaranteed that the pci_ctl->parent platform_device will have the
	 * iommu driver bound and will already have a group set. So we just
	 * re-use this group as the group for every device in the hose.
	 */
	group = iommu_group_get(pci_bus_to_host(pdev->bus)->parent);
	if (WARN_ON(!group))
		return ERR_PTR(-EINVAL);
	return group;
}

static struct iommu_device *fsl_pamu_probe_device(struct device *dev)
{
	/*
	 * uboot must fill the fsl,liodn for platform devices to be supported by
	 * the iommu.
	 */
	if (!dev_is_pci(dev) &&
	    !of_property_present(dev->of_node, "fsl,liodn"))
		return ERR_PTR(-ENODEV);

	return &pamu_iommu;
}

static const struct iommu_ops fsl_pamu_ops = {
	.default_domain = &fsl_pamu_platform_domain,
	.capable	= fsl_pamu_capable,
	.domain_alloc	= fsl_pamu_domain_alloc,
	.probe_device	= fsl_pamu_probe_device,
	.device_group   = fsl_pamu_device_group,
	.default_domain_ops = &(const struct iommu_domain_ops) {
		.attach_dev	= fsl_pamu_attach_device,
		.iova_to_phys	= fsl_pamu_iova_to_phys,
		.free		= fsl_pamu_domain_free,
	}
};

int __init pamu_domain_init(void)
{
	int ret = 0;

	ret = iommu_init_mempool();
	if (ret)
		return ret;

	ret = iommu_device_sysfs_add(&pamu_iommu, NULL, NULL, "iommu0");
	if (ret)
		return ret;

	ret = iommu_device_register(&pamu_iommu, &fsl_pamu_ops, NULL);
	if (ret) {
		iommu_device_sysfs_remove(&pamu_iommu);
		pr_err("Can't register iommu device\n");
	}

	return ret;
}
