Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0afd1df8 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss2: Add cnss_smmu_unmap API"

parents 68a0158f 9579cd02
Loading
Loading
Loading
Loading
+45 −4
Original line number Diff line number Diff line
@@ -2261,10 +2261,11 @@ int cnss_smmu_map(struct device *dev,
	}

	len = roundup(size + paddr - rounddown(paddr, PAGE_SIZE), PAGE_SIZE);
	iova = roundup(pci_priv->smmu_iova_ipa_start, PAGE_SIZE);
	iova = roundup(pci_priv->smmu_iova_ipa_current, PAGE_SIZE);

	if (iova >=
	    (pci_priv->smmu_iova_ipa_start + pci_priv->smmu_iova_ipa_len)) {
	if (pci_priv->iommu_geometry &&
	    iova >= pci_priv->smmu_iova_ipa_start +
		    pci_priv->smmu_iova_ipa_len) {
		cnss_pr_err("No IOVA space to map, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n",
			    iova,
			    &pci_priv->smmu_iova_ipa_start,
@@ -2272,6 +2273,8 @@ int cnss_smmu_map(struct device *dev,
		return -ENOMEM;
	}

	cnss_pr_dbg("IOMMU map: iova %lx len %zu\n", iova, len);

	ret = iommu_map(pci_priv->smmu_mapping->domain, iova,
			rounddown(paddr, PAGE_SIZE), len,
			IOMMU_READ | IOMMU_WRITE);
@@ -2280,13 +2283,50 @@ int cnss_smmu_map(struct device *dev,
		return ret;
	}

	pci_priv->smmu_iova_ipa_start = iova + len;
	pci_priv->smmu_iova_ipa_current = iova + len;
	*iova_addr = (uint32_t)(iova + paddr - rounddown(paddr, PAGE_SIZE));
	cnss_pr_dbg("IOMMU map: iova_addr %lx", *iova_addr);

	return 0;
}
EXPORT_SYMBOL(cnss_smmu_map);

int cnss_smmu_unmap(struct device *dev, uint32_t iova_addr, size_t size)
{
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
	unsigned long iova;
	size_t unmapped;
	size_t len;

	if (!pci_priv)
		return -ENODEV;

	iova = rounddown(iova_addr, PAGE_SIZE);
	len = roundup(size + iova_addr - iova, PAGE_SIZE);

	if (iova >= pci_priv->smmu_iova_ipa_start +
		    pci_priv->smmu_iova_ipa_len) {
		cnss_pr_err("Out of IOVA space to unmap, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n",
			    iova,
			    &pci_priv->smmu_iova_ipa_start,
			    pci_priv->smmu_iova_ipa_len);
		return -ENOMEM;
	}

	cnss_pr_dbg("IOMMU unmap: iova %lx len %zu\n", iova, len);

	unmapped = iommu_unmap(pci_priv->smmu_mapping->domain, iova, len);
	if (unmapped != len) {
		cnss_pr_err("IOMMU unmap failed, unmapped = %zu, requested = %zu\n",
			    unmapped, len);
		return -EINVAL;
	}

	pci_priv->smmu_iova_ipa_current = iova;
	return 0;
}
EXPORT_SYMBOL(cnss_smmu_unmap);

int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info)
{
	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
@@ -3371,6 +3411,7 @@ static int cnss_pci_get_smmu_cfg(struct cnss_plat_data *plat_priv)
	}

	pci_priv->smmu_iova_ipa_start = res->start;
	pci_priv->smmu_iova_ipa_current = res->start;
	pci_priv->smmu_iova_ipa_len = resource_size(res);
	cnss_pr_dbg("%s - smmu_iova_ipa_start: %pa, smmu_iova_ipa_len: %zu\n",
		    (plat_priv->is_converged_dt ?
+1 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ struct cnss_pci_data {
	dma_addr_t smmu_iova_start;
	size_t smmu_iova_len;
	dma_addr_t smmu_iova_ipa_start;
	dma_addr_t smmu_iova_ipa_current;
	size_t smmu_iova_ipa_len;
	void __iomem *bar;
	struct cnss_msi_config *msi_config;
+1 −0
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ extern int cnss_get_platform_cap(struct device *dev,
extern struct dma_iommu_mapping *cnss_smmu_get_mapping(struct device *dev);
extern int cnss_smmu_map(struct device *dev,
			 phys_addr_t paddr, uint32_t *iova_addr, size_t size);
extern int cnss_smmu_unmap(struct device *dev, uint32_t iova_addr, size_t size);
extern int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info);
extern int cnss_request_bus_bandwidth(struct device *dev, int bandwidth);
extern int cnss_power_up(struct device *dev);