lkml.org 
[lkml]   [2022]   [Sep]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v8 7/7] remoteproc: qcom: Add support for memory sandbox
Date
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>
---
Changes since V6:
-- Update smmu map and unmap function names.
-- Revert adsp_ops const change.
-- Move iommu check to within smmu map/unmap functions.
Changes since V5:
-- Remove adsp_rproc_unmap_smmu, adsp_of_unmap_smmu, adsp_of_map_smmu and
adsp_rproc_map_smmu functions.
-- Remove find_loaded_rsc_table call back initialization.
-- Rename adsp_sandbox_needed to has_iommu.
Changes since V4:
-- Split the code and add appropriate APIs for resource allocation and free.
-- Update adsp_unmap_smmu with missing free ops call.
-- Update normalizing length value in adsp_of_unmap_smmu.
Changes since V3:
-- Rename is_adsp_sb_needed to adsp_sandbox_needed.
-- Add smmu unmapping in error case and in adsp stop.
Changes since V2:
-- Replace platform_bus_type with adsp->dev->bus.
-- Use API of_parse_phandle_with_args() instead of of_parse_phandle_with_fixed_args().
-- Replace adsp->is_wpss with adsp->is_adsp.
-- Update error handling in adsp_start().

drivers/remoteproc/qcom_q6v5_adsp.c | 56 ++++++++++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
index e463fbc..d89f3fa 100644
--- a/drivers/remoteproc/qcom_q6v5_adsp.c
+++ b/drivers/remoteproc/qcom_q6v5_adsp.c
@@ -9,6 +9,7 @@
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/iommu.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
@@ -48,6 +49,8 @@
#define LPASS_PWR_ON_REG 0x10
#define LPASS_HALTREQ_REG 0x0

+#define SID_MASK_DEFAULT 0xF
+
#define QDSP6SS_XO_CBCR 0x38
#define QDSP6SS_CORE_CBCR 0x20
#define QDSP6SS_SLEEP_CBCR 0x3c
@@ -333,6 +336,47 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw)
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)
{
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
@@ -343,9 +387,15 @@ static int adsp_start(struct rproc *rproc)
if (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);
if (ret)
- goto disable_irqs;
+ goto adsp_smmu_unmap;

ret = qcom_rproc_pds_enable(adsp, adsp->proxy_pds,
adsp->proxy_pd_count);
@@ -401,6 +451,8 @@ static int adsp_start(struct rproc *rproc)
qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
disable_xo_clk:
clk_disable_unprepare(adsp->xo);
+adsp_smmu_unmap:
+ adsp_unmap_carveout(rproc);
disable_irqs:
qcom_q6v5_unprepare(&adsp->q6v5);

@@ -429,6 +481,8 @@ static int adsp_stop(struct rproc *rproc)
if (ret)
dev_err(adsp->dev, "failed to shutdown: %d\n", ret);

+ adsp_unmap_carveout(rproc);
+
handover = qcom_q6v5_unprepare(&adsp->q6v5);
if (handover)
qcom_adsp_pil_handover(&adsp->q6v5);
--
2.7.4
\
 
 \ /
  Last update: 2022-09-23 15:09    [W:0.112 / U:0.052 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site