mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 11:56:58 +00:00
Merge tag 'rproc-v6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux
Pull remoteproc updates from Bjorn Andersson: - Add support for the compute DSP in the Qualcomm SDM660 platform, and finally fix up the way MSM8974 audio DSP remoteproc driver manages its power rails - Replace the usage of of_reserved_mem_lookup() with of_reserved_mem_region_to_resource() to clean things up across most of the drivers - Perform a variety of housekeeping and cleanup work across iMX, Mediatek, and TI remoteproc drivers * tag 'rproc-v6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (45 commits) remoteproc: qcom_q6v5_wcss: use optional reset for wcss_q6_bcr_reset remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs remoteproc: qcom_wcnss: Fix NULL vs IS_ERR() bug in wcnss_alloc_memory_region() remoteproc: qcom: q6v5: Fix NULL vs IS_ERR() bug in q6v5_alloc_memory_region() remoteproc: qcom: pas: Fix a couple NULL vs IS_ERR() bugs remoteproc: qcom_q6v5_adsp: Fix a NULL vs IS_ERR() check in adsp_alloc_memory_region() remoteproc: imx_dsp_rproc: Fix NULL vs IS_ERR() bug in imx_dsp_rproc_add_carveout() remoteproc: st: Fix indexing of memory-regions remoteproc: qcom: pas: Add support for SDM660 CDSP dt-bindings: remoteproc: qcom: adsp: Add SDM660 CDSP compatible dt-bindings: remoteproc: qcom: adsp: Add missing constrains for SDM660 ADSP dt-bindings: remoteproc: qcom,sc8280xp-pas: Fix CDSP power desc remoteproc: omap: Remove redundant pm_runtime_mark_last_busy() calls remoteproc: qcom: Use of_reserved_mem_region_* functions for "memory-region" remoteproc: qcom_q6v5_pas: Use resource with CX PD for MSM8974 dt-bindings: remoteproc: qcom,adsp: Make msm8974 use CX as power domain remoteproc: Use of_reserved_mem_region_* functions for "memory-region" remoteproc: imx_dsp_rproc: Simplify start/stop error handling remoteproc: imx_rproc: Remove enum imx_rproc_method remoteproc: imx_dsp_rproc: Simplify IMX_RPROC_RESET_CONTROLLER switch case ...
This commit is contained in:
@@ -24,6 +24,7 @@ properties:
|
||||
- qcom,msm8998-adsp-pas
|
||||
- qcom,msm8998-slpi-pas
|
||||
- qcom,sdm660-adsp-pas
|
||||
- qcom,sdm660-cdsp-pas
|
||||
- qcom,sdm845-adsp-pas
|
||||
- qcom,sdm845-cdsp-pas
|
||||
- qcom,sdm845-slpi-pas
|
||||
@@ -31,9 +32,6 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
cx-supply:
|
||||
description: Phandle to the CX regulator
|
||||
|
||||
px-supply:
|
||||
description: Phandle to the PX regulator
|
||||
|
||||
@@ -69,6 +67,8 @@ allOf:
|
||||
- qcom,msm8996-slpi-pil
|
||||
- qcom,msm8998-adsp-pas
|
||||
- qcom,msm8998-slpi-pas
|
||||
- qcom,sdm660-adsp-pas
|
||||
- qcom,sdm660-cdsp-pas
|
||||
- qcom,sdm845-adsp-pas
|
||||
- qcom,sdm845-cdsp-pas
|
||||
- qcom,sdm845-slpi-pas
|
||||
@@ -93,6 +93,8 @@ allOf:
|
||||
- qcom,msm8996-slpi-pil
|
||||
- qcom,msm8998-adsp-pas
|
||||
- qcom,msm8998-slpi-pas
|
||||
- qcom,sdm660-adsp-pas
|
||||
- qcom,sdm660-cdsp-pas
|
||||
- qcom,sdm845-adsp-pas
|
||||
- qcom,sdm845-cdsp-pas
|
||||
- qcom,sdm845-slpi-pas
|
||||
@@ -103,16 +105,6 @@ allOf:
|
||||
interrupt-names:
|
||||
maxItems: 5
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8974-adsp-pil
|
||||
then:
|
||||
required:
|
||||
- cx-supply
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@@ -120,8 +112,11 @@ allOf:
|
||||
enum:
|
||||
- qcom,msm8226-adsp-pil
|
||||
- qcom,msm8953-adsp-pil
|
||||
- qcom,msm8974-adsp-pil
|
||||
- qcom,msm8996-adsp-pil
|
||||
- qcom,msm8998-adsp-pas
|
||||
- qcom,sdm660-adsp-pas
|
||||
- qcom,sdm660-cdsp-pas
|
||||
then:
|
||||
properties:
|
||||
power-domains:
|
||||
@@ -178,6 +173,7 @@ allOf:
|
||||
- qcom,msm8998-adsp-pas
|
||||
- qcom,msm8998-slpi-pas
|
||||
- qcom,sdm660-adsp-pas
|
||||
- qcom,sdm660-cdsp-pas
|
||||
then:
|
||||
properties:
|
||||
qcom,qmp: false
|
||||
@@ -187,6 +183,7 @@ examples:
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
adsp {
|
||||
compatible = "qcom,msm8974-adsp-pil";
|
||||
|
||||
@@ -204,7 +201,8 @@ examples:
|
||||
clocks = <&rpmcc RPM_CXO_CLK>;
|
||||
clock-names = "xo";
|
||||
|
||||
cx-supply = <&pm8841_s2>;
|
||||
power-domains = <&rpmpd MSM8974_VDDCX>;
|
||||
power-domain-names = "cx";
|
||||
|
||||
memory-region = <&adsp_region>;
|
||||
|
||||
|
||||
@@ -91,9 +91,13 @@ allOf:
|
||||
power-domains:
|
||||
items:
|
||||
- description: NSP power domain
|
||||
- description: CX power domain
|
||||
- description: MXC power domain
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: nsp
|
||||
- const: cx
|
||||
- const: mxc
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -261,56 +261,6 @@ static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Specific configuration for i.MX8MP */
|
||||
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8mp = {
|
||||
.att = imx_dsp_rproc_att_imx8mp,
|
||||
.att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8mp),
|
||||
.method = IMX_RPROC_RESET_CONTROLLER,
|
||||
};
|
||||
|
||||
static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = {
|
||||
.dcfg = &dsp_rproc_cfg_imx8mp,
|
||||
.reset = imx8mp_dsp_reset,
|
||||
};
|
||||
|
||||
/* Specific configuration for i.MX8ULP */
|
||||
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8ulp = {
|
||||
.src_reg = IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
|
||||
.src_mask = IMX8ULP_SYSCTRL0_DSP_STALL,
|
||||
.src_start = 0,
|
||||
.src_stop = IMX8ULP_SYSCTRL0_DSP_STALL,
|
||||
.att = imx_dsp_rproc_att_imx8ulp,
|
||||
.att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8ulp),
|
||||
.method = IMX_RPROC_MMIO,
|
||||
};
|
||||
|
||||
static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8ulp = {
|
||||
.dcfg = &dsp_rproc_cfg_imx8ulp,
|
||||
.reset = imx8ulp_dsp_reset,
|
||||
};
|
||||
|
||||
/* Specific configuration for i.MX8QXP */
|
||||
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qxp = {
|
||||
.att = imx_dsp_rproc_att_imx8qxp,
|
||||
.att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8qxp),
|
||||
.method = IMX_RPROC_SCU_API,
|
||||
};
|
||||
|
||||
static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qxp = {
|
||||
.dcfg = &dsp_rproc_cfg_imx8qxp,
|
||||
};
|
||||
|
||||
/* Specific configuration for i.MX8QM */
|
||||
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qm = {
|
||||
.att = imx_dsp_rproc_att_imx8qm,
|
||||
.att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8qm),
|
||||
.method = IMX_RPROC_SCU_API,
|
||||
};
|
||||
|
||||
static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qm = {
|
||||
.dcfg = &dsp_rproc_cfg_imx8qm,
|
||||
};
|
||||
|
||||
static int imx_dsp_rproc_ready(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
@@ -388,6 +338,28 @@ static int imx_dsp_rproc_handle_rsc(struct rproc *rproc, u32 rsc_type,
|
||||
return RSC_HANDLED;
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_mmio_start(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
const struct imx_rproc_dcfg *dcfg = priv->dsp_dcfg->dcfg;
|
||||
|
||||
return regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, dcfg->src_start);
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_reset_ctrl_start(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
|
||||
return reset_control_deassert(priv->run_stall);
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_scu_api_start(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
|
||||
return imx_sc_pm_cpu_start(priv->ipc_handle, IMX_SC_R_DSP, true, rproc->bootaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start function for rproc_ops
|
||||
*
|
||||
@@ -404,32 +376,41 @@ static int imx_dsp_rproc_start(struct rproc *rproc)
|
||||
struct device *dev = rproc->dev.parent;
|
||||
int ret;
|
||||
|
||||
switch (dcfg->method) {
|
||||
case IMX_RPROC_MMIO:
|
||||
ret = regmap_update_bits(priv->regmap,
|
||||
dcfg->src_reg,
|
||||
dcfg->src_mask,
|
||||
dcfg->src_start);
|
||||
break;
|
||||
case IMX_RPROC_SCU_API:
|
||||
ret = imx_sc_pm_cpu_start(priv->ipc_handle,
|
||||
IMX_SC_R_DSP,
|
||||
true,
|
||||
rproc->bootaddr);
|
||||
break;
|
||||
case IMX_RPROC_RESET_CONTROLLER:
|
||||
ret = reset_control_deassert(priv->run_stall);
|
||||
break;
|
||||
default:
|
||||
if (!dcfg->ops || !dcfg->ops->start)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = dcfg->ops->start(rproc);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable remote core!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to enable remote core!\n");
|
||||
else if (priv->flags & WAIT_FW_READY)
|
||||
if (priv->flags & WAIT_FW_READY)
|
||||
return imx_dsp_rproc_ready(rproc);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_mmio_stop(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
const struct imx_rproc_dcfg *dcfg = priv->dsp_dcfg->dcfg;
|
||||
|
||||
return regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, dcfg->src_stop);
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_reset_ctrl_stop(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
|
||||
return reset_control_assert(priv->run_stall);
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_scu_api_stop(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
|
||||
return imx_sc_pm_cpu_start(priv->ipc_handle, IMX_SC_R_DSP, false, rproc->bootaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -449,30 +430,18 @@ static int imx_dsp_rproc_stop(struct rproc *rproc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (dcfg->method) {
|
||||
case IMX_RPROC_MMIO:
|
||||
ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
|
||||
dcfg->src_stop);
|
||||
break;
|
||||
case IMX_RPROC_SCU_API:
|
||||
ret = imx_sc_pm_cpu_start(priv->ipc_handle,
|
||||
IMX_SC_R_DSP,
|
||||
false,
|
||||
rproc->bootaddr);
|
||||
break;
|
||||
case IMX_RPROC_RESET_CONTROLLER:
|
||||
ret = reset_control_assert(priv->run_stall);
|
||||
break;
|
||||
default:
|
||||
if (!dcfg->ops || !dcfg->ops->stop)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = dcfg->ops->stop(rproc);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to stop remote core\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to stop remote core\n");
|
||||
else
|
||||
priv->flags &= ~REMOTE_IS_READY;
|
||||
priv->flags &= ~REMOTE_IS_READY;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -689,11 +658,9 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
|
||||
struct rproc *rproc = priv->rproc;
|
||||
struct device *dev = rproc->dev.parent;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct of_phandle_iterator it;
|
||||
struct rproc_mem_entry *mem;
|
||||
struct reserved_mem *rmem;
|
||||
void __iomem *cpu_addr;
|
||||
int a;
|
||||
int a, i = 0;
|
||||
u64 da;
|
||||
|
||||
/* Remap required addresses */
|
||||
@@ -724,49 +691,40 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
|
||||
rproc_add_carveout(rproc, mem);
|
||||
}
|
||||
|
||||
of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
|
||||
while (of_phandle_iterator_next(&it) == 0) {
|
||||
while (1) {
|
||||
int err;
|
||||
struct resource res;
|
||||
|
||||
err = of_reserved_mem_region_to_resource(np, i++, &res);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Ignore the first memory region which will be used vdev buffer.
|
||||
* No need to do extra handlings, rproc_add_virtio_dev will handle it.
|
||||
*/
|
||||
if (!strcmp(it.node->name, "vdev0buffer"))
|
||||
if (strstarts(res.name, "vdev0buffer"))
|
||||
continue;
|
||||
|
||||
rmem = of_reserved_mem_lookup(it.node);
|
||||
if (!rmem) {
|
||||
of_node_put(it.node);
|
||||
dev_err(dev, "unable to acquire memory-region\n");
|
||||
if (imx_dsp_rproc_sys_to_da(priv, res.start, resource_size(&res), &da))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (imx_dsp_rproc_sys_to_da(priv, rmem->base, rmem->size, &da)) {
|
||||
of_node_put(it.node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
|
||||
if (!cpu_addr) {
|
||||
of_node_put(it.node);
|
||||
dev_err(dev, "failed to map memory %p\n", &rmem->base);
|
||||
return -ENOMEM;
|
||||
cpu_addr = devm_ioremap_resource_wc(dev, &res);
|
||||
if (IS_ERR(cpu_addr)) {
|
||||
dev_err(dev, "failed to map memory %pR\n", &res);
|
||||
return PTR_ERR(cpu_addr);
|
||||
}
|
||||
|
||||
/* Register memory region */
|
||||
mem = rproc_mem_entry_init(dev, (void __force *)cpu_addr, (dma_addr_t)rmem->base,
|
||||
rmem->size, da, NULL, NULL, it.node->name);
|
||||
|
||||
if (mem) {
|
||||
rproc_coredump_add_segment(rproc, da, rmem->size);
|
||||
} else {
|
||||
of_node_put(it.node);
|
||||
mem = rproc_mem_entry_init(dev, (void __force *)cpu_addr, (dma_addr_t)res.start,
|
||||
resource_size(&res), da, NULL, NULL,
|
||||
"%.*s", strchrnul(res.name, '@') - res.name, res.name);
|
||||
if (!mem)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rproc_coredump_add_segment(rproc, da, resource_size(&res));
|
||||
rproc_add_carveout(rproc, mem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Prepare function for rproc_ops */
|
||||
@@ -784,7 +742,7 @@ static int imx_dsp_rproc_prepare(struct rproc *rproc)
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unprepare function for rproc_ops */
|
||||
@@ -792,7 +750,7 @@ static int imx_dsp_rproc_unprepare(struct rproc *rproc)
|
||||
{
|
||||
pm_runtime_put_sync(rproc->dev.parent);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Kick function for rproc_ops */
|
||||
@@ -1062,14 +1020,50 @@ static const struct rproc_ops imx_dsp_rproc_ops = {
|
||||
static int imx_dsp_attach_pm_domains(struct imx_dsp_rproc *priv)
|
||||
{
|
||||
struct device *dev = priv->rproc->dev.parent;
|
||||
int ret;
|
||||
|
||||
/* A single PM domain is already attached. */
|
||||
if (dev->pm_domain)
|
||||
return 0;
|
||||
|
||||
ret = dev_pm_domain_attach_list(dev, NULL, &priv->pd_list);
|
||||
return ret < 0 ? ret : 0;
|
||||
return devm_pm_domain_attach_list(dev, NULL, &priv->pd_list);
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_mmio_detect_mode(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
struct device *dev = rproc->dev.parent;
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,dsp-ctrl");
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(dev, "failed to find syscon\n");
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
priv->regmap = regmap;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_reset_ctrl_detect_mode(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
struct device *dev = rproc->dev.parent;
|
||||
|
||||
priv->run_stall = devm_reset_control_get_exclusive(dev, "runstall");
|
||||
if (IS_ERR(priv->run_stall)) {
|
||||
dev_err(dev, "Failed to get DSP runstall reset control\n");
|
||||
return PTR_ERR(priv->run_stall);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_dsp_rproc_scu_api_detect_mode(struct rproc *rproc)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
|
||||
return imx_scu_get_handle(&priv->ipc_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1087,38 +1081,12 @@ static int imx_dsp_attach_pm_domains(struct imx_dsp_rproc *priv)
|
||||
static int imx_dsp_rproc_detect_mode(struct imx_dsp_rproc *priv)
|
||||
{
|
||||
const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
|
||||
struct device *dev = priv->rproc->dev.parent;
|
||||
struct regmap *regmap;
|
||||
int ret = 0;
|
||||
const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
|
||||
|
||||
switch (dsp_dcfg->dcfg->method) {
|
||||
case IMX_RPROC_SCU_API:
|
||||
ret = imx_scu_get_handle(&priv->ipc_handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case IMX_RPROC_MMIO:
|
||||
regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,dsp-ctrl");
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(dev, "failed to find syscon\n");
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
if (dcfg->ops && dcfg->ops->detect_mode)
|
||||
return dcfg->ops->detect_mode(priv->rproc);
|
||||
|
||||
priv->regmap = regmap;
|
||||
break;
|
||||
case IMX_RPROC_RESET_CONTROLLER:
|
||||
priv->run_stall = devm_reset_control_get_exclusive(dev, "runstall");
|
||||
if (IS_ERR(priv->run_stall)) {
|
||||
dev_err(dev, "Failed to get DSP runstall reset control\n");
|
||||
return PTR_ERR(priv->run_stall);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static const char *imx_dsp_clks_names[DSP_RPROC_CLK_MAX] = {
|
||||
@@ -1152,11 +1120,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
|
||||
ret = rproc_of_parse_firmware(dev, 0, &fw_name);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
|
||||
|
||||
rproc = devm_rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops,
|
||||
fw_name, sizeof(*priv));
|
||||
@@ -1179,52 +1144,28 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
|
||||
INIT_WORK(&priv->rproc_work, imx_dsp_rproc_vq_work);
|
||||
|
||||
ret = imx_dsp_rproc_detect_mode(priv);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed on imx_dsp_rproc_detect_mode\n");
|
||||
|
||||
/* There are multiple power domains required by DSP on some platform */
|
||||
ret = imx_dsp_attach_pm_domains(priv);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
|
||||
return ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "failed on imx_dsp_attach_pm_domains\n");
|
||||
|
||||
/* Get clocks */
|
||||
ret = imx_dsp_rproc_clk_get(priv);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed on imx_dsp_rproc_clk_get\n");
|
||||
goto err_detach_domains;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed on imx_dsp_rproc_clk_get\n");
|
||||
|
||||
init_completion(&priv->pm_comp);
|
||||
rproc->auto_boot = false;
|
||||
ret = rproc_add(rproc);
|
||||
if (ret) {
|
||||
dev_err(dev, "rproc_add failed\n");
|
||||
goto err_detach_domains;
|
||||
}
|
||||
ret = devm_rproc_add(dev, rproc);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "rproc_add failed\n");
|
||||
|
||||
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_XTENSA);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_detach_domains:
|
||||
dev_pm_domain_detach_list(priv->pd_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void imx_dsp_rproc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rproc *rproc = platform_get_drvdata(pdev);
|
||||
struct imx_dsp_rproc *priv = rproc->priv;
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
rproc_del(rproc);
|
||||
dev_pm_domain_detach_list(priv->pd_list);
|
||||
return devm_pm_runtime_enable(dev);
|
||||
}
|
||||
|
||||
/* pm runtime functions */
|
||||
@@ -1364,6 +1305,74 @@ static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
|
||||
RUNTIME_PM_OPS(imx_dsp_runtime_suspend, imx_dsp_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct imx_rproc_plat_ops imx_dsp_rproc_ops_mmio = {
|
||||
.start = imx_dsp_rproc_mmio_start,
|
||||
.stop = imx_dsp_rproc_mmio_stop,
|
||||
.detect_mode = imx_dsp_rproc_mmio_detect_mode,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_plat_ops imx_dsp_rproc_ops_reset_ctrl = {
|
||||
.start = imx_dsp_rproc_reset_ctrl_start,
|
||||
.stop = imx_dsp_rproc_reset_ctrl_stop,
|
||||
.detect_mode = imx_dsp_rproc_reset_ctrl_detect_mode,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_plat_ops imx_dsp_rproc_ops_scu_api = {
|
||||
.start = imx_dsp_rproc_scu_api_start,
|
||||
.stop = imx_dsp_rproc_scu_api_stop,
|
||||
.detect_mode = imx_dsp_rproc_scu_api_detect_mode,
|
||||
};
|
||||
|
||||
/* Specific configuration for i.MX8MP */
|
||||
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8mp = {
|
||||
.att = imx_dsp_rproc_att_imx8mp,
|
||||
.att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8mp),
|
||||
.ops = &imx_dsp_rproc_ops_reset_ctrl,
|
||||
};
|
||||
|
||||
static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = {
|
||||
.dcfg = &dsp_rproc_cfg_imx8mp,
|
||||
.reset = imx8mp_dsp_reset,
|
||||
};
|
||||
|
||||
/* Specific configuration for i.MX8ULP */
|
||||
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8ulp = {
|
||||
.src_reg = IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
|
||||
.src_mask = IMX8ULP_SYSCTRL0_DSP_STALL,
|
||||
.src_start = 0,
|
||||
.src_stop = IMX8ULP_SYSCTRL0_DSP_STALL,
|
||||
.att = imx_dsp_rproc_att_imx8ulp,
|
||||
.att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8ulp),
|
||||
.ops = &imx_dsp_rproc_ops_mmio,
|
||||
};
|
||||
|
||||
static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8ulp = {
|
||||
.dcfg = &dsp_rproc_cfg_imx8ulp,
|
||||
.reset = imx8ulp_dsp_reset,
|
||||
};
|
||||
|
||||
/* Specific configuration for i.MX8QXP */
|
||||
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qxp = {
|
||||
.att = imx_dsp_rproc_att_imx8qxp,
|
||||
.att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8qxp),
|
||||
.ops = &imx_dsp_rproc_ops_scu_api,
|
||||
};
|
||||
|
||||
static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qxp = {
|
||||
.dcfg = &dsp_rproc_cfg_imx8qxp,
|
||||
};
|
||||
|
||||
/* Specific configuration for i.MX8QM */
|
||||
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qm = {
|
||||
.att = imx_dsp_rproc_att_imx8qm,
|
||||
.att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8qm),
|
||||
.ops = &imx_dsp_rproc_ops_scu_api,
|
||||
};
|
||||
|
||||
static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qm = {
|
||||
.dcfg = &dsp_rproc_cfg_imx8qm,
|
||||
};
|
||||
|
||||
static const struct of_device_id imx_dsp_rproc_of_match[] = {
|
||||
{ .compatible = "fsl,imx8qxp-hifi4", .data = &imx_dsp_rproc_cfg_imx8qxp },
|
||||
{ .compatible = "fsl,imx8qm-hifi4", .data = &imx_dsp_rproc_cfg_imx8qm },
|
||||
@@ -1375,7 +1384,6 @@ MODULE_DEVICE_TABLE(of, imx_dsp_rproc_of_match);
|
||||
|
||||
static struct platform_driver imx_dsp_rproc_driver = {
|
||||
.probe = imx_dsp_rproc_probe,
|
||||
.remove = imx_dsp_rproc_remove,
|
||||
.driver = {
|
||||
.name = "imx-dsp-rproc",
|
||||
.of_match_table = imx_dsp_rproc_of_match,
|
||||
|
||||
@@ -93,7 +93,7 @@ struct imx_rproc_mem {
|
||||
#define ATT_CORE(I) BIT((I))
|
||||
|
||||
static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block);
|
||||
static void imx_rproc_free_mbox(struct rproc *rproc);
|
||||
static void imx_rproc_free_mbox(void *data);
|
||||
|
||||
struct imx_rproc {
|
||||
struct device *dev;
|
||||
@@ -490,50 +490,44 @@ static int imx_rproc_prepare(struct rproc *rproc)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
struct device_node *np = priv->dev->of_node;
|
||||
struct of_phandle_iterator it;
|
||||
struct rproc_mem_entry *mem;
|
||||
struct reserved_mem *rmem;
|
||||
int i = 0;
|
||||
u32 da;
|
||||
|
||||
/* Register associated reserved memory regions */
|
||||
of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
|
||||
while (of_phandle_iterator_next(&it) == 0) {
|
||||
while (1) {
|
||||
int err;
|
||||
struct resource res;
|
||||
|
||||
err = of_reserved_mem_region_to_resource(np, i++, &res);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Ignore the first memory region which will be used vdev buffer.
|
||||
* No need to do extra handlings, rproc_add_virtio_dev will handle it.
|
||||
*/
|
||||
if (!strcmp(it.node->name, "vdev0buffer"))
|
||||
if (strstarts(res.name, "vdev0buffer"))
|
||||
continue;
|
||||
|
||||
if (!strcmp(it.node->name, "rsc-table"))
|
||||
if (strstarts(res.name, "rsc-table"))
|
||||
continue;
|
||||
|
||||
rmem = of_reserved_mem_lookup(it.node);
|
||||
if (!rmem) {
|
||||
of_node_put(it.node);
|
||||
dev_err(priv->dev, "unable to acquire memory-region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* No need to translate pa to da, i.MX use same map */
|
||||
da = rmem->base;
|
||||
da = res.start;
|
||||
|
||||
/* Register memory region */
|
||||
mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)rmem->base, rmem->size, da,
|
||||
mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)res.start,
|
||||
resource_size(&res), da,
|
||||
imx_rproc_mem_alloc, imx_rproc_mem_release,
|
||||
it.node->name);
|
||||
|
||||
if (mem) {
|
||||
rproc_coredump_add_segment(rproc, da, rmem->size);
|
||||
} else {
|
||||
of_node_put(it.node);
|
||||
"%.*s", strchrnul(res.name, '@') - res.name,
|
||||
res.name);
|
||||
if (!mem)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rproc_coredump_add_segment(rproc, da, resource_size(&res));
|
||||
rproc_add_carveout(rproc, mem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
|
||||
@@ -575,13 +569,9 @@ static int imx_rproc_attach(struct rproc *rproc)
|
||||
return imx_rproc_xtr_mbox_init(rproc, true);
|
||||
}
|
||||
|
||||
static int imx_rproc_detach(struct rproc *rproc)
|
||||
static int imx_rproc_scu_api_detach(struct rproc *rproc)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
|
||||
|
||||
if (dcfg->method != IMX_RPROC_SCU_API)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id))
|
||||
return -EOPNOTSUPP;
|
||||
@@ -591,6 +581,17 @@ static int imx_rproc_detach(struct rproc *rproc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_rproc_detach(struct rproc *rproc)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
|
||||
|
||||
if (!dcfg->ops || !dcfg->ops->detach)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return dcfg->ops->detach(rproc);
|
||||
}
|
||||
|
||||
static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
@@ -664,47 +665,37 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
|
||||
}
|
||||
|
||||
/* memory-region is optional property */
|
||||
nph = of_count_phandle_with_args(np, "memory-region", NULL);
|
||||
nph = of_reserved_mem_region_count(np);
|
||||
if (nph <= 0)
|
||||
return 0;
|
||||
|
||||
/* remap optional addresses */
|
||||
for (a = 0; a < nph; a++) {
|
||||
struct device_node *node;
|
||||
struct resource res;
|
||||
|
||||
node = of_parse_phandle(np, "memory-region", a);
|
||||
if (!node)
|
||||
continue;
|
||||
/* Not map vdevbuffer, vdevring region */
|
||||
if (!strncmp(node->name, "vdev", strlen("vdev"))) {
|
||||
of_node_put(node);
|
||||
continue;
|
||||
}
|
||||
err = of_address_to_resource(node, 0, &res);
|
||||
err = of_reserved_mem_region_to_resource(np, a, &res);
|
||||
if (err) {
|
||||
dev_err(dev, "unable to resolve memory region\n");
|
||||
of_node_put(node);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (b >= IMX_RPROC_MEM_MAX) {
|
||||
of_node_put(node);
|
||||
/* Not map vdevbuffer, vdevring region */
|
||||
if (strstarts(res.name, "vdev"))
|
||||
continue;
|
||||
|
||||
if (b >= IMX_RPROC_MEM_MAX)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Not use resource version, because we might share region */
|
||||
priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, res.start, resource_size(&res));
|
||||
priv->mem[b].cpu_addr = devm_ioremap_resource_wc(&pdev->dev, &res);
|
||||
if (!priv->mem[b].cpu_addr) {
|
||||
dev_err(dev, "failed to remap %pr\n", &res);
|
||||
of_node_put(node);
|
||||
return -ENOMEM;
|
||||
}
|
||||
priv->mem[b].sys_addr = res.start;
|
||||
priv->mem[b].size = resource_size(&res);
|
||||
if (!strcmp(node->name, "rsc-table"))
|
||||
if (!strcmp(res.name, "rsc-table"))
|
||||
priv->rsc_table = priv->mem[b].cpu_addr;
|
||||
of_node_put(node);
|
||||
b++;
|
||||
}
|
||||
|
||||
@@ -780,8 +771,9 @@ static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imx_rproc_free_mbox(struct rproc *rproc)
|
||||
static void imx_rproc_free_mbox(void *data)
|
||||
{
|
||||
struct rproc *rproc = data;
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
|
||||
if (priv->tx_ch) {
|
||||
@@ -795,13 +787,9 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
|
||||
}
|
||||
}
|
||||
|
||||
static void imx_rproc_put_scu(struct rproc *rproc)
|
||||
static void imx_rproc_put_scu(void *data)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
|
||||
|
||||
if (dcfg->method != IMX_RPROC_SCU_API)
|
||||
return;
|
||||
struct imx_rproc *priv = data;
|
||||
|
||||
if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
|
||||
dev_pm_domain_detach_list(priv->pd_list);
|
||||
@@ -943,6 +931,10 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
|
||||
else
|
||||
priv->core_index = 0;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, imx_rproc_put_scu, priv);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add action for put scu\n");
|
||||
|
||||
/*
|
||||
* If Mcore resource is not owned by Acore partition, It is kicked by ROM,
|
||||
* and Linux could only do IPC with Mcore and nothing else.
|
||||
@@ -1001,35 +993,6 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
|
||||
return dcfg->ops->detect_mode(priv->rproc);
|
||||
}
|
||||
|
||||
static int imx_rproc_clk_enable(struct imx_rproc *priv)
|
||||
{
|
||||
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
|
||||
struct device *dev = priv->dev;
|
||||
int ret;
|
||||
|
||||
/* Remote core is not under control of Linux or it is managed by SCU API */
|
||||
if (dcfg->method == IMX_RPROC_NONE || dcfg->method == IMX_RPROC_SCU_API)
|
||||
return 0;
|
||||
|
||||
priv->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(priv->clk)) {
|
||||
dev_err(dev, "Failed to get clock\n");
|
||||
return PTR_ERR(priv->clk);
|
||||
}
|
||||
|
||||
/*
|
||||
* clk for M4 block including memory. Should be
|
||||
* enabled before .start for FW transfer.
|
||||
*/
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_rproc_sys_off_handler(struct sys_off_data *data)
|
||||
{
|
||||
struct rproc *rproc = data->cb_data;
|
||||
@@ -1046,6 +1009,13 @@ static int imx_rproc_sys_off_handler(struct sys_off_data *data)
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static void imx_rproc_destroy_workqueue(void *data)
|
||||
{
|
||||
struct workqueue_struct *workqueue = data;
|
||||
|
||||
destroy_workqueue(workqueue);
|
||||
}
|
||||
|
||||
static int imx_rproc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -1077,25 +1047,38 @@ static int imx_rproc_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(dev, imx_rproc_destroy_workqueue, priv->workqueue);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add devm destroy workqueue action\n");
|
||||
|
||||
INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
|
||||
|
||||
ret = imx_rproc_xtr_mbox_init(rproc, true);
|
||||
if (ret)
|
||||
goto err_put_wkq;
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, imx_rproc_free_mbox, rproc);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to add devm free mbox action: %d\n", ret);
|
||||
|
||||
ret = imx_rproc_addr_init(priv, pdev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed on imx_rproc_addr_init\n");
|
||||
goto err_put_mbox;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed on imx_rproc_addr_init\n");
|
||||
|
||||
ret = imx_rproc_detect_mode(priv);
|
||||
if (ret)
|
||||
goto err_put_mbox;
|
||||
return dev_err_probe(dev, ret, "failed on detect mode\n");
|
||||
|
||||
ret = imx_rproc_clk_enable(priv);
|
||||
if (ret)
|
||||
goto err_put_scu;
|
||||
/*
|
||||
* Handle clocks when remote core is under control of Linux AND the
|
||||
* clocks are not managed by system firmware.
|
||||
*/
|
||||
if (dcfg->flags & IMX_RPROC_NEED_CLKS) {
|
||||
priv->clk = devm_clk_get_enabled(dev, NULL);
|
||||
if (IS_ERR(priv->clk))
|
||||
return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to enable clock\n");
|
||||
}
|
||||
|
||||
if (rproc->state != RPROC_DETACHED)
|
||||
rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
|
||||
@@ -1110,45 +1093,32 @@ static int imx_rproc_probe(struct platform_device *pdev)
|
||||
ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF_PREPARE,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
imx_rproc_sys_off_handler, rproc);
|
||||
if (ret) {
|
||||
dev_err(dev, "register power off handler failure\n");
|
||||
goto err_put_clk;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "register power off handler failure\n");
|
||||
|
||||
ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART_PREPARE,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
imx_rproc_sys_off_handler, rproc);
|
||||
if (ret) {
|
||||
dev_err(dev, "register restart handler failure\n");
|
||||
goto err_put_clk;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "register restart handler failure\n");
|
||||
}
|
||||
|
||||
if (dcfg->method == IMX_RPROC_SCU_API) {
|
||||
pm_runtime_enable(dev);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "pm_runtime get failed: %d\n", ret);
|
||||
goto err_put_clk;
|
||||
}
|
||||
}
|
||||
pm_runtime_enable(dev);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "pm_runtime get failed\n");
|
||||
|
||||
ret = rproc_add(rproc);
|
||||
ret = devm_rproc_add(dev, rproc);
|
||||
if (ret) {
|
||||
dev_err(dev, "rproc_add failed\n");
|
||||
goto err_put_clk;
|
||||
goto err_put_pm;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_clk:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
err_put_scu:
|
||||
imx_rproc_put_scu(rproc);
|
||||
err_put_mbox:
|
||||
imx_rproc_free_mbox(rproc);
|
||||
err_put_wkq:
|
||||
destroy_workqueue(priv->workqueue);
|
||||
err_put_pm:
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1158,15 +1128,8 @@ static void imx_rproc_remove(struct platform_device *pdev)
|
||||
struct rproc *rproc = platform_get_drvdata(pdev);
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
|
||||
if (priv->dcfg->method == IMX_RPROC_SCU_API) {
|
||||
pm_runtime_disable(priv->dev);
|
||||
pm_runtime_put(priv->dev);
|
||||
}
|
||||
clk_disable_unprepare(priv->clk);
|
||||
rproc_del(rproc);
|
||||
imx_rproc_put_scu(rproc);
|
||||
imx_rproc_free_mbox(rproc);
|
||||
destroy_workqueue(priv->workqueue);
|
||||
pm_runtime_disable(priv->dev);
|
||||
pm_runtime_put_noidle(priv->dev);
|
||||
}
|
||||
|
||||
static const struct imx_rproc_plat_ops imx_rproc_ops_arm_smc = {
|
||||
@@ -1184,6 +1147,7 @@ static const struct imx_rproc_plat_ops imx_rproc_ops_mmio = {
|
||||
static const struct imx_rproc_plat_ops imx_rproc_ops_scu_api = {
|
||||
.start = imx_rproc_scu_api_start,
|
||||
.stop = imx_rproc_scu_api_stop,
|
||||
.detach = imx_rproc_scu_api_detach,
|
||||
.detect_mode = imx_rproc_scu_api_detect_mode,
|
||||
};
|
||||
|
||||
@@ -1196,15 +1160,15 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = {
|
||||
.gpr_wait = IMX8M_GPR22_CM7_CPUWAIT,
|
||||
.att = imx_rproc_att_imx8mn,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8mn),
|
||||
.method = IMX_RPROC_MMIO,
|
||||
.ops = &imx_rproc_ops_mmio,
|
||||
.flags = IMX_RPROC_NEED_CLKS,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
|
||||
.att = imx_rproc_att_imx8mn,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8mn),
|
||||
.method = IMX_RPROC_SMC,
|
||||
.ops = &imx_rproc_ops_arm_smc,
|
||||
.flags = IMX_RPROC_NEED_CLKS,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
|
||||
@@ -1214,34 +1178,30 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
|
||||
.src_stop = IMX7D_M4_STOP,
|
||||
.att = imx_rproc_att_imx8mq,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8mq),
|
||||
.method = IMX_RPROC_MMIO,
|
||||
.ops = &imx_rproc_ops_mmio,
|
||||
.flags = IMX_RPROC_NEED_CLKS,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = {
|
||||
.att = imx_rproc_att_imx8qm,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8qm),
|
||||
.method = IMX_RPROC_SCU_API,
|
||||
.ops = &imx_rproc_ops_scu_api,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
|
||||
.att = imx_rproc_att_imx8qxp,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8qxp),
|
||||
.method = IMX_RPROC_SCU_API,
|
||||
.ops = &imx_rproc_ops_scu_api,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
|
||||
.att = imx_rproc_att_imx8ulp,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp),
|
||||
.method = IMX_RPROC_NONE,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
|
||||
.att = imx_rproc_att_imx7ulp,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx7ulp),
|
||||
.method = IMX_RPROC_NONE,
|
||||
.flags = IMX_RPROC_NEED_SYSTEM_OFF,
|
||||
};
|
||||
|
||||
@@ -1252,8 +1212,8 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
|
||||
.src_stop = IMX7D_M4_STOP,
|
||||
.att = imx_rproc_att_imx7d,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx7d),
|
||||
.method = IMX_RPROC_MMIO,
|
||||
.ops = &imx_rproc_ops_mmio,
|
||||
.flags = IMX_RPROC_NEED_CLKS,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = {
|
||||
@@ -1263,15 +1223,15 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = {
|
||||
.src_stop = IMX6SX_M4_STOP,
|
||||
.att = imx_rproc_att_imx6sx,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx6sx),
|
||||
.method = IMX_RPROC_MMIO,
|
||||
.ops = &imx_rproc_ops_mmio,
|
||||
.flags = IMX_RPROC_NEED_CLKS,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
|
||||
.att = imx_rproc_att_imx93,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx93),
|
||||
.method = IMX_RPROC_SMC,
|
||||
.ops = &imx_rproc_ops_arm_smc,
|
||||
.flags = IMX_RPROC_NEED_CLKS,
|
||||
};
|
||||
|
||||
static const struct of_device_id imx_rproc_of_match[] = {
|
||||
|
||||
@@ -15,25 +15,14 @@ struct imx_rproc_att {
|
||||
int flags;
|
||||
};
|
||||
|
||||
/* Remote core start/stop method */
|
||||
enum imx_rproc_method {
|
||||
IMX_RPROC_NONE,
|
||||
/* Through syscon regmap */
|
||||
IMX_RPROC_MMIO,
|
||||
/* Through ARM SMCCC */
|
||||
IMX_RPROC_SMC,
|
||||
/* Through System Control Unit API */
|
||||
IMX_RPROC_SCU_API,
|
||||
/* Through Reset Controller API */
|
||||
IMX_RPROC_RESET_CONTROLLER,
|
||||
};
|
||||
|
||||
/* dcfg flags */
|
||||
#define IMX_RPROC_NEED_SYSTEM_OFF BIT(0)
|
||||
#define IMX_RPROC_NEED_CLKS BIT(1)
|
||||
|
||||
struct imx_rproc_plat_ops {
|
||||
int (*start)(struct rproc *rproc);
|
||||
int (*stop)(struct rproc *rproc);
|
||||
int (*detach)(struct rproc *rproc);
|
||||
int (*detect_mode)(struct rproc *rproc);
|
||||
};
|
||||
|
||||
@@ -46,7 +35,6 @@ struct imx_rproc_dcfg {
|
||||
u32 gpr_wait;
|
||||
const struct imx_rproc_att *att;
|
||||
size_t att_size;
|
||||
enum imx_rproc_method method;
|
||||
u32 flags;
|
||||
const struct imx_rproc_plat_ops *ops;
|
||||
};
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/remoteproc.h>
|
||||
#include <linux/remoteproc/mtk_scp.h>
|
||||
#include <linux/rpmsg/mtk_rpmsg.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "mtk_common.h"
|
||||
#include "remoteproc_internal.h"
|
||||
@@ -1093,22 +1094,74 @@ static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* scp_get_default_fw_path() - Get default SCP firmware path
|
||||
* @dev: SCP Device
|
||||
* @core_id: SCP Core number
|
||||
*
|
||||
* This function generates a path based on the following format:
|
||||
* mediatek/(soc_model)/scp(_cX).img; for multi-core or
|
||||
* mediatek/(soc_model)/scp.img for single core SCP HW
|
||||
*
|
||||
* Return: A devm allocated string containing the full path to
|
||||
* a SCP firmware or an error pointer
|
||||
*/
|
||||
static const char *scp_get_default_fw_path(struct device *dev, int core_id)
|
||||
{
|
||||
struct device_node *np = core_id < 0 ? dev->of_node : dev->parent->of_node;
|
||||
const char *compatible, *soc;
|
||||
char scp_fw_file[7];
|
||||
int ret;
|
||||
|
||||
/* Use only the first compatible string */
|
||||
ret = of_property_read_string_index(np, "compatible", 0, &compatible);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
/* If the compatible string's length is implausible bail out early */
|
||||
if (strlen(compatible) < strlen("mediatek,mtXXXX-scp"))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* If the compatible string starts with "mediatek,mt" assume that it's ok */
|
||||
if (!str_has_prefix(compatible, "mediatek,mt"))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (core_id >= 0)
|
||||
ret = snprintf(scp_fw_file, sizeof(scp_fw_file), "scp_c%d", core_id);
|
||||
else
|
||||
ret = snprintf(scp_fw_file, sizeof(scp_fw_file), "scp");
|
||||
if (ret >= sizeof(scp_fw_file))
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
||||
/* Not using strchr here, as strlen of a const gets optimized by compiler */
|
||||
soc = &compatible[strlen("mediatek,")];
|
||||
|
||||
return devm_kasprintf(dev, GFP_KERNEL, "mediatek/%.*s/%s.img",
|
||||
(int)strlen("mtXXXX"), soc, scp_fw_file);
|
||||
}
|
||||
|
||||
static struct mtk_scp *scp_rproc_init(struct platform_device *pdev,
|
||||
struct mtk_scp_of_cluster *scp_cluster,
|
||||
const struct mtk_scp_of_data *of_data)
|
||||
const struct mtk_scp_of_data *of_data,
|
||||
int core_id)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct mtk_scp *scp;
|
||||
struct rproc *rproc;
|
||||
struct resource *res;
|
||||
const char *fw_name = "scp.img";
|
||||
const char *fw_name;
|
||||
int ret, i;
|
||||
const struct mtk_scp_sizes_data *scp_sizes;
|
||||
|
||||
ret = rproc_of_parse_firmware(dev, 0, &fw_name);
|
||||
if (ret < 0 && ret != -EINVAL)
|
||||
return ERR_PTR(ret);
|
||||
if (ret) {
|
||||
fw_name = scp_get_default_fw_path(dev, core_id);
|
||||
if (IS_ERR(fw_name)) {
|
||||
dev_err(dev, "Cannot get firmware path: %ld\n", PTR_ERR(fw_name));
|
||||
return ERR_CAST(fw_name);
|
||||
}
|
||||
}
|
||||
|
||||
rproc = devm_rproc_alloc(dev, np->name, &scp_ops, fw_name, sizeof(*scp));
|
||||
if (!rproc) {
|
||||
@@ -1212,7 +1265,7 @@ static int scp_add_single_core(struct platform_device *pdev,
|
||||
struct mtk_scp *scp;
|
||||
int ret;
|
||||
|
||||
scp = scp_rproc_init(pdev, scp_cluster, of_device_get_match_data(dev));
|
||||
scp = scp_rproc_init(pdev, scp_cluster, of_device_get_match_data(dev), -1);
|
||||
if (IS_ERR(scp))
|
||||
return PTR_ERR(scp);
|
||||
|
||||
@@ -1259,7 +1312,7 @@ static int scp_add_multi_core(struct platform_device *pdev,
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
scp = scp_rproc_init(cpdev, scp_cluster, cluster_of_data[core_id]);
|
||||
scp = scp_rproc_init(cpdev, scp_cluster, cluster_of_data[core_id], core_id);
|
||||
put_device(&cpdev->dev);
|
||||
if (IS_ERR(scp)) {
|
||||
ret = PTR_ERR(scp);
|
||||
|
||||
@@ -555,7 +555,6 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid)
|
||||
dev_err(dev, "failed to send mailbox message, status = %d\n",
|
||||
ret);
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
@@ -656,7 +655,6 @@ static int omap_rproc_start(struct rproc *rproc)
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
@@ -714,7 +712,6 @@ enable_device:
|
||||
reset_control_deassert(oproc->reset);
|
||||
out:
|
||||
/* schedule the next auto-suspend */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -625,27 +625,22 @@ static int adsp_init_mmio(struct qcom_adsp *adsp,
|
||||
|
||||
static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
|
||||
{
|
||||
struct reserved_mem *rmem = NULL;
|
||||
struct device_node *node;
|
||||
int ret;
|
||||
struct resource res;
|
||||
|
||||
node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
|
||||
if (node)
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
|
||||
if (!rmem) {
|
||||
ret = of_reserved_mem_region_to_resource(adsp->dev->of_node, 0, &res);
|
||||
if (ret) {
|
||||
dev_err(adsp->dev, "unable to resolve memory-region\n");
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
adsp->mem_phys = adsp->mem_reloc = rmem->base;
|
||||
adsp->mem_size = rmem->size;
|
||||
adsp->mem_region = devm_ioremap_wc(adsp->dev,
|
||||
adsp->mem_phys, adsp->mem_size);
|
||||
if (!adsp->mem_region) {
|
||||
dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
|
||||
&rmem->base, adsp->mem_size);
|
||||
return -EBUSY;
|
||||
adsp->mem_phys = adsp->mem_reloc = res.start;
|
||||
adsp->mem_size = resource_size(&res);
|
||||
adsp->mem_region = devm_ioremap_resource_wc(adsp->dev, &res);
|
||||
if (IS_ERR(adsp->mem_region)) {
|
||||
dev_err(adsp->dev, "unable to map memory region: %pR\n", &res);
|
||||
return PTR_ERR(adsp->mem_region);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1970,8 +1970,8 @@ static int q6v5_init_reset(struct q6v5 *qproc)
|
||||
static int q6v5_alloc_memory_region(struct q6v5 *qproc)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct reserved_mem *rmem;
|
||||
struct device_node *node;
|
||||
struct resource res;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* In the absence of mba/mpss sub-child, extract the mba and mpss
|
||||
@@ -1979,71 +1979,49 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc)
|
||||
*/
|
||||
child = of_get_child_by_name(qproc->dev->of_node, "mba");
|
||||
if (!child) {
|
||||
node = of_parse_phandle(qproc->dev->of_node,
|
||||
"memory-region", 0);
|
||||
ret = of_reserved_mem_region_to_resource(qproc->dev->of_node, 0, &res);
|
||||
} else {
|
||||
node = of_parse_phandle(child, "memory-region", 0);
|
||||
ret = of_reserved_mem_region_to_resource(child, 0, &res);
|
||||
of_node_put(child);
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
dev_err(qproc->dev, "no mba memory-region specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
if (!rmem) {
|
||||
if (ret) {
|
||||
dev_err(qproc->dev, "unable to resolve mba region\n");
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
qproc->mba_phys = rmem->base;
|
||||
qproc->mba_size = rmem->size;
|
||||
qproc->mba_phys = res.start;
|
||||
qproc->mba_size = resource_size(&res);
|
||||
|
||||
if (!child) {
|
||||
node = of_parse_phandle(qproc->dev->of_node,
|
||||
"memory-region", 1);
|
||||
ret = of_reserved_mem_region_to_resource(qproc->dev->of_node, 1, &res);
|
||||
} else {
|
||||
child = of_get_child_by_name(qproc->dev->of_node, "mpss");
|
||||
node = of_parse_phandle(child, "memory-region", 0);
|
||||
ret = of_reserved_mem_region_to_resource(child, 0, &res);
|
||||
of_node_put(child);
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
dev_err(qproc->dev, "no mpss memory-region specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
if (!rmem) {
|
||||
if (ret) {
|
||||
dev_err(qproc->dev, "unable to resolve mpss region\n");
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
qproc->mpss_phys = qproc->mpss_reloc = rmem->base;
|
||||
qproc->mpss_size = rmem->size;
|
||||
qproc->mpss_phys = qproc->mpss_reloc = res.start;
|
||||
qproc->mpss_size = resource_size(&res);
|
||||
|
||||
if (!child) {
|
||||
node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2);
|
||||
ret = of_reserved_mem_region_to_resource(qproc->dev->of_node, 2, &res);
|
||||
} else {
|
||||
child = of_get_child_by_name(qproc->dev->of_node, "metadata");
|
||||
node = of_parse_phandle(child, "memory-region", 0);
|
||||
ret = of_reserved_mem_region_to_resource(child, 0, &res);
|
||||
of_node_put(child);
|
||||
}
|
||||
|
||||
if (!node)
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
if (!rmem) {
|
||||
dev_err(qproc->dev, "unable to resolve metadata region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qproc->mdata_phys = rmem->base;
|
||||
qproc->mdata_size = rmem->size;
|
||||
qproc->mdata_phys = res.start;
|
||||
qproc->mdata_size = resource_size(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -547,54 +547,38 @@ static void qcom_pas_pds_detach(struct qcom_pas *pas, struct device **pds, size_
|
||||
|
||||
static int qcom_pas_alloc_memory_region(struct qcom_pas *pas)
|
||||
{
|
||||
struct reserved_mem *rmem;
|
||||
struct device_node *node;
|
||||
struct resource res;
|
||||
int ret;
|
||||
|
||||
node = of_parse_phandle(pas->dev->of_node, "memory-region", 0);
|
||||
if (!node) {
|
||||
dev_err(pas->dev, "no memory-region specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
if (!rmem) {
|
||||
ret = of_reserved_mem_region_to_resource(pas->dev->of_node, 0, &res);
|
||||
if (ret) {
|
||||
dev_err(pas->dev, "unable to resolve memory-region\n");
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pas->mem_phys = pas->mem_reloc = rmem->base;
|
||||
pas->mem_size = rmem->size;
|
||||
pas->mem_region = devm_ioremap_wc(pas->dev, pas->mem_phys, pas->mem_size);
|
||||
if (!pas->mem_region) {
|
||||
dev_err(pas->dev, "unable to map memory region: %pa+%zx\n",
|
||||
&rmem->base, pas->mem_size);
|
||||
return -EBUSY;
|
||||
pas->mem_phys = pas->mem_reloc = res.start;
|
||||
pas->mem_size = resource_size(&res);
|
||||
pas->mem_region = devm_ioremap_resource_wc(pas->dev, &res);
|
||||
if (IS_ERR(pas->mem_region)) {
|
||||
dev_err(pas->dev, "unable to map memory region: %pR\n", &res);
|
||||
return PTR_ERR(pas->mem_region);
|
||||
}
|
||||
|
||||
if (!pas->dtb_pas_id)
|
||||
return 0;
|
||||
|
||||
node = of_parse_phandle(pas->dev->of_node, "memory-region", 1);
|
||||
if (!node) {
|
||||
dev_err(pas->dev, "no dtb memory-region specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
if (!rmem) {
|
||||
ret = of_reserved_mem_region_to_resource(pas->dev->of_node, 1, &res);
|
||||
if (ret) {
|
||||
dev_err(pas->dev, "unable to resolve dtb memory-region\n");
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pas->dtb_mem_phys = pas->dtb_mem_reloc = rmem->base;
|
||||
pas->dtb_mem_size = rmem->size;
|
||||
pas->dtb_mem_region = devm_ioremap_wc(pas->dev, pas->dtb_mem_phys, pas->dtb_mem_size);
|
||||
if (!pas->dtb_mem_region) {
|
||||
dev_err(pas->dev, "unable to map dtb memory region: %pa+%zx\n",
|
||||
&rmem->base, pas->dtb_mem_size);
|
||||
return -EBUSY;
|
||||
pas->dtb_mem_phys = pas->dtb_mem_reloc = res.start;
|
||||
pas->dtb_mem_size = resource_size(&res);
|
||||
pas->dtb_mem_region = devm_ioremap_resource_wc(pas->dev, &res);
|
||||
if (IS_ERR(pas->dtb_mem_region)) {
|
||||
dev_err(pas->dev, "unable to map dtb memory region: %pR\n", &res);
|
||||
return PTR_ERR(pas->dtb_mem_region);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -603,7 +587,6 @@ static int qcom_pas_alloc_memory_region(struct qcom_pas *pas)
|
||||
static int qcom_pas_assign_memory_region(struct qcom_pas *pas)
|
||||
{
|
||||
struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT];
|
||||
struct device_node *node;
|
||||
unsigned int perm_size;
|
||||
int offset;
|
||||
int ret;
|
||||
@@ -612,17 +595,15 @@ static int qcom_pas_assign_memory_region(struct qcom_pas *pas)
|
||||
return 0;
|
||||
|
||||
for (offset = 0; offset < pas->region_assign_count; ++offset) {
|
||||
struct reserved_mem *rmem = NULL;
|
||||
struct resource res;
|
||||
|
||||
node = of_parse_phandle(pas->dev->of_node, "memory-region",
|
||||
pas->region_assign_idx + offset);
|
||||
if (node)
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
if (!rmem) {
|
||||
ret = of_reserved_mem_region_to_resource(pas->dev->of_node,
|
||||
pas->region_assign_idx + offset,
|
||||
&res);
|
||||
if (ret) {
|
||||
dev_err(pas->dev, "unable to resolve shareable memory-region index %d\n",
|
||||
offset);
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pas->region_assign_shared) {
|
||||
@@ -637,8 +618,8 @@ static int qcom_pas_assign_memory_region(struct qcom_pas *pas)
|
||||
perm_size = 1;
|
||||
}
|
||||
|
||||
pas->region_assign_phys[offset] = rmem->base;
|
||||
pas->region_assign_size[offset] = rmem->size;
|
||||
pas->region_assign_phys[offset] = res.start;
|
||||
pas->region_assign_size[offset] = resource_size(&res);
|
||||
pas->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS);
|
||||
|
||||
ret = qcom_scm_assign_mem(pas->region_assign_phys[offset],
|
||||
@@ -1461,7 +1442,7 @@ static const struct of_device_id qcom_pas_of_match[] = {
|
||||
{ .compatible = "qcom,milos-wpss-pas", .data = &sc7280_wpss_resource},
|
||||
{ .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource},
|
||||
{ .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
|
||||
{ .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
|
||||
{ .compatible = "qcom,msm8974-adsp-pil", .data = &msm8996_adsp_resource},
|
||||
{ .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
|
||||
{ .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init},
|
||||
{ .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
|
||||
@@ -1488,6 +1469,7 @@ static const struct of_device_id qcom_pas_of_match[] = {
|
||||
{ .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
|
||||
{ .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
|
||||
{ .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
|
||||
{ .compatible = "qcom,sdm660-cdsp-pas", .data = &cdsp_resource_init},
|
||||
{ .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
|
||||
{ .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
|
||||
{ .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init},
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
#define TCSR_WCSS_CLK_MASK 0x1F
|
||||
#define TCSR_WCSS_CLK_ENABLE 0x14
|
||||
|
||||
#define MAX_HALT_REG 3
|
||||
#define MAX_HALT_REG 4
|
||||
enum {
|
||||
WCSS_IPQ8074,
|
||||
WCSS_QCS404,
|
||||
@@ -811,7 +811,8 @@ static int q6v5_wcss_init_reset(struct q6v5_wcss *wcss,
|
||||
}
|
||||
}
|
||||
|
||||
wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_bcr_reset");
|
||||
wcss->wcss_q6_bcr_reset = devm_reset_control_get_optional_exclusive(dev,
|
||||
"wcss_q6_bcr_reset");
|
||||
if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
|
||||
dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
|
||||
return PTR_ERR(wcss->wcss_q6_bcr_reset);
|
||||
@@ -864,37 +865,32 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wcss->halt_q6 = halt_reg[0];
|
||||
wcss->halt_wcss = halt_reg[1];
|
||||
wcss->halt_nc = halt_reg[2];
|
||||
wcss->halt_q6 = halt_reg[1];
|
||||
wcss->halt_wcss = halt_reg[2];
|
||||
wcss->halt_nc = halt_reg[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int q6v5_alloc_memory_region(struct q6v5_wcss *wcss)
|
||||
{
|
||||
struct reserved_mem *rmem = NULL;
|
||||
struct device_node *node;
|
||||
struct device *dev = wcss->dev;
|
||||
struct resource res;
|
||||
int ret;
|
||||
|
||||
node = of_parse_phandle(dev->of_node, "memory-region", 0);
|
||||
if (node)
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
|
||||
if (!rmem) {
|
||||
ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res);
|
||||
if (ret) {
|
||||
dev_err(dev, "unable to acquire memory-region\n");
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
wcss->mem_phys = rmem->base;
|
||||
wcss->mem_reloc = rmem->base;
|
||||
wcss->mem_size = rmem->size;
|
||||
wcss->mem_region = devm_ioremap_wc(dev, wcss->mem_phys, wcss->mem_size);
|
||||
if (!wcss->mem_region) {
|
||||
dev_err(dev, "unable to map memory region: %pa+%pa\n",
|
||||
&rmem->base, &rmem->size);
|
||||
return -EBUSY;
|
||||
wcss->mem_phys = res.start;
|
||||
wcss->mem_reloc = res.start;
|
||||
wcss->mem_size = resource_size(&res);
|
||||
wcss->mem_region = devm_ioremap_resource_wc(dev, &res);
|
||||
if (IS_ERR(wcss->mem_region)) {
|
||||
dev_err(dev, "unable to map memory region: %pR\n", &res);
|
||||
return PTR_ERR(wcss->mem_region);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -526,26 +526,21 @@ static int wcnss_request_irq(struct qcom_wcnss *wcnss,
|
||||
|
||||
static int wcnss_alloc_memory_region(struct qcom_wcnss *wcnss)
|
||||
{
|
||||
struct reserved_mem *rmem = NULL;
|
||||
struct device_node *node;
|
||||
struct resource res;
|
||||
int ret;
|
||||
|
||||
node = of_parse_phandle(wcnss->dev->of_node, "memory-region", 0);
|
||||
if (node)
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
|
||||
if (!rmem) {
|
||||
ret = of_reserved_mem_region_to_resource(wcnss->dev->of_node, 0, &res);
|
||||
if (ret) {
|
||||
dev_err(wcnss->dev, "unable to resolve memory-region\n");
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
wcnss->mem_phys = wcnss->mem_reloc = rmem->base;
|
||||
wcnss->mem_size = rmem->size;
|
||||
wcnss->mem_region = devm_ioremap_wc(wcnss->dev, wcnss->mem_phys, wcnss->mem_size);
|
||||
if (!wcnss->mem_region) {
|
||||
dev_err(wcnss->dev, "unable to map memory region: %pa+%zx\n",
|
||||
&rmem->base, wcnss->mem_size);
|
||||
return -EBUSY;
|
||||
wcnss->mem_phys = wcnss->mem_reloc = res.start;
|
||||
wcnss->mem_size = resource_size(&res);
|
||||
wcnss->mem_region = devm_ioremap_resource_wc(wcnss->dev, &res);
|
||||
if (IS_ERR(wcnss->mem_region)) {
|
||||
dev_err(wcnss->dev, "unable to map memory region: %pR\n", &res);
|
||||
return PTR_ERR(wcnss->mem_region);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -52,46 +52,36 @@ static int rcar_rproc_prepare(struct rproc *rproc)
|
||||
{
|
||||
struct device *dev = rproc->dev.parent;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct of_phandle_iterator it;
|
||||
struct rproc_mem_entry *mem;
|
||||
struct reserved_mem *rmem;
|
||||
int i = 0;
|
||||
u32 da;
|
||||
|
||||
/* Register associated reserved memory regions */
|
||||
of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
|
||||
while (of_phandle_iterator_next(&it) == 0) {
|
||||
while (1) {
|
||||
struct resource res;
|
||||
int ret;
|
||||
|
||||
rmem = of_reserved_mem_lookup(it.node);
|
||||
if (!rmem) {
|
||||
of_node_put(it.node);
|
||||
dev_err(&rproc->dev,
|
||||
"unable to acquire memory-region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = of_reserved_mem_region_to_resource(np, i++, &res);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
if (rmem->base > U32_MAX) {
|
||||
of_node_put(it.node);
|
||||
if (res.start > U32_MAX)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* No need to translate pa to da, R-Car use same map */
|
||||
da = rmem->base;
|
||||
da = res.start;
|
||||
mem = rproc_mem_entry_init(dev, NULL,
|
||||
rmem->base,
|
||||
rmem->size, da,
|
||||
res.start,
|
||||
resource_size(&res), da,
|
||||
rcar_rproc_mem_alloc,
|
||||
rcar_rproc_mem_release,
|
||||
it.node->name);
|
||||
res.name);
|
||||
|
||||
if (!mem) {
|
||||
of_node_put(it.node);
|
||||
if (!mem)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rproc_add_carveout(rproc, mem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcar_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
|
||||
|
||||
@@ -16,29 +16,25 @@
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/panic_notifier.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/panic_notifier.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/remoteproc.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/virtio_ids.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/virtio_ring.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "remoteproc_internal.h"
|
||||
|
||||
@@ -159,7 +155,6 @@ phys_addr_t rproc_va_to_pa(void *cpu_addr)
|
||||
WARN_ON(!virt_addr_valid(cpu_addr));
|
||||
return virt_to_phys(cpu_addr);
|
||||
}
|
||||
EXPORT_SYMBOL(rproc_va_to_pa);
|
||||
|
||||
/**
|
||||
* rproc_da_to_va() - lookup the kernel virtual address for a remoteproc address
|
||||
@@ -1989,7 +1984,7 @@ EXPORT_SYMBOL(rproc_boot);
|
||||
int rproc_shutdown(struct rproc *rproc)
|
||||
{
|
||||
struct device *dev = &rproc->dev;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
ret = mutex_lock_interruptible(&rproc->lock);
|
||||
if (ret) {
|
||||
|
||||
@@ -120,43 +120,41 @@ static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
|
||||
struct device *dev = rproc->dev.parent;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct rproc_mem_entry *mem;
|
||||
struct reserved_mem *rmem;
|
||||
struct of_phandle_iterator it;
|
||||
int index = 0;
|
||||
int entries;
|
||||
|
||||
of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
|
||||
while (of_phandle_iterator_next(&it) == 0) {
|
||||
rmem = of_reserved_mem_lookup(it.node);
|
||||
if (!rmem) {
|
||||
of_node_put(it.node);
|
||||
dev_err(dev, "unable to acquire memory-region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
entries = of_reserved_mem_region_count(np);
|
||||
|
||||
for (int index = 0; index < entries; index++) {
|
||||
struct resource res;
|
||||
int ret;
|
||||
|
||||
ret = of_reserved_mem_region_to_resource(np, index, &res);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* No need to map vdev buffer */
|
||||
if (strcmp(it.node->name, "vdev0buffer")) {
|
||||
if (!strstarts(res.name, "vdev0buffer")) {
|
||||
/* Register memory region */
|
||||
mem = rproc_mem_entry_init(dev, NULL,
|
||||
(dma_addr_t)rmem->base,
|
||||
rmem->size, rmem->base,
|
||||
(dma_addr_t)res.start,
|
||||
resource_size(&res), res.start,
|
||||
st_rproc_mem_alloc,
|
||||
st_rproc_mem_release,
|
||||
it.node->name);
|
||||
"%.*s",
|
||||
strchrnul(res.name, '@') - res.name,
|
||||
res.name);
|
||||
} else {
|
||||
/* Register reserved memory for vdev buffer allocation */
|
||||
mem = rproc_of_resm_mem_entry_init(dev, index,
|
||||
rmem->size,
|
||||
rmem->base,
|
||||
it.node->name);
|
||||
resource_size(&res),
|
||||
res.start,
|
||||
"vdev0buffer");
|
||||
}
|
||||
|
||||
if (!mem) {
|
||||
of_node_put(it.node);
|
||||
if (!mem)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rproc_add_carveout(rproc, mem);
|
||||
index++;
|
||||
}
|
||||
|
||||
return rproc_elf_load_rsc_table(rproc, fw);
|
||||
|
||||
@@ -213,60 +213,52 @@ static int stm32_rproc_prepare(struct rproc *rproc)
|
||||
{
|
||||
struct device *dev = rproc->dev.parent;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct of_phandle_iterator it;
|
||||
struct rproc_mem_entry *mem;
|
||||
struct reserved_mem *rmem;
|
||||
u64 da;
|
||||
int index = 0;
|
||||
int index = 0, mr = 0;
|
||||
|
||||
/* Register associated reserved memory regions */
|
||||
of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
|
||||
while (of_phandle_iterator_next(&it) == 0) {
|
||||
rmem = of_reserved_mem_lookup(it.node);
|
||||
if (!rmem) {
|
||||
of_node_put(it.node);
|
||||
dev_err(dev, "unable to acquire memory-region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
while (1) {
|
||||
struct resource res;
|
||||
int ret;
|
||||
|
||||
if (stm32_rproc_pa_to_da(rproc, rmem->base, &da) < 0) {
|
||||
of_node_put(it.node);
|
||||
dev_err(dev, "memory region not valid %pa\n",
|
||||
&rmem->base);
|
||||
ret = of_reserved_mem_region_to_resource(np, mr++, &res);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
if (stm32_rproc_pa_to_da(rproc, res.start, &da) < 0) {
|
||||
dev_err(dev, "memory region not valid %pR\n", &res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* No need to map vdev buffer */
|
||||
if (strcmp(it.node->name, "vdev0buffer")) {
|
||||
if (!strstarts(res.name, "vdev0buffer")) {
|
||||
/* Register memory region */
|
||||
mem = rproc_mem_entry_init(dev, NULL,
|
||||
(dma_addr_t)rmem->base,
|
||||
rmem->size, da,
|
||||
(dma_addr_t)res.start,
|
||||
resource_size(&res), da,
|
||||
stm32_rproc_mem_alloc,
|
||||
stm32_rproc_mem_release,
|
||||
it.node->name);
|
||||
|
||||
"%.*s", strchrnul(res.name, '@') - res.name,
|
||||
res.name);
|
||||
if (mem)
|
||||
rproc_coredump_add_segment(rproc, da,
|
||||
rmem->size);
|
||||
resource_size(&res));
|
||||
} else {
|
||||
/* Register reserved memory for vdev buffer alloc */
|
||||
mem = rproc_of_resm_mem_entry_init(dev, index,
|
||||
rmem->size,
|
||||
rmem->base,
|
||||
it.node->name);
|
||||
resource_size(&res),
|
||||
res.start,
|
||||
"vdev0buffer");
|
||||
}
|
||||
|
||||
if (!mem) {
|
||||
of_node_put(it.node);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rproc_add_carveout(rproc, mem);
|
||||
index++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
|
||||
|
||||
@@ -470,13 +470,10 @@ int k3_reserved_mem_init(struct k3_rproc *kproc)
|
||||
{
|
||||
struct device *dev = kproc->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct device_node *rmem_np;
|
||||
struct reserved_mem *rmem;
|
||||
int num_rmems;
|
||||
int ret, i;
|
||||
|
||||
num_rmems = of_property_count_elems_of_size(np, "memory-region",
|
||||
sizeof(phandle));
|
||||
num_rmems = of_reserved_mem_region_count(np);
|
||||
if (num_rmems < 0) {
|
||||
dev_err(dev, "device does not reserved memory regions (%d)\n",
|
||||
num_rmems);
|
||||
@@ -505,23 +502,20 @@ int k3_reserved_mem_init(struct k3_rproc *kproc)
|
||||
|
||||
/* use remaining reserved memory regions for static carveouts */
|
||||
for (i = 0; i < num_rmems; i++) {
|
||||
rmem_np = of_parse_phandle(np, "memory-region", i + 1);
|
||||
if (!rmem_np)
|
||||
return -EINVAL;
|
||||
struct resource res;
|
||||
|
||||
rmem = of_reserved_mem_lookup(rmem_np);
|
||||
of_node_put(rmem_np);
|
||||
if (!rmem)
|
||||
return -EINVAL;
|
||||
ret = of_reserved_mem_region_to_resource(np, i + 1, &res);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
kproc->rmem[i].bus_addr = rmem->base;
|
||||
kproc->rmem[i].bus_addr = res.start;
|
||||
/* 64-bit address regions currently not supported */
|
||||
kproc->rmem[i].dev_addr = (u32)rmem->base;
|
||||
kproc->rmem[i].size = rmem->size;
|
||||
kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
|
||||
kproc->rmem[i].dev_addr = (u32)res.start;
|
||||
kproc->rmem[i].size = resource_size(&res);
|
||||
kproc->rmem[i].cpu_addr = devm_ioremap_resource_wc(dev, &res);
|
||||
if (!kproc->rmem[i].cpu_addr) {
|
||||
dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
|
||||
i + 1, &rmem->base, &rmem->size);
|
||||
dev_err(dev, "failed to map reserved memory#%d at %pR\n",
|
||||
i + 1, &res);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -492,53 +492,46 @@ static int add_mem_regions_carveout(struct rproc *rproc)
|
||||
{
|
||||
struct rproc_mem_entry *rproc_mem;
|
||||
struct zynqmp_r5_core *r5_core;
|
||||
struct of_phandle_iterator it;
|
||||
struct reserved_mem *rmem;
|
||||
int i = 0;
|
||||
|
||||
r5_core = rproc->priv;
|
||||
|
||||
/* Register associated reserved memory regions */
|
||||
of_phandle_iterator_init(&it, r5_core->np, "memory-region", NULL, 0);
|
||||
while (1) {
|
||||
int err;
|
||||
struct resource res;
|
||||
|
||||
while (of_phandle_iterator_next(&it) == 0) {
|
||||
rmem = of_reserved_mem_lookup(it.node);
|
||||
if (!rmem) {
|
||||
of_node_put(it.node);
|
||||
dev_err(&rproc->dev, "unable to acquire memory-region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
err = of_reserved_mem_region_to_resource(r5_core->np, i, &res);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(it.node->name, "vdev0buffer")) {
|
||||
if (strstarts(res.name, "vdev0buffer")) {
|
||||
/* Init reserved memory for vdev buffer */
|
||||
rproc_mem = rproc_of_resm_mem_entry_init(&rproc->dev, i,
|
||||
rmem->size,
|
||||
rmem->base,
|
||||
it.node->name);
|
||||
resource_size(&res),
|
||||
res.start,
|
||||
"vdev0buffer");
|
||||
} else {
|
||||
/* Register associated reserved memory regions */
|
||||
rproc_mem = rproc_mem_entry_init(&rproc->dev, NULL,
|
||||
(dma_addr_t)rmem->base,
|
||||
rmem->size, rmem->base,
|
||||
(dma_addr_t)res.start,
|
||||
resource_size(&res), res.start,
|
||||
zynqmp_r5_mem_region_map,
|
||||
zynqmp_r5_mem_region_unmap,
|
||||
it.node->name);
|
||||
"%.*s",
|
||||
strchrnul(res.name, '@') - res.name,
|
||||
res.name);
|
||||
}
|
||||
|
||||
if (!rproc_mem) {
|
||||
of_node_put(it.node);
|
||||
if (!rproc_mem)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rproc_add_carveout(rproc, rproc_mem);
|
||||
rproc_coredump_add_segment(rproc, rmem->base, rmem->size);
|
||||
rproc_coredump_add_segment(rproc, res.start, resource_size(&res));
|
||||
|
||||
dev_dbg(&rproc->dev, "reserved mem carveout %s addr=%llx, size=0x%llx",
|
||||
it.node->name, rmem->base, rmem->size);
|
||||
dev_dbg(&rproc->dev, "reserved mem carveout %pR\n", &res);
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_sram_carveouts(struct rproc *rproc)
|
||||
@@ -808,7 +801,6 @@ static int zynqmp_r5_get_rsc_table_va(struct zynqmp_r5_core *r5_core)
|
||||
struct device *dev = r5_core->dev;
|
||||
struct rsc_tbl_data *rsc_data_va;
|
||||
struct resource res_mem;
|
||||
struct device_node *np;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -818,14 +810,7 @@ static int zynqmp_r5_get_rsc_table_va(struct zynqmp_r5_core *r5_core)
|
||||
* contains that data structure which holds resource table address, size
|
||||
* and some magic number to validate correct resource table entry.
|
||||
*/
|
||||
np = of_parse_phandle(r5_core->np, "memory-region", 0);
|
||||
if (!np) {
|
||||
dev_err(dev, "failed to get memory region dev node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_address_to_resource(np, 0, &res_mem);
|
||||
of_node_put(np);
|
||||
ret = of_reserved_mem_region_to_resource(r5_core->np, 0, &res_mem);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get memory-region resource addr\n");
|
||||
return -EINVAL;
|
||||
|
||||
Reference in New Issue
Block a user