* [PATCH v7 00/12] Add support for MT8195 SCP 2nd core
@ 2023-02-15 4:12 Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 01/12] dt-bindings: remoteproc: mediatek: Improve the rpmsg subnode definition Tinghan Shen
` (11 more replies)
0 siblings, 12 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The mediatek remoteproc driver currently only allows bringing up a
single core SCP, e.g. MT8183. It also only bringing up the 1st
core in SoCs with a dual-core SCP, e.g. MT8195. This series support
to bring-up the 2nd core of the dual-core SCP.
v6 -> v7:
1. merge the mtk_scp_cluster struct into the mtk_scp structure
at the "Probe multi-core SCP" patch
v5 -> v6:
1. move the mtk_scp_of_regs structure from mtk_common.h to mtk_scp.c
2. rename the SCP core 0 label from 'scp' to 'scp_c0'
v4 -> v5:
1. move resource release actions to the platform driver remove operation
2. fix dual-core watchdog handling
v3 -> v4:
1. change the representation of dual-core SCP in dts file and update SCP yaml
2. rewrite SCP driver to reflect the change of dts node
3. drop 'remove redundant call of rproc_boot for SCP' in v3 for further investigation
v2 -> v3:
1. change the representation of dual-core SCP in dts file and update SCP yaml
2. rewrite SCP driver to reflect the change of dts node
3. add SCP core 1 node to mt8195.dtsi
4. remove redundant call of rproc_boot for SCP
5. refine IPI error message
v1 -> v2:
1. update dt-binding property description
2. remove kconfig for scp dual driver
3. merge mtk_scp_dual.c and mtk_scp_subdev.c to mtk_scp.c
Tinghan Shen (12):
dt-bindings: remoteproc: mediatek: Improve the rpmsg subnode
definition
arm64: dts: mediatek: mt8183-kukui: Update the node name of SCP rpmsg
subnode
dt-bindings: remoteproc: mediatek: Support MT8195 dual-core SCP
remoteproc: mediatek: Add SCP core 1 register definitions
remoteproc: mediatek: Add MT8195 SCP core 1 operations
remoteproc: mediatek: Extract remoteproc initialization flow
remoteproc: mediatek: Probe multi-core SCP
remoteproc: mediatek: Control SCP core 1 by rproc subdevice
remoteproc: mediatek: Setup MT8195 SCP core 1 SRAM offset
remoteproc: mediatek: Handle MT8195 SCP core 1 watchdog timeout
remoteproc: mediatek: Refine ipi handler error message
arm64: dts: mediatek: mt8195: Add SCP 2nd core
.../bindings/remoteproc/mtk,scp.yaml | 176 +++++++-
.../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 2 +-
.../boot/dts/mediatek/mt8195-cherry.dtsi | 6 +-
arch/arm64/boot/dts/mediatek/mt8195.dtsi | 32 +-
drivers/remoteproc/mtk_common.h | 38 ++
drivers/remoteproc/mtk_scp.c | 401 ++++++++++++++++--
6 files changed, 596 insertions(+), 59 deletions(-)
--
2.18.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v7 01/12] dt-bindings: remoteproc: mediatek: Improve the rpmsg subnode definition
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 02/12] arm64: dts: mediatek: mt8183-kukui: Update the node name of SCP rpmsg subnode Tinghan Shen
` (10 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Improve the definition of the rpmsg subnode by
assigning a distinct node name and adding the
definition source of node properties.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../bindings/remoteproc/mtk,scp.yaml | 31 +++++++++----------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
index 895415772d1d..271081df0e46 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -58,6 +58,18 @@ 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
+
required:
- compatible
- reg
@@ -89,21 +101,7 @@ allOf:
reg-names:
maxItems: 2
-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 +116,8 @@ 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";
};
};
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 02/12] arm64: dts: mediatek: mt8183-kukui: Update the node name of SCP rpmsg subnode
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 01/12] dt-bindings: remoteproc: mediatek: Improve the rpmsg subnode definition Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-16 11:47 ` Matthias Brugger
2023-02-15 4:12 ` [PATCH v7 03/12] dt-bindings: remoteproc: mediatek: Support MT8195 dual-core SCP Tinghan Shen
` (9 subsequent siblings)
11 siblings, 1 reply; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Align the node name with the definition in SCP bindings.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index fbe14b13051a..a259eb043de5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -810,7 +810,7 @@
pinctrl-names = "default";
pinctrl-0 = <&scp_pins>;
- cros_ec {
+ cros-ec-rpmsg {
compatible = "google,cros-ec-rpmsg";
mediatek,rpmsg-name = "cros-ec-rpmsg";
};
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 03/12] dt-bindings: remoteproc: mediatek: Support MT8195 dual-core SCP
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 01/12] dt-bindings: remoteproc: mediatek: Improve the rpmsg subnode definition Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 02/12] arm64: dts: mediatek: mt8183-kukui: Update the node name of SCP rpmsg subnode Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 04/12] remoteproc: mediatek: Add SCP core 1 register definitions Tinghan Shen
` (8 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Extend the SCP binding to describe the MT8195 dual-core SCP.
Under different applications, the MT8195 SCP can be used as single-core
or dual-core. This change keeps the single-core definitions and
adds new definitions for the dual-core use case.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
.../bindings/remoteproc/mtk,scp.yaml | 145 +++++++++++++++++-
1 file changed, 141 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
index 271081df0e46..09102dda4942 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -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:
@@ -70,6 +68,81 @@ properties:
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
@@ -99,7 +172,37 @@ 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: false
@@ -121,3 +224,37 @@ examples:
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";
+ };
+ };
+ };
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 04/12] remoteproc: mediatek: Add SCP core 1 register definitions
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (2 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 03/12] dt-bindings: remoteproc: mediatek: Support MT8195 dual-core SCP Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-16 11:42 ` Matthias Brugger
2023-02-15 4:12 ` [PATCH v7 05/12] remoteproc: mediatek: Add MT8195 SCP core 1 operations Tinghan Shen
` (7 subsequent siblings)
11 siblings, 1 reply; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Add MT8195 SCP core 1 related register definitions.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/remoteproc/mtk_common.h | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index ea6fa1100a00..3778894c96f3 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -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
@@ -56,6 +57,26 @@
#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_SRAM_REMAP_LOW 0
+#define SCP_SRAM_REMAP_HIGH 1
+#define SCP_SRAM_REMAP_OFFSET 2
+#define SCP_SRAM_REMAP_SIZE 3
+
#define SCP_FW_VER_LEN 32
#define SCP_SHARE_BUFFER_SIZE 288
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 05/12] remoteproc: mediatek: Add MT8195 SCP core 1 operations
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (3 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 04/12] remoteproc: mediatek: Add SCP core 1 register definitions Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 06/12] remoteproc: mediatek: Extract remoteproc initialization flow Tinghan Shen
` (6 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The SCP rproc driver has a set of chip dependent callbacks for
boot sequence and IRQ handling. Implement these callbacks for MT8195
SCP core 1.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/remoteproc/mtk_scp.c | 56 ++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index d421a2ccaa1e..b92274067522 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -176,6 +176,16 @@ static void mt8192_scp_reset_deassert(struct mtk_scp *scp)
writel(1, scp->reg_base + MT8192_CORE0_SW_RSTN_CLR);
}
+static void mt8195_scp_c1_reset_assert(struct mtk_scp *scp)
+{
+ writel(1, scp->reg_base + MT8195_CORE1_SW_RSTN_SET);
+}
+
+static void mt8195_scp_c1_reset_deassert(struct mtk_scp *scp)
+{
+ writel(1, scp->reg_base + MT8195_CORE1_SW_RSTN_CLR);
+}
+
static void mt8183_scp_irq_handler(struct mtk_scp *scp)
{
u32 scp_to_host;
@@ -212,6 +222,18 @@ static void mt8192_scp_irq_handler(struct mtk_scp *scp)
}
}
+static void mt8195_scp_c1_irq_handler(struct mtk_scp *scp)
+{
+ u32 scp_to_host;
+
+ scp_to_host = readl(scp->reg_base + MT8195_SSHUB2APMCU_IPC_SET);
+
+ if (scp_to_host & MT8192_SCP_IPC_INT_BIT)
+ scp_ipi_handler(scp);
+
+ writel(scp_to_host, scp->reg_base + MT8195_SSHUB2APMCU_IPC_CLR);
+}
+
static irqreturn_t scp_irq_handler(int irq, void *priv)
{
struct mtk_scp *scp = priv;
@@ -453,6 +475,19 @@ static int mt8195_scp_before_load(struct mtk_scp *scp)
return 0;
}
+static int mt8195_scp_c1_before_load(struct mtk_scp *scp)
+{
+ scp_sram_power_on(scp->reg_base + MT8195_CPU1_SRAM_PD, 0);
+
+ /* hold SCP in reset while loading FW. */
+ scp->data->scp_reset_assert(scp);
+
+ /* enable MPU for all memory regions */
+ writel(0xff, scp->reg_base + MT8195_CORE1_MEM_ATT_PREDEF);
+
+ return 0;
+}
+
static int scp_load(struct rproc *rproc, const struct firmware *fw)
{
struct mtk_scp *scp = rproc->priv;
@@ -625,6 +660,15 @@ static void mt8195_scp_stop(struct mtk_scp *scp)
writel(0, scp->reg_base + MT8192_CORE0_WDT_CFG);
}
+static void mt8195_scp_c1_stop(struct mtk_scp *scp)
+{
+ /* Power off CPU SRAM */
+ scp_sram_power_off(scp->reg_base + MT8195_CPU1_SRAM_PD, 0);
+
+ /* Disable SCP watchdog */
+ writel(0, scp->reg_base + MT8195_CORE1_WDT_CFG);
+}
+
static int scp_stop(struct rproc *rproc)
{
struct mtk_scp *scp = (struct mtk_scp *)rproc->priv;
@@ -990,6 +1034,18 @@ static const struct mtk_scp_of_data mt8195_of_data = {
.host_to_scp_int_bit = MT8192_HOST_IPC_INT_BIT,
};
+static const struct mtk_scp_of_data mt8195_of_data_c1 = {
+ .scp_clk_get = mt8195_scp_clk_get,
+ .scp_before_load = mt8195_scp_c1_before_load,
+ .scp_irq_handler = mt8195_scp_c1_irq_handler,
+ .scp_reset_assert = mt8195_scp_c1_reset_assert,
+ .scp_reset_deassert = mt8195_scp_c1_reset_deassert,
+ .scp_stop = mt8195_scp_c1_stop,
+ .scp_da_to_va = mt8192_scp_da_to_va,
+ .host_to_scp_reg = MT8192_GIPC_IN_SET,
+ .host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT,
+};
+
static const struct of_device_id mtk_scp_of_match[] = {
{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 06/12] remoteproc: mediatek: Extract remoteproc initialization flow
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (4 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 05/12] remoteproc: mediatek: Add MT8195 SCP core 1 operations Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 07/12] remoteproc: mediatek: Probe multi-core SCP Tinghan Shen
` (5 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
This is the preparation for probing multi-core SCP. The remoteproc
initialization flow is similar on cores and is reuesd to avoid
redundant code.
The registers of config and l1tcm are shared for multi-core
SCP. Reuse the mapped addresses for all cores.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/remoteproc/mtk_scp.c | 62 ++++++++++++++++++++++++------------
1 file changed, 42 insertions(+), 20 deletions(-)
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index b92274067522..6270c388727a 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -23,6 +23,13 @@
#define MAX_CODE_SIZE 0x500000
#define SECTION_NAME_IPI_BUFFER ".ipi_buffer"
+struct mtk_scp_of_regs {
+ void __iomem *reg_base;
+ void __iomem *l1tcm_base;
+ size_t l1tcm_size;
+ phys_addr_t l1tcm_phys;
+};
+
/**
* scp_get() - get a reference to SCP.
*
@@ -854,7 +861,8 @@ static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
}
}
-static int scp_probe(struct platform_device *pdev)
+static int scp_rproc_init(struct platform_device *pdev,
+ struct mtk_scp_of_regs *of_regs)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
@@ -878,6 +886,11 @@ static int scp_probe(struct platform_device *pdev)
scp->data = of_device_get_match_data(dev);
platform_set_drvdata(pdev, scp);
+ scp->reg_base = of_regs->reg_base;
+ scp->l1tcm_base = of_regs->l1tcm_base;
+ scp->l1tcm_size = of_regs->l1tcm_size;
+ scp->l1tcm_phys = of_regs->l1tcm_phys;
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
scp->sram_base = devm_ioremap_resource(dev, res);
if (IS_ERR(scp->sram_base))
@@ -887,24 +900,6 @@ static int scp_probe(struct platform_device *pdev)
scp->sram_size = resource_size(res);
scp->sram_phys = res->start;
- /* l1tcm is an optional memory region */
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "l1tcm");
- scp->l1tcm_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(scp->l1tcm_base)) {
- ret = PTR_ERR(scp->l1tcm_base);
- if (ret != -EINVAL) {
- return dev_err_probe(dev, ret, "Failed to map l1tcm memory\n");
- }
- } else {
- scp->l1tcm_size = resource_size(res);
- scp->l1tcm_phys = res->start;
- }
-
- scp->reg_base = devm_platform_ioremap_resource_byname(pdev, "cfg");
- if (IS_ERR(scp->reg_base))
- return dev_err_probe(dev, PTR_ERR(scp->reg_base),
- "Failed to parse and map cfg memory\n");
-
ret = scp->data->scp_clk_get(scp);
if (ret)
return ret;
@@ -932,7 +927,6 @@ static int scp_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0), NULL,
scp_irq_handler, IRQF_ONESHOT,
pdev->name, scp);
-
if (ret) {
dev_err(dev, "failed to request irq\n");
goto remove_subdev;
@@ -956,6 +950,34 @@ static int scp_probe(struct platform_device *pdev)
return ret;
}
+static int scp_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct mtk_scp_of_regs scp_regs;
+ int ret;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
+ scp_regs.reg_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(scp_regs.reg_base))
+ return dev_err_probe(dev, PTR_ERR(scp_regs.reg_base),
+ "Failed to parse and map cfg memory\n");
+
+ /* l1tcm is an optional memory region */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "l1tcm");
+ scp_regs.l1tcm_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(scp_regs.l1tcm_base)) {
+ ret = PTR_ERR(scp_regs.l1tcm_base);
+ if (ret != -EINVAL)
+ return dev_err_probe(dev, ret, "Failed to map l1tcm memory\n");
+ } else {
+ scp_regs.l1tcm_size = resource_size(res);
+ scp_regs.l1tcm_phys = res->start;
+ }
+
+ return scp_rproc_init(pdev, &scp_regs);
+}
+
static int scp_remove(struct platform_device *pdev)
{
struct mtk_scp *scp = platform_get_drvdata(pdev);
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 07/12] remoteproc: mediatek: Probe multi-core SCP
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (5 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 06/12] remoteproc: mediatek: Extract remoteproc initialization flow Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 12:29 ` AngeloGioacchino Del Regno
2023-02-15 4:12 ` [PATCH v7 08/12] remoteproc: mediatek: Control SCP core 1 by rproc subdevice Tinghan Shen
` (4 subsequent siblings)
11 siblings, 1 reply; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The difference of single-core SCP and multi-core SCP device tree is
the presence of child device nodes described SCP cores. The SCP
driver populates the platform device and checks the child nodes
to identify whether it's a single-core SCP or a multi-core SCP.
The resource structure of the multi-core SCP is a list of remoteproc
instances which is different to the single-core SCP. The corresponding
resource releasing action is based on the type of SCP.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
---
drivers/remoteproc/mtk_common.h | 4 +
drivers/remoteproc/mtk_scp.c | 179 +++++++++++++++++++++++++++++---
2 files changed, 168 insertions(+), 15 deletions(-)
diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 3778894c96f3..7821cb15d6fd 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -140,6 +140,10 @@ struct mtk_scp {
size_t dram_size;
struct rproc_subdev *rpmsg_subdev;
+
+ struct list_head elem;
+ struct list_head cluster_cores;
+ struct list_head *cluster;
};
/**
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 6270c388727a..6588e5acb159 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -862,7 +862,9 @@ static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
}
static int scp_rproc_init(struct platform_device *pdev,
- struct mtk_scp_of_regs *of_regs)
+ struct mtk_scp_of_regs *of_regs,
+ const struct mtk_scp_of_data *of_data,
+ bool is_multi_core)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
@@ -883,7 +885,7 @@ static int scp_rproc_init(struct platform_device *pdev,
scp = (struct mtk_scp *)rproc->priv;
scp->rproc = rproc;
scp->dev = dev;
- scp->data = of_device_get_match_data(dev);
+ scp->data = of_data;
platform_set_drvdata(pdev, scp);
scp->reg_base = of_regs->reg_base;
@@ -932,9 +934,11 @@ static int scp_rproc_init(struct platform_device *pdev,
goto remove_subdev;
}
- ret = rproc_add(rproc);
- if (ret)
- goto remove_subdev;
+ if (!is_multi_core) {
+ ret = rproc_add(rproc);
+ if (ret)
+ goto remove_subdev;
+ }
return 0;
@@ -950,9 +954,125 @@ static int scp_rproc_init(struct platform_device *pdev,
return ret;
}
+static void scp_rproc_free(struct mtk_scp *scp)
+{
+ int i;
+
+ scp_remove_rpmsg_subdev(scp);
+ scp_ipi_unregister(scp, SCP_IPI_INIT);
+ scp_unmap_memory_region(scp);
+ for (i = 0; i < SCP_IPI_MAX; i++)
+ mutex_destroy(&scp->ipi_desc[i].lock);
+ mutex_destroy(&scp->send_lock);
+}
+
+static void scp_rproc_exit(struct platform_device *pdev)
+{
+ struct mtk_scp *scp = platform_get_drvdata(pdev);
+
+ rproc_del(scp->rproc);
+ scp_rproc_free(scp);
+}
+
+static int scp_cluster_init(struct platform_device *pdev,
+ struct mtk_scp_of_regs *of_regs)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev_of_node(dev);
+ struct platform_device *cpdev;
+ struct device_node *child;
+ const struct mtk_scp_of_data **cluster_of_data;
+ struct list_head *cluster;
+ struct mtk_scp *scp, *temp;
+ int core_id, num_cores;
+ int ret;
+
+ cluster_of_data = (const struct mtk_scp_of_data **)of_device_get_match_data(dev);
+
+ for (num_cores = 0; cluster_of_data[num_cores]; num_cores++)
+ ;
+
+ cluster = NULL;
+ core_id = 0;
+ for_each_available_child_of_node(np, child) {
+ if (core_id >= num_cores) {
+ ret = -EINVAL;
+ dev_err(dev, "Not support core %d\n", core_id);
+ of_node_put(child);
+ goto init_fail;
+ }
+
+ cpdev = of_find_device_by_node(child);
+ if (!cpdev) {
+ ret = -ENODEV;
+ dev_err(dev, "Not found platform device for core %d\n", core_id);
+ of_node_put(child);
+ goto init_fail;
+ }
+
+ ret = scp_rproc_init(cpdev, of_regs, cluster_of_data[core_id], true);
+ if (ret) {
+ dev_err(dev, "Failed to initialize core %d rproc\n", core_id);
+ put_device(&cpdev->dev);
+ of_node_put(child);
+ goto init_fail;
+ }
+
+ scp = platform_get_drvdata(cpdev);
+ put_device(&cpdev->dev);
+ if (core_id == 0) {
+ INIT_LIST_HEAD(&scp->cluster_cores);
+ cluster = &scp->cluster_cores;
+ platform_set_drvdata(pdev, cluster);
+ }
+
+ list_add_tail(&scp->elem, cluster);
+ scp->cluster = cluster;
+
+ of_node_put(child);
+ core_id++;
+ }
+
+ list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
+ ret = rproc_add(scp->rproc);
+ if (ret)
+ goto add_fail;
+ }
+
+ return 0;
+
+add_fail:
+ list_for_each_entry_continue(scp, cluster, elem) {
+ rproc_del(scp->rproc);
+ }
+init_fail:
+ if (cluster) {
+ list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
+ list_del(&scp->elem);
+ scp_rproc_free(scp);
+ }
+ }
+ return ret;
+}
+
+static void scp_cluster_exit(struct platform_device *pdev)
+{
+ struct list_head *cluster = platform_get_drvdata(pdev);
+ struct platform_device *cpdev;
+ struct mtk_scp *scp, *temp;
+
+ list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
+ list_del(&scp->elem);
+ cpdev = to_platform_device(scp->dev);
+ scp_rproc_exit(cpdev);
+ }
+}
+
static int scp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *core_node;
struct resource *res;
struct mtk_scp_of_regs scp_regs;
int ret;
@@ -975,21 +1095,43 @@ static int scp_probe(struct platform_device *pdev)
scp_regs.l1tcm_phys = res->start;
}
- return scp_rproc_init(pdev, &scp_regs);
+ ret = devm_of_platform_populate(dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
+
+ core_node = of_get_child_by_name(np, "scp");
+ of_node_put(core_node);
+
+ if (!core_node) {
+ dev_info(dev, "single-core scp\n");
+
+ ret = scp_rproc_init(pdev, &scp_regs, of_device_get_match_data(dev), false);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to initialize single-core scp\n");
+ } else {
+ dev_info(dev, "multi-core scp\n");
+
+ ret = scp_cluster_init(pdev, &scp_regs);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to initialize scp cluster\n");
+ }
+
+ return 0;
}
static int scp_remove(struct platform_device *pdev)
{
- struct mtk_scp *scp = platform_get_drvdata(pdev);
- int i;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *core_node;
- rproc_del(scp->rproc);
- scp_remove_rpmsg_subdev(scp);
- scp_ipi_unregister(scp, SCP_IPI_INIT);
- scp_unmap_memory_region(scp);
- for (i = 0; i < SCP_IPI_MAX; i++)
- mutex_destroy(&scp->ipi_desc[i].lock);
- mutex_destroy(&scp->send_lock);
+ core_node = of_get_child_by_name(np, "scp");
+ of_node_put(core_node);
+
+ if (!core_node)
+ scp_rproc_exit(pdev);
+ else
+ scp_cluster_exit(pdev);
return 0;
}
@@ -1068,12 +1210,19 @@ static const struct mtk_scp_of_data mt8195_of_data_c1 = {
.host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT,
};
+static const struct mtk_scp_of_data *mt8195_of_data_cores[] = {
+ &mt8195_of_data,
+ &mt8195_of_data_c1,
+ NULL
+};
+
static const struct of_device_id mtk_scp_of_match[] = {
{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
{ .compatible = "mediatek,mt8188-scp", .data = &mt8188_of_data },
{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
+ { .compatible = "mediatek,mt8195-scp-dual", .data = &mt8195_of_data_cores },
{},
};
MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 08/12] remoteproc: mediatek: Control SCP core 1 by rproc subdevice
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (6 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 07/12] remoteproc: mediatek: Probe multi-core SCP Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 09/12] remoteproc: mediatek: Setup MT8195 SCP core 1 SRAM offset Tinghan Shen
` (3 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Register SCP core 1 as a subdevice of core 0 for the boot sequence
and watchdog timeout handling. The core 1 has to boot after core 0
because the SCP clock and SRAM power is controlled by SCP core 0.
As for watchdog timeout handling, the remoteproc framework helps to
stop/start subdevices automatically when SCP driver receives watchdog
timeout event.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/remoteproc/mtk_common.h | 9 +++++
drivers/remoteproc/mtk_scp.c | 66 +++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 7821cb15d6fd..d333cefc29da 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -112,6 +112,13 @@ struct mtk_scp_of_data {
size_t ipi_buf_offset;
};
+struct mtk_scp_core_subdev {
+ struct rproc_subdev subdev;
+ struct mtk_scp *scp;
+};
+
+#define to_core_subdev(d) container_of(d, struct mtk_scp_core_subdev, subdev)
+
struct mtk_scp {
struct device *dev;
struct rproc *rproc;
@@ -144,6 +151,8 @@ struct mtk_scp {
struct list_head elem;
struct list_head cluster_cores;
struct list_head *cluster;
+
+ struct mtk_scp_core_subdev *core_subdev;
};
/**
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 6588e5acb159..be995c88d333 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -861,6 +861,60 @@ static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
}
}
+static int scp_core_subdev_start(struct rproc_subdev *subdev)
+{
+ struct mtk_scp_core_subdev *core_subdev = to_core_subdev(subdev);
+ struct mtk_scp *scp = core_subdev->scp;
+
+ rproc_boot(scp->rproc);
+
+ return 0;
+}
+
+static void scp_core_subdev_stop(struct rproc_subdev *subdev, bool crashed)
+{
+ struct mtk_scp_core_subdev *core_subdev = to_core_subdev(subdev);
+ struct mtk_scp *scp = core_subdev->scp;
+
+ rproc_shutdown(scp->rproc);
+}
+
+static int scp_core_subdev_register(struct mtk_scp *scp)
+{
+ struct device *dev = scp->dev;
+ struct mtk_scp_core_subdev *core_subdev;
+ struct mtk_scp *scp_c0;
+
+ scp_c0 = list_first_entry(scp->cluster, struct mtk_scp, elem);
+ if (!scp_c0)
+ return -ENODATA;
+
+ core_subdev = devm_kzalloc(dev, sizeof(*core_subdev), GFP_KERNEL);
+ if (!core_subdev)
+ return -ENOMEM;
+
+ core_subdev->scp = scp;
+ core_subdev->subdev.start = scp_core_subdev_start;
+ core_subdev->subdev.stop = scp_core_subdev_stop;
+
+ scp->core_subdev = core_subdev;
+ rproc_add_subdev(scp_c0->rproc, &scp->core_subdev->subdev);
+
+ return 0;
+}
+
+static void scp_core_subdev_unregister(struct mtk_scp *scp)
+{
+ struct mtk_scp *scp_c0;
+
+ if (scp->core_subdev) {
+ scp_c0 = list_first_entry(scp->cluster, struct mtk_scp, elem);
+ rproc_remove_subdev(scp_c0->rproc, &scp->core_subdev->subdev);
+ devm_kfree(scp->dev, scp->core_subdev);
+ scp->core_subdev = NULL;
+ }
+}
+
static int scp_rproc_init(struct platform_device *pdev,
struct mtk_scp_of_regs *of_regs,
const struct mtk_scp_of_data *of_data,
@@ -958,6 +1012,7 @@ static void scp_rproc_free(struct mtk_scp *scp)
{
int i;
+ scp_core_subdev_unregister(scp);
scp_remove_rpmsg_subdev(scp);
scp_ipi_unregister(scp, SCP_IPI_INIT);
scp_unmap_memory_region(scp);
@@ -1034,6 +1089,17 @@ static int scp_cluster_init(struct platform_device *pdev,
}
list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
+ if (!list_is_first(&scp->elem, cluster)) {
+ ret = scp_core_subdev_register(scp);
+ if (ret) {
+ dev_err_probe(scp->dev, ret, "Failed to register as subdev\n");
+ goto add_fail;
+ }
+
+ /* sub cores are booted as subdevices of core 0 */
+ scp->rproc->auto_boot = false;
+ }
+
ret = rproc_add(scp->rproc);
if (ret)
goto add_fail;
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 09/12] remoteproc: mediatek: Setup MT8195 SCP core 1 SRAM offset
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (7 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 08/12] remoteproc: mediatek: Control SCP core 1 by rproc subdevice Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 10/12] remoteproc: mediatek: Handle MT8195 SCP core 1 watchdog timeout Tinghan Shen
` (2 subsequent siblings)
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Because MT8195 SCP core 0 and core 1 both boot from head of SRAM and
have the same viewpoint of SRAM, SCP has a "core 1 SRAM offset"
configuration to control the access destination of SCP core 1 to boot
core 1 from different SRAM location.
The "core 1 SRAM offset" configuration is composed by a range
and an offset. It works like a simple memory mapped mechanism.
When SCP core 1 accesses a SRAM address located in the range,
the SCP bus adds the configured offset to the address to
shift the physical destination address on SCP SRAM. This shifting is
transparent to the software running on SCP core 1.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/remoteproc/mtk_scp.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index be995c88d333..6d88b53fc07e 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -484,6 +484,9 @@ static int mt8195_scp_before_load(struct mtk_scp *scp)
static int mt8195_scp_c1_before_load(struct mtk_scp *scp)
{
+ u32 sec_ctrl;
+ struct mtk_scp *scp_c0;
+
scp_sram_power_on(scp->reg_base + MT8195_CPU1_SRAM_PD, 0);
/* hold SCP in reset while loading FW. */
@@ -492,6 +495,30 @@ static int mt8195_scp_c1_before_load(struct mtk_scp *scp)
/* enable MPU for all memory regions */
writel(0xff, scp->reg_base + MT8195_CORE1_MEM_ATT_PREDEF);
+ /*
+ * The L2TCM_OFFSET_RANGE and L2TCM_OFFSET shift the destination address
+ * on SRAM when SCP core 1 accesses SRAM.
+ *
+ * This configuration solves booting the SCP core 0 and core 1 from
+ * different SRAM address because core 0 and core 1 both boot from
+ * the head of SRAM by default. this must be configured before boot SCP core 1.
+ *
+ * The value of L2TCM_OFFSET_RANGE is from the viewpoint of SCP core 1.
+ * When SCP core 1 issues address within the range (L2TCM_OFFSET_RANGE),
+ * the address will be added with a fixed offset (L2TCM_OFFSET) on the bus.
+ * The shift action is tranparent to software.
+ */
+ writel(0, scp->reg_base + MT8195_L2TCM_OFFSET_RANGE_0_LOW);
+ writel(scp->sram_size, scp->reg_base + MT8195_L2TCM_OFFSET_RANGE_0_HIGH);
+
+ scp_c0 = list_first_entry(scp->cluster, struct mtk_scp, elem);
+ writel(scp->sram_phys - scp_c0->sram_phys, scp->reg_base + MT8195_L2TCM_OFFSET);
+
+ /* enable SRAM offset when fetching instruction and data */
+ sec_ctrl = readl(scp->reg_base + MT8195_SEC_CTRL);
+ sec_ctrl |= MT8195_CORE_OFFSET_ENABLE_I | MT8195_CORE_OFFSET_ENABLE_D;
+ writel(sec_ctrl, scp->reg_base + MT8195_SEC_CTRL);
+
return 0;
}
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 10/12] remoteproc: mediatek: Handle MT8195 SCP core 1 watchdog timeout
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (8 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 09/12] remoteproc: mediatek: Setup MT8195 SCP core 1 SRAM offset Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 11/12] remoteproc: mediatek: Refine ipi handler error message Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 12/12] arm64: dts: mediatek: mt8195: Add SCP 2nd core Tinghan Shen
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The MT8195 SCP core 1 watchdog timeout needs to be handled in the
SCP core 0 IRQ handler because the MT8195 SCP core 1 watchdog timeout
IRQ is wired on the same IRQ entry for core 0 watchdog timeout.
MT8195 SCP has a watchdog status register to identify the watchdog
timeout source when IRQ triggered.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/remoteproc/mtk_common.h | 4 ++++
drivers/remoteproc/mtk_scp.c | 25 ++++++++++++++++++++++++-
2 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index d333cefc29da..1641d41dab5f 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -55,6 +55,10 @@
#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
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 6d88b53fc07e..6bc5f7f138d5 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -229,6 +229,29 @@ static void mt8192_scp_irq_handler(struct mtk_scp *scp)
}
}
+static void mt8195_scp_irq_handler(struct mtk_scp *scp)
+{
+ u32 scp_to_host;
+
+ scp_to_host = readl(scp->reg_base + MT8192_SCP2APMCU_IPC_SET);
+
+ if (scp_to_host & MT8192_SCP_IPC_INT_BIT) {
+ scp_ipi_handler(scp);
+ } else {
+ u32 reason = readl(scp->reg_base + MT8195_SYS_STATUS);
+
+ if (reason & MT8195_CORE0_WDT)
+ writel(1, scp->reg_base + MT8192_CORE0_WDT_IRQ);
+
+ if (reason & MT8195_CORE1_WDT)
+ writel(1, scp->reg_base + MT8195_CORE1_WDT_IRQ);
+
+ scp_wdt_handler(scp, reason);
+ }
+
+ writel(scp_to_host, scp->reg_base + MT8192_SCP2APMCU_IPC_CLR);
+}
+
static void mt8195_scp_c1_irq_handler(struct mtk_scp *scp)
{
u32 scp_to_host;
@@ -1282,7 +1305,7 @@ static const struct mtk_scp_of_data mt8192_of_data = {
static const struct mtk_scp_of_data mt8195_of_data = {
.scp_clk_get = mt8195_scp_clk_get,
.scp_before_load = mt8195_scp_before_load,
- .scp_irq_handler = mt8192_scp_irq_handler,
+ .scp_irq_handler = mt8195_scp_irq_handler,
.scp_reset_assert = mt8192_scp_reset_assert,
.scp_reset_deassert = mt8192_scp_reset_deassert,
.scp_stop = mt8195_scp_stop,
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 11/12] remoteproc: mediatek: Refine ipi handler error message
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (9 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 10/12] remoteproc: mediatek: Handle MT8195 SCP core 1 watchdog timeout Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 12/12] arm64: dts: mediatek: mt8195: Add SCP 2nd core Tinghan Shen
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The error message doesn't accurately reflect the cause of
the error. The error is due to a handler not being found,
not an invalid IPI ID.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/remoteproc/mtk_scp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 6bc5f7f138d5..006493f4bb4c 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -113,7 +113,7 @@ static void scp_ipi_handler(struct mtk_scp *scp)
scp_ipi_lock(scp, id);
handler = ipi_desc[id].handler;
if (!handler) {
- dev_err(scp->dev, "No such ipi id = %d\n", id);
+ dev_err(scp->dev, "No handler for ipi id = %d\n", id);
scp_ipi_unlock(scp, id);
return;
}
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v7 12/12] arm64: dts: mediatek: mt8195: Add SCP 2nd core
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
` (10 preceding siblings ...)
2023-02-15 4:12 ` [PATCH v7 11/12] remoteproc: mediatek: Refine ipi handler error message Tinghan Shen
@ 2023-02-15 4:12 ` Tinghan Shen
11 siblings, 0 replies; 17+ messages in thread
From: Tinghan Shen @ 2023-02-15 4:12 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Tinghan Shen
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Rewrite the MT8195 SCP device node as a cluster and
add the SCP 2nd core in it.
Since the SCP device node is changed to multi-core structure,
enable SCP cluster to enable probing SCP core 0.
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
.../boot/dts/mediatek/mt8195-cherry.dtsi | 6 +++-
arch/arm64/boot/dts/mediatek/mt8195.dtsi | 32 ++++++++++++++-----
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index 56749cfe7c33..31415d71b6a4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -933,7 +933,11 @@
interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
};
-&scp {
+&scp_cluster {
+ status = "okay";
+};
+
+&scp_c0 {
status = "okay";
firmware-name = "mediatek/mt8195/scp.img";
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 8f1264d5290b..31209ef7e55d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -826,14 +826,30 @@
clocks = <&infracfg_ao CLK_INFRA_AO_GCE2>;
};
- scp: scp@10500000 {
- compatible = "mediatek,mt8195-scp";
- reg = <0 0x10500000 0 0x100000>,
- <0 0x10720000 0 0xe0000>,
- <0 0x10700000 0 0x8000>;
- reg-names = "sram", "cfg", "l1tcm";
- interrupts = <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH 0>;
+ scp_cluster: scp@10500000 {
+ compatible = "mediatek,mt8195-scp-dual";
+ reg = <0 0x10720000 0 0xe0000>, <0 0x10700000 0 0x8000>;
+ reg-names = "cfg", "l1tcm";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0x10500000 0x100000>;
status = "disabled";
+
+ scp_c0: scp@0 {
+ compatible = "mediatek,scp-core";
+ reg = <0x0 0xa0000>;
+ reg-names = "sram";
+ interrupts = <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ scp_c1: scp@a0000 {
+ compatible = "mediatek,scp-core";
+ reg = <0xa0000 0x20000>;
+ reg-names = "sram";
+ interrupts = <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
};
scp_adsp: clock-controller@10720000 {
@@ -2291,7 +2307,7 @@
<&iommu_vdo M4U_PORT_L19_VENC_REF_LUMA>,
<&iommu_vdo M4U_PORT_L19_VENC_REF_CHROMA>;
interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH 0>;
- mediatek,scp = <&scp>;
+ mediatek,scp = <&scp_c0>;
clocks = <&vencsys CLK_VENC_VENC>;
clock-names = "venc_sel";
assigned-clocks = <&topckgen CLK_TOP_VENC>;
--
2.18.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v7 07/12] remoteproc: mediatek: Probe multi-core SCP
2023-02-15 4:12 ` [PATCH v7 07/12] remoteproc: mediatek: Probe multi-core SCP Tinghan Shen
@ 2023-02-15 12:29 ` AngeloGioacchino Del Regno
2023-02-16 2:40 ` TingHan Shen (沈廷翰)
0 siblings, 1 reply; 17+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-02-15 12:29 UTC (permalink / raw)
To: Tinghan Shen, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Matthias Brugger
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Il 15/02/23 05:12, Tinghan Shen ha scritto:
> The difference of single-core SCP and multi-core SCP device tree is
> the presence of child device nodes described SCP cores. The SCP
> driver populates the platform device and checks the child nodes
> to identify whether it's a single-core SCP or a multi-core SCP.
>
> The resource structure of the multi-core SCP is a list of remoteproc
> instances which is different to the single-core SCP. The corresponding
> resource releasing action is based on the type of SCP.
>
> Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
> ---
> drivers/remoteproc/mtk_common.h | 4 +
> drivers/remoteproc/mtk_scp.c | 179 +++++++++++++++++++++++++++++---
> 2 files changed, 168 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
> index 3778894c96f3..7821cb15d6fd 100644
> --- a/drivers/remoteproc/mtk_common.h
> +++ b/drivers/remoteproc/mtk_common.h
> @@ -140,6 +140,10 @@ struct mtk_scp {
> size_t dram_size;
>
> struct rproc_subdev *rpmsg_subdev;
> +
> + struct list_head elem;
> + struct list_head cluster_cores;
> + struct list_head *cluster;
I don't understand why you need both `cluster_cores` and `cluster`... check below.
> };
>
> /**
> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> index 6270c388727a..6588e5acb159 100644
> --- a/drivers/remoteproc/mtk_scp.c
> +++ b/drivers/remoteproc/mtk_scp.c
> @@ -862,7 +862,9 @@ static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
> }
>
> static int scp_rproc_init(struct platform_device *pdev,
> - struct mtk_scp_of_regs *of_regs)
> + struct mtk_scp_of_regs *of_regs,
> + const struct mtk_scp_of_data *of_data,
> + bool is_multi_core)
> {
> struct device *dev = &pdev->dev;
> struct device_node *np = dev->of_node;
> @@ -883,7 +885,7 @@ static int scp_rproc_init(struct platform_device *pdev,
> scp = (struct mtk_scp *)rproc->priv;
> scp->rproc = rproc;
> scp->dev = dev;
> - scp->data = of_device_get_match_data(dev);
> + scp->data = of_data;
> platform_set_drvdata(pdev, scp);
>
> scp->reg_base = of_regs->reg_base;
> @@ -932,9 +934,11 @@ static int scp_rproc_init(struct platform_device *pdev,
> goto remove_subdev;
> }
>
> - ret = rproc_add(rproc);
> - if (ret)
> - goto remove_subdev;
> + if (!is_multi_core) {
> + ret = rproc_add(rproc);
> + if (ret)
> + goto remove_subdev;
> + }
>
> return 0;
>
> @@ -950,9 +954,125 @@ static int scp_rproc_init(struct platform_device *pdev,
> return ret;
> }
>
> +static void scp_rproc_free(struct mtk_scp *scp)
> +{
> + int i;
> +
> + scp_remove_rpmsg_subdev(scp);
> + scp_ipi_unregister(scp, SCP_IPI_INIT);
> + scp_unmap_memory_region(scp);
> + for (i = 0; i < SCP_IPI_MAX; i++)
> + mutex_destroy(&scp->ipi_desc[i].lock);
> + mutex_destroy(&scp->send_lock);
> +}
> +
> +static void scp_rproc_exit(struct platform_device *pdev)
> +{
> + struct mtk_scp *scp = platform_get_drvdata(pdev);
> +
> + rproc_del(scp->rproc);
> + scp_rproc_free(scp);
> +}
> +
> +static int scp_cluster_init(struct platform_device *pdev,
> + struct mtk_scp_of_regs *of_regs)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev_of_node(dev);
> + struct platform_device *cpdev;
> + struct device_node *child;
> + const struct mtk_scp_of_data **cluster_of_data;
> + struct list_head *cluster;
Here you have a local `cluster` pointer.....
> + struct mtk_scp *scp, *temp;
> + int core_id, num_cores;
> + int ret;
> +
> + cluster_of_data = (const struct mtk_scp_of_data **)of_device_get_match_data(dev);
> +
> + for (num_cores = 0; cluster_of_data[num_cores]; num_cores++)
> + ;
> +
> + cluster = NULL;
(unrelated: please initialize cluster and core_id on the declaration, not here)
> + core_id = 0;
> + for_each_available_child_of_node(np, child) {
> + if (core_id >= num_cores) {
> + ret = -EINVAL;
> + dev_err(dev, "Not support core %d\n", core_id);
> + of_node_put(child);
> + goto init_fail;
> + }
> +
> + cpdev = of_find_device_by_node(child);
> + if (!cpdev) {
> + ret = -ENODEV;
> + dev_err(dev, "Not found platform device for core %d\n", core_id);
> + of_node_put(child);
> + goto init_fail;
> + }
> +
> + ret = scp_rproc_init(cpdev, of_regs, cluster_of_data[core_id], true);
> + if (ret) {
> + dev_err(dev, "Failed to initialize core %d rproc\n", core_id);
> + put_device(&cpdev->dev);
> + of_node_put(child);
> + goto init_fail;
> + }
> +
> + scp = platform_get_drvdata(cpdev);
> + put_device(&cpdev->dev);
> + if (core_id == 0) {
> + INIT_LIST_HEAD(&scp->cluster_cores);
...then here you initialize cluster_cores,
> + cluster = &scp->cluster_cores;
and assign to your local `cluster` pointer and even set it
> + platform_set_drvdata(pdev, cluster);
as platform drvdata.
> + }
> +
> + list_add_tail(&scp->elem, cluster);
Still using the local `cluster` pointer, which is `scp->cluster_cores`
> + scp->cluster = cluster;
...and here, `scp->cluster` effectively points to local `cluster`, which is
anyway `scp->cluster_cores`.
As far as I understand, `scp->cluster` is EITHER `scp->cluster_cores` or NULL,
hence the question: why do you need both scp->cluster and scp->cluster_cores,
if they're always pointing to the same list?
P.S.: I won't cut the rest of the patch so that the readers of this reply won't
have to click around to see the whole code; comments end here!
Regards,
Angelo
> +
> + of_node_put(child);
> + core_id++;
> + }
> +
> + list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
> + ret = rproc_add(scp->rproc);
> + if (ret)
> + goto add_fail;
> + }
> +
> + return 0;
> +
> +add_fail:
> + list_for_each_entry_continue(scp, cluster, elem) {
> + rproc_del(scp->rproc);
> + }
> +init_fail:
> + if (cluster) {
> + list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
> + list_del(&scp->elem);
> + scp_rproc_free(scp);
> + }
> + }
> + return ret;
> +}
> +
> +static void scp_cluster_exit(struct platform_device *pdev)
> +{
> + struct list_head *cluster = platform_get_drvdata(pdev);
> + struct platform_device *cpdev;
> + struct mtk_scp *scp, *temp;
> +
> + list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
> + list_del(&scp->elem);
> + cpdev = to_platform_device(scp->dev);
> + scp_rproc_exit(cpdev);
> + }
> +}
> +
> static int scp_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct device_node *core_node;
> struct resource *res;
> struct mtk_scp_of_regs scp_regs;
> int ret;
> @@ -975,21 +1095,43 @@ static int scp_probe(struct platform_device *pdev)
> scp_regs.l1tcm_phys = res->start;
> }
>
> - return scp_rproc_init(pdev, &scp_regs);
> + ret = devm_of_platform_populate(dev);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
> +
> + core_node = of_get_child_by_name(np, "scp");
> + of_node_put(core_node);
> +
> + if (!core_node) {
> + dev_info(dev, "single-core scp\n");
> +
> + ret = scp_rproc_init(pdev, &scp_regs, of_device_get_match_data(dev), false);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to initialize single-core scp\n");
> + } else {
> + dev_info(dev, "multi-core scp\n");
> +
> + ret = scp_cluster_init(pdev, &scp_regs);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to initialize scp cluster\n");
> + }
> +
> + return 0;
> }
>
> static int scp_remove(struct platform_device *pdev)
> {
> - struct mtk_scp *scp = platform_get_drvdata(pdev);
> - int i;
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct device_node *core_node;
>
> - rproc_del(scp->rproc);
> - scp_remove_rpmsg_subdev(scp);
> - scp_ipi_unregister(scp, SCP_IPI_INIT);
> - scp_unmap_memory_region(scp);
> - for (i = 0; i < SCP_IPI_MAX; i++)
> - mutex_destroy(&scp->ipi_desc[i].lock);
> - mutex_destroy(&scp->send_lock);
> + core_node = of_get_child_by_name(np, "scp");
> + of_node_put(core_node);
> +
> + if (!core_node)
> + scp_rproc_exit(pdev);
> + else
> + scp_cluster_exit(pdev);
>
> return 0;
> }
> @@ -1068,12 +1210,19 @@ static const struct mtk_scp_of_data mt8195_of_data_c1 = {
> .host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT,
> };
>
> +static const struct mtk_scp_of_data *mt8195_of_data_cores[] = {
> + &mt8195_of_data,
> + &mt8195_of_data_c1,
> + NULL
> +};
> +
> static const struct of_device_id mtk_scp_of_match[] = {
> { .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
> { .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
> { .compatible = "mediatek,mt8188-scp", .data = &mt8188_of_data },
> { .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
> { .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
> + { .compatible = "mediatek,mt8195-scp-dual", .data = &mt8195_of_data_cores },
> {},
> };
> MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 07/12] remoteproc: mediatek: Probe multi-core SCP
2023-02-15 12:29 ` AngeloGioacchino Del Regno
@ 2023-02-16 2:40 ` TingHan Shen (沈廷翰)
0 siblings, 0 replies; 17+ messages in thread
From: TingHan Shen (沈廷翰) @ 2023-02-16 2:40 UTC (permalink / raw)
To: mathieu.poirier@linaro.org, matthias.bgg@gmail.com,
angelogioacchino.delregno@collabora.com, andersson@kernel.org,
robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org
Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
Project_Global_Chrome_Upstream_Group
On Wed, 2023-02-15 at 13:29 +0100, AngeloGioacchino Del Regno wrote:
> Il 15/02/23 05:12, Tinghan Shen ha scritto:
> > The difference of single-core SCP and multi-core SCP device tree is
> > the presence of child device nodes described SCP cores. The SCP
> > driver populates the platform device and checks the child nodes
> > to identify whether it's a single-core SCP or a multi-core SCP.
> >
> > The resource structure of the multi-core SCP is a list of remoteproc
> > instances which is different to the single-core SCP. The corresponding
> > resource releasing action is based on the type of SCP.
> >
> > Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
> > ---
> > drivers/remoteproc/mtk_common.h | 4 +
> > drivers/remoteproc/mtk_scp.c | 179 +++++++++++++++++++++++++++++---
> > 2 files changed, 168 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
> > index 3778894c96f3..7821cb15d6fd 100644
> > --- a/drivers/remoteproc/mtk_common.h
> > +++ b/drivers/remoteproc/mtk_common.h
> > @@ -140,6 +140,10 @@ struct mtk_scp {
> > size_t dram_size;
> >
> > struct rproc_subdev *rpmsg_subdev;
> > +
> > + struct list_head elem;
> > + struct list_head cluster_cores;
> > + struct list_head *cluster;
>
> I don't understand why you need both `cluster_cores` and `cluster`... check below.
>
> > };
> >
> > /**
> > diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> > index 6270c388727a..6588e5acb159 100644
> > --- a/drivers/remoteproc/mtk_scp.c
> > +++ b/drivers/remoteproc/mtk_scp.c
> > @@ -862,7 +862,9 @@ static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
> > }
> >
> > static int scp_rproc_init(struct platform_device *pdev,
> > - struct mtk_scp_of_regs *of_regs)
> > + struct mtk_scp_of_regs *of_regs,
> > + const struct mtk_scp_of_data *of_data,
> > + bool is_multi_core)
> > {
> > struct device *dev = &pdev->dev;
> > struct device_node *np = dev->of_node;
> > @@ -883,7 +885,7 @@ static int scp_rproc_init(struct platform_device *pdev,
> > scp = (struct mtk_scp *)rproc->priv;
> > scp->rproc = rproc;
> > scp->dev = dev;
> > - scp->data = of_device_get_match_data(dev);
> > + scp->data = of_data;
> > platform_set_drvdata(pdev, scp);
> >
> > scp->reg_base = of_regs->reg_base;
> > @@ -932,9 +934,11 @@ static int scp_rproc_init(struct platform_device *pdev,
> > goto remove_subdev;
> > }
> >
> > - ret = rproc_add(rproc);
> > - if (ret)
> > - goto remove_subdev;
> > + if (!is_multi_core) {
> > + ret = rproc_add(rproc);
> > + if (ret)
> > + goto remove_subdev;
> > + }
> >
> > return 0;
> >
> > @@ -950,9 +954,125 @@ static int scp_rproc_init(struct platform_device *pdev,
> > return ret;
> > }
> >
> > +static void scp_rproc_free(struct mtk_scp *scp)
> > +{
> > + int i;
> > +
> > + scp_remove_rpmsg_subdev(scp);
> > + scp_ipi_unregister(scp, SCP_IPI_INIT);
> > + scp_unmap_memory_region(scp);
> > + for (i = 0; i < SCP_IPI_MAX; i++)
> > + mutex_destroy(&scp->ipi_desc[i].lock);
> > + mutex_destroy(&scp->send_lock);
> > +}
> > +
> > +static void scp_rproc_exit(struct platform_device *pdev)
> > +{
> > + struct mtk_scp *scp = platform_get_drvdata(pdev);
> > +
> > + rproc_del(scp->rproc);
> > + scp_rproc_free(scp);
> > +}
> > +
> > +static int scp_cluster_init(struct platform_device *pdev,
> > + struct mtk_scp_of_regs *of_regs)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct device_node *np = dev_of_node(dev);
> > + struct platform_device *cpdev;
> > + struct device_node *child;
> > + const struct mtk_scp_of_data **cluster_of_data;
> > + struct list_head *cluster;
>
> Here you have a local `cluster` pointer.....
>
> > + struct mtk_scp *scp, *temp;
> > + int core_id, num_cores;
> > + int ret;
> > +
> > + cluster_of_data = (const struct mtk_scp_of_data **)of_device_get_match_data(dev);
> > +
> > + for (num_cores = 0; cluster_of_data[num_cores]; num_cores++)
> > + ;
> > +
> > + cluster = NULL;
>
> (unrelated: please initialize cluster and core_id on the declaration, not here)
Ok. I'll update this in the next version.
>
> > + core_id = 0;
> > + for_each_available_child_of_node(np, child) {
> > + if (core_id >= num_cores) {
> > + ret = -EINVAL;
> > + dev_err(dev, "Not support core %d\n", core_id);
> > + of_node_put(child);
> > + goto init_fail;
> > + }
> > +
> > + cpdev = of_find_device_by_node(child);
> > + if (!cpdev) {
> > + ret = -ENODEV;
> > + dev_err(dev, "Not found platform device for core %d\n", core_id);
> > + of_node_put(child);
> > + goto init_fail;
> > + }
> > +
> > + ret = scp_rproc_init(cpdev, of_regs, cluster_of_data[core_id], true);
> > + if (ret) {
> > + dev_err(dev, "Failed to initialize core %d rproc\n", core_id);
> > + put_device(&cpdev->dev);
> > + of_node_put(child);
> > + goto init_fail;
> > + }
> > +
> > + scp = platform_get_drvdata(cpdev);
> > + put_device(&cpdev->dev);
> > + if (core_id == 0) {
> > + INIT_LIST_HEAD(&scp->cluster_cores);
>
> ...then here you initialize cluster_cores,
>
> > + cluster = &scp->cluster_cores;
>
> and assign to your local `cluster` pointer and even set it
>
> > + platform_set_drvdata(pdev, cluster);
>
> as platform drvdata.
>
> > + }
> > +
> > + list_add_tail(&scp->elem, cluster);
>
> Still using the local `cluster` pointer, which is `scp->cluster_cores`
>
> > + scp->cluster = cluster;
>
> ...and here, `scp->cluster` effectively points to local `cluster`, which is
> anyway `scp->cluster_cores`.
>
> As far as I understand, `scp->cluster` is EITHER `scp->cluster_cores` or NULL,
> hence the question: why do you need both scp->cluster and scp->cluster_cores,
> if they're always pointing to the same list?
>
> P.S.: I won't cut the rest of the patch so that the readers of this reply won't
> have to click around to see the whole code; comments end here!
>
> Regards,
> Angelo
It's because each core is represented by a mtk_scp structure and they are linked in the list of core 0.
After initialized, the data structure is depicted as below,
mtk_scp for core 0 mtk_scp for core 1
elem <----------------------elem (list)
|
V
cluster_cores <----┐ cluster_cores (not used)
Λ |
| |
*cluster └--------*cluster (pointer)
For the 2nd core scp, its cluster_cores is useless.
So, I add the *cluster to point back to the cores list in the 1st core's data structure.
Best regards,
TingHan
>
> > +
> > + of_node_put(child);
> > + core_id++;
> > + }
> > +
> > + list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
> > + ret = rproc_add(scp->rproc);
> > + if (ret)
> > + goto add_fail;
> > + }
> > +
> > + return 0;
> > +
> > +add_fail:
> > + list_for_each_entry_continue(scp, cluster, elem) {
> > + rproc_del(scp->rproc);
> > + }
> > +init_fail:
> > + if (cluster) {
> > + list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
> > + list_del(&scp->elem);
> > + scp_rproc_free(scp);
> > + }
> > + }
> > + return ret;
> > +}
> > +
> > +static void scp_cluster_exit(struct platform_device *pdev)
> > +{
> > + struct list_head *cluster = platform_get_drvdata(pdev);
> > + struct platform_device *cpdev;
> > + struct mtk_scp *scp, *temp;
> > +
> > + list_for_each_entry_safe_reverse(scp, temp, cluster, elem) {
> > + list_del(&scp->elem);
> > + cpdev = to_platform_device(scp->dev);
> > + scp_rproc_exit(cpdev);
> > + }
> > +}
> > +
> > static int scp_probe(struct platform_device *pdev)
> > {
> > struct device *dev = &pdev->dev;
> > + struct device_node *np = dev->of_node;
> > + struct device_node *core_node;
> > struct resource *res;
> > struct mtk_scp_of_regs scp_regs;
> > int ret;
> > @@ -975,21 +1095,43 @@ static int scp_probe(struct platform_device *pdev)
> > scp_regs.l1tcm_phys = res->start;
> > }
> >
> > - return scp_rproc_init(pdev, &scp_regs);
> > + ret = devm_of_platform_populate(dev);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
> > +
> > + core_node = of_get_child_by_name(np, "scp");
> > + of_node_put(core_node);
> > +
> > + if (!core_node) {
> > + dev_info(dev, "single-core scp\n");
> > +
> > + ret = scp_rproc_init(pdev, &scp_regs, of_device_get_match_data(dev), false);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "Failed to initialize single-core scp\n");
> > + } else {
> > + dev_info(dev, "multi-core scp\n");
> > +
> > + ret = scp_cluster_init(pdev, &scp_regs);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "Failed to initialize scp cluster\n");
> > + }
> > +
> > + return 0;
> > }
> >
> > static int scp_remove(struct platform_device *pdev)
> > {
> > - struct mtk_scp *scp = platform_get_drvdata(pdev);
> > - int i;
> > + struct device *dev = &pdev->dev;
> > + struct device_node *np = dev->of_node;
> > + struct device_node *core_node;
> >
> > - rproc_del(scp->rproc);
> > - scp_remove_rpmsg_subdev(scp);
> > - scp_ipi_unregister(scp, SCP_IPI_INIT);
> > - scp_unmap_memory_region(scp);
> > - for (i = 0; i < SCP_IPI_MAX; i++)
> > - mutex_destroy(&scp->ipi_desc[i].lock);
> > - mutex_destroy(&scp->send_lock);
> > + core_node = of_get_child_by_name(np, "scp");
> > + of_node_put(core_node);
> > +
> > + if (!core_node)
> > + scp_rproc_exit(pdev);
> > + else
> > + scp_cluster_exit(pdev);
> >
> > return 0;
> > }
> > @@ -1068,12 +1210,19 @@ static const struct mtk_scp_of_data mt8195_of_data_c1 = {
> > .host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT,
> > };
> >
> > +static const struct mtk_scp_of_data *mt8195_of_data_cores[] = {
> > + &mt8195_of_data,
> > + &mt8195_of_data_c1,
> > + NULL
> > +};
> > +
> > static const struct of_device_id mtk_scp_of_match[] = {
> > { .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
> > { .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
> > { .compatible = "mediatek,mt8188-scp", .data = &mt8188_of_data },
> > { .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
> > { .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
> > + { .compatible = "mediatek,mt8195-scp-dual", .data = &mt8195_of_data_cores },
> > {},
> > };
> > MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
>
>
--
Best regards,
TingHan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 04/12] remoteproc: mediatek: Add SCP core 1 register definitions
2023-02-15 4:12 ` [PATCH v7 04/12] remoteproc: mediatek: Add SCP core 1 register definitions Tinghan Shen
@ 2023-02-16 11:42 ` Matthias Brugger
0 siblings, 0 replies; 17+ messages in thread
From: Matthias Brugger @ 2023-02-16 11:42 UTC (permalink / raw)
To: Tinghan Shen, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, AngeloGioacchino Del Regno
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
On 15/02/2023 05:12, Tinghan Shen wrote:
> Add MT8195 SCP core 1 related register definitions.
>
> Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
In general I would say this patch should be squashed into 5/12, but please see
comments below.
> ---
> drivers/remoteproc/mtk_common.h | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
> index ea6fa1100a00..3778894c96f3 100644
> --- a/drivers/remoteproc/mtk_common.h
> +++ b/drivers/remoteproc/mtk_common.h
> @@ -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
> @@ -56,6 +57,26 @@
>
> #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
Should be part of 10/12 maybe?
> +#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
Should be part of 9/12 maybe
> +#define SCP_SRAM_REMAP_LOW 0
> +#define SCP_SRAM_REMAP_HIGH 1
> +#define SCP_SRAM_REMAP_OFFSET 2
> +#define SCP_SRAM_REMAP_SIZE 3
Never used.
> +
> #define SCP_FW_VER_LEN 32
> #define SCP_SHARE_BUFFER_SIZE 288
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v7 02/12] arm64: dts: mediatek: mt8183-kukui: Update the node name of SCP rpmsg subnode
2023-02-15 4:12 ` [PATCH v7 02/12] arm64: dts: mediatek: mt8183-kukui: Update the node name of SCP rpmsg subnode Tinghan Shen
@ 2023-02-16 11:47 ` Matthias Brugger
0 siblings, 0 replies; 17+ messages in thread
From: Matthias Brugger @ 2023-02-16 11:47 UTC (permalink / raw)
To: Tinghan Shen, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, AngeloGioacchino Del Regno
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
On 15/02/2023 05:12, Tinghan Shen wrote:
> Align the node name with the definition in SCP bindings.
>
> Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
> arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
> index fbe14b13051a..a259eb043de5 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
> @@ -810,7 +810,7 @@
> pinctrl-names = "default";
> pinctrl-0 = <&scp_pins>;
>
> - cros_ec {
> + cros-ec-rpmsg {
> compatible = "google,cros-ec-rpmsg";
There are more users of "google,cros-ec-rpmsg" which would nedd to be updated.
Regards,
Matthias
> mediatek,rpmsg-name = "cros-ec-rpmsg";
> };
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2023-02-16 11:47 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-15 4:12 [PATCH v7 00/12] Add support for MT8195 SCP 2nd core Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 01/12] dt-bindings: remoteproc: mediatek: Improve the rpmsg subnode definition Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 02/12] arm64: dts: mediatek: mt8183-kukui: Update the node name of SCP rpmsg subnode Tinghan Shen
2023-02-16 11:47 ` Matthias Brugger
2023-02-15 4:12 ` [PATCH v7 03/12] dt-bindings: remoteproc: mediatek: Support MT8195 dual-core SCP Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 04/12] remoteproc: mediatek: Add SCP core 1 register definitions Tinghan Shen
2023-02-16 11:42 ` Matthias Brugger
2023-02-15 4:12 ` [PATCH v7 05/12] remoteproc: mediatek: Add MT8195 SCP core 1 operations Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 06/12] remoteproc: mediatek: Extract remoteproc initialization flow Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 07/12] remoteproc: mediatek: Probe multi-core SCP Tinghan Shen
2023-02-15 12:29 ` AngeloGioacchino Del Regno
2023-02-16 2:40 ` TingHan Shen (沈廷翰)
2023-02-15 4:12 ` [PATCH v7 08/12] remoteproc: mediatek: Control SCP core 1 by rproc subdevice Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 09/12] remoteproc: mediatek: Setup MT8195 SCP core 1 SRAM offset Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 10/12] remoteproc: mediatek: Handle MT8195 SCP core 1 watchdog timeout Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 11/12] remoteproc: mediatek: Refine ipi handler error message Tinghan Shen
2023-02-15 4:12 ` [PATCH v7 12/12] arm64: dts: mediatek: mt8195: Add SCP 2nd core Tinghan Shen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).