cnss2: Add support for PCIe WLAN IPA uc SMMU feature
To add support for PCIe WLAN IPA uc SMMU feature, prvoide related platform api for wlan driver to get the smmu map handle and do the mapping. Change-Id: I672b1a48879ada65b3ddb3f16c4bd787dc1b70a6 Signed-off-by: Frank Liu <qiliu@codeaurora.org>
This commit is contained in:
parent
414b079b7f
commit
26eff67153
3 changed files with 71 additions and 0 deletions
|
@ -1414,6 +1414,61 @@ void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv)
|
|||
CNSS_REASON_TIMEOUT);
|
||||
}
|
||||
|
||||
struct dma_iommu_mapping *cnss_smmu_get_mapping(struct device *dev)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
|
||||
|
||||
if (!pci_priv)
|
||||
return NULL;
|
||||
|
||||
return pci_priv->smmu_mapping;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_smmu_get_mapping);
|
||||
|
||||
int cnss_smmu_map(struct device *dev,
|
||||
phys_addr_t paddr, 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 len;
|
||||
int ret = 0;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (!iova_addr) {
|
||||
cnss_pr_err("iova_addr is NULL, paddr %pa, size %zu\n",
|
||||
&paddr, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
len = roundup(size + paddr - rounddown(paddr, PAGE_SIZE), PAGE_SIZE);
|
||||
iova = roundup(pci_priv->smmu_iova_ipa_start, PAGE_SIZE);
|
||||
|
||||
if (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,
|
||||
pci_priv->smmu_iova_ipa_len);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = iommu_map(pci_priv->smmu_mapping->domain, iova,
|
||||
rounddown(paddr, PAGE_SIZE), len,
|
||||
IOMMU_READ | IOMMU_WRITE);
|
||||
if (ret) {
|
||||
cnss_pr_err("PA to IOVA mapping failed, ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pci_priv->smmu_iova_ipa_start = iova + len;
|
||||
*iova_addr = (uint32_t)(iova + paddr - rounddown(paddr, PAGE_SIZE));
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_smmu_map);
|
||||
|
||||
int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -2129,6 +2184,17 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
|
|||
&pci_priv->smmu_iova_start,
|
||||
pci_priv->smmu_iova_len);
|
||||
|
||||
res = platform_get_resource_byname(plat_priv->plat_dev,
|
||||
IORESOURCE_MEM,
|
||||
"smmu_iova_ipa");
|
||||
if (res) {
|
||||
pci_priv->smmu_iova_ipa_start = res->start;
|
||||
pci_priv->smmu_iova_ipa_len = resource_size(res);
|
||||
cnss_pr_dbg("smmu_iova_ipa_start: %pa, smmu_iova_ipa_len: %zu\n",
|
||||
&pci_priv->smmu_iova_ipa_start,
|
||||
pci_priv->smmu_iova_ipa_len);
|
||||
}
|
||||
|
||||
ret = cnss_pci_init_smmu(pci_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to init SMMU, err = %d\n", ret);
|
||||
|
|
|
@ -73,6 +73,8 @@ struct cnss_pci_data {
|
|||
struct dma_iommu_mapping *smmu_mapping;
|
||||
dma_addr_t smmu_iova_start;
|
||||
size_t smmu_iova_len;
|
||||
dma_addr_t smmu_iova_ipa_start;
|
||||
size_t smmu_iova_ipa_len;
|
||||
void __iomem *bar;
|
||||
struct cnss_msi_config *msi_config;
|
||||
u32 msi_ep_base_data;
|
||||
|
|
|
@ -171,6 +171,9 @@ extern int cnss_get_fw_files_for_target(struct device *dev,
|
|||
u32 target_type, u32 target_version);
|
||||
extern int cnss_get_platform_cap(struct device *dev,
|
||||
struct cnss_platform_cap *cap);
|
||||
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_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);
|
||||
|
|
Loading…
Add table
Reference in a new issue