Commit b8dd631f authored by Linus Torvalds's avatar Linus Torvalds

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

Pull remoteproc updates from Bjorn Andersson:
 "Support for controlling the second core in Mediatek's SCP dual-core
  setup is introduced.

  Support for audio, compute and modem DSPs on Qualcomm SM6375, and the
  audio DSP in SC7180 are introduced. The peripheral NoC clock is
  dropped from MSM8996 modem DSP, as this is handled through the
  interconnect provider.

  In the zynqmp driver the setup for TCM memory, and device address
  translation thereof, when operating in lockstep mode is corrected.

  A few bug fixes and cleanups are introduces across the ST and STM32
  remoteproc drivers"

* tag 'rproc-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (28 commits)
  remoteproc: st: Fix sometimes uninitialized ret in st_rproc_probe()
  remoteproc: st: Use device_get_match_data()
  remoteproc: zynqmp: Change tcm address translation method
  remoteproc: mediatek: Refactor single core check and fix retrocompatibility
  remoteproc: qcom: q6v5-mss: Remove PNoC clock from 8996 MSS
  dt-bindings: remoteproc: qcom,msm8996-mss-pil: Remove PNoC clock
  dt-bindings: remoteproc: qcom,adsp: Remove AGGRE2 clock
  remoteproc: qcom: pas: Add SM6375 MPSS
  remoteproc: qcom: pas: Add SM6375 ADSP & CDSP
  dt-bindings: remoteproc: qcom,sm6375-pas: Document remoteprocs
  dt-bindings: remoteproc: pru: Add Interrupt property
  remoteproc: qcom: pas: Add sc7180 adsp
  dt-bindings: remoteproc: qcom: sc7180-pas: Add ADSP compatible
  arm64: dts: mediatek: Update the node name of SCP rpmsg subnode
  remoteproc: zynqmp: fix TCM carveouts in lockstep mode
  remoteproc: mediatek: Refine ipi handler error message
  remoteproc: mediatek: Report watchdog crash to all cores
  remoteproc: mediatek: Handle MT8195 SCP core 1 watchdog timeout
  remoteproc: mediatek: Setup MT8195 SCP core 1 SRAM offset
  remoteproc: mediatek: Remove dependency of MT8195 SCP L2TCM power control on dual-core SCP
  ...
parents c87271ee 3d8a1869
......@@ -21,6 +21,7 @@ properties:
- mediatek,mt8188-scp
- mediatek,mt8192-scp
- mediatek,mt8195-scp
- mediatek,mt8195-scp-dual
reg:
description:
......@@ -31,10 +32,7 @@ properties:
reg-names:
minItems: 2
items:
- const: sram
- const: cfg
- const: l1tcm
maxItems: 3
clocks:
description:
......@@ -58,6 +56,93 @@ properties:
memory-region:
maxItems: 1
cros-ec-rpmsg:
$ref: /schemas/mfd/google,cros-ec.yaml
description:
This subnode represents the rpmsg device. The properties
of this node are defined by the individual bindings for
the rpmsg devices.
required:
- mediatek,rpmsg-name
unevaluatedProperties: false
'#address-cells':
const: 1
'#size-cells':
const: 1
ranges:
description:
Standard ranges definition providing address translations for
local SCP SRAM address spaces to bus addresses.
patternProperties:
"^scp@[a-f0-9]+$":
type: object
description:
The MediaTek SCP integrated to SoC might be a multi-core version.
The other cores are represented as child nodes of the boot core.
There are some integration differences for the IP like the usage of
address translator for translating SoC bus addresses into address space
for the processor.
Each SCP core has own cache memory. The SRAM and L1TCM are shared by
cores. The power of cache, SRAM and L1TCM power should be enabled
before booting SCP cores. The size of cache, SRAM, and L1TCM are varied
on differnt SoCs.
The SCP cores do not use an MMU, but has a set of registers to
control the translations between 32-bit CPU addresses into system bus
addresses. Cache and memory access settings are provided through a
Memory Protection Unit (MPU), programmable only from the SCP.
properties:
compatible:
enum:
- mediatek,scp-core
reg:
description: The base address and size of SRAM.
maxItems: 1
reg-names:
const: sram
interrupts:
maxItems: 1
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
description:
If present, name (or relative path) of the file within the
firmware search path containing the firmware image used when
initializing sub cores of multi-core SCP.
memory-region:
maxItems: 1
cros-ec-rpmsg:
$ref: /schemas/mfd/google,cros-ec.yaml
description:
This subnode represents the rpmsg device. The properties
of this node are defined by the individual bindings for
the rpmsg devices.
required:
- mediatek,rpmsg-name
unevaluatedProperties: false
required:
- compatible
- reg
- reg-names
additionalProperties: false
required:
- compatible
- reg
......@@ -87,23 +172,39 @@ allOf:
reg:
maxItems: 2
reg-names:
items:
- const: sram
- const: cfg
- if:
properties:
compatible:
enum:
- mediatek,mt8192-scp
- mediatek,mt8195-scp
then:
properties:
reg:
maxItems: 3
reg-names:
items:
- const: sram
- const: cfg
- const: l1tcm
- if:
properties:
compatible:
enum:
- mediatek,mt8195-scp-dual
then:
properties:
reg:
maxItems: 2
reg-names:
items:
- const: cfg
- const: l1tcm
additionalProperties:
type: object
description:
Subnodes of the SCP represent rpmsg devices. The names of the devices
are not important. The properties of these nodes are defined by the
individual bindings for the rpmsg devices.
properties:
mediatek,rpmsg-name:
$ref: /schemas/types.yaml#/definitions/string-array
description:
Contains the name for the rpmsg device. Used to match
the subnode to rpmsg device announced by SCP.
required:
- mediatek,rpmsg-name
additionalProperties: false
examples:
- |
......@@ -118,7 +219,42 @@ examples:
clocks = <&infracfg CLK_INFRA_SCPSYS>;
clock-names = "main";
cros_ec {
cros-ec-rpmsg {
compatible = "google,cros-ec-rpmsg";
mediatek,rpmsg-name = "cros-ec-rpmsg";
};
};
- |
scp@10500000 {
compatible = "mediatek,mt8195-scp-dual";
reg = <0x10720000 0xe0000>,
<0x10700000 0x8000>;
reg-names = "cfg", "l1tcm";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x10500000 0x100000>;
scp@0 {
compatible = "mediatek,scp-core";
reg = <0x0 0xa0000>;
reg-names = "sram";
cros-ec-rpmsg {
compatible = "google,cros-ec-rpmsg";
mediatek,rpmsg-name = "cros-ec-rpmsg";
};
};
scp@a0000 {
compatible = "mediatek,scp-core";
reg = <0xa0000 0x20000>;
reg-names = "sram";
cros-ec-rpmsg {
compatible = "google,cros-ec-rpmsg";
mediatek,rpmsg-name = "cros-ec-rpmsg";
};
};
};
......@@ -66,7 +66,9 @@ allOf:
- qcom,msm8953-adsp-pil
- qcom,msm8974-adsp-pil
- qcom,msm8996-adsp-pil
- qcom,msm8996-slpi-pil
- qcom,msm8998-adsp-pas
- qcom,msm8998-slpi-pas
- qcom,sdm845-adsp-pas
- qcom,sdm845-cdsp-pas
- qcom,sdm845-slpi-pas
......@@ -79,24 +81,6 @@ allOf:
items:
- const: xo
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8996-slpi-pil
- qcom,msm8998-slpi-pas
then:
properties:
clocks:
items:
- description: XO clock
- description: AGGRE2 clock
clock-names:
items:
- const: xo
- const: aggre2
- if:
properties:
compatible:
......
......@@ -220,7 +220,6 @@ allOf:
- description: GCC MSS GPLL0 clock
- description: GCC MSS SNOC_AXI clock
- description: GCC MSS MNOC_AXI clock
- description: RPM PNOC clock
- description: RPM QDSS clock
clock-names:
items:
......@@ -231,7 +230,6 @@ allOf:
- const: gpll0_mss
- const: snoc_axi
- const: mnoc_axi
- const: pnoc
- const: qdss
glink-edge: false
required:
......
......@@ -16,6 +16,7 @@ description:
properties:
compatible:
enum:
- qcom,sc7180-adsp-pas
- qcom,sc7180-mpss-pas
- qcom,sc7280-mpss-pas
......@@ -30,26 +31,6 @@ properties:
items:
- const: xo
interrupts:
minItems: 6
interrupt-names:
minItems: 6
power-domains:
minItems: 2
items:
- description: CX power domain
- description: MX power domain
- description: MSS power domain
power-domain-names:
minItems: 2
items:
- const: cx
- const: mx
- const: mss
memory-region:
maxItems: 1
description: Reference to the reserved-memory for the Hexagon core
......@@ -71,6 +52,40 @@ required:
allOf:
- $ref: /schemas/remoteproc/qcom,pas-common.yaml#
- if:
properties:
compatible:
enum:
- qcom,sc7180-adsp-pas
then:
properties:
interrupts:
maxItems: 5
interrupt-names:
maxItems: 5
else:
properties:
interrupts:
minItems: 6
interrupt-names:
minItems: 6
- if:
properties:
compatible:
enum:
- qcom,sc7180-adsp-pas
then:
properties:
power-domains:
items:
- description: LCX power domain
- description: LMX power domain
power-domain-names:
items:
- const: lcx
- const: lmx
- if:
properties:
compatible:
......@@ -79,15 +94,31 @@ allOf:
then:
properties:
power-domains:
minItems: 3
items:
- description: CX power domain
- description: MX power domain
- description: MSS power domain
power-domain-names:
minItems: 3
else:
items:
- const: cx
- const: mx
- const: mss
- if:
properties:
compatible:
enum:
- qcom,sc7280-mpss-pas
then:
properties:
power-domains:
maxItems: 2
items:
- description: CX power domain
- description: MX power domain
power-domain-names:
maxItems: 2
items:
- const: cx
- const: mx
unevaluatedProperties: false
......
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/remoteproc/qcom,sm6375-pas.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM6375 Peripheral Authentication Service
maintainers:
- Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
description:
Qualcomm SM6375 SoC Peripheral Authentication Service loads and boots
firmware on the Qualcomm DSP Hexagon cores.
properties:
compatible:
enum:
- qcom,sm6375-adsp-pas
- qcom,sm6375-cdsp-pas
- qcom,sm6375-mpss-pas
reg:
maxItems: 1
clocks:
items:
- description: XO clock
clock-names:
items:
- const: xo
memory-region:
maxItems: 1
description: Reference to the reserved-memory for the Hexagon core
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
description: Firmware name for the Hexagon core
smd-edge: false
required:
- compatible
- reg
allOf:
- $ref: /schemas/remoteproc/qcom,pas-common.yaml#
- if:
properties:
compatible:
enum:
- qcom,sm6375-adsp-pas
- qcom,sm6375-cdsp-pas
then:
properties:
interrupts:
maxItems: 5
interrupt-names:
maxItems: 5
else:
properties:
interrupts:
minItems: 6
interrupt-names:
minItems: 6
- if:
properties:
compatible:
enum:
- qcom,sm6375-adsp-pas
then:
properties:
power-domains:
items:
- description: LCX power domain
- description: LMX power domain
power-domain-names:
items:
- const: lcx
- const: lmx
- if:
properties:
compatible:
enum:
- qcom,sm6375-cdsp-pas
- qcom,sm6375-mpss-pas
then:
properties:
power-domains:
items:
- description: CX power domain
power-domain-names:
items:
- const: cx
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
#include <dt-bindings/power/qcom-rpmpd.h>
remoteproc_adsp: remoteproc@a400000 {
compatible = "qcom,sm6375-adsp-pas";
reg = <0x0a400000 0x100>;
interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
<&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
<&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
<&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
<&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "wdog", "fatal", "ready",
"handover", "stop-ack";
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>;
clock-names = "xo";
power-domains = <&rpmpd SM6375_VDD_LPI_CX>,
<&rpmpd SM6375_VDD_LPI_MX>;
power-domain-names = "lcx", "lmx";
memory-region = <&pil_adsp_mem>;
qcom,smem-states = <&smp2p_adsp_out 0>;
qcom,smem-state-names = "stop";
glink-edge {
interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
IPCC_MPROC_SIGNAL_GLINK_QMP
IRQ_TYPE_EDGE_RISING>;
mboxes = <&ipcc IPCC_CLIENT_LPASS
IPCC_MPROC_SIGNAL_GLINK_QMP>;
label = "lpass";
qcom,remote-pid = <2>;
/* ... */
};
};
......@@ -66,6 +66,17 @@ properties:
Should contain the name of the default firmware image
file located on the firmware search path.
interrupts:
maxItems: 1
description:
Interrupt specifiers enable the virtio/rpmsg communication between MPU
and the PRU/RTU cores. For the values of the interrupt cells please refer
to interrupt-controller/ti,pruss-intc.yaml schema.
interrupt-names:
items:
- const: vring
if:
properties:
compatible:
......@@ -171,6 +182,9 @@ examples:
<0x22400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-pru0_0-fw";
interrupt-parent = <&icssg0_intc>;
interrupts = <16 2 2>;
interrupt-names = "vring";
};
rtu0_0: rtu@4000 {
......@@ -180,6 +194,9 @@ examples:
<0x23400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-rtu0_0-fw";
interrupt-parent = <&icssg0_intc>;
interrupts = <20 4 4>;
interrupt-names = "vring";
};
tx_pru0_0: txpru@a000 {
......@@ -198,6 +215,9 @@ examples:
<0x24400 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-pru0_1-fw";
interrupt-parent = <&icssg0_intc>;
interrupts = <18 3 3>;
interrupt-names = "vring";
};
rtu0_1: rtu@6000 {
......@@ -207,6 +227,9 @@ examples:
<0x23c00 0x100>;
reg-names = "iram", "control", "debug";
firmware-name = "am65x-rtu0_1-fw";
interrupt-parent = <&icssg0_intc>;
interrupts = <22 5 5>;
interrupt-names = "vring";
};
tx_pru0_1: txpru@c000 {
......
......@@ -859,7 +859,7 @@ &scp {
pinctrl-names = "default";
pinctrl-0 = <&scp_pins>;
cros_ec {
cros-ec-rpmsg {
compatible = "google,cros-ec-rpmsg";
mediatek,rpmsg-name = "cros-ec-rpmsg";
};
......
......@@ -1312,7 +1312,7 @@ &scp {
pinctrl-names = "default";
pinctrl-0 = <&scp_pins>;
cros-ec {
cros-ec-rpmsg {
compatible = "google,cros-ec-rpmsg";
mediatek,rpmsg-name = "cros-ec-rpmsg";
};
......
......@@ -47,6 +47,7 @@
#define MT8192_SCP2SPM_IPC_CLR 0x4094
#define MT8192_GIPC_IN_SET 0x4098
#define MT8192_HOST_IPC_INT_BIT BIT(0)
#define MT8195_CORE1_HOST_IPC_INT_BIT BIT(4)
#define MT8192_CORE0_SW_RSTN_CLR 0x10000
#define MT8192_CORE0_SW_RSTN_SET 0x10004
......@@ -54,8 +55,28 @@
#define MT8192_CORE0_WDT_IRQ 0x10030
#define MT8192_CORE0_WDT_CFG 0x10034
#define MT8195_SYS_STATUS 0x4004
#define MT8195_CORE0_WDT BIT(16)
#define MT8195_CORE1_WDT BIT(17)
#define MT8195_L1TCM_SRAM_PDN_RESERVED_RSI_BITS GENMASK(7, 4)
#define MT8195_CPU1_SRAM_PD 0x1084
#define MT8195_SSHUB2APMCU_IPC_SET 0x4088
#define MT8195_SSHUB2APMCU_IPC_CLR 0x408C
#define MT8195_CORE1_SW_RSTN_CLR 0x20000
#define MT8195_CORE1_SW_RSTN_SET 0x20004
#define MT8195_CORE1_MEM_ATT_PREDEF 0x20008
#define MT8195_CORE1_WDT_IRQ 0x20030
#define MT8195_CORE1_WDT_CFG 0x20034
#define MT8195_SEC_CTRL 0x85000
#define MT8195_CORE_OFFSET_ENABLE_D BIT(13)
#define MT8195_CORE_OFFSET_ENABLE_I BIT(12)
#define MT8195_L2TCM_OFFSET_RANGE_0_LOW 0x850b0
#define MT8195_L2TCM_OFFSET_RANGE_0_HIGH 0x850b4
#define MT8195_L2TCM_OFFSET 0x850d0
#define SCP_FW_VER_LEN 32
#define SCP_SHARE_BUFFER_SIZE 288
......@@ -91,17 +112,24 @@ struct mtk_scp_of_data {
size_t ipi_buf_offset;
};
struct mtk_scp_of_cluster {
void __iomem *reg_base;
void __iomem *l1tcm_base;
size_t l1tcm_size;
phys_addr_t l1tcm_phys;
struct list_head mtk_scp_list;
/* Prevent concurrent operations of this structure and L2TCM power control. */
struct mutex cluster_lock;
u32 l2tcm_refcnt;
};
struct mtk_scp {
struct device *dev;
struct rproc *rproc;
struct clk *clk;
void __iomem *reg_base;
void __iomem *sram_base;
size_t sram_size;
phys_addr_t sram_phys;
void __iomem *l1tcm_base;
size_t l1tcm_size;
phys_addr_t l1tcm_phys;
const struct mtk_scp_of_data *data;
......@@ -119,6 +147,9 @@ struct mtk_scp {
size_t dram_size;
struct rproc_subdev *rpmsg_subdev;
struct list_head elem;
struct mtk_scp_of_cluster *cluster;
};
/**
......
This diff is collapsed.
......@@ -177,7 +177,7 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len,
mutex_lock(&scp->send_lock);
/* Wait until SCP receives the last command */
ret = readl_poll_timeout_atomic(scp->reg_base + scp->data->host_to_scp_reg,
ret = readl_poll_timeout_atomic(scp->cluster->reg_base + scp->data->host_to_scp_reg,
val, !val, 0, SCP_TIMEOUT_US);
if (ret) {
dev_err(scp->dev, "%s: IPI timeout!\n", __func__);
......@@ -192,7 +192,7 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len,
scp->ipi_id_ack[id] = false;
/* send the command to SCP */
writel(scp->data->host_to_scp_int_bit,
scp->reg_base + scp->data->host_to_scp_reg);
scp->cluster->reg_base + scp->data->host_to_scp_reg);
if (wait) {
/* wait for SCP's ACK */
......
......@@ -2322,7 +2322,6 @@ static const struct rproc_hexagon_res msm8996_mss = {
},
.proxy_clk_names = (char*[]){
"xo",
"pnoc",
"qdss",
NULL
},
......
......@@ -813,6 +813,21 @@ static const struct adsp_data sm6350_adsp_resource = {
.ssctl_id = 0x14,
};
static const struct adsp_data sm6375_mpss_resource = {
.crash_reason_smem = 421,
.firmware_name = "modem.mdt",
.pas_id = 4,
.minidump_id = 3,
.auto_boot = false,
.proxy_pd_names = (char*[]){
"cx",
NULL
},
.ssr_name = "mpss",
.sysmon_name = "modem",
.ssctl_id = 0x12,
};
static const struct adsp_data sm8150_adsp_resource = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
......@@ -1161,6 +1176,7 @@ 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,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
{ .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
{ .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
{ .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
......@@ -1180,6 +1196,9 @@ static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
{ .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
{ .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
{ .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource},
{ .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource},
{ .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource},
{ .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
{ .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
{ .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
......
......@@ -16,10 +16,9 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/remoteproc.h>
#include <linux/reset.h>
......@@ -341,7 +340,6 @@ static int st_rproc_parse_dt(struct platform_device *pdev)
static int st_rproc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *match;
struct st_rproc *ddata;
struct device_node *np = dev->of_node;
struct rproc *rproc;
......@@ -349,19 +347,17 @@ static int st_rproc_probe(struct platform_device *pdev)
int enabled;
int ret, i;
match = of_match_device(st_rproc_match, dev);
if (!match || !match->data) {
dev_err(dev, "No device match found\n");
return -ENODEV;
}
rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
if (!rproc)
return -ENOMEM;
rproc->has_iommu = false;
ddata = rproc->priv;
ddata->config = (struct st_rproc_config *)match->data;
ddata->config = (struct st_rproc_config *)device_get_match_data(dev);
if (!ddata->config) {
ret = -ENODEV;
goto free_rproc;
}
platform_set_drvdata(pdev, rproc);
......
......@@ -712,9 +712,9 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev,
unsigned int tzen;
int err, irq;
irq = platform_get_irq(pdev, 0);
irq = platform_get_irq_optional(pdev, 0);
if (irq == -EPROBE_DEFER)
return dev_err_probe(dev, irq, "failed to get interrupt\n");
return irq;
if (irq > 0) {
err = devm_request_irq(dev, irq, stm32_rproc_wdg, 0,
......
......@@ -39,12 +39,14 @@ enum zynqmp_r5_cluster_mode {
* struct mem_bank_data - Memory Bank description
*
* @addr: Start address of memory bank
* @da: device address
* @size: Size of Memory bank
* @pm_domain_id: Power-domains id of memory bank for firmware to turn on/off
* @bank_name: name of the bank for remoteproc framework
*/
struct mem_bank_data {
phys_addr_t addr;
u32 da;
size_t size;
u32 pm_domain_id;
char *bank_name;
......@@ -75,11 +77,19 @@ struct mbox_info {
* Hardcoded TCM bank values. This will be removed once TCM bindings are
* accepted for system-dt specifications and upstreamed in linux kernel
*/
static const struct mem_bank_data zynqmp_tcm_banks[] = {
{0xffe00000UL, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
{0xffe20000UL, 0x10000UL, PD_R5_0_BTCM, "btcm0"},
{0xffe90000UL, 0x10000UL, PD_R5_1_ATCM, "atcm1"},
{0xffeb0000UL, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
{0xffe20000UL, 0x20000, 0x10000UL, PD_R5_0_BTCM, "btcm0"},
{0xffe90000UL, 0x0, 0x10000UL, PD_R5_1_ATCM, "atcm1"},
{0xffeb0000UL, 0x20000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
};
/* In lockstep mode cluster combines each 64KB TCM and makes 128KB TCM */
static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
{0xffe00000UL, 0x0, 0x20000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 128KB each */
{0xffe20000UL, 0x20000, 0x20000UL, PD_R5_0_BTCM, "btcm0"},
{0, 0, 0, PD_R5_1_ATCM, ""},
{0, 0, 0, PD_R5_1_BTCM, ""},
};
/**
......@@ -526,30 +536,6 @@ static int tcm_mem_map(struct rproc *rproc,
/* clear TCMs */
memset_io(va, 0, mem->len);
/*
* The R5s expect their TCM banks to be at address 0x0 and 0x2000,
* while on the Linux side they are at 0xffexxxxx.
*
* Zero out the high 12 bits of the address. This will give
* expected values for TCM Banks 0A and 0B (0x0 and 0x20000).
*/
mem->da &= 0x000fffff;
/*
* TCM Banks 1A and 1B still have to be translated.
*
* Below handle these two banks' absolute addresses (0xffe90000 and
* 0xffeb0000) and convert to the expected relative addresses
* (0x0 and 0x20000).
*/
if (mem->da == 0x90000 || mem->da == 0xB0000)
mem->da -= 0x90000;
/* if translated TCM bank address is not valid report error */
if (mem->da != 0x0 && mem->da != 0x20000) {
dev_err(&rproc->dev, "invalid TCM address: %x\n", mem->da);
return -EINVAL;
}
return 0;
}
......@@ -571,6 +557,7 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
u32 pm_domain_id;
size_t bank_size;
char *bank_name;
u32 da;
r5_core = rproc->priv;
dev = r5_core->dev;
......@@ -583,6 +570,7 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
*/
for (i = 0; i < num_banks; i++) {
bank_addr = r5_core->tcm_banks[i]->addr;
da = r5_core->tcm_banks[i]->da;
bank_name = r5_core->tcm_banks[i]->bank_name;
bank_size = r5_core->tcm_banks[i]->size;
pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
......@@ -595,11 +583,11 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
goto release_tcm_split;
}
dev_dbg(dev, "TCM carveout split mode %s addr=%llx, size=0x%lx",
bank_name, bank_addr, bank_size);
dev_dbg(dev, "TCM carveout split mode %s addr=%llx, da=0x%x, size=0x%lx",
bank_name, bank_addr, da, bank_size);
rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
bank_size, bank_addr,
bank_size, da,
tcm_mem_map, tcm_mem_unmap,
bank_name);
if (!rproc_mem) {
......@@ -640,6 +628,7 @@ static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
struct device *dev;
u32 pm_domain_id;
char *bank_name;
u32 da;
r5_core = rproc->priv;
dev = r5_core->dev;
......@@ -650,14 +639,11 @@ static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
/*
* In lockstep mode, TCM is contiguous memory block
* However, each TCM block still needs to be enabled individually.
* So, Enable each TCM block individually, but add their size
* to create contiguous memory region.
* So, Enable each TCM block individually.
* Although ATCM and BTCM is contiguous memory block, add two separate
* carveouts for both.
*/
bank_addr = r5_core->tcm_banks[0]->addr;
bank_name = r5_core->tcm_banks[0]->bank_name;
for (i = 0; i < num_banks; i++) {
bank_size += r5_core->tcm_banks[i]->size;
pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
/* Turn on each TCM bank individually */
......@@ -668,23 +654,32 @@ static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
goto release_tcm_lockstep;
}
}
dev_dbg(dev, "TCM add carveout lockstep mode %s addr=0x%llx, size=0x%lx",
bank_name, bank_addr, bank_size);
/* Register TCM address range, TCM map and unmap functions */
rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
bank_size, bank_addr,
tcm_mem_map, tcm_mem_unmap,
bank_name);
if (!rproc_mem) {
ret = -ENOMEM;
goto release_tcm_lockstep;
}
bank_size = r5_core->tcm_banks[i]->size;
if (bank_size == 0)
continue;
/* If registration is success, add carveouts */
rproc_add_carveout(rproc, rproc_mem);
bank_addr = r5_core->tcm_banks[i]->addr;
da = r5_core->tcm_banks[i]->da;
bank_name = r5_core->tcm_banks[i]->bank_name;
/* Register TCM address range, TCM map and unmap functions */
rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
bank_size, da,
tcm_mem_map, tcm_mem_unmap,
bank_name);
if (!rproc_mem) {
ret = -ENOMEM;
zynqmp_pm_release_node(pm_domain_id);
goto release_tcm_lockstep;
}
/* If registration is success, add carveouts */
rproc_add_carveout(rproc, rproc_mem);
dev_dbg(dev, "TCM carveout lockstep mode %s addr=0x%llx, da=0x%x, size=0x%lx",
bank_name, bank_addr, da, bank_size);
}
return 0;
......@@ -895,12 +890,19 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
*/
static int zynqmp_r5_get_tcm_node(struct zynqmp_r5_cluster *cluster)
{
const struct mem_bank_data *zynqmp_tcm_banks;
struct device *dev = cluster->dev;
struct zynqmp_r5_core *r5_core;
int tcm_bank_count, tcm_node;
int i, j;
tcm_bank_count = ARRAY_SIZE(zynqmp_tcm_banks);
if (cluster->mode == SPLIT_MODE) {
zynqmp_tcm_banks = zynqmp_tcm_banks_split;
tcm_bank_count = ARRAY_SIZE(zynqmp_tcm_banks_split);
} else {
zynqmp_tcm_banks = zynqmp_tcm_banks_lockstep;
tcm_bank_count = ARRAY_SIZE(zynqmp_tcm_banks_lockstep);
}
/* count per core tcm banks */
tcm_bank_count = tcm_bank_count / cluster->core_count;
......
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