remoteproc updates for v6.19

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.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmkzOh0ACgkQCx85Pw2Z
 rcXl+hAA4BBJ2e9mq1eWh0d7LSMHg0F5idNZF2dswdSha6qJpJFZphAawhjASiGU
 LQTYMvJP3bSYaPSVr+ZO21399a2/xw1tR+nfYMeHrhdgKSYDEiJervt7Aoi5TyUI
 60OIHcs2DjvhaFPVD42UJ8gHwNilfLinV4dQZCm+aC1wdDg20tSkdIiolSZH5RH1
 S6o08c3jZTnH65ROTd3uzp5F8qG0qoPyyEuMpa1Vrk/C/T8is9yliEDFCrQtX9OS
 g+ARXMqFXYXLwwI6mMV6L6tY/VXuM0my5Uc02K3d6Zu8+B6m4uIvsVRribILPrdA
 6ME+RCPqrgTtR3gWqJD8aCudWXncwmqnRTGbi7HcqR5A5TR3Ke7iolf9WF291vsY
 qE8fjKscQIhWlRLlMDhv1zM3s+YVZE+oHJbC3hQN8g3m49I2eq3caYduKXcvjjoa
 RH3ZytUwx1cQ6ZJ0vnRxV5yPcddxZtL6tG7f4x8wn+orx2uMh8utpaHCJQbw286l
 XLV5CEN9bNgIwdsSY5POCGb6zoSHNyuXdzSKRtGUDRa4VC+Qc3LxeeVj46NJCc8I
 Q1tDguCl+2MY2wew5o+b77gPOc7xETbJ2oRtoAVShlnenmvhKrgKnRehR/GOhCqU
 gjOY2rW/oS7Ac8D9L4K6XU9WD0TReoeakZY0l+S5W9HXJQ2TK7o=
 =t4y4
 -----END PGP SIGNATURE-----

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
  ...
pull/1354/merge
Linus Torvalds 2025-12-06 09:55:38 -08:00
commit e637b37a52
18 changed files with 567 additions and 659 deletions

View File

@ -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>;

View File

@ -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

View File

@ -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,

View File

@ -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[] = {

View File

@ -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;
};

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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},

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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) {

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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;