Commit 5c480f1d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'rproc-v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux

Pull remoteproc updates from Bjorn Andersson:

 - Add remoteproc support for the Cortex M4F found in AM62x and AM64x of
   the TI K3 family, support for the modem remoteproc in the Qualcomm
   SDX75, and audio, compute and general-purpose DSPs of the Qualcomm
   SA8775P.

 - Add support for blocking and non-blocking mailbox transmissions to
   the i.MX remoteproc driver, and implement poweroff and reboot
   mechanisms using them. Plus a few bug fixes and minor improvements.

 - Cleanups and bug fixes for the TI K3 DSP and R5F drivers

 - Support mapping SRAM regions into the AMD-Xilinx Zynqmp R5 cores

 - Use devres helpers for various allocations in the Ingenic, TI DA8xx,
   TI Keystone, TI K3, ST slim drivers

 - Replace uses of of_{find,get}_property() with of_property_present()
   where possible

* tag 'rproc-v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (25 commits)
  remoteporc: ingenic: Use devm_platform_ioremap_resource_byname()
  remoteproc: da8xx: Use devm_platform_ioremap_resource_byname()
  remoteproc: st_slim: Use devm_platform_ioremap_resource_byname()
  remoteproc: xlnx: Add sram support
  remoteproc: k3-r5: Fix error handling when power-up failed
  remoteproc: imx_rproc: Add support for poweroff and reboot
  remoteproc: imx_rproc: Allow setting of the mailbox transmit mode
  remoteproc: k3-r5: Delay notification of wakeup event
  remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem
  remoteproc: k3: Factor out TI-SCI processor control OF get function
  dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs
  remoteproc: k3-dsp: Acquire mailbox handle during probe routine
  remoteproc: k3-r5: Acquire mailbox handle during probe routine
  remoteproc: k3-r5: Use devm_rproc_alloc() helper
  remoteproc: qcom: pas: Add support for SA8775p ADSP, CDSP and GPDSP
  remoteproc: qcom: pas: Add SDX75 remoteproc support
  dt-bindings: remoteproc: qcom,sm8550-pas: document the SDX75 PAS
  remoteproc: keystone: Use devm_rproc_alloc() helper
  remoteproc: keystone: Use devm_kasprintf() to build name string
  dt-bindings: remoteproc: xlnx,zynqmp-r5fss: Add missing "additionalProperties" on child nodes
  ...
parents 7bc21c5e 38a0e38b
......@@ -16,6 +16,7 @@ description:
properties:
compatible:
enum:
- qcom,sdx75-mpss-pas
- qcom,sm8550-adsp-pas
- qcom,sm8550-cdsp-pas
- qcom,sm8550-mpss-pas
......@@ -113,6 +114,7 @@ allOf:
properties:
compatible:
enum:
- qcom,sdx75-mpss-pas
- qcom,sm8650-mpss-pas
then:
properties:
......@@ -146,6 +148,7 @@ allOf:
properties:
compatible:
enum:
- qcom,sdx75-mpss-pas
- qcom,sm8550-mpss-pas
- qcom,sm8650-mpss-pas
then:
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/remoteproc/ti,k3-m4f-rproc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI K3 M4F processor subsystems
maintainers:
- Hari Nagalla <hnagalla@ti.com>
- Mathieu Poirier <mathieu.poirier@linaro.org>
description: |
Some K3 family SoCs have Arm Cortex M4F cores. AM64x is a SoC in K3
family with a M4F core. Typically safety oriented applications may use
the M4F core in isolation without an IPC. Where as some industrial and
home automation applications, may use the M4F core as a remote processor
with IPC communications.
$ref: /schemas/arm/keystone/ti,k3-sci-common.yaml#
properties:
compatible:
enum:
- ti,am64-m4fss
power-domains:
maxItems: 1
"#address-cells":
const: 2
"#size-cells":
const: 2
reg:
items:
- description: IRAM internal memory region
- description: DRAM internal memory region
reg-names:
items:
- const: iram
- const: dram
resets:
maxItems: 1
firmware-name:
maxItems: 1
description: Name of firmware to load for the M4F core
mboxes:
description:
OMAP Mailbox specifier denoting the sub-mailbox, to be used for
communication with the remote processor. This property should match
with the sub-mailbox node used in the firmware image.
maxItems: 1
memory-region:
description:
phandle to the reserved memory nodes to be associated with the
remoteproc device. Optional memory regions available for firmware
specific purposes.
(see reserved-memory/reserved-memory.yaml in dtschema project)
maxItems: 8
items:
- description: regions used for DMA allocations like vrings, vring buffers
and memory dedicated to firmware's specific purposes.
additionalItems: true
required:
- compatible
- reg
- reg-names
- ti,sci
- ti,sci-dev-id
- ti,sci-proc-ids
- resets
- firmware-name
unevaluatedProperties: false
examples:
- |
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb00000 {
compatible = "shared-dma-pool";
reg = <0x00 0x9cb00000 0x00 0x100000>;
no-map;
};
mcu_m4fss_memory_region: m4f-memory@9cc00000 {
compatible = "shared-dma-pool";
reg = <0x00 0x9cc00000 0x00 0xe00000>;
no-map;
};
};
soc {
#address-cells = <2>;
#size-cells = <2>;
mailbox0_cluster0: mailbox-0 {
#mbox-cells = <1>;
};
remoteproc@5000000 {
compatible = "ti,am64-m4fss";
reg = <0x00 0x5000000 0x00 0x30000>,
<0x00 0x5040000 0x00 0x10000>;
reg-names = "iram", "dram";
resets = <&k3_reset 9 1>;
firmware-name = "am62-mcu-m4f0_0-fw";
mboxes = <&mailbox0_cluster0>, <&mbox_m4_0>;
memory-region = <&mcu_m4fss_dma_memory_region>,
<&mcu_m4fss_memory_region>;
ti,sci = <&dmsc>;
ti,sci-dev-id = <9>;
ti,sci-proc-ids = <0x18 0xff>;
};
};
......@@ -62,6 +62,7 @@ properties:
patternProperties:
"^r(.*)@[0-9a-f]+$":
type: object
additionalProperties: false
description: |
The RPU is located in the Low Power Domain of the Processor Subsystem.
Each processor includes separate L1 instruction and data caches and
......
......@@ -340,6 +340,19 @@ config TI_K3_DSP_REMOTEPROC
It's safe to say N here if you're not interested in utilizing
the DSP slave processors.
config TI_K3_M4_REMOTEPROC
tristate "TI K3 M4 remoteproc support"
depends on ARCH_K3 || COMPILE_TEST
select MAILBOX
select OMAP2PLUS_MBOX
help
Say m here to support TI's M4 remote processor subsystems
on various TI K3 family of SoCs through the remote processor
framework.
It's safe to say N here if you're not interested in utilizing
a remote processor.
config TI_K3_R5_REMOTEPROC
tristate "TI K3 R5 remoteproc support"
depends on ARCH_K3
......
......@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC) += st_remoteproc.o
obj-$(CONFIG_ST_SLIM_REMOTEPROC) += st_slim_rproc.o
obj-$(CONFIG_STM32_RPROC) += stm32_rproc.o
obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
obj-$(CONFIG_TI_K3_M4_REMOTEPROC) += ti_k3_m4_remoteproc.o
obj-$(CONFIG_TI_K3_R5_REMOTEPROC) += ti_k3_r5_remoteproc.o
obj-$(CONFIG_XLNX_R5_REMOTEPROC) += xlnx_r5_remoteproc.o
......@@ -239,8 +239,6 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
struct da8xx_rproc *drproc;
struct rproc *rproc;
struct irq_data *irq_data;
struct resource *bootreg_res;
struct resource *chipsig_res;
struct clk *dsp_clk;
struct reset_control *dsp_reset;
void __iomem *chipsig;
......@@ -258,15 +256,11 @@ static int da8xx_rproc_probe(struct platform_device *pdev)
return -EINVAL;
}
bootreg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"host1cfg");
bootreg = devm_ioremap_resource(dev, bootreg_res);
bootreg = devm_platform_ioremap_resource_byname(pdev, "host1cfg");
if (IS_ERR(bootreg))
return PTR_ERR(bootreg);
chipsig_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"chipsig");
chipsig = devm_ioremap_resource(dev, chipsig_res);
chipsig = devm_platform_ioremap_resource_byname(pdev, "chipsig");
if (IS_ERR(chipsig))
return PTR_ERR(chipsig);
......
......@@ -509,7 +509,7 @@ static int imx_dsp_rproc_mbox_alloc(struct imx_dsp_rproc *priv)
struct mbox_client *cl;
int ret;
if (!of_get_property(dev->of_node, "mbox-names", NULL))
if (!of_property_present(dev->of_node, "mbox-names"))
return 0;
cl = &priv->cl;
......
......@@ -18,6 +18,7 @@
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/remoteproc.h>
#include <linux/workqueue.h>
......@@ -90,7 +91,7 @@ struct imx_rproc_mem {
#define ATT_CORE_MASK 0xffff
#define ATT_CORE(I) BIT((I))
static int imx_rproc_xtr_mbox_init(struct rproc *rproc);
static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block);
static void imx_rproc_free_mbox(struct rproc *rproc);
struct imx_rproc {
......@@ -119,20 +120,16 @@ struct imx_rproc {
static const struct imx_rproc_att imx_rproc_att_imx93[] = {
/* dev addr , sys addr , size , flags */
/* TCM CODE NON-SECURE */
{ 0x0FFC0000, 0x201C0000, 0x00020000, ATT_OWN | ATT_IOMEM },
{ 0x0FFE0000, 0x201E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
{ 0x0FFC0000, 0x201C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
/* TCM CODE SECURE */
{ 0x1FFC0000, 0x201C0000, 0x00020000, ATT_OWN | ATT_IOMEM },
{ 0x1FFE0000, 0x201E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
{ 0x1FFC0000, 0x201C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
/* TCM SYS NON-SECURE*/
{ 0x20000000, 0x20200000, 0x00020000, ATT_OWN | ATT_IOMEM },
{ 0x20020000, 0x20220000, 0x00020000, ATT_OWN | ATT_IOMEM },
{ 0x20000000, 0x20200000, 0x00040000, ATT_OWN | ATT_IOMEM },
/* TCM SYS SECURE*/
{ 0x30000000, 0x20200000, 0x00020000, ATT_OWN | ATT_IOMEM },
{ 0x30020000, 0x20220000, 0x00020000, ATT_OWN | ATT_IOMEM },
{ 0x30000000, 0x20200000, 0x00040000, ATT_OWN | ATT_IOMEM },
/* DDR */
{ 0x80000000, 0x80000000, 0x10000000, 0 },
......@@ -210,11 +207,9 @@ static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
/* QSPI Code - alias */
{ 0x08000000, 0x08000000, 0x08000000, 0 },
/* DDR (Code) - alias */
{ 0x10000000, 0x80000000, 0x0FFE0000, 0 },
/* TCML */
{ 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM},
/* TCMU */
{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM},
{ 0x10000000, 0x40000000, 0x0FFE0000, 0 },
/* TCML/U */
{ 0x1FFE0000, 0x007E0000, 0x00040000, ATT_OWN | ATT_IOMEM},
/* OCRAM_S */
{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
/* OCRAM */
......@@ -339,6 +334,7 @@ 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,
};
static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
......@@ -375,7 +371,7 @@ static int imx_rproc_start(struct rproc *rproc)
struct arm_smccc_res res;
int ret;
ret = imx_rproc_xtr_mbox_init(rproc);
ret = imx_rproc_xtr_mbox_init(rproc, true);
if (ret)
return ret;
......@@ -635,7 +631,7 @@ static void imx_rproc_kick(struct rproc *rproc, int vqid)
static int imx_rproc_attach(struct rproc *rproc)
{
return imx_rproc_xtr_mbox_init(rproc);
return imx_rproc_xtr_mbox_init(rproc, true);
}
static int imx_rproc_detach(struct rproc *rproc)
......@@ -666,6 +662,17 @@ static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc
return (struct resource_table *)priv->rsc_table;
}
static struct resource_table *
imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
{
struct imx_rproc *priv = rproc->priv;
if (priv->rsc_table)
return (struct resource_table *)priv->rsc_table;
return rproc_elf_find_loaded_rsc_table(rproc, fw);
}
static const struct rproc_ops imx_rproc_ops = {
.prepare = imx_rproc_prepare,
.attach = imx_rproc_attach,
......@@ -676,7 +683,7 @@ static const struct rproc_ops imx_rproc_ops = {
.da_to_va = imx_rproc_da_to_va,
.load = rproc_elf_load_segments,
.parse_fw = imx_rproc_parse_fw,
.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
.find_loaded_rsc_table = imx_rproc_elf_find_loaded_rsc_table,
.get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
.sanity_check = rproc_elf_sanity_check,
.get_boot_addr = rproc_elf_get_boot_addr,
......@@ -789,7 +796,7 @@ static void imx_rproc_rx_callback(struct mbox_client *cl, void *msg)
queue_work(priv->workqueue, &priv->rproc_work);
}
static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block)
{
struct imx_rproc *priv = rproc->priv;
struct device *dev = priv->dev;
......@@ -807,12 +814,12 @@ static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
if (priv->tx_ch && priv->rx_ch)
return 0;
if (!of_get_property(dev->of_node, "mbox-names", NULL))
if (!of_property_present(dev->of_node, "mbox-names"))
return 0;
cl = &priv->cl;
cl->dev = dev;
cl->tx_block = true;
cl->tx_block = tx_block;
cl->tx_tout = 100;
cl->knows_txdone = false;
cl->rx_callback = imx_rproc_rx_callback;
......@@ -1045,6 +1052,22 @@ static int imx_rproc_clk_enable(struct imx_rproc *priv)
return 0;
}
static int imx_rproc_sys_off_handler(struct sys_off_data *data)
{
struct rproc *rproc = data->cb_data;
int ret;
imx_rproc_free_mbox(rproc);
ret = imx_rproc_xtr_mbox_init(rproc, false);
if (ret) {
dev_err(&rproc->dev, "Failed to request non-blocking mbox\n");
return NOTIFY_BAD;
}
return NOTIFY_DONE;
}
static int imx_rproc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
......@@ -1076,7 +1099,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
return -ENOMEM;
}
ret = imx_rproc_xtr_mbox_init(rproc);
INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
ret = imx_rproc_xtr_mbox_init(rproc, true);
if (ret)
goto err_put_wkq;
......@@ -1094,11 +1119,33 @@ static int imx_rproc_probe(struct platform_device *pdev)
if (ret)
goto err_put_scu;
INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
if (rproc->state != RPROC_DETACHED)
rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
if (dcfg->flags & IMX_RPROC_NEED_SYSTEM_OFF) {
/*
* setup mailbox to non-blocking mode in
* [SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_MODE_RESTART_PREPARE]
* phase before invoking [SYS_OFF_MODE_POWER_OFF, SYS_OFF_MODE_RESTART]
* atomic chain, see kernel/reboot.c.
*/
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;
}
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;
}
}
ret = rproc_add(rproc);
if (ret) {
dev_err(dev, "rproc_add failed\n");
......
......@@ -26,6 +26,9 @@ enum imx_rproc_method {
IMX_RPROC_SCU_API,
};
/* dcfg flags */
#define IMX_RPROC_NEED_SYSTEM_OFF BIT(0)
struct imx_rproc_dcfg {
u32 src_reg;
u32 src_mask;
......@@ -36,6 +39,7 @@ struct imx_rproc_dcfg {
const struct imx_rproc_att *att;
size_t att_size;
enum imx_rproc_method method;
u32 flags;
};
#endif /* _IMX_RPROC_H */
......@@ -183,8 +183,7 @@ static int ingenic_rproc_probe(struct platform_device *pdev)
vpu->dev = &pdev->dev;
platform_set_drvdata(pdev, vpu);
mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aux");
vpu->aux_base = devm_ioremap_resource(dev, mem);
vpu->aux_base = devm_platform_ioremap_resource_byname(pdev, "aux");
if (IS_ERR(vpu->aux_base)) {
dev_err(dev, "Failed to ioremap\n");
return PTR_ERR(vpu->aux_base);
......
......@@ -366,8 +366,6 @@ static int keystone_rproc_probe(struct platform_device *pdev)
struct rproc *rproc;
int dsp_id;
char *fw_name = NULL;
char *template = "keystone-dsp%d-fw";
int name_len = 0;
int ret = 0;
if (!np) {
......@@ -382,14 +380,12 @@ static int keystone_rproc_probe(struct platform_device *pdev)
}
/* construct a custom default fw name - subject to change in future */
name_len = strlen(template); /* assuming a single digit alias */
fw_name = devm_kzalloc(dev, name_len, GFP_KERNEL);
fw_name = devm_kasprintf(dev, GFP_KERNEL, "keystone-dsp%d-fw", dsp_id);
if (!fw_name)
return -ENOMEM;
snprintf(fw_name, name_len, template, dsp_id);
rproc = rproc_alloc(dev, dev_name(dev), &keystone_rproc_ops, fw_name,
sizeof(*ksproc));
rproc = devm_rproc_alloc(dev, dev_name(dev), &keystone_rproc_ops,
fw_name, sizeof(*ksproc));
if (!rproc)
return -ENOMEM;
......@@ -400,13 +396,11 @@ static int keystone_rproc_probe(struct platform_device *pdev)
ret = keystone_rproc_of_get_dev_syscon(pdev, ksproc);
if (ret)
goto free_rproc;
return ret;
ksproc->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(ksproc->reset)) {
ret = PTR_ERR(ksproc->reset);
goto free_rproc;
}
if (IS_ERR(ksproc->reset))
return PTR_ERR(ksproc->reset);
/* enable clock for accessing DSP internal memories */
pm_runtime_enable(dev);
......@@ -471,8 +465,6 @@ static int keystone_rproc_probe(struct platform_device *pdev)
pm_runtime_put_sync(dev);
disable_rpm:
pm_runtime_disable(dev);
free_rproc:
rproc_free(rproc);
return ret;
}
......@@ -484,7 +476,6 @@ static void keystone_rproc_remove(struct platform_device *pdev)
gpiod_put(ksproc->kick_gpio);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
rproc_free(ksproc->rproc);
of_reserved_mem_device_release(&pdev->dev);
}
......
......@@ -829,6 +829,23 @@ static const struct adsp_data adsp_resource_init = {
.ssctl_id = 0x14,
};
static const struct adsp_data sa8775p_adsp_resource = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mbn",
.pas_id = 1,
.minidump_id = 5,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"lcx",
"lmx",
NULL
},
.load_state = "adsp",
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
};
static const struct adsp_data sdm845_adsp_resource_init = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
......@@ -942,6 +959,42 @@ static const struct adsp_data cdsp_resource_init = {
.ssctl_id = 0x17,
};
static const struct adsp_data sa8775p_cdsp0_resource = {
.crash_reason_smem = 601,
.firmware_name = "cdsp0.mbn",
.pas_id = 18,
.minidump_id = 7,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
"mxc",
"nsp",
NULL
},
.load_state = "cdsp",
.ssr_name = "cdsp",
.sysmon_name = "cdsp",
.ssctl_id = 0x17,
};
static const struct adsp_data sa8775p_cdsp1_resource = {
.crash_reason_smem = 633,
.firmware_name = "cdsp1.mbn",
.pas_id = 30,
.minidump_id = 20,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
"mxc",
"nsp",
NULL
},
.load_state = "nsp",
.ssr_name = "cdsp1",
.sysmon_name = "cdsp1",
.ssctl_id = 0x20,
};
static const struct adsp_data sdm845_cdsp_resource_init = {
.crash_reason_smem = 601,
.firmware_name = "cdsp.mdt",
......@@ -1083,6 +1136,40 @@ static const struct adsp_data sm8350_cdsp_resource = {
.ssctl_id = 0x17,
};
static const struct adsp_data sa8775p_gpdsp0_resource = {
.crash_reason_smem = 640,
.firmware_name = "gpdsp0.mbn",
.pas_id = 39,
.minidump_id = 21,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
"mxc",
NULL
},
.load_state = "gpdsp0",
.ssr_name = "gpdsp0",
.sysmon_name = "gpdsp0",
.ssctl_id = 0x21,
};
static const struct adsp_data sa8775p_gpdsp1_resource = {
.crash_reason_smem = 641,
.firmware_name = "gpdsp1.mbn",
.pas_id = 40,
.minidump_id = 22,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
"mxc",
NULL
},
.load_state = "gpdsp1",
.ssr_name = "gpdsp1",
.sysmon_name = "gpdsp1",
.ssctl_id = 0x22,
};
static const struct adsp_data mpss_resource_init = {
.crash_reason_smem = 421,
.firmware_name = "modem.mdt",
......@@ -1329,6 +1416,11 @@ static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
{ .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource},
{ .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource},
{ .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource},
{ .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource},
{ .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource},
{ .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
{ .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
{ .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource},
......@@ -1346,6 +1438,7 @@ static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
{ .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init},
{ .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
{ .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource},
{ .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init},
{ .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init},
{ .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource},
......
......@@ -259,16 +259,14 @@ struct st_slim_rproc *st_slim_rproc_alloc(struct platform_device *pdev,
slim_rproc->mem[i].size = resource_size(res);
}
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "slimcore");
slim_rproc->slimcore = devm_ioremap_resource(dev, res);
slim_rproc->slimcore = devm_platform_ioremap_resource_byname(pdev, "slimcore");
if (IS_ERR(slim_rproc->slimcore)) {
dev_err(&pdev->dev, "failed to ioremap slimcore IO\n");
err = PTR_ERR(slim_rproc->slimcore);
goto err;
}
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "peripherals");
slim_rproc->peri = devm_ioremap_resource(dev, res);
slim_rproc->peri = devm_platform_ioremap_resource_byname(pdev, "peripherals");
if (IS_ERR(slim_rproc->peri)) {
dev_err(&pdev->dev, "failed to ioremap peripherals IO\n");
err = PTR_ERR(slim_rproc->peri);
......
......@@ -115,6 +115,10 @@ static void k3_dsp_rproc_mbox_callback(struct mbox_client *client, void *data)
const char *name = kproc->rproc->name;
u32 msg = omap_mbox_message(data);
/* Do not forward messages from a detached core */
if (kproc->rproc->state == RPROC_DETACHED)
return;
dev_dbg(dev, "mbox msg: 0x%x\n", msg);
switch (msg) {
......@@ -155,6 +159,10 @@ static void k3_dsp_rproc_kick(struct rproc *rproc, int vqid)
mbox_msg_t msg = (mbox_msg_t)vqid;
int ret;
/* Do not forward messages to a detached core */
if (kproc->rproc->state == RPROC_DETACHED)
return;
/* send the index of the triggered virtqueue in the mailbox payload */
ret = mbox_send_message(kproc->mbox, (void *)msg);
if (ret < 0)
......@@ -230,12 +238,9 @@ static int k3_dsp_rproc_request_mbox(struct rproc *rproc)
client->knows_txdone = false;
kproc->mbox = mbox_request_channel(client, 0);
if (IS_ERR(kproc->mbox)) {
ret = -EBUSY;
dev_err(dev, "mbox_request_channel failed: %ld\n",
PTR_ERR(kproc->mbox));
return ret;
}
if (IS_ERR(kproc->mbox))
return dev_err_probe(dev, PTR_ERR(kproc->mbox),
"mbox_request_channel failed\n");
/*
* Ping the remote processor, this is only for sanity-sake for now;
......@@ -315,32 +320,23 @@ static int k3_dsp_rproc_start(struct rproc *rproc)
u32 boot_addr;
int ret;
ret = k3_dsp_rproc_request_mbox(rproc);
if (ret)
return ret;
boot_addr = rproc->bootaddr;
if (boot_addr & (kproc->data->boot_align_addr - 1)) {
dev_err(dev, "invalid boot address 0x%x, must be aligned on a 0x%x boundary\n",
boot_addr, kproc->data->boot_align_addr);
ret = -EINVAL;
goto put_mbox;
return -EINVAL;
}
dev_dbg(dev, "booting DSP core using boot addr = 0x%x\n", boot_addr);
ret = ti_sci_proc_set_config(kproc->tsp, boot_addr, 0, 0);
if (ret)
goto put_mbox;
return ret;
ret = k3_dsp_rproc_release(kproc);
if (ret)
goto put_mbox;
return ret;
return 0;
put_mbox:
mbox_free_channel(kproc->mbox);
return ret;
}
/*
......@@ -353,8 +349,6 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
{
struct k3_dsp_rproc *kproc = rproc->priv;
mbox_free_channel(kproc->mbox);
k3_dsp_rproc_reset(kproc);
return 0;
......@@ -363,42 +357,22 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
/*
* Attach to a running DSP remote processor (IPC-only mode)
*
* This rproc attach callback only needs to request the mailbox, the remote
* processor is already booted, so there is no need to issue any TI-SCI
* commands to boot the DSP core. This callback is invoked only in IPC-only
* mode.
* This rproc attach callback is a NOP. The remote processor is already booted,
* and all required resources have been acquired during probe routine, so there
* is no need to issue any TI-SCI commands to boot the DSP core. This callback
* is invoked only in IPC-only mode and exists because rproc_validate() checks
* for its existence.
*/
static int k3_dsp_rproc_attach(struct rproc *rproc)
{
struct k3_dsp_rproc *kproc = rproc->priv;
struct device *dev = kproc->dev;
int ret;
ret = k3_dsp_rproc_request_mbox(rproc);
if (ret)
return ret;
dev_info(dev, "DSP initialized in IPC-only mode\n");
return 0;
}
static int k3_dsp_rproc_attach(struct rproc *rproc) { return 0; }
/*
* Detach from a running DSP remote processor (IPC-only mode)
*
* This rproc detach callback performs the opposite operation to attach callback
* and only needs to release the mailbox, the DSP core is not stopped and will
* be left to continue to run its booted firmware. This callback is invoked only
* in IPC-only mode.
* This rproc detach callback is a NOP. The DSP core is not stopped and will be
* left to continue to run its booted firmware. This callback is invoked only in
* IPC-only mode and exists for sanity sake.
*/
static int k3_dsp_rproc_detach(struct rproc *rproc)
{
struct k3_dsp_rproc *kproc = rproc->priv;
struct device *dev = kproc->dev;
mbox_free_channel(kproc->mbox);
dev_info(dev, "DSP deinitialized in IPC-only mode\n");
return 0;
}
static int k3_dsp_rproc_detach(struct rproc *rproc) { return 0; }
/*
* This function implements the .get_loaded_rsc_table() callback and is used
......@@ -636,32 +610,6 @@ static void k3_dsp_release_tsp(void *data)
ti_sci_proc_release(tsp);
}
static
struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev,
const struct ti_sci_handle *sci)
{
struct ti_sci_proc *tsp;
u32 temp[2];
int ret;
ret = of_property_read_u32_array(dev->of_node, "ti,sci-proc-ids",
temp, 2);
if (ret < 0)
return ERR_PTR(ret);
tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL);
if (!tsp)
return ERR_PTR(-ENOMEM);
tsp->dev = dev;
tsp->sci = sci;
tsp->ops = &sci->ops.proc_ops;
tsp->proc_id = temp[0];
tsp->host_id = temp[1];
return tsp;
}
static int k3_dsp_rproc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
......@@ -697,6 +645,10 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
kproc->dev = dev;
kproc->data = data;
ret = k3_dsp_rproc_request_mbox(rproc);
if (ret)
return ret;
kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(kproc->ti_sci))
return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
......@@ -711,7 +663,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(kproc->reset),
"failed to get reset\n");
kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
kproc->tsp = ti_sci_proc_of_get_tsp(dev, kproc->ti_sci);
if (IS_ERR(kproc->tsp))
return dev_err_probe(dev, PTR_ERR(kproc->tsp),
"failed to construct ti-sci proc control\n");
......@@ -789,6 +741,8 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev)
if (ret)
dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret));
}
mbox_free_channel(kproc->mbox);
}
static const struct k3_dsp_mem_data c66_mems[] = {
......
This diff is collapsed.
......@@ -194,6 +194,10 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client *client, void *data)
const char *name = kproc->rproc->name;
u32 msg = omap_mbox_message(data);
/* Do not forward message from a detached core */
if (kproc->rproc->state == RPROC_DETACHED)
return;
dev_dbg(dev, "mbox msg: 0x%x\n", msg);
switch (msg) {
......@@ -229,6 +233,10 @@ static void k3_r5_rproc_kick(struct rproc *rproc, int vqid)
mbox_msg_t msg = (mbox_msg_t)vqid;
int ret;
/* Do not forward message to a detached core */
if (kproc->rproc->state == RPROC_DETACHED)
return;
/* send the index of the triggered virtqueue in the mailbox payload */
ret = mbox_send_message(kproc->mbox, (void *)msg);
if (ret < 0)
......@@ -399,12 +407,9 @@ static int k3_r5_rproc_request_mbox(struct rproc *rproc)
client->knows_txdone = false;
kproc->mbox = mbox_request_channel(client, 0);
if (IS_ERR(kproc->mbox)) {
ret = -EBUSY;
dev_err(dev, "mbox_request_channel failed: %ld\n",
PTR_ERR(kproc->mbox));
return ret;
}
if (IS_ERR(kproc->mbox))
return dev_err_probe(dev, PTR_ERR(kproc->mbox),
"mbox_request_channel failed\n");
/*
* Ping the remote processor, this is only for sanity-sake for now;
......@@ -464,8 +469,6 @@ static int k3_r5_rproc_prepare(struct rproc *rproc)
ret);
return ret;
}
core->released_from_reset = true;
wake_up_interruptible(&cluster->core_transition);
/*
* Newer IP revisions like on J7200 SoCs support h/w auto-initialization
......@@ -552,10 +555,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
u32 boot_addr;
int ret;
ret = k3_r5_rproc_request_mbox(rproc);
if (ret)
return ret;
boot_addr = rproc->bootaddr;
/* TODO: add boot_addr sanity checking */
dev_dbg(dev, "booting R5F core using boot addr = 0x%x\n", boot_addr);
......@@ -564,7 +563,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
core = kproc->core;
ret = ti_sci_proc_set_config(core->tsp, boot_addr, 0, 0);
if (ret)
goto put_mbox;
return ret;
/* unhalt/run all applicable cores */
if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
......@@ -580,13 +579,15 @@ static int k3_r5_rproc_start(struct rproc *rproc)
if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
dev_err(dev, "%s: can not start core 1 before core 0\n",
__func__);
ret = -EPERM;
goto put_mbox;
return -EPERM;
}
ret = k3_r5_core_run(core);
if (ret)
goto put_mbox;
return ret;
core->released_from_reset = true;
wake_up_interruptible(&cluster->core_transition);
}
return 0;
......@@ -596,8 +597,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
if (k3_r5_core_halt(core))
dev_warn(core->dev, "core halt back failed\n");
}
put_mbox:
mbox_free_channel(kproc->mbox);
return ret;
}
......@@ -658,8 +657,6 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
goto out;
}
mbox_free_channel(kproc->mbox);
return 0;
unroll_core_halt:
......@@ -674,42 +671,22 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
/*
* Attach to a running R5F remote processor (IPC-only mode)
*
* The R5F attach callback only needs to request the mailbox, the remote
* processor is already booted, so there is no need to issue any TI-SCI
* commands to boot the R5F cores in IPC-only mode. This callback is invoked
* only in IPC-only mode.
* The R5F attach callback is a NOP. The remote processor is already booted, and
* all required resources have been acquired during probe routine, so there is
* no need to issue any TI-SCI commands to boot the R5F cores in IPC-only mode.
* This callback is invoked only in IPC-only mode and exists because
* rproc_validate() checks for its existence.
*/
static int k3_r5_rproc_attach(struct rproc *rproc)
{
struct k3_r5_rproc *kproc = rproc->priv;
struct device *dev = kproc->dev;
int ret;
ret = k3_r5_rproc_request_mbox(rproc);
if (ret)
return ret;
dev_info(dev, "R5F core initialized in IPC-only mode\n");
return 0;
}
static int k3_r5_rproc_attach(struct rproc *rproc) { return 0; }
/*
* Detach from a running R5F remote processor (IPC-only mode)
*
* The R5F detach callback performs the opposite operation to attach callback
* and only needs to release the mailbox, the R5F cores are not stopped and
* will be left in booted state in IPC-only mode. This callback is invoked
* only in IPC-only mode.
* The R5F detach callback is a NOP. The R5F cores are not stopped and will be
* left in booted state in IPC-only mode. This callback is invoked only in
* IPC-only mode and exists for sanity sake.
*/
static int k3_r5_rproc_detach(struct rproc *rproc)
{
struct k3_r5_rproc *kproc = rproc->priv;
struct device *dev = kproc->dev;
mbox_free_channel(kproc->mbox);
dev_info(dev, "R5F core deinitialized in IPC-only mode\n");
return 0;
}
static int k3_r5_rproc_detach(struct rproc *rproc) { return 0; }
/*
* This function implements the .get_loaded_rsc_table() callback and is used
......@@ -1259,8 +1236,8 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
goto out;
}
rproc = rproc_alloc(cdev, dev_name(cdev), &k3_r5_rproc_ops,
fw_name, sizeof(*kproc));
rproc = devm_rproc_alloc(cdev, dev_name(cdev), &k3_r5_rproc_ops,
fw_name, sizeof(*kproc));
if (!rproc) {
ret = -ENOMEM;
goto out;
......@@ -1278,9 +1255,13 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
kproc->rproc = rproc;
core->rproc = rproc;
ret = k3_r5_rproc_request_mbox(rproc);
if (ret)
return ret;
ret = k3_r5_rproc_configure_mode(kproc);
if (ret < 0)
goto err_config;
goto out;
if (ret)
goto init_rmem;
......@@ -1288,7 +1269,7 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
if (ret) {
dev_err(dev, "initial configure failed, ret = %d\n",
ret);
goto err_config;
goto out;
}
init_rmem:
......@@ -1298,7 +1279,7 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
if (ret) {
dev_err(dev, "reserved memory init failed, ret = %d\n",
ret);
goto err_config;
goto out;
}
ret = rproc_add(rproc);
......@@ -1332,7 +1313,7 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
dev_err(dev,
"Timed out waiting for %s core to power up!\n",
rproc->name);
return ret;
goto err_powerup;
}
}
......@@ -1348,12 +1329,10 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
}
}
err_powerup:
rproc_del(rproc);
err_add:
k3_r5_reserved_mem_exit(kproc);
err_config:
rproc_free(rproc);
core->rproc = NULL;
out:
/* undo core0 upon any failures on core1 in split-mode */
if (cluster->mode == CLUSTER_MODE_SPLIT && core == core1) {
......@@ -1395,12 +1374,11 @@ static void k3_r5_cluster_rproc_exit(void *data)
}
}
mbox_free_channel(kproc->mbox);
rproc_del(rproc);
k3_r5_reserved_mem_exit(kproc);
rproc_free(rproc);
core->rproc = NULL;
}
}
......@@ -1533,32 +1511,6 @@ static int k3_r5_core_of_get_sram_memories(struct platform_device *pdev,
return 0;
}
static
struct ti_sci_proc *k3_r5_core_of_get_tsp(struct device *dev,
const struct ti_sci_handle *sci)
{
struct ti_sci_proc *tsp;
u32 temp[2];
int ret;
ret = of_property_read_u32_array(dev_of_node(dev), "ti,sci-proc-ids",
temp, 2);
if (ret < 0)
return ERR_PTR(ret);
tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL);
if (!tsp)
return ERR_PTR(-ENOMEM);
tsp->dev = dev;
tsp->sci = sci;
tsp->ops = &sci->ops.proc_ops;
tsp->proc_id = temp[0];
tsp->host_id = temp[1];
return tsp;
}
static int k3_r5_core_of_init(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
......@@ -1633,7 +1585,7 @@ static int k3_r5_core_of_init(struct platform_device *pdev)
goto err;
}
core->tsp = k3_r5_core_of_get_tsp(dev, core->ti_sci);
core->tsp = ti_sci_proc_of_get_tsp(dev, core->ti_sci);
if (IS_ERR(core->tsp)) {
ret = PTR_ERR(core->tsp);
dev_err(dev, "failed to construct ti-sci proc control, ret = %d\n",
......
......@@ -28,6 +28,32 @@ struct ti_sci_proc {
u8 host_id;
};
static inline
struct ti_sci_proc *ti_sci_proc_of_get_tsp(struct device *dev,
const struct ti_sci_handle *sci)
{
struct ti_sci_proc *tsp;
u32 temp[2];
int ret;
ret = of_property_read_u32_array(dev_of_node(dev), "ti,sci-proc-ids",
temp, 2);
if (ret < 0)
return ERR_PTR(ret);
tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL);
if (!tsp)
return ERR_PTR(-ENOMEM);
tsp->dev = dev;
tsp->sci = sci;
tsp->ops = &sci->ops.proc_ops;
tsp->proc_id = temp[0];
tsp->host_id = temp[1];
return tsp;
}
static inline int ti_sci_proc_request(struct ti_sci_proc *tsp)
{
int ret;
......
......@@ -56,6 +56,17 @@ struct mem_bank_data {
char *bank_name;
};
/**
* struct zynqmp_sram_bank - sram bank description
*
* @sram_res: sram address region information
* @da: device address of sram
*/
struct zynqmp_sram_bank {
struct resource sram_res;
u32 da;
};
/**
* struct mbox_info
*
......@@ -120,6 +131,8 @@ static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
* struct zynqmp_r5_core
*
* @rsc_tbl_va: resource table virtual address
* @sram: Array of sram memories assigned to this core
* @num_sram: number of sram for this core
* @dev: device of RPU instance
* @np: device node of RPU instance
* @tcm_bank_count: number TCM banks accessible to this RPU
......@@ -131,6 +144,8 @@ static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
*/
struct zynqmp_r5_core {
void __iomem *rsc_tbl_va;
struct zynqmp_sram_bank *sram;
int num_sram;
struct device *dev;
struct device_node *np;
int tcm_bank_count;
......@@ -494,6 +509,45 @@ static int add_mem_regions_carveout(struct rproc *rproc)
return 0;
}
static int add_sram_carveouts(struct rproc *rproc)
{
struct zynqmp_r5_core *r5_core = rproc->priv;
struct rproc_mem_entry *rproc_mem;
struct zynqmp_sram_bank *sram;
dma_addr_t dma_addr;
size_t len;
int da, i;
for (i = 0; i < r5_core->num_sram; i++) {
sram = &r5_core->sram[i];
dma_addr = (dma_addr_t)sram->sram_res.start;
len = resource_size(&sram->sram_res);
da = sram->da;
rproc_mem = rproc_mem_entry_init(&rproc->dev, NULL,
dma_addr,
len, da,
zynqmp_r5_mem_region_map,
zynqmp_r5_mem_region_unmap,
sram->sram_res.name);
if (!rproc_mem) {
dev_err(&rproc->dev, "failed to add sram %s da=0x%x, size=0x%lx",
sram->sram_res.name, da, len);
return -ENOMEM;
}
rproc_add_carveout(rproc, rproc_mem);
rproc_coredump_add_segment(rproc, da, len);
dev_dbg(&rproc->dev, "sram carveout %s addr=%llx, da=0x%x, size=0x%lx",
sram->sram_res.name, dma_addr, da, len);
}
return 0;
}
/*
* tcm_mem_unmap()
* @rproc: single R5 core's corresponding rproc instance
......@@ -669,6 +723,12 @@ static int zynqmp_r5_rproc_prepare(struct rproc *rproc)
return ret;
}
ret = add_sram_carveouts(rproc);
if (ret) {
dev_err(&rproc->dev, "failed to get sram carveout %d\n", ret);
return ret;
}
return 0;
}
......@@ -881,6 +941,77 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
return ERR_PTR(ret);
}
static int zynqmp_r5_get_sram_banks(struct zynqmp_r5_core *r5_core)
{
struct device_node *np = r5_core->np;
struct device *dev = r5_core->dev;
struct zynqmp_sram_bank *sram;
struct device_node *sram_np;
int num_sram, i, ret;
u64 abs_addr, size;
/* "sram" is optional property. Do not fail, if unavailable. */
if (!of_property_present(r5_core->np, "sram"))
return 0;
num_sram = of_property_count_elems_of_size(np, "sram", sizeof(phandle));
if (num_sram <= 0) {
dev_err(dev, "Invalid sram property, ret = %d\n",
num_sram);
return -EINVAL;
}
sram = devm_kcalloc(dev, num_sram,
sizeof(struct zynqmp_sram_bank), GFP_KERNEL);
if (!sram)
return -ENOMEM;
for (i = 0; i < num_sram; i++) {
sram_np = of_parse_phandle(np, "sram", i);
if (!sram_np) {
dev_err(dev, "failed to get sram %d phandle\n", i);
return -EINVAL;
}
if (!of_device_is_available(sram_np)) {
dev_err(dev, "sram device not available\n");
ret = -EINVAL;
goto fail_sram_get;
}
ret = of_address_to_resource(sram_np, 0, &sram[i].sram_res);
if (ret) {
dev_err(dev, "addr to res failed\n");
goto fail_sram_get;
}
/* Get SRAM device address */
ret = of_property_read_reg(sram_np, i, &abs_addr, &size);
if (ret) {
dev_err(dev, "failed to get reg property\n");
goto fail_sram_get;
}
sram[i].da = (u32)abs_addr;
of_node_put(sram_np);
dev_dbg(dev, "sram %d: name=%s, addr=0x%llx, da=0x%x, size=0x%llx\n",
i, sram[i].sram_res.name, sram[i].sram_res.start,
sram[i].da, resource_size(&sram[i].sram_res));
}
r5_core->sram = sram;
r5_core->num_sram = num_sram;
return 0;
fail_sram_get:
of_node_put(sram_np);
return ret;
}
static int zynqmp_r5_get_tcm_node_from_dt(struct zynqmp_r5_cluster *cluster)
{
int i, j, tcm_bank_count, ret, tcm_pd_idx, pd_count;
......@@ -1059,7 +1190,7 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
r5_core = cluster->r5_cores[0];
/* Maintain backward compatibility for zynqmp by using hardcode TCM address. */
if (of_find_property(r5_core->np, "reg", NULL))
if (of_property_present(r5_core->np, "reg"))
ret = zynqmp_r5_get_tcm_node_from_dt(cluster);
else if (device_is_compatible(dev, "xlnx,zynqmp-r5fss"))
ret = zynqmp_r5_get_tcm_node(cluster);
......@@ -1086,7 +1217,7 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
return ret;
}
if (of_find_property(dev_of_node(dev), "xlnx,tcm-mode", NULL) ||
if (of_property_present(dev_of_node(dev), "xlnx,tcm-mode") ||
device_is_compatible(dev, "xlnx,zynqmp-r5fss")) {
ret = zynqmp_pm_set_tcm_config(r5_core->pm_domain_id,
tcm_mode);
......@@ -1095,6 +1226,10 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
return ret;
}
}
ret = zynqmp_r5_get_sram_banks(r5_core);
if (ret)
return ret;
}
return 0;
......@@ -1147,7 +1282,7 @@ static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster)
return -EINVAL;
}
if (of_find_property(dev_node, "xlnx,tcm-mode", NULL)) {
if (of_property_present(dev_node, "xlnx,tcm-mode")) {
ret = of_property_read_u32(dev_node, "xlnx,tcm-mode", (u32 *)&tcm_mode);
if (ret)
return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment