mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
remoteproc: qcom: Add support for memory sandbox
Update pil driver with SMMU mapping for allowing authorised memory access to ADSP firmware, by carveout reserved adsp memory region from device tree file. Signed-off-by: Srinivasa Rao Mandadapu <quic_srivasam@quicinc.com> Signed-off-by: Bjorn Andersson <andersson@kernel.org> Link: https://lore.kernel.org/r/1664368073-13659-8-git-send-email-quic_srivasam@quicinc.com
This commit is contained in:
parent
9ece961916
commit
f22eedff28
|
|
@ -9,6 +9,7 @@
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/iommu.h>
|
||||||
#include <linux/iopoll.h>
|
#include <linux/iopoll.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/mfd/syscon.h>
|
#include <linux/mfd/syscon.h>
|
||||||
|
|
@ -48,6 +49,8 @@
|
||||||
#define LPASS_PWR_ON_REG 0x10
|
#define LPASS_PWR_ON_REG 0x10
|
||||||
#define LPASS_HALTREQ_REG 0x0
|
#define LPASS_HALTREQ_REG 0x0
|
||||||
|
|
||||||
|
#define SID_MASK_DEFAULT 0xF
|
||||||
|
|
||||||
#define QDSP6SS_XO_CBCR 0x38
|
#define QDSP6SS_XO_CBCR 0x38
|
||||||
#define QDSP6SS_CORE_CBCR 0x20
|
#define QDSP6SS_CORE_CBCR 0x20
|
||||||
#define QDSP6SS_SLEEP_CBCR 0x3c
|
#define QDSP6SS_SLEEP_CBCR 0x3c
|
||||||
|
|
@ -332,6 +335,47 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void adsp_unmap_carveout(struct rproc *rproc)
|
||||||
|
{
|
||||||
|
struct qcom_adsp *adsp = rproc->priv;
|
||||||
|
|
||||||
|
if (adsp->has_iommu)
|
||||||
|
iommu_unmap(rproc->domain, adsp->mem_phys, adsp->mem_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int adsp_map_carveout(struct rproc *rproc)
|
||||||
|
{
|
||||||
|
struct qcom_adsp *adsp = rproc->priv;
|
||||||
|
struct of_phandle_args args;
|
||||||
|
long long sid;
|
||||||
|
unsigned long iova;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!adsp->has_iommu)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!rproc->domain)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = of_parse_phandle_with_args(adsp->dev->of_node, "iommus", "#iommu-cells", 0, &args);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
sid = args.args[0] & SID_MASK_DEFAULT;
|
||||||
|
|
||||||
|
/* Add SID configuration for ADSP Firmware to SMMU */
|
||||||
|
iova = adsp->mem_phys | (sid << 32);
|
||||||
|
|
||||||
|
ret = iommu_map(rproc->domain, iova, adsp->mem_phys,
|
||||||
|
adsp->mem_size, IOMMU_READ | IOMMU_WRITE);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(adsp->dev, "Unable to map ADSP Physical Memory\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int adsp_start(struct rproc *rproc)
|
static int adsp_start(struct rproc *rproc)
|
||||||
{
|
{
|
||||||
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
|
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
|
||||||
|
|
@ -342,9 +386,15 @@ static int adsp_start(struct rproc *rproc)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ret = adsp_map_carveout(rproc);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(adsp->dev, "ADSP smmu mapping failed\n");
|
||||||
|
goto disable_irqs;
|
||||||
|
}
|
||||||
|
|
||||||
ret = clk_prepare_enable(adsp->xo);
|
ret = clk_prepare_enable(adsp->xo);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto disable_irqs;
|
goto adsp_smmu_unmap;
|
||||||
|
|
||||||
ret = qcom_rproc_pds_enable(adsp, adsp->proxy_pds,
|
ret = qcom_rproc_pds_enable(adsp, adsp->proxy_pds,
|
||||||
adsp->proxy_pd_count);
|
adsp->proxy_pd_count);
|
||||||
|
|
@ -400,6 +450,8 @@ static int adsp_start(struct rproc *rproc)
|
||||||
qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
|
qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
|
||||||
disable_xo_clk:
|
disable_xo_clk:
|
||||||
clk_disable_unprepare(adsp->xo);
|
clk_disable_unprepare(adsp->xo);
|
||||||
|
adsp_smmu_unmap:
|
||||||
|
adsp_unmap_carveout(rproc);
|
||||||
disable_irqs:
|
disable_irqs:
|
||||||
qcom_q6v5_unprepare(&adsp->q6v5);
|
qcom_q6v5_unprepare(&adsp->q6v5);
|
||||||
|
|
||||||
|
|
@ -428,6 +480,8 @@ static int adsp_stop(struct rproc *rproc)
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
|
dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
|
||||||
|
|
||||||
|
adsp_unmap_carveout(rproc);
|
||||||
|
|
||||||
handover = qcom_q6v5_unprepare(&adsp->q6v5);
|
handover = qcom_q6v5_unprepare(&adsp->q6v5);
|
||||||
if (handover)
|
if (handover)
|
||||||
qcom_adsp_pil_handover(&adsp->q6v5);
|
qcom_adsp_pil_handover(&adsp->q6v5);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user