mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-05 11:35:03 +07:00
ath10k: Add support for targets without trustzone
Add the support to attach and map iommu domain for targets which do not have the support of TrustZone. Tested HW: WCN3990 Tested FW: WLAN.HL.3.1-01040-QCAHLSWMTPLZ-1 Signed-off-by: Rakesh Pillai <pillair@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/1586971906-20985-4-git-send-email-pillair@codeaurora.org
This commit is contained in:
parent
727fec790e
commit
1423f43273
@ -12,6 +12,7 @@
|
|||||||
#include <linux/property.h>
|
#include <linux/property.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/iommu.h>
|
||||||
|
|
||||||
#include "ce.h"
|
#include "ce.h"
|
||||||
#include "coredump.h"
|
#include "coredump.h"
|
||||||
@ -1499,6 +1500,111 @@ static int ath10k_setup_msa_resources(struct ath10k *ar, u32 msa_size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ath10k_fw_init(struct ath10k *ar)
|
||||||
|
{
|
||||||
|
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
|
||||||
|
struct device *host_dev = &ar_snoc->dev->dev;
|
||||||
|
struct platform_device_info info;
|
||||||
|
struct iommu_domain *iommu_dom;
|
||||||
|
struct platform_device *pdev;
|
||||||
|
struct device_node *node;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
node = of_get_child_by_name(host_dev->of_node, "wifi-firmware");
|
||||||
|
if (!node) {
|
||||||
|
ar_snoc->use_tz = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.fwnode = &node->fwnode;
|
||||||
|
info.parent = host_dev;
|
||||||
|
info.name = node->name;
|
||||||
|
info.dma_mask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
pdev = platform_device_register_full(&info);
|
||||||
|
if (IS_ERR(pdev)) {
|
||||||
|
of_node_put(node);
|
||||||
|
return PTR_ERR(pdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdev->dev.of_node = node;
|
||||||
|
|
||||||
|
ret = of_dma_configure(&pdev->dev, node, true);
|
||||||
|
if (ret) {
|
||||||
|
ath10k_err(ar, "dma configure fail: %d\n", ret);
|
||||||
|
goto err_unregister;
|
||||||
|
}
|
||||||
|
|
||||||
|
ar_snoc->fw.dev = &pdev->dev;
|
||||||
|
|
||||||
|
iommu_dom = iommu_domain_alloc(&platform_bus_type);
|
||||||
|
if (!iommu_dom) {
|
||||||
|
ath10k_err(ar, "failed to allocate iommu domain\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_unregister;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = iommu_attach_device(iommu_dom, ar_snoc->fw.dev);
|
||||||
|
if (ret) {
|
||||||
|
ath10k_err(ar, "could not attach device: %d\n", ret);
|
||||||
|
goto err_iommu_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
ar_snoc->fw.iommu_domain = iommu_dom;
|
||||||
|
ar_snoc->fw.fw_start_addr = ar->msa.paddr;
|
||||||
|
|
||||||
|
ret = iommu_map(iommu_dom, ar_snoc->fw.fw_start_addr,
|
||||||
|
ar->msa.paddr, ar->msa.mem_size,
|
||||||
|
IOMMU_READ | IOMMU_WRITE);
|
||||||
|
if (ret) {
|
||||||
|
ath10k_err(ar, "failed to map firmware region: %d\n", ret);
|
||||||
|
goto err_iommu_detach;
|
||||||
|
}
|
||||||
|
|
||||||
|
of_node_put(node);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_iommu_detach:
|
||||||
|
iommu_detach_device(iommu_dom, ar_snoc->fw.dev);
|
||||||
|
|
||||||
|
err_iommu_free:
|
||||||
|
iommu_domain_free(iommu_dom);
|
||||||
|
|
||||||
|
err_unregister:
|
||||||
|
platform_device_unregister(pdev);
|
||||||
|
of_node_put(node);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath10k_fw_deinit(struct ath10k *ar)
|
||||||
|
{
|
||||||
|
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
|
||||||
|
const size_t mapped_size = ar_snoc->fw.mapped_mem_size;
|
||||||
|
struct iommu_domain *iommu;
|
||||||
|
size_t unmapped_size;
|
||||||
|
|
||||||
|
if (ar_snoc->use_tz)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
iommu = ar_snoc->fw.iommu_domain;
|
||||||
|
|
||||||
|
unmapped_size = iommu_unmap(iommu, ar_snoc->fw.fw_start_addr,
|
||||||
|
mapped_size);
|
||||||
|
if (unmapped_size != mapped_size)
|
||||||
|
ath10k_err(ar, "failed to unmap firmware: %zu\n",
|
||||||
|
unmapped_size);
|
||||||
|
|
||||||
|
iommu_detach_device(iommu, ar_snoc->fw.dev);
|
||||||
|
iommu_domain_free(iommu);
|
||||||
|
|
||||||
|
platform_device_unregister(to_platform_device(ar_snoc->fw.dev));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct of_device_id ath10k_snoc_dt_match[] = {
|
static const struct of_device_id ath10k_snoc_dt_match[] = {
|
||||||
{ .compatible = "qcom,wcn3990-wifi",
|
{ .compatible = "qcom,wcn3990-wifi",
|
||||||
.data = &drv_priv,
|
.data = &drv_priv,
|
||||||
@ -1607,16 +1713,25 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
|
|||||||
goto err_power_off;
|
goto err_power_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = ath10k_fw_init(ar);
|
||||||
|
if (ret) {
|
||||||
|
ath10k_err(ar, "failed to initialize firmware: %d\n", ret);
|
||||||
|
goto err_power_off;
|
||||||
|
}
|
||||||
|
|
||||||
ret = ath10k_qmi_init(ar, msa_size);
|
ret = ath10k_qmi_init(ar, msa_size);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret);
|
ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret);
|
||||||
goto err_power_off;
|
goto err_fw_deinit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
|
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_fw_deinit:
|
||||||
|
ath10k_fw_deinit(ar);
|
||||||
|
|
||||||
err_power_off:
|
err_power_off:
|
||||||
ath10k_hw_power_off(ar);
|
ath10k_hw_power_off(ar);
|
||||||
|
|
||||||
@ -1648,6 +1763,7 @@ static int ath10k_snoc_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
ath10k_core_unregister(ar);
|
ath10k_core_unregister(ar);
|
||||||
ath10k_hw_power_off(ar);
|
ath10k_hw_power_off(ar);
|
||||||
|
ath10k_fw_deinit(ar);
|
||||||
ath10k_snoc_free_irq(ar);
|
ath10k_snoc_free_irq(ar);
|
||||||
ath10k_snoc_release_resource(ar);
|
ath10k_snoc_release_resource(ar);
|
||||||
ath10k_qmi_deinit(ar);
|
ath10k_qmi_deinit(ar);
|
||||||
|
@ -55,6 +55,13 @@ struct regulator_bulk_data;
|
|||||||
struct ath10k_snoc {
|
struct ath10k_snoc {
|
||||||
struct platform_device *dev;
|
struct platform_device *dev;
|
||||||
struct ath10k *ar;
|
struct ath10k *ar;
|
||||||
|
unsigned int use_tz;
|
||||||
|
struct ath10k_firmware {
|
||||||
|
struct device *dev;
|
||||||
|
dma_addr_t fw_start_addr;
|
||||||
|
struct iommu_domain *iommu_domain;
|
||||||
|
size_t mapped_mem_size;
|
||||||
|
} fw;
|
||||||
void __iomem *mem;
|
void __iomem *mem;
|
||||||
dma_addr_t mem_pa;
|
dma_addr_t mem_pa;
|
||||||
struct ath10k_snoc_target_info target_info;
|
struct ath10k_snoc_target_info target_info;
|
||||||
|
Loading…
Reference in New Issue
Block a user